Merge branch 'master' into blender2.8
authorJulian Eisel <eiseljulian@gmail.com>
Sun, 9 Apr 2017 20:51:38 +0000 (22:51 +0200)
committerJulian Eisel <eiseljulian@gmail.com>
Sun, 9 Apr 2017 20:51:38 +0000 (22:51 +0200)
865 files changed:
.gitmodules
CMakeLists.txt
GNUmakefile
build_files/build_environment/install_deps.sh
build_files/cmake/macros.cmake
build_files/cmake/platform/platform_apple.cmake
doc/python_api/examples/gpu.offscreen.1.py
doc/python_api/sphinx_doc_gen.py
intern/CMakeLists.txt
intern/cycles/blender/addon/ui.py
intern/gawain/CMakeLists.txt [new file with mode: 0644]
intern/gawain/gawain/attrib_binding.h [new file with mode: 0644]
intern/gawain/gawain/batch.h [new file with mode: 0644]
intern/gawain/gawain/buffer_id.h [new file with mode: 0644]
intern/gawain/gawain/common.h [new file with mode: 0644]
intern/gawain/gawain/element.h [new file with mode: 0644]
intern/gawain/gawain/imm_util.h [new file with mode: 0644]
intern/gawain/gawain/immediate.h [new file with mode: 0644]
intern/gawain/gawain/primitive.h [new file with mode: 0644]
intern/gawain/gawain/shader_interface.h [new file with mode: 0644]
intern/gawain/gawain/vertex_buffer.h [new file with mode: 0644]
intern/gawain/gawain/vertex_format.h [new file with mode: 0644]
intern/gawain/src/attrib_binding.c [new file with mode: 0644]
intern/gawain/src/batch.c [new file with mode: 0644]
intern/gawain/src/buffer_id.cpp [new file with mode: 0644]
intern/gawain/src/element.c [new file with mode: 0644]
intern/gawain/src/imm_util.c [new file with mode: 0644]
intern/gawain/src/immediate.c [new file with mode: 0644]
intern/gawain/src/primitive.c [new file with mode: 0644]
intern/gawain/src/shader_interface.c [new file with mode: 0644]
intern/gawain/src/vertex_buffer.c [new file with mode: 0644]
intern/gawain/src/vertex_format.c [new file with mode: 0644]
intern/ghost/intern/GHOST_ContextCGL.h
intern/ghost/intern/GHOST_ContextCGL.mm
intern/ghost/intern/GHOST_ContextGLX.cpp
intern/ghost/intern/GHOST_ContextWGL.cpp
intern/ghost/intern/GHOST_ContextWGL.h
intern/ghost/intern/GHOST_WindowCocoa.mm
intern/ghost/intern/GHOST_WindowWin32.cpp
intern/ghost/intern/GHOST_WindowX11.cpp
intern/ghost/test/CMakeLists.txt
intern/opencolorio/CMakeLists.txt
intern/opencolorio/gpu_shader_display_transform.glsl
intern/opencolorio/gpu_shader_display_transform_vertex.glsl [new file with mode: 0644]
intern/opencolorio/ocio_impl_glsl.cc
make.bat
release/darwin/blender.app/Contents/Info.plist
release/scripts/modules/bpy_extras/object_utils.py
release/scripts/presets/keyconfig/3dsmax.py
release/scripts/presets/keyconfig/maya.py
release/scripts/startup/bl_operators/clip.py
release/scripts/startup/bl_operators/freestyle.py
release/scripts/startup/bl_operators/object.py
release/scripts/startup/bl_operators/rigidbody.py
release/scripts/startup/bl_ui/__init__.py
release/scripts/startup/bl_ui/properties_collection.py [new file with mode: 0644]
release/scripts/startup/bl_ui/properties_data_camera.py
release/scripts/startup/bl_ui/properties_data_lamp.py
release/scripts/startup/bl_ui/properties_data_mesh.py
release/scripts/startup/bl_ui/properties_physics_cloth.py
release/scripts/startup/bl_ui/properties_render.py
release/scripts/startup/bl_ui/properties_render_layer.py
release/scripts/startup/bl_ui/space_info.py
release/scripts/startup/bl_ui/space_outliner.py
release/scripts/startup/bl_ui/space_view3d.py
release/scripts/templates_py/batch_export.py
release/scripts/templates_py/operator_modal_view3d_raycast.py
source/CMakeLists.txt
source/blender/CMakeLists.txt
source/blender/alembic/CMakeLists.txt
source/blender/alembic/intern/abc_exporter.cc
source/blender/alembic/intern/abc_exporter.h
source/blender/alembic/intern/abc_mesh.cc
source/blender/alembic/intern/abc_object.cc
source/blender/alembic/intern/abc_util.cc
source/blender/alembic/intern/abc_util.h
source/blender/alembic/intern/alembic_capi.cc
source/blender/blenfont/BLF_api.h
source/blender/blenfont/intern/blf.c
source/blender/blenfont/intern/blf_font.c
source/blender/blenfont/intern/blf_glyph.c
source/blender/blenfont/intern/blf_internal.h
source/blender/blenfont/intern/blf_internal_types.h
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_armature.h
source/blender/blenkernel/BKE_blender_version.h
source/blender/blenkernel/BKE_camera.h
source/blender/blenkernel/BKE_collection.h [new file with mode: 0644]
source/blender/blenkernel/BKE_collision.h
source/blender/blenkernel/BKE_context.h
source/blender/blenkernel/BKE_depsgraph.h
source/blender/blenkernel/BKE_group.h
source/blender/blenkernel/BKE_layer.h [new file with mode: 0644]
source/blender/blenkernel/BKE_mesh_render.h [new file with mode: 0644]
source/blender/blenkernel/BKE_modifier.h
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/BKE_outliner_treehash.h
source/blender/blenkernel/BKE_paint.h
source/blender/blenkernel/BKE_scene.h
source/blender/blenkernel/BKE_screen.h
source/blender/blenkernel/BKE_sequencer.h
source/blender/blenkernel/CMakeLists.txt
source/blender/blenkernel/depsgraph_private.h [deleted file]
source/blender/blenkernel/intern/CCGSubSurf.c
source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/armature_update.c
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/blender_copybuffer.c
source/blender/blenkernel/intern/blender_undo.c
source/blender/blenkernel/intern/cachefile.c
source/blender/blenkernel/intern/camera.c
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/collection.c [new file with mode: 0644]
source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/context.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/dynamicpaint.c
source/blender/blenkernel/intern/editderivedmesh.c
source/blender/blenkernel/intern/effect.c
source/blender/blenkernel/intern/group.c
source/blender/blenkernel/intern/icons.c
source/blender/blenkernel/intern/idprop.c
source/blender/blenkernel/intern/lattice.c
source/blender/blenkernel/intern/layer.c [new file with mode: 0644]
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/library_query.c
source/blender/blenkernel/intern/library_remap.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/mball.c
source/blender/blenkernel/intern/mball_tessellate.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenkernel/intern/mesh_render.c [new file with mode: 0644]
source/blender/blenkernel/intern/mesh_validate.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/object_dupli.c
source/blender/blenkernel/intern/object_update.c
source/blender/blenkernel/intern/outliner_treehash.c
source/blender/blenkernel/intern/paint.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/pbvh.c
source/blender/blenkernel/intern/pointcache.c
source/blender/blenkernel/intern/rigidbody.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/screen.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenkernel/intern/smoke.c
source/blender/blenkernel/intern/softbody.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/blenkernel/intern/text.c
source/blender/blenlib/BLI_ghash.h
source/blender/blenlib/BLI_iterator.h [new file with mode: 0644]
source/blender/blenlib/BLI_listbase.h
source/blender/blenlib/BLI_math_color.h
source/blender/blenlib/BLI_math_matrix.h
source/blender/blenlib/BLI_math_vector.h
source/blender/blenlib/CMakeLists.txt
source/blender/blenlib/intern/listbase.c
source/blender/blenlib/intern/math_color_inline.c
source/blender/blenlib/intern/math_matrix.c
source/blender/blenlib/intern/math_vector.c
source/blender/blenlib/intern/math_vector_inline.c
source/blender/blenlib/intern/scanfill_utils.c
source/blender/blenloader/CMakeLists.txt
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/readfile.h
source/blender/blenloader/intern/versioning_250.c
source/blender/blenloader/intern/versioning_270.c
source/blender/blenloader/intern/versioning_280.c [new file with mode: 0644]
source/blender/blenloader/intern/writefile.c
source/blender/bmesh/tools/bmesh_intersect.c
source/blender/collada/AnimationExporter.cpp
source/blender/collada/ArmatureImporter.cpp
source/blender/collada/CMakeLists.txt
source/blender/collada/DocumentImporter.cpp
source/blender/collada/EffectExporter.cpp
source/blender/collada/collada.cpp
source/blender/collada/collada.h
source/blender/collada/collada_utils.cpp
source/blender/depsgraph/CMakeLists.txt
source/blender/depsgraph/DEG_depsgraph.h
source/blender/depsgraph/DEG_depsgraph_build.h
source/blender/depsgraph/intern/builder/deg_builder.cc
source/blender/depsgraph/intern/builder/deg_builder.h
source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
source/blender/depsgraph/intern/builder/deg_builder_nodes.h
source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc [new file with mode: 0644]
source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.h
source/blender/depsgraph/intern/builder/deg_builder_relations_layer.cc [new file with mode: 0644]
source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc
source/blender/depsgraph/intern/depsgraph.cc
source/blender/depsgraph/intern/depsgraph.h
source/blender/depsgraph/intern/depsgraph_build.cc
source/blender/depsgraph/intern/depsgraph_eval.cc
source/blender/depsgraph/intern/depsgraph_tag.cc
source/blender/depsgraph/intern/depsgraph_type_defines.cc
source/blender/depsgraph/intern/depsgraph_types.h
source/blender/depsgraph/intern/eval/deg_eval.cc
source/blender/depsgraph/intern/eval/deg_eval.h
source/blender/depsgraph/intern/nodes/deg_node.cc
source/blender/depsgraph/intern/nodes/deg_node.h
source/blender/depsgraph/intern/nodes/deg_node_component.cc
source/blender/depsgraph/intern/nodes/deg_node_component.h
source/blender/depsgraph/util/deg_util_foreach.h
source/blender/depsgraph/util/deg_util_function.h
source/blender/draw/CMakeLists.txt [new file with mode: 0644]
source/blender/draw/DRW_engine.h [new file with mode: 0644]
source/blender/draw/engines/clay/clay.c [new file with mode: 0644]
source/blender/draw/engines/clay/clay.h [new file with mode: 0644]
source/blender/draw/engines/clay/shaders/clay_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/clay/shaders/clay_vert.glsl [new file with mode: 0644]
source/blender/draw/engines/clay/shaders/ssao_alchemy.glsl [new file with mode: 0644]
source/blender/draw/engines/clay/shaders/ssao_groundtruth.glsl [new file with mode: 0644]
source/blender/draw/engines/eevee/eevee.c [new file with mode: 0644]
source/blender/draw/engines/eevee/eevee.h [new file with mode: 0644]
source/blender/draw/engines/eevee/eevee_lights.c [new file with mode: 0644]
source/blender/draw/engines/eevee/eevee_lut.h [new file with mode: 0644]
source/blender/draw/engines/eevee/eevee_private.h [new file with mode: 0644]
source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl [new file with mode: 0644]
source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl [new file with mode: 0644]
source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl [new file with mode: 0644]
source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl [new file with mode: 0644]
source/blender/draw/engines/eevee/shaders/ltc_lib.glsl [new file with mode: 0644]
source/blender/draw/engines/eevee/shaders/tonemap_frag.glsl [new file with mode: 0644]
source/blender/draw/intern/DRW_render.h [new file with mode: 0644]
source/blender/draw/intern/draw_armature.c [new file with mode: 0644]
source/blender/draw/intern/draw_cache.c [new file with mode: 0644]
source/blender/draw/intern/draw_cache.h [new file with mode: 0644]
source/blender/draw/intern/draw_common.c [new file with mode: 0644]
source/blender/draw/intern/draw_common.h [new file with mode: 0644]
source/blender/draw/intern/draw_manager.c [new file with mode: 0644]
source/blender/draw/intern/draw_view.c [new file with mode: 0644]
source/blender/draw/intern/draw_view.h [new file with mode: 0644]
source/blender/draw/modes/draw_mode_engines.h [new file with mode: 0644]
source/blender/draw/modes/edit_armature_mode.c [new file with mode: 0644]
source/blender/draw/modes/edit_curve_mode.c [new file with mode: 0644]
source/blender/draw/modes/edit_lattice_mode.c [new file with mode: 0644]
source/blender/draw/modes/edit_mesh_mode.c [new file with mode: 0644]
source/blender/draw/modes/edit_metaball_mode.c [new file with mode: 0644]
source/blender/draw/modes/edit_surface_mode.c [new file with mode: 0644]
source/blender/draw/modes/edit_text_mode.c [new file with mode: 0644]
source/blender/draw/modes/object_mode.c [new file with mode: 0644]
source/blender/draw/modes/paint_texture_mode.c [new file with mode: 0644]
source/blender/draw/modes/paint_vertex_mode.c [new file with mode: 0644]
source/blender/draw/modes/paint_weight_mode.c [new file with mode: 0644]
source/blender/draw/modes/particle_mode.c [new file with mode: 0644]
source/blender/draw/modes/pose_mode.c [new file with mode: 0644]
source/blender/draw/modes/sculpt_mode.c [new file with mode: 0644]
source/blender/draw/modes/shaders/common_globals_lib.glsl [new file with mode: 0644]
source/blender/draw/modes/shaders/edit_normals_face_vert.glsl [new file with mode: 0644]
source/blender/draw/modes/shaders/edit_normals_geom.glsl [new file with mode: 0644]
source/blender/draw/modes/shaders/edit_normals_vert.glsl [new file with mode: 0644]
source/blender/draw/modes/shaders/edit_overlay_facedot_frag.glsl [new file with mode: 0644]
source/blender/draw/modes/shaders/edit_overlay_facedot_vert.glsl [new file with mode: 0644]
source/blender/draw/modes/shaders/edit_overlay_facefill_frag.glsl [new file with mode: 0644]
source/blender/draw/modes/shaders/edit_overlay_facefill_vert.glsl [new file with mode: 0644]
source/blender/draw/modes/shaders/edit_overlay_frag.glsl [new file with mode: 0644]
source/blender/draw/modes/shaders/edit_overlay_geom_edge.glsl [new file with mode: 0644]
source/blender/draw/modes/shaders/edit_overlay_geom_tri.glsl [new file with mode: 0644]
source/blender/draw/modes/shaders/edit_overlay_loosevert_vert.glsl [new file with mode: 0644]
source/blender/draw/modes/shaders/edit_overlay_mix_frag.glsl [new file with mode: 0644]
source/blender/draw/modes/shaders/edit_overlay_vert.glsl [new file with mode: 0644]
source/blender/draw/modes/shaders/object_grid_frag.glsl [new file with mode: 0644]
source/blender/draw/modes/shaders/object_grid_vert.glsl [new file with mode: 0644]
source/blender/draw/modes/shaders/object_outline_detect_frag.glsl [new file with mode: 0644]
source/blender/draw/modes/shaders/object_outline_expand_frag.glsl [new file with mode: 0644]
source/blender/draw/modes/shaders/object_outline_resolve_frag.glsl [new file with mode: 0644]
source/blender/editors/animation/anim_channels_defines.c
source/blender/editors/animation/anim_channels_edit.c
source/blender/editors/animation/anim_draw.c
source/blender/editors/animation/anim_filter.c
source/blender/editors/animation/anim_markers.c
source/blender/editors/animation/keyframes_draw.c
source/blender/editors/animation/keyframes_edit.c
source/blender/editors/armature/armature_intern.h
source/blender/editors/armature/armature_relations.c
source/blender/editors/armature/armature_select.c
source/blender/editors/armature/editarmature_sketch.c
source/blender/editors/armature/pose_select.c
source/blender/editors/armature/reeb.c
source/blender/editors/curve/editcurve.c
source/blender/editors/curve/editcurve_paint.c
source/blender/editors/curve/editfont.c
source/blender/editors/gpencil/drawgpencil.c
source/blender/editors/gpencil/gpencil_brush.c
source/blender/editors/gpencil/gpencil_convert.c
source/blender/editors/gpencil/gpencil_paint.c
source/blender/editors/gpencil/gpencil_utils.c
source/blender/editors/include/BIF_gl.h
source/blender/editors/include/BIF_glutil.h
source/blender/editors/include/ED_anim_api.h
source/blender/editors/include/ED_armature.h
source/blender/editors/include/ED_image.h
source/blender/editors/include/ED_keyframes_draw.h
source/blender/editors/include/ED_node.h
source/blender/editors/include/ED_object.h
source/blender/editors/include/ED_particle.h
source/blender/editors/include/ED_screen.h
source/blender/editors/include/ED_sculpt.h
source/blender/editors/include/ED_transform.h
source/blender/editors/include/ED_uvedit.h
source/blender/editors/include/ED_view3d.h
source/blender/editors/include/UI_interface.h
source/blender/editors/include/UI_interface_icons.h
source/blender/editors/include/UI_resources.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_align.c
source/blender/editors/interface/interface_draw.c
source/blender/editors/interface/interface_eyedropper.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_icons.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_ops.c
source/blender/editors/interface/interface_panel.c
source/blender/editors/interface/interface_regions.c
source/blender/editors/interface/interface_style.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/interface/resources.c
source/blender/editors/interface/view2d.c
source/blender/editors/io/io_collada.c
source/blender/editors/mask/mask_draw.c
source/blender/editors/mesh/editmesh_knife.c
source/blender/editors/mesh/editmesh_loopcut.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/mesh/mesh_data.c
source/blender/editors/mesh/mesh_navmesh.c
source/blender/editors/mesh/meshtools.c
source/blender/editors/object/object_add.c
source/blender/editors/object/object_bake.c
source/blender/editors/object/object_constraint.c
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_group.c
source/blender/editors/object/object_hook.c
source/blender/editors/object/object_intern.h
source/blender/editors/object/object_modifier.c
source/blender/editors/object/object_ops.c
source/blender/editors/object/object_relations.c
source/blender/editors/object/object_select.c
source/blender/editors/object/object_vgroup.c
source/blender/editors/physics/particle_edit.c
source/blender/editors/physics/particle_object.c
source/blender/editors/physics/physics_fluid.c
source/blender/editors/physics/physics_ops.c
source/blender/editors/physics/physics_pointcache.c
source/blender/editors/physics/rigidbody_constraint.c
source/blender/editors/physics/rigidbody_object.c
source/blender/editors/render/render_internal.c
source/blender/editors/render/render_opengl.c
source/blender/editors/render/render_preview.c
source/blender/editors/render/render_shading.c
source/blender/editors/render/render_update.c
source/blender/editors/screen/CMakeLists.txt
source/blender/editors/screen/area.c
source/blender/editors/screen/glutil.c
source/blender/editors/screen/screen_context.c
source/blender/editors/screen/screen_draw.c [new file with mode: 0644]
source/blender/editors/screen/screen_edit.c
source/blender/editors/screen/screen_intern.h
source/blender/editors/screen/screen_ops.c
source/blender/editors/screen/screendump.c
source/blender/editors/sculpt_paint/paint_cursor.c
source/blender/editors/sculpt_paint/paint_hide.c
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/sculpt_paint/paint_image_proj.c
source/blender/editors/sculpt_paint/paint_intern.h
source/blender/editors/sculpt_paint/paint_mask.c
source/blender/editors/sculpt_paint/paint_stroke.c
source/blender/editors/sculpt_paint/paint_utils.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/editors/sculpt_paint/sculpt_uv.c
source/blender/editors/sound/sound_ops.c
source/blender/editors/space_action/action_draw.c
source/blender/editors/space_api/spacetypes.c
source/blender/editors/space_buttons/buttons_context.c
source/blender/editors/space_buttons/space_buttons.c
source/blender/editors/space_clip/clip_dopesheet_draw.c
source/blender/editors/space_clip/clip_draw.c
source/blender/editors/space_clip/clip_graph_draw.c
source/blender/editors/space_clip/clip_intern.h
source/blender/editors/space_clip/clip_utils.c
source/blender/editors/space_clip/space_clip.c
source/blender/editors/space_clip/tracking_ops_orient.c
source/blender/editors/space_console/console_draw.c
source/blender/editors/space_file/file_draw.c
source/blender/editors/space_graph/graph_draw.c
source/blender/editors/space_graph/space_graph.c
source/blender/editors/space_image/CMakeLists.txt
source/blender/editors/space_image/image_draw.c
source/blender/editors/space_image/image_edit.c
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_image/space_image.c
source/blender/editors/space_info/info_stats.c
source/blender/editors/space_info/textview.c
source/blender/editors/space_logic/logic_window.c
source/blender/editors/space_nla/nla_channels.c
source/blender/editors/space_nla/nla_draw.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/node_draw.c
source/blender/editors/space_node/node_intern.h
source/blender/editors/space_outliner/CMakeLists.txt
source/blender/editors/space_outliner/outliner_collections.c [new file with mode: 0644]
source/blender/editors/space_outliner/outliner_draw.c
source/blender/editors/space_outliner/outliner_edit.c
source/blender/editors/space_outliner/outliner_intern.h
source/blender/editors/space_outliner/outliner_ops.c
source/blender/editors/space_outliner/outliner_select.c
source/blender/editors/space_outliner/outliner_tools.c
source/blender/editors/space_outliner/outliner_tree.c
source/blender/editors/space_outliner/outliner_utils.c [new file with mode: 0644]
source/blender/editors/space_outliner/space_outliner.c
source/blender/editors/space_sequencer/sequencer_draw.c
source/blender/editors/space_sequencer/sequencer_edit.c
source/blender/editors/space_sequencer/sequencer_intern.h
source/blender/editors/space_text/text_draw.c
source/blender/editors/space_time/space_time.c
source/blender/editors/space_view3d/CMakeLists.txt
source/blender/editors/space_view3d/drawanimviz.c
source/blender/editors/space_view3d/drawarmature.c
source/blender/editors/space_view3d/drawmesh.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/drawsimdebug.c
source/blender/editors/space_view3d/drawvolume.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/space_view3d/view3d_buttons.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/space_view3d/view3d_draw_legacy.c [new file with mode: 0644]
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_fly.c
source/blender/editors/space_view3d/view3d_header.c
source/blender/editors/space_view3d/view3d_intern.h
source/blender/editors/space_view3d/view3d_ops.c
source/blender/editors/space_view3d/view3d_project.c
source/blender/editors/space_view3d/view3d_ruler.c
source/blender/editors/space_view3d/view3d_select.c
source/blender/editors/space_view3d/view3d_view.c
source/blender/editors/space_view3d/view3d_walk.c
source/blender/editors/transform/CMakeLists.txt
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform.h
source/blender/editors/transform/transform_constraints.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c
source/blender/editors/transform/transform_manipulator.c
source/blender/editors/transform/transform_orientations.c
source/blender/editors/transform/transform_snap.c
source/blender/editors/transform/transform_snap_object.c
source/blender/editors/util/ed_util.c
source/blender/editors/util/undo.c
source/blender/editors/uvedit/CMakeLists.txt
source/blender/editors/uvedit/uvedit_draw.c
source/blender/editors/uvedit/uvedit_smart_stitch.c
source/blender/freestyle/CMakeLists.txt
source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp
source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h
source/blender/gpu/CMakeLists.txt
source/blender/gpu/GPU_basic_shader.h
source/blender/gpu/GPU_batch.h [new file with mode: 0644]
source/blender/gpu/GPU_buffers.h
source/blender/gpu/GPU_debug.h
source/blender/gpu/GPU_draw.h
source/blender/gpu/GPU_extensions.h
source/blender/gpu/GPU_framebuffer.h
source/blender/gpu/GPU_glew.h
source/blender/gpu/GPU_immediate.h [new file with mode: 0644]
source/blender/gpu/GPU_immediate_util.h [new file with mode: 0644]
source/blender/gpu/GPU_lamp.h [new file with mode: 0644]
source/blender/gpu/GPU_legacy_stubs.h [new file with mode: 0644]
source/blender/gpu/GPU_material.h
source/blender/gpu/GPU_matrix.h [new file with mode: 0644]
source/blender/gpu/GPU_shader.h
source/blender/gpu/GPU_texture.h
source/blender/gpu/GPU_uniformbuffer.h [new file with mode: 0644]
source/blender/gpu/GPU_viewport.h [new file with mode: 0644]
source/blender/gpu/intern/gpu_basic_shader.c
source/blender/gpu/intern/gpu_batch.c [new file with mode: 0644]
source/blender/gpu/intern/gpu_buffers.c
source/blender/gpu/intern/gpu_codegen.c
source/blender/gpu/intern/gpu_compositing.c
source/blender/gpu/intern/gpu_debug.c
source/blender/gpu/intern/gpu_draw.c
source/blender/gpu/intern/gpu_extensions.c
source/blender/gpu/intern/gpu_framebuffer.c
source/blender/gpu/intern/gpu_immediate.c [new file with mode: 0644]
source/blender/gpu/intern/gpu_immediate_util.c [new file with mode: 0644]
source/blender/gpu/intern/gpu_init_exit.c
source/blender/gpu/intern/gpu_lamp.c [new file with mode: 0644]
source/blender/gpu/intern/gpu_lamp_private.h [new file with mode: 0644]
source/blender/gpu/intern/gpu_material.c
source/blender/gpu/intern/gpu_matrix.c [new file with mode: 0644]
source/blender/gpu/intern/gpu_select.c
source/blender/gpu/intern/gpu_select_pick.c
source/blender/gpu/intern/gpu_select_sample_query.c
source/blender/gpu/intern/gpu_shader.c
source/blender/gpu/intern/gpu_shader_private.h [new file with mode: 0644]
source/blender/gpu/intern/gpu_texture.c
source/blender/gpu/intern/gpu_uniformbuffer.c [new file with mode: 0644]
source/blender/gpu/intern/gpu_viewport.c [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_2D_flat_color_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_2D_image_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_2D_line_dashed_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_2D_line_dashed_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_aa_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_outline_aa_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_2D_point_varying_size_varying_color_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_2D_smooth_color_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_2D_smooth_color_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_2D_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_3D_clipped_uniform_color_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_3D_flat_color_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_3D_groundline_geom.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_3D_groundpoint_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_3D_image_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_3D_passthrough_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_3D_point_fixed_size_varying_color_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_aa_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_outline_aa_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_3D_point_varying_size_varying_color_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_3D_point_varying_size_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_3D_smooth_color_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_3D_smooth_color_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_3D_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_basic_frag.glsl
source/blender/gpu/shaders/gpu_shader_basic_geom.glsl
source/blender/gpu/shaders/gpu_shader_basic_vert.glsl
source/blender/gpu/shaders/gpu_shader_checker_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_depth_only_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_diag_stripes_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_edges_front_back_ortho_vert.glsl [new file with mode: 0755]
source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_geom.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_legacy_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_vert.glsl [new file with mode: 0755]
source/blender/gpu/shaders/gpu_shader_edges_overlay_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_edges_overlay_geom.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_edges_overlay_simple_geom.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_edges_overlay_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_fire_frag.glsl
source/blender/gpu/shaders/gpu_shader_flat_color_alpha_test_0_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_flat_color_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_fullscreen_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl
source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl
source/blender/gpu/shaders/gpu_shader_fx_dof_hq_geo.glsl
source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl
source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl
source/blender/gpu/shaders/gpu_shader_fx_lib.glsl
source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl
source/blender/gpu/shaders/gpu_shader_fx_vert.glsl [deleted file]
source/blender/gpu/shaders/gpu_shader_geometry.glsl
source/blender/gpu/shaders/gpu_shader_image_color_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_image_depth_linear_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_image_mask_uniform_color_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_image_modulate_alpha_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_image_rect_modulate_alpha_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_image_shuffle_color_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_instance_camera_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_instance_distance_line_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_geom.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_axis_name_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_instance_screenspace_variying_color_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_instance_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_keyframe_diamond_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_material.glsl
source/blender/gpu/shaders/gpu_shader_point_uniform_color_aa_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_point_uniform_color_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_point_uniform_color_outline_aa_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_point_varying_color_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_point_varying_color_outline_aa_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl
source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl
source/blender/gpu/shaders/gpu_shader_simple_lighting_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl
source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl
source/blender/gpu/shaders/gpu_shader_text_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_text_vert.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl [new file with mode: 0644]
source/blender/gpu/shaders/gpu_shader_vertex.glsl
source/blender/gpu/shaders/gpu_shader_vertex_world.glsl
source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl
source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl
source/blender/makesdna/DNA_ID.h
source/blender/makesdna/DNA_action_types.h
source/blender/makesdna/DNA_camera_types.h
source/blender/makesdna/DNA_gpencil_types.h
source/blender/makesdna/DNA_layer_types.h [new file with mode: 0644]
source/blender/makesdna/DNA_manipulator_types.h [new file with mode: 0644]
source/blender/makesdna/DNA_material_types.h
source/blender/makesdna/DNA_mesh_types.h
source/blender/makesdna/DNA_object_types.h
source/blender/makesdna/DNA_outliner_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_screen_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesdna/DNA_view3d_types.h
source/blender/makesdna/DNA_world_types.h
source/blender/makesdna/intern/makesdna.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/RNA_enum_types.h
source/blender/makesrna/intern/CMakeLists.txt
source/blender/makesrna/intern/rna_brush.c
source/blender/makesrna/intern/rna_context.c
source/blender/makesrna/intern/rna_group.c
source/blender/makesrna/intern/rna_image_api.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_object_api.c
source/blender/makesrna/intern/rna_object_force.c
source/blender/makesrna/intern/rna_render.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_scene_api.c
source/blender/makesrna/intern/rna_sculpt_paint.c
source/blender/makesrna/intern/rna_space.c
source/blender/makesrna/intern/rna_texture.c
source/blender/makesrna/intern/rna_ui_api.c
source/blender/modifiers/CMakeLists.txt
source/blender/modifiers/intern/MOD_armature.c
source/blender/modifiers/intern/MOD_array.c
source/blender/modifiers/intern/MOD_bevel.c
source/blender/modifiers/intern/MOD_boolean.c
source/blender/modifiers/intern/MOD_build.c
source/blender/modifiers/intern/MOD_cast.c
source/blender/modifiers/intern/MOD_cloth.c
source/blender/modifiers/intern/MOD_collision.c
source/blender/modifiers/intern/MOD_correctivesmooth.c
source/blender/modifiers/intern/MOD_curve.c
source/blender/modifiers/intern/MOD_datatransfer.c
source/blender/modifiers/intern/MOD_decimate.c
source/blender/modifiers/intern/MOD_displace.c
source/blender/modifiers/intern/MOD_dynamicpaint.c
source/blender/modifiers/intern/MOD_edgesplit.c
source/blender/modifiers/intern/MOD_explode.c
source/blender/modifiers/intern/MOD_fluidsim.c
source/blender/modifiers/intern/MOD_hook.c
source/blender/modifiers/intern/MOD_laplaciandeform.c
source/blender/modifiers/intern/MOD_laplaciansmooth.c
source/blender/modifiers/intern/MOD_lattice.c
source/blender/modifiers/intern/MOD_mask.c
source/blender/modifiers/intern/MOD_meshcache.c
source/blender/modifiers/intern/MOD_meshdeform.c
source/blender/modifiers/intern/MOD_meshsequencecache.c
source/blender/modifiers/intern/MOD_mirror.c
source/blender/modifiers/intern/MOD_multires.c
source/blender/modifiers/intern/MOD_none.c
source/blender/modifiers/intern/MOD_normal_edit.c
source/blender/modifiers/intern/MOD_ocean.c
source/blender/modifiers/intern/MOD_particleinstance.c
source/blender/modifiers/intern/MOD_particlesystem.c
source/blender/modifiers/intern/MOD_remesh.c
source/blender/modifiers/intern/MOD_screw.c
source/blender/modifiers/intern/MOD_shapekey.c
source/blender/modifiers/intern/MOD_shrinkwrap.c
source/blender/modifiers/intern/MOD_simpledeform.c
source/blender/modifiers/intern/MOD_skin.c
source/blender/modifiers/intern/MOD_smoke.c
source/blender/modifiers/intern/MOD_smooth.c
source/blender/modifiers/intern/MOD_softbody.c
source/blender/modifiers/intern/MOD_solidify.c
source/blender/modifiers/intern/MOD_subsurf.c
source/blender/modifiers/intern/MOD_surface.c
source/blender/modifiers/intern/MOD_surfacedeform.c
source/blender/modifiers/intern/MOD_triangulate.c
source/blender/modifiers/intern/MOD_uvproject.c
source/blender/modifiers/intern/MOD_uvwarp.c
source/blender/modifiers/intern/MOD_warp.c
source/blender/modifiers/intern/MOD_wave.c
source/blender/modifiers/intern/MOD_weightvgedit.c
source/blender/modifiers/intern/MOD_weightvgmix.c
source/blender/modifiers/intern/MOD_weightvgproximity.c
source/blender/modifiers/intern/MOD_wireframe.c
source/blender/nodes/shader/node_shader_tree.c
source/blender/nodes/shader/node_shader_util.h
source/blender/nodes/texture/node_texture_tree.c
source/blender/python/bmesh/CMakeLists.txt
source/blender/python/bmesh/bmesh_py_types.c
source/blender/python/generic/bgl.c
source/blender/python/generic/blf_py_api.c
source/blender/python/intern/gpu_offscreen.c
source/blender/render/CMakeLists.txt
source/blender/render/extern/include/RE_engine.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/envmap.c
source/blender/render/intern/source/external_engine.c
source/blender/render/intern/source/multires_bake.c
source/blender/render/intern/source/pipeline.c
source/blender/windowmanager/CMakeLists.txt
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm_dragdrop.c
source/blender/windowmanager/intern/wm_draw.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_files.c
source/blender/windowmanager/intern/wm_files_link.c
source/blender/windowmanager/intern/wm_gesture.c
source/blender/windowmanager/intern/wm_init_exit.c
source/blender/windowmanager/intern/wm_operators.c
source/blender/windowmanager/intern/wm_playanim.c
source/blender/windowmanager/intern/wm_stereo.c
source/blender/windowmanager/intern/wm_subwindow.c
source/blender/windowmanager/intern/wm_window.c
source/blender/windowmanager/manipulators/WM_manipulator_api.h [new file with mode: 0644]
source/blender/windowmanager/manipulators/WM_manipulator_library.h [new file with mode: 0644]
source/blender/windowmanager/manipulators/WM_manipulator_types.h [new file with mode: 0644]
source/blender/windowmanager/manipulators/intern/manipulator_library/arrow2d_manipulator.c [new file with mode: 0644]
source/blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c [new file with mode: 0644]
source/blender/windowmanager/manipulators/intern/manipulator_library/cage_manipulator.c [new file with mode: 0644]
source/blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c [new file with mode: 0644]
source/blender/windowmanager/manipulators/intern/manipulator_library/geom_arrow_manipulator.c [new file with mode: 0644]
source/blender/windowmanager/manipulators/intern/manipulator_library/geom_cube_manipulator.c [new file with mode: 0644]
source/blender/windowmanager/manipulators/intern/manipulator_library/geom_dial_manipulator.c [new file with mode: 0644]
source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_geometry.h [new file with mode: 0644]
source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_library_intern.h [new file with mode: 0644]
source/blender/windowmanager/manipulators/intern/manipulator_library/manipulator_library_utils.c [new file with mode: 0644]
source/blender/windowmanager/manipulators/intern/manipulator_library/primitive_manipulator.c [new file with mode: 0644]
source/blender/windowmanager/manipulators/intern/wm_manipulator.c [new file with mode: 0644]
source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h [new file with mode: 0644]
source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c [new file with mode: 0644]
source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c [new file with mode: 0644]
source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h [new file with mode: 0644]
source/blender/windowmanager/wm.h
source/blender/windowmanager/wm_draw.h
source/blender/windowmanager/wm_event_system.h
source/blender/windowmanager/wm_event_types.h
source/blender/windowmanager/wm_window.h
source/blenderplayer/CMakeLists.txt
source/blenderplayer/bad_level_call_stubs/CMakeLists.txt
source/blenderplayer/bad_level_call_stubs/stubs.c
source/creator/creator.c
source/creator/creator_args.c
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/GamePlayer/ghost/CMakeLists.txt
source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
source/gameengine/Ketsji/KX_Camera.cpp
source/gameengine/Ketsji/KX_Dome.cpp
source/gameengine/Ketsji/KX_Light.cpp
source/gameengine/Ketsji/KX_Light.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp
tests/python/CMakeLists.txt
tests/python/render_layer/CMakeLists.txt [new file with mode: 0644]
tests/python/render_layer/render_layer_common.py [new file with mode: 0644]
tests/python/render_layer/test_active_collection.py [new file with mode: 0644]
tests/python/render_layer/test_collection_rename.py [new file with mode: 0644]
tests/python/render_layer/test_evaluation_selectability_a.py [new file with mode: 0644]
tests/python/render_layer/test_evaluation_selectability_b.py [new file with mode: 0644]
tests/python/render_layer/test_evaluation_selectability_c.py [new file with mode: 0644]
tests/python/render_layer/test_evaluation_selectability_d.py [new file with mode: 0644]
tests/python/render_layer/test_evaluation_selectability_e.py [new file with mode: 0644]
tests/python/render_layer/test_evaluation_selectability_f.py [new file with mode: 0644]
tests/python/render_layer/test_evaluation_visibility_a.py [new file with mode: 0644]
tests/python/render_layer/test_evaluation_visibility_b.py [new file with mode: 0644]
tests/python/render_layer/test_evaluation_visibility_c.py [new file with mode: 0644]
tests/python/render_layer/test_evaluation_visibility_d.py [new file with mode: 0644]
tests/python/render_layer/test_evaluation_visibility_e.py [new file with mode: 0644]
tests/python/render_layer/test_evaluation_visibility_f.py [new file with mode: 0644]
tests/python/render_layer/test_evaluation_visibility_g.py [new file with mode: 0644]
tests/python/render_layer/test_evaluation_visibility_h.py [new file with mode: 0644]
tests/python/render_layer/test_evaluation_visibility_i.py [new file with mode: 0644]
tests/python/render_layer/test_layer_linking.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_layer_collection_a.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_layer_collection_b.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_layer_collection_c.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_layer_collection_d.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_layer_collection_e.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_layer_collection_f.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_layer_collection_g.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_layer_collection_h.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_layer_collection_i.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_layer_collection_j.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_layer_collection_k.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_layer_collection_l.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_scene_collection_a.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_scene_collection_b.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_scene_collection_c.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_scene_collection_d.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_scene_collection_e.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_scene_collection_f.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_scene_collection_g.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_scene_collection_h.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_scene_collection_i.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_scene_collection_sync_a.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_scene_collection_sync_b.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_scene_collection_sync_c.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_scene_collection_sync_d.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_scene_collection_sync_e.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_scene_collection_sync_f.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_scene_collection_sync_g.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_scene_collection_sync_h.py [new file with mode: 0644]
tests/python/render_layer/test_move_above_below_scene_collection_sync_i.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_layer_collection_a.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_layer_collection_b.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_layer_collection_c.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_layer_collection_d.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_layer_collection_e.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_layer_collection_f.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_layer_collection_g.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_layer_collection_h.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_layer_collection_i.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_layer_collection_j.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_a.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_b.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_c.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_d.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_e.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_f.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_g.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_h.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_i.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_j.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_k.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_l.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_sync_a.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_sync_b.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_sync_c.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_sync_d.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_sync_e.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_sync_f.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_sync_g.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_sync_h.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_sync_i.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_sync_j.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_sync_k.py [new file with mode: 0644]
tests/python/render_layer/test_move_into_scene_collection_sync_l.py [new file with mode: 0644]
tests/python/render_layer/test_object_add_cylinder.py [new file with mode: 0644]
tests/python/render_layer/test_object_add_empty.py [new file with mode: 0644]
tests/python/render_layer/test_object_add_no_collection_cylinder.py [new file with mode: 0644]
tests/python/render_layer/test_object_add_no_collection_empty.py [new file with mode: 0644]
tests/python/render_layer/test_object_add_no_collection_torus.py [new file with mode: 0644]
tests/python/render_layer/test_object_add_torus.py [new file with mode: 0644]
tests/python/render_layer/test_object_copy.py [new file with mode: 0644]
tests/python/render_layer/test_object_delete_a.py [new file with mode: 0644]
tests/python/render_layer/test_object_delete_b.py [new file with mode: 0644]
tests/python/render_layer/test_object_link_a.py [new file with mode: 0644]
tests/python/render_layer/test_object_link_b.py [new file with mode: 0644]
tests/python/render_layer/test_object_link_c.py [new file with mode: 0644]
tests/python/render_layer/test_operator_context.py [new file with mode: 0644]
tests/python/render_layer/test_scene_copy_a.py [new file with mode: 0644]
tests/python/render_layer/test_scene_copy_b.py [new file with mode: 0644]
tests/python/render_layer/test_scene_copy_c.py [new file with mode: 0644]
tests/python/render_layer/test_scene_copy_d.py [new file with mode: 0644]
tests/python/render_layer/test_scene_write_read.py [new file with mode: 0644]
tests/python/render_layer/test_syncing.py [new file with mode: 0644]

index 2f52bfce372b882b593e2efe06516acfdf769eab..11ce247b455ca380ccb110c16444d3b51388adb6 100644 (file)
@@ -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
index 3a91e1b655a00771919433df32ffcd77d7cee666..7b05bcb11bb0ba4e3a394b9667f1e17e2a008a10 100644 (file)
@@ -242,6 +242,10 @@ 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 Intel compatibility)" ON)
+
+option(WITH_LEGACY_OPENGL  "Enable build of legacy OpenGL" ON)
+
 # Compositor
 option(WITH_COMPOSITOR         "Enable the tile based nodal compositor" ON)
 
@@ -472,12 +476,6 @@ mark_as_advanced(
        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)
@@ -498,11 +496,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)
@@ -1057,11 +1054,6 @@ 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()
@@ -1289,9 +1281,7 @@ else()
 
 endif()
 
-if(NOT WITH_GLU)
-       list(APPEND GL_DEFINITIONS -DGLEW_NO_GLU)
-endif()
+list(APPEND GL_DEFINITIONS -DGLEW_NO_GLU)
 
 #-----------------------------------------------------------------------------
 # Configure Bullet
@@ -1799,7 +1789,6 @@ 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)
index 86964e68873e08789c7294bff68d122a53433560..7ee011911f82c96fc6b385341bf1c706ee5597de 100644 (file)
@@ -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
 
 
 # -----------------------------------------------------------------------------
index 7aaa37285c194b3a1e78ee239ee8b360d9c1eaef..479585656d1cd0f53d9d153aa0e380a00d969449 100755 (executable)
@@ -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.2"
 PYTHON_VERSION_MIN="3.5"
@@ -499,9 +494,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
     ;;
@@ -793,7 +785,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.
index b7f6649e5070e5fe0b81e2756bee1365ed1b8b39..27728917af50dcce39deb714883a2dc0f06d8700 100644 (file)
@@ -598,6 +598,8 @@ function(SETUP_BLENDER_SORTED_LIBS)
                bf_alembic
                bf_bmesh
                bf_gpu
+               bf_draw
+               bf_intern_gawain
                bf_blenloader
                bf_blenkernel
                bf_physics
index 04485e31d981ebc222ca5bb91f0e4ac9a09294a8..f2a6aee7a5960e0266dc17e1004b9bc4eb26a2db 100644 (file)
@@ -23,6 +23,8 @@
 
 # Libraries configuration for Apple.
 
+set(MACOSX_DEPLOYMENT_TARGET "10.9")
+
 if(NOT DEFINED LIBDIR)
        if(WITH_CXX11)
                set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin)
index 75ddf804e7078143e143c62f674702627d4af5a0..ff1a7ad7cced21c34b19b4eadc731171057fac8d 100644 (file)
@@ -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,
index 47bb323e57409edf54140a46a782f5910f7ec0f3..0316b6cd23eb943207b02a966ea506dbb1e6ed4c 100644 (file)
@@ -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),
index bfe230250ae7db42cc40cb5188f0a3d597b4ca24..af3b9296077143af1a7023585270d5aa310c74c3 100644 (file)
@@ -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)
index 2b50d272be81dc4dbf76aa0ad01c597e31bd23ce..39d918bd70f34080efe13ef8a9f0c85f936d4b92 100644 (file)
@@ -1589,6 +1589,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)
diff --git a/intern/gawain/CMakeLists.txt b/intern/gawain/CMakeLists.txt
new file mode 100644 (file)
index 0000000..99adab8
--- /dev/null
@@ -0,0 +1,34 @@
+
+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
+)
+
+# remove this when we switch to core profile
+add_definitions(-DWITH_GL_PROFILE_COMPAT)
+
+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 (file)
index 0000000..9e2431c
--- /dev/null
@@ -0,0 +1,24 @@
+
+// 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 "vertex_format.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;
+
+void clear_AttribBinding(AttribBinding*);
+
+void get_attrib_locations(const VertexFormat*, AttribBinding*, GLuint program);
+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 (file)
index 0000000..532c45a
--- /dev/null
@@ -0,0 +1,111 @@
+
+// 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"
+
+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;
+} 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);
+// 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]);
+
+
+
+
+
+
+#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
diff --git a/intern/gawain/gawain/buffer_id.h b/intern/gawain/gawain/buffer_id.h
new file mode 100644 (file)
index 0000000..3f67458
--- /dev/null
@@ -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 (file)
index 0000000..b734da4
--- /dev/null
@@ -0,0 +1,36 @@
+
+// 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
+
+#define TRUST_NO_ONE !defined(NDEBUG)
+// strict error checking, enabled for debug builds during early development
+
+#include <GL/glew.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#if TRUST_NO_ONE
+  #include <assert.h>
+#endif
+
+#define APPLE_LEGACY (defined(__APPLE__) && defined(WITH_GL_PROFILE_COMPAT))
+
+#if APPLE_LEGACY
+  #undef glGenVertexArrays
+  #define glGenVertexArrays glGenVertexArraysAPPLE
+
+  #undef glDeleteVertexArrays
+  #define glDeleteVertexArrays glDeleteVertexArraysAPPLE
+
+  #undef glBindVertexArray
+  #define glBindVertexArray glBindVertexArrayAPPLE
+#endif
diff --git a/intern/gawain/gawain/element.h b/intern/gawain/gawain/element.h
new file mode 100644 (file)
index 0000000..f22d7c0
--- /dev/null
@@ -0,0 +1,64 @@
+
+// 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_UNSIGNED_BYTE, // GL has this, Vulkan does not
+       INDEX_U16 = GL_UNSIGNED_SHORT,
+       INDEX_U32 = GL_UNSIGNED_INT
+} IndexType;
+
+typedef struct {
+       unsigned index_ct;
+#if TRACK_INDEX_RANGE
+       IndexType 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*);
diff --git a/intern/gawain/gawain/imm_util.h b/intern/gawain/gawain/imm_util.h
new file mode 100644 (file)
index 0000000..730bd7c
--- /dev/null
@@ -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 (file)
index 0000000..6a03954
--- /dev/null
@@ -0,0 +1,112 @@
+
+// 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"
+
+#define IMM_BATCH_COMBO 1
+
+
+VertexFormat* immVertexFormat(void); // returns a cleared vertex format, ready for add_attrib
+
+void immBindProgram(GLuint program); // 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 immAttrib2s(unsigned attrib_id, short x, short y);
+
+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 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 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 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 (file)
index 0000000..c9123ec
--- /dev/null
@@ -0,0 +1,46 @@
+
+// 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,
+
+#ifdef WITH_GL_PROFILE_COMPAT
+       PRIM_QUADS_XXX, // legacy GL has this, modern GL & Vulkan do not
+#endif
+
+       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);
+
+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 (file)
index 0000000..bdb0bbf
--- /dev/null
@@ -0,0 +1,49 @@
+
+// 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_3D,  // mat4 ModelViewMatrix
+       UNIFORM_PROJECTION_3D, // mat4 ProjectionMatrix
+       UNIFORM_MVP_3D,        // mat4 ModelViewProjectionMatrix
+       UNIFORM_NORMAL_3D,     // mat3 NormalMatrix
+       UNIFORM_INV_NORMAL_3D, // mat3 InverseNormalMatrix
+
+       UNIFORM_MODELVIEW_2D,  // mat3 ModelViewMatrix
+       UNIFORM_PROJECTION_2D, // mat3 ProjectionMatrix
+       UNIFORM_MVP_2D,        // mat3 ModelViewProjectionMatrix
+
+       UNIFORM_COLOR, // vec4 color
+
+       UNIFORM_CUSTOM // custom uniform, not one of the above built-ins
+} BuiltinUniform;
+
+typedef struct {
+       const char* name;
+       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*);
diff --git a/intern/gawain/gawain/vertex_buffer.h b/intern/gawain/gawain/vertex_buffer.h
new file mode 100644 (file)
index 0000000..687f15e
--- /dev/null
@@ -0,0 +1,64 @@
+
+// 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_format.h"
+
+// How to create a VertexBuffer:
+// 1) verts = create_VertexBuffer() or init_VertexBuffer(verts)
+// 2) add_attrib(verts->format, ...)
+// 3) allocate_vertex_data(verts, vertex_ct) <-- finalizes/packs vertex format
+// 4) fillAttrib(verts, pos, application_pos_buffer)
+// 5) prime_VertexBuffer(verts);
+
+// 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 setAttrib 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*);
diff --git a/intern/gawain/gawain/vertex_format.h b/intern/gawain/gawain/vertex_format.h
new file mode 100644 (file)
index 0000000..a5cab4a
--- /dev/null
@@ -0,0 +1,88 @@
+
+// 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 AVG_VERTEX_ATTRIB_NAME_LEN 5
+#define VERTEX_ATTRIB_NAMES_BUFFER_LEN ((AVG_VERTEX_ATTRIB_NAME_LEN + 1) * MAX_VERTEX_ATTRIBS)
+
+#define USE_10_10_10 defined(_WIN32)
+// (GLEW_VERSION_3_3 || GLEW_ARB_vertex_type_2_10_10_10_rev)
+//   ^-- this is only guaranteed on Windows right now, will be true on all platforms soon
+
+typedef enum {
+       COMP_I8,
+       COMP_U8,
+       COMP_I16,
+       COMP_U16,
+       COMP_I32,
+       COMP_U32,
+
+       COMP_F32,
+
+#if USE_10_10_10
+       COMP_I10
+#endif
+} 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;
+} Attrib;
+
+typedef struct {
+       unsigned attrib_ct; // 0 to 16 (MAX_VERTEX_ATTRIBS)
+       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);
+
+// format conversion
+
+#if USE_10_10_10
+
+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]);
+
+#endif // USE_10_10_10
+
+// for internal use
+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 (file)
index 0000000..bb42aaf
--- /dev/null
@@ -0,0 +1,69 @@
+
+// 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"
+
+#if MAX_VERTEX_ATTRIBS != 16
+  #error "attrib binding code assumes MAX_VERTEX_ATTRIBS = 16"
+#endif
+
+void clear_AttribBinding(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, GLuint program)
+       {
+#if TRUST_NO_ONE
+       assert(glIsProgram(program));
+#endif
+
+       clear_AttribBinding(binding);
+
+       for (unsigned a_idx = 0; a_idx < format->attrib_ct; ++a_idx)
+               {
+               const Attrib* a = format->attribs + a_idx;
+               GLint loc = glGetAttribLocation(program, a->name);
+
+#if TRUST_NO_ONE
+               assert(loc != -1);
+               // TODO: make this a recoverable runtime error? indicates mismatch between vertex format and program
+#endif
+
+               write_attrib_location(binding, a_idx, loc);
+               }
+       }
diff --git a/intern/gawain/src/batch.c b/intern/gawain/src/batch.c
new file mode 100644 (file)
index 0000000..7e904cb
--- /dev/null
@@ -0,0 +1,404 @@
+
+// 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 <stdlib.h>
+
+// necessary functions from matrix API
+extern void gpuBindMatrices(GLuint program);
+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)
+       {
+#if TRUST_NO_ONE
+       assert(glIsProgram(program));
+#endif
+
+       batch->program = program;
+       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;
+
+                       const GLint loc = glGetAttribLocation(batch->program, a->name);
+
+                       if (loc == -1) continue;
+
+                       glEnableVertexAttribArray(loc);
+
+                       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);
+                               }
+                       }
+               }
+
+       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;
+               }
+       }
+
+void Batch_Uniform1i(Batch* batch, const char* name, int value)
+       {
+       int loc = glGetUniformLocation(batch->program, name);
+
+#if TRUST_NO_ONE
+       assert(loc != -1);
+#endif
+
+       glUniform1i(loc, value);
+       }
+
+void Batch_Uniform1b(Batch* batch, const char* name, bool value)
+       {
+       int loc = glGetUniformLocation(batch->program, name);
+
+#if TRUST_NO_ONE
+       assert(loc != -1);
+#endif
+
+       glUniform1i(loc, value ? GL_TRUE : GL_FALSE);
+       }
+
+void Batch_Uniform2f(Batch* batch, const char* name, float x, float y)
+       {
+       int loc = glGetUniformLocation(batch->program, name);
+
+#if TRUST_NO_ONE
+       assert(loc != -1);
+#endif
+
+       glUniform2f(loc, x, y);
+       }
+
+void Batch_Uniform3f(Batch* batch, const char* name, float x, float y, float z)
+       {
+       int loc = glGetUniformLocation(batch->program, name);
+
+#if TRUST_NO_ONE
+       assert(loc != -1);
+#endif
+
+       glUniform3f(loc, x, y, z);
+       }
+
+void Batch_Uniform4f(Batch* batch, const char* name, float x, float y, float z, float w)
+       {
+       int loc = glGetUniformLocation(batch->program, name);
+
+#if TRUST_NO_ONE
+       assert(loc != -1);
+#endif
+
+       glUniform4f(loc, x, y, z, w);
+       }
+
+void Batch_Uniform1f(Batch* batch, const char* name, float x)
+       {
+       int loc = glGetUniformLocation(batch->program, name);
+
+#if TRUST_NO_ONE
+       assert(loc != -1);
+#endif
+
+       glUniform1f(loc, x);
+       }
+
+void Batch_Uniform3fv(Batch* batch, const char* name, const float data[3])
+       {
+       int loc = glGetUniformLocation(batch->program, name);
+
+#if TRUST_NO_ONE
+       assert(loc != -1);
+#endif
+
+       glUniform3fv(loc, 1, data);
+       }
+
+void Batch_Uniform4fv(Batch* batch, const char* name, const float data[4])
+       {
+       int loc = glGetUniformLocation(batch->program, name);
+
+#if TRUST_NO_ONE
+       assert(loc != -1);
+#endif
+
+       glUniform4fv(loc, 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->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->index_type, 0, el->base_index);
+               else
+                       glDrawRangeElements(batch->gl_prim_type, el->min_index, el->max_index, el->index_ct, el->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->index_type, 0, el->base_index);
+               else
+                       glDrawRangeElements(batch->gl_prim_type, el->min_index, el->max_index, el->index_ct, el->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);
+}
+
diff --git a/intern/gawain/src/buffer_id.cpp b/intern/gawain/src/buffer_id.cpp
new file mode 100644 (file)
index 0000000..450656c
--- /dev/null
@@ -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 (file)
index 0000000..3c3ca1c
--- /dev/null
@@ -0,0 +1,283 @@
+
+// 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
+
+unsigned ElementList_size(const ElementList* elem)
+       {
+#if TRACK_INDEX_RANGE
+       switch (elem->index_type)
+               {
+               case INDEX_U8: return elem->index_ct * sizeof(GLubyte);
+               case INDEX_U16: return elem->index_ct * sizeof(GLushort);
+               case INDEX_U32: return elem->index_ct * sizeof(GLuint);
+               default:
+       #if TRUST_NO_ONE
+                       assert(false);
+       #endif
+                       return 0;
+               }
+
+#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)
+       {
+       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;
+               }
+#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 (file)
index 0000000..74caeb6
--- /dev/null
@@ -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 (file)
index 0000000..15cd1cc
--- /dev/null
@@ -0,0 +1,884 @@
+
+// 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 "attrib_binding.h"
+#include "buffer_id.h"
+#include <string.h>
+
+// necessary functions from matrix API
+extern void gpuBindMatrices(GLuint program);
+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;
+       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);
+
+#if APPLE_LEGACY
+       glBufferParameteriAPPLE(GL_ARRAY_BUFFER, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);
+       glBufferParameteriAPPLE(GL_ARRAY_BUFFER, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
+#endif
+
+       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)
+       {
+#if TRUST_NO_ONE
+       assert(imm.bound_program == 0);
+       assert(glIsProgram(program));
+#endif
+
+       if (!imm.vertex_format.packed)
+               VertexFormat_pack(&imm.vertex_format);
+
+       glUseProgram(program);
+       get_attrib_locations(&imm.vertex_format, &imm.attrib_binding, program);
+       imm.bound_program = program;
+
+       gpuBindMatrices(program);
+       }
+
+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;
+  #ifdef WITH_GL_PROFILE_COMPAT
+               case PRIM_QUADS_XXX:
+                       return vertex_ct % 4 == 0;
+  #endif
+               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 APPLE_LEGACY
+               glBufferData(GL_ARRAY_BUFFER, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW);
+#else
+               if (GLEW_VERSION_4_3 || GLEW_ARB_invalidate_subdata)
+                       glInvalidateBufferData(imm.vbo_id);
+               else
+                       glMapBufferRange(GL_ARRAY_BUFFER, 0, IMM_BUFFER_SIZE, GL_MAP_INVALIDATE_BUFFER_BIT);
+#endif
+
+               imm.buffer_offset = 0;
+               }
+
+//     printf("mapping %u to %u\n", imm.buffer_offset, imm.buffer_offset + bytes_needed - 1);
+
+#if APPLE_LEGACY
+       imm.buffer_data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY) + imm.buffer_offset;
+#else
+       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));
+#endif
+
+#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);
+
+       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.bound_program);
+       }
+
+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);
+                       }
+#if !APPLE_LEGACY
+               // 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);
+#endif
+               }
+
+#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
+               {
+#if APPLE_LEGACY
+               // tell OpenGL what range was modified so it doesn't copy the whole buffer
+               // printf("flushing %u to %u\n", imm.buffer_offset, imm.buffer_offset + buffer_bytes_used - 1);
+               glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER, imm.buffer_offset, buffer_bytes_used);
+#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 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 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 ---
+
+void immUniform1f(const char* name, float x)
+       {
+       int loc = glGetUniformLocation(imm.bound_program, name);
+
+#if TRUST_NO_ONE
+       assert(loc != -1);
+#endif
+
+       glUniform1f(loc, x);
+       }
+
+void immUniform2f(const char* name, float x, float y)
+{
+       int loc = glGetUniformLocation(imm.bound_program, name);
+
+#if TRUST_NO_ONE
+       assert(loc != -1);
+#endif
+
+       glUniform2f(loc, x, y);
+}
+
+void immUniform2fv(const char* name, const float data[2])
+{
+       int loc = glGetUniformLocation(imm.bound_program, name);
+
+#if TRUST_NO_ONE
+       assert(loc != -1);
+#endif
+
+       glUniform2fv(loc, 1, data);
+}
+
+void immUniform3f(const char* name, float x, float y, float z)
+       {
+       int loc = glGetUniformLocation(imm.bound_program, name);
+
+#if TRUST_NO_ONE
+       assert(loc != -1);
+#endif
+
+       glUniform3f(loc, x, y, z);
+       }
+
+void immUniform3fv(const char* name, const float data[3])
+       {
+       int loc = glGetUniformLocation(imm.bound_program, name);
+
+#if TRUST_NO_ONE
+       assert(loc != -1);
+#endif
+
+       glUniform3fv(loc, 1, data);
+       }
+
+void immUniformArray3fv(const char* name, const float *data, int count)
+       {
+       int loc = glGetUniformLocation(imm.bound_program, name);
+
+#if TRUST_NO_ONE
+       assert(loc != -1);
+       assert(count > 0);
+#endif
+
+       glUniform3fv(loc, count, data);
+       }
+
+void immUniform4f(const char* name, float x, float y, float z, float w)
+       {
+       int loc = glGetUniformLocation(imm.bound_program, name);
+
+#if TRUST_NO_ONE
+       assert(loc != -1);
+#endif
+
+       glUniform4f(loc, x, y, z, w);
+       }
+
+void immUniform4fv(const char* name, const float data[4])
+       {
+       int loc = glGetUniformLocation(imm.bound_program, name);
+
+#if TRUST_NO_ONE
+       assert(loc != -1);
+#endif
+
+       glUniform4fv(loc, 1, data);
+       }
+
+void immUniformMatrix4fv(const char* name, const float data[4][4])
+       {
+       int loc = glGetUniformLocation(imm.bound_program, name);
+
+#if TRUST_NO_ONE
+       assert(loc != -1);
+#endif
+
+       glUniformMatrix4fv(loc, 1, GL_FALSE, (float *)data);
+       }
+
+void immUniform1i(const char* name, int x)
+       {
+       int loc = glGetUniformLocation(imm.bound_program, name);
+
+#if TRUST_NO_ONE
+       assert(loc != -1);
+#endif
+
+       glUniform1i(loc, x);
+       }
+
+
+// --- convenience functions for setting "uniform vec4 color" ---
+
+void immUniformColor4f(float r, float g, float b, float a)
+       {
+       immUniform4f("color", r, g, b, a);
+       }
+
+void immUniformColor4fv(const float rgba[4])
+       {
+       immUniform4fv("color", rgba);
+       }
+
+void immUniformColor3f(float r, float g, float b)
+       {
+       immUniform4f("color", r, g, b, 1.0f);
+       }
+
+void immUniformColor3fv(const float rgb[3])
+       {
+       immUniform4f("color", rgb[0], rgb[1], rgb[2], 1.0f);
+       }
+
+void immUniformColor3fvAlpha(const float rgb[3], float a)
+       {
+       immUniform4f("color", 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;
+       immUniform4f("color", 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;
+       immUniform4f("color", scale * r, scale * g, scale * b, scale * a);
+       }
+
+void immUniformColor3ubv(const unsigned char rgb[3])
+       {
+       immUniformColor3ub(rgb[0], rgb[1], rgb[2]);
+       }
+
+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 (file)
index 0000000..21cee01
--- /dev/null
@@ -0,0 +1,70 @@
+
+// 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"
+
+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,
+
+#ifdef WITH_GL_PROFILE_COMPAT
+               [PRIM_QUADS_XXX] = PRIM_CLASS_SURFACE,
+#endif
+
+               [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,
+
+#ifdef WITH_GL_PROFILE_COMPAT
+               [PRIM_QUADS_XXX] = GL_QUADS,
+#endif
+               };
+
+       return table[prim_type];
+       }
diff --git a/intern/gawain/src/shader_interface.c b/intern/gawain/src/shader_interface.c
new file mode 100644 (file)
index 0000000..93a1283
--- /dev/null
@@ -0,0 +1,140 @@
+
+// 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>
+
+#define DEBUG_SHADER_INTERFACE 0
+
+#if DEBUG_SHADER_INTERFACE
+ #include <stdio.h>
+#endif
+
+#if 0
+
+static const char* BuiltinUniform_name(BuiltinUniform u)
+       {
+       static const char* names[] =
+               {
+               [UNIFORM_NONE] = NULL,
+
+               [UNIFORM_MODELVIEW_3D] = "ModelViewMatrix",
+               [UNIFORM_PROJECTION_3D] = "ProjectionMatrix",
+               [UNIFORM_MVP_3D] = "ModelViewProjectionMatrix",
+               [UNIFORM_NORMAL_3D] = "NormalMatrix",
+               [UNIFORM_INV_NORMAL_3D] = "InverseNormalMatrix",
+
+               [UNIFORM_MODELVIEW_2D] = "ModelViewMatrix",
+               [UNIFORM_PROJECTION_2D] = "ProjectionMatrix",
+               [UNIFORM_MVP_2D] = "ModelViewProjectionMatrix",
+
+               [UNIFORM_COLOR] = "color",
+
+               [UNIFORM_CUSTOM] = NULL
+               };
+
+       return names[u];
+       }
+
+#endif
+
+static bool setup_builtin_uniform(ShaderInput* input, const char* name)
+       {
+       // TODO: reject DOUBLE, IMAGE, ATOMIC_COUNTER gl_types
+
+       // TODO: 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
+       input->name = name;
+       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);
+
+       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);
+
+               if (setup_builtin_uniform(input, name))
+                       ; // reclaim space from name buffer (don't advance offset)
+               else
+                       name_buffer_offset += name_len + 1; // include NULL terminator
+
+               input->location = glGetUniformLocation(program, name);
+
+#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->name = name;
+               name_buffer_offset += name_len + 1; // include NULL terminator
+
+               input->location = glGetAttribLocation(program, name);
+
+#if DEBUG_SHADER_INTERFACE
+               printf("attrib[%u] '%s' at location %d\n", i, name, input->location);
+#endif
+               }
+
+       // TODO: realloc shaderface to shrink name buffer
+       //       each input->name will need adjustment (except static built-in names)
+
+#if DEBUG_SHADER_INTERFACE
+       printf("using %u of %u bytes from name buffer\n", name_buffer_offset, name_buffer_len);
+       printf("}\n"); // exit function
+#endif
+
+       return shaderface;
+       }
+
+void ShaderInterface_discard(ShaderInterface* shaderface)
+       {
+       // allocated as one chunk, so discard is simple
+       free(shaderface);
+       }
diff --git a/intern/gawain/src/vertex_buffer.c b/intern/gawain/src/vertex_buffer.c
new file mode 100644 (file)
index 0000000..ab488a0
--- /dev/null
@@ -0,0 +1,170 @@
+
+// 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 "vertex_buffer.h"
+#include "buffer_id.h"
+#include <stdlib.h>
+#include <string.h>
+
+#define KEEP_SINGLE_COPY 1
+
+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);
+#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 VertexFormat* format = &verts->format;
+
+       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, vertex_buffer_size(format, verts->vertex_ct), verts->data, GL_STATIC_DRAW);
+
+#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);
+       }
diff --git a/intern/gawain/src/vertex_format.c b/intern/gawain/src/vertex_format.c
new file mode 100644 (file)
index 0000000..924cff4
--- /dev/null
@@ -0,0 +1,268 @@
+
+// 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 <stdlib.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;
+#endif
+       }
+
+void VertexFormat_copy(VertexFormat* dest, const VertexFormat* src)
+       {
+       // copy regular struct fields
+       memcpy(dest, src, sizeof(VertexFormat));
+       }
+
+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,
+
+       #if USE_10_10_10
+               [COMP_I10] = GL_INT_2_10_10_10_REV
+       #endif
+               };
+       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 USE_10_10_10
+       if (a->comp_type == COMP_I10)
+               return 4; // always packed as 10_10_10_2
+#endif
+
+       return a->comp_ct * comp_sz(a->comp_type);
+       }
+
+static unsigned attrib_align(const Attrib *a)
+       {
+#if USE_10_10_10
+       if (a->comp_type == COMP_I10)
+               return 4; // always packed as 10_10_10_2
+#endif
+
+       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);
+#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->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;
+ #if USE_10_10_10
+               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;
+ #endif
+               default:
+                       // integer types can be kept as int or converted/normalized to float
+                       assert(fetch_mode != KEEP_FLOAT);
+               }
+#endif
+
+       const unsigned attrib_id = format->attrib_ct++;
+       Attrib* attrib = format->attribs + attrib_id;
+
+       attrib->name = copy_attrib_name(format, name);
+       attrib->comp_type = comp_type;
+       attrib->gl_comp_type = convert_comp_type_to_gl(comp_type);
+#if USE_10_10_10
+       attrib->comp_ct = (comp_type == COMP_I10) ? 4 : comp_ct; // system needs 10_10_10_2 to be 4 or BGRA
+#else
+       attrib->comp_ct = comp_ct;
+#endif
+       attrib->sz = attrib_sz(attrib);
+       attrib->offset = 0; // offsets & stride are calculated later (during pack)
+       attrib->fetch_mode = fetch_mode;
+
+       return attrib_id;
+       }
+
+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&nb