diff --git a/defold-spine/commonsrc/spine_ddf.proto b/defold-spine/commonsrc/spine_ddf.proto index 22efa9d..232719b 100644 --- a/defold-spine/commonsrc/spine_ddf.proto +++ b/defold-spine/commonsrc/spine_ddf.proto @@ -22,6 +22,7 @@ message SpineModelDesc BLEND_MODE_ADD = 1 [(displayName) = "Add"]; BLEND_MODE_MULT = 3 [(displayName) = "Multiply"]; BLEND_MODE_SCREEN = 4 [(displayName) = "Screen"]; + BLEND_MODE_INHERIT = 5 [(displayName) = "Inherit"]; } required string spine_scene = 1 [(resource)=true]; diff --git a/defold-spine/commonsrc/vertices.cpp b/defold-spine/commonsrc/vertices.cpp index 0ed46f1..4cac557 100644 --- a/defold-spine/commonsrc/vertices.cpp +++ b/defold-spine/commonsrc/vertices.cpp @@ -143,8 +143,23 @@ uint32_t CalcVertexBufferSize(const spSkeleton* skeleton, uint32_t* out_max_tria return count; } +uint32_t CalcDrawDescCount(const spSkeleton* skeleton) +{ + uint32_t count = 0; + for (int s = 0; s < skeleton->slotsCount; ++s) + { + spSlot* slot = skeleton->drawOrder[s]; + spAttachment* attachment = slot->attachment; + if (!attachment) + { + continue; + } + count++; + } + return count; +} -uint32_t GenerateVertexData(dmArray& vertex_buffer, const spSkeleton* skeleton, const dmVMath::Matrix4& world) +uint32_t GenerateVertexData(dmArray& vertex_buffer, const spSkeleton* skeleton, const dmVMath::Matrix4& world, dmArray* draw_descs_out) { dmArray scratch; // scratch buffer @@ -170,28 +185,7 @@ uint32_t GenerateVertexData(dmArray& vertex_buffer, const spSkeleto continue; } - // We let the user override the blend mode for the whole spine scene at the .spinemodel level - // // Fetch the blend mode from the slot and - // // translate it to the engine blend mode - // BlendMode engineBlendMode; - // switch (slot->data->blendMode) { - // case SP_BLEND_MODE_NORMAL: - // engineBlendMode = BLEND_NORMAL; - // break; - // case SP_BLEND_MODE_ADDITIVE: - // engineBlendMode = BLEND_ADDITIVE; - // break; - // case SP_BLEND_MODE_MULTIPLY: - // engineBlendMode = BLEND_MULTIPLY; - // break; - // case SP_BLEND_MODE_SCREEN: - // engineBlendMode = BLEND_SCREEN; - // break; - // default: - // // unknown Spine blend mode, fall back to - // // normal blend mode - // engineBlendMode = BLEND_NORMAL; - // } + uint32_t batch_vindex_start = vindex; // Calculate the tinting color based on the skeleton's color // and the slot's color. Each color channel is given in the @@ -271,6 +265,15 @@ uint32_t GenerateVertexData(dmArray& vertex_buffer, const spSkeleto addVertex(&vertex_buffer[vindex++], scratch[index], scratch[index + 1], uvs[index], uvs[index + 1], colorR, colorG, colorB, colorA, page_index); } } + + if (draw_descs_out) + { + SpineDrawDesc desc; + desc.m_VertexStart = batch_vindex_start; + desc.m_BlendMode = (uint32_t) slot->data->blendMode; + desc.m_VertexCount = vindex - batch_vindex_start; + draw_descs_out->Push(desc); + } } scratch.SetSize(0); @@ -295,4 +298,30 @@ uint32_t GenerateVertexData(dmArray& vertex_buffer, const spSkeleto return vcount; } +void MergeDrawDescs(const dmArray& src, dmArray& dst) +{ + dst.SetCapacity(src.Size()); + dst.SetSize(src.Size()); + + SpineDrawDesc* current_draw_desc = dst.Begin(); + *current_draw_desc = src[0]; + + // If we are using "inherit" blending mode, we need to produce render objects based + // on the blend mode. If two consecutive draws have the same blend mode, we can merge them. + for (int i = 1; i < src.Size(); ++i) + { + if (current_draw_desc->m_BlendMode == src[i].m_BlendMode) + { + current_draw_desc->m_VertexCount += src[i].m_VertexCount; + } + else + { + current_draw_desc++; + *current_draw_desc = src[i]; + } + } + uint32_t trimmed_size = current_draw_desc - dst.Begin() + 1; + dst.SetSize(trimmed_size); +} + } // dmSpine diff --git a/defold-spine/editor/src/spineext.clj b/defold-spine/editor/src/spineext.clj index 9274e64..3f23d60 100644 --- a/defold-spine/editor/src/spineext.clj +++ b/defold-spine/editor/src/spineext.clj @@ -346,9 +346,22 @@ (defn- set-constants! [^GL2 gl shader ro] (doall (map (fn [constant] (set-constant! gl shader constant)) (.m_Constants ro)))) +(defn- blend-factor-value-to-blend-mode [blend-factor-value] + (case blend-factor-value + 0 :blend-mode-alpha + 1 :blend-mode-add + 2 :blend-mode-mult + 3 :blend-mode-screen + :blend-mode-alpha)) + (defn- do-render-object! [^GL2 gl render-args shader renderable ro] (let [start (.m_VertexStart ro) ; the name is from the engine, but in this case refers to the index count (.m_VertexCount ro) + renderable-user-data (:user-data renderable) + renderable-blend-mode (:blend-mode renderable-user-data) + blend-mode (if (= renderable-blend-mode :blend-mode-inherit) + (blend-factor-value-to-blend-mode (.m_BlendFactor ro)) + renderable-blend-mode) face-winding (if (not= (.m_FaceWindingCCW ro) 0) GL/GL_CCW GL/GL_CW) _ (set-constants! gl shader ro) ro-transform (double-array (.m (.m_WorldTransform ro))) @@ -363,7 +376,7 @@ (:view render-args) (:projection render-args) (:texture render-args)))] - + (gl/set-blend-mode gl blend-mode) (shader/set-uniform shader gl "world_view_proj" (:world-view-proj render-args)) (when (not= (.m_SetFaceWinding ro) 0) (gl/gl-front-face gl face-winding)) @@ -373,8 +386,7 @@ (gl/gl-draw-arrays gl triangle-mode start count)) (when use-index-buffer (gl/gl-draw-elements gl triangle-mode start count)) - ; reset blend state - (.glBlendFunc gl GL/GL_SRC_ALPHA GL/GL_ONE_MINUS_SRC_ALPHA))) + (gl/set-blend-mode gl :blend-mode-alpha))) (set! *warn-on-reflection* true) @@ -391,7 +403,6 @@ (defn- render-group-transparent [^GL2 gl render-args override-shader group] (let [renderable (:renderable group) user-data (:user-data renderable) - blend-mode (:blend-mode user-data) gpu-texture (or (get user-data :gpu-texture) texture/white-pixel) shader (if (not= override-shader nil) override-shader (:shader user-data)) vb (:vertex-buffer group) @@ -399,7 +410,6 @@ vertex-binding (vtx/use-with ::spine-trans vb shader)] (gl/with-gl-bindings gl render-args [gpu-texture shader vertex-binding] (setup-gl gl) - (gl/set-blend-mode gl blend-mode) (doall (map (fn [ro] (do-render-object! gl render-args shader renderable ro)) render-objects)) (restore-gl gl)))) @@ -428,20 +438,19 @@ (g/defnk produce-main-scene [_node-id aabb material-shader gpu-texture default-tex-params aabb spine-scene-pb spine-data-handle] (when (and gpu-texture) - (let [blend-mode :blend-mode-alpha] - (assoc {:node-id _node-id :aabb aabb} - :renderable {:render-fn render-spine-scenes - :tags #{:spine} - :batch-key [gpu-texture material-shader] - :select-batch-key _node-id - :user-data {:aabb aabb - :spine-scene-pb spine-scene-pb - :spine-data-handle spine-data-handle - :shader material-shader - :gpu-texture gpu-texture - :tex-params default-tex-params - :blend-mode blend-mode} - :passes [pass/transparent pass/selection]})))) + (assoc {:node-id _node-id :aabb aabb} + :renderable {:render-fn render-spine-scenes + :tags #{:spine} + :batch-key [gpu-texture material-shader] + :select-batch-key _node-id + :user-data {:aabb aabb + :spine-scene-pb spine-scene-pb + :spine-data-handle spine-data-handle + :shader material-shader + :gpu-texture gpu-texture + :tex-params default-tex-params + :blend-mode :blend-mode-alpha} + :passes [pass/transparent pass/selection]}))) (defn- make-spine-outline-scene [_node-id aabb] {:aabb aabb @@ -776,7 +785,7 @@ ;;////////////////////////////////////////////////////////////////////////////////////////////// -(g/defnk produce-model-pb [spine-scene-resource default-animation skin material-resource blend-mode create-go-bones playback-rate offset] +(g/defnk produce-model-pb [spine-scene-resource blend-mode default-animation skin material-resource create-go-bones playback-rate offset] (cond-> {:spine-scene (resource/resource->proj-path spine-scene-resource) :default-animation default-animation :skin skin @@ -953,13 +962,14 @@ (output updatable g/Any :cached produce-spine-data-handle-updatable) - (output scene g/Any :cached (g/fnk [_node-id spine-main-scene aabb material-shader tex-params spine-data-handle default-animation skin updatable] + (output scene g/Any :cached (g/fnk [_node-id spine-main-scene aabb blend-mode material-shader tex-params spine-data-handle default-animation skin updatable] (if (and (some? material-shader) (some? (:renderable spine-main-scene))) (let [aabb aabb spine-scene-node-id (:node-id spine-main-scene)] (-> spine-main-scene (assoc-in [:renderable :user-data :shader] material-shader) (update-in [:renderable :user-data :gpu-texture] texture/set-params tex-params) + (assoc-in [:renderable :user-data :blend-mode] blend-mode) (assoc-in [:renderable :user-data :skin] skin) (assoc-in [:renderable :user-data :animation] default-animation) (assoc-in [:renderable :user-data :spine-data-handle] spine-data-handle) diff --git a/defold-spine/include/common/vertices.h b/defold-spine/include/common/vertices.h index 3d0da9e..8cd5c87 100644 --- a/defold-spine/include/common/vertices.h +++ b/defold-spine/include/common/vertices.h @@ -7,7 +7,6 @@ struct spSkeleton; - namespace dmSpine { @@ -27,8 +26,17 @@ struct SpineModelBounds float maxY; }; +struct SpineDrawDesc +{ + uint32_t m_VertexStart; + uint32_t m_VertexCount; + uint32_t m_BlendMode; // spBlendMode +}; + uint32_t CalcVertexBufferSize(const spSkeleton* skeleton, uint32_t* out_max_triangle_count); -uint32_t GenerateVertexData(dmArray& vertex_buffer, const spSkeleton* skeleton, const dmVMath::Matrix4& world); +uint32_t CalcDrawDescCount(const spSkeleton* skeleton); +uint32_t GenerateVertexData(dmArray& vertex_buffer, const spSkeleton* skeleton, const dmVMath::Matrix4& world, dmArray* draw_descs); void GetSkeletonBounds(const spSkeleton* skeleton, SpineModelBounds& bounds); +void MergeDrawDescs(const dmArray& src, dmArray& dst); } // dmSpine diff --git a/defold-spine/plugins/lib/arm64-osx/libSpineExt.dylib b/defold-spine/plugins/lib/arm64-osx/libSpineExt.dylib index ba0d749..f420f80 100644 Binary files a/defold-spine/plugins/lib/arm64-osx/libSpineExt.dylib and b/defold-spine/plugins/lib/arm64-osx/libSpineExt.dylib differ diff --git a/defold-spine/plugins/lib/x86_64-linux/libSpineExt.so b/defold-spine/plugins/lib/x86_64-linux/libSpineExt.so index a61ce19..862ee36 100644 Binary files a/defold-spine/plugins/lib/x86_64-linux/libSpineExt.so and b/defold-spine/plugins/lib/x86_64-linux/libSpineExt.so differ diff --git a/defold-spine/plugins/lib/x86_64-osx/libSpineExt.dylib b/defold-spine/plugins/lib/x86_64-osx/libSpineExt.dylib index 00a38cb..9b4f8f1 100644 Binary files a/defold-spine/plugins/lib/x86_64-osx/libSpineExt.dylib and b/defold-spine/plugins/lib/x86_64-osx/libSpineExt.dylib differ diff --git a/defold-spine/plugins/lib/x86_64-win32/libSpineExt.dll b/defold-spine/plugins/lib/x86_64-win32/libSpineExt.dll index 3d5b62f..ffc1164 100644 Binary files a/defold-spine/plugins/lib/x86_64-win32/libSpineExt.dll and b/defold-spine/plugins/lib/x86_64-win32/libSpineExt.dll differ diff --git a/defold-spine/plugins/share/pluginSpineExt.jar b/defold-spine/plugins/share/pluginSpineExt.jar index 48c105f..89843db 100644 Binary files a/defold-spine/plugins/share/pluginSpineExt.jar and b/defold-spine/plugins/share/pluginSpineExt.jar differ diff --git a/defold-spine/pluginsrc/com/defold/bob/pipeline/Spine.java b/defold-spine/pluginsrc/com/defold/bob/pipeline/Spine.java index 9cbd7a1..44e21b6 100644 --- a/defold-spine/pluginsrc/com/defold/bob/pipeline/Spine.java +++ b/defold-spine/pluginsrc/com/defold/bob/pipeline/Spine.java @@ -256,7 +256,7 @@ static public class RenderObject extends Structure { public int m_NumConstants; public int m_VertexStart; public int m_VertexCount; - public int pad1; + public int m_BlendFactor; public byte m_SetBlendFactors; public byte m_SetStencilTest; public byte m_SetFaceWinding; @@ -268,7 +268,7 @@ static public class RenderObject extends Structure { protected List getFieldOrder() { return Arrays.asList(new String[] { "m_StencilTestParams", "m_WorldTransform", "m_Constants", - "m_NumConstants", "m_VertexStart", "m_VertexCount", "pad1", + "m_NumConstants", "m_VertexStart", "m_VertexCount", "m_BlendFactor", "m_SetBlendFactors", "m_SetStencilTest", "m_SetFaceWinding", "m_FaceWindingCCW", "m_UseIndexBuffer", "m_IsTriangleStrip", "pad2"}); } diff --git a/defold-spine/pluginsrc/plugin.cpp b/defold-spine/pluginsrc/plugin.cpp index ec6022a..869473f 100644 --- a/defold-spine/pluginsrc/plugin.cpp +++ b/defold-spine/pluginsrc/plugin.cpp @@ -676,24 +676,35 @@ static void UpdateRenderData(SpineFile* file) file->m_RenderObjects.SetSize(0); file->m_VertexBuffer.SetSize(0); - uint32_t ro_count = 1; + uint32_t ro_count = dmSpine::CalcDrawDescCount(file->m_SkeletonInstance); AdjustArraySize(file->m_RenderObjects, ro_count); + dmArray draw_descs; + draw_descs.SetCapacity(ro_count); + dmVMath::Matrix4 transform = dmVMath::Matrix4::identity(); - dmSpine::GenerateVertexData(file->m_VertexBuffer, file->m_SkeletonInstance, transform); + dmSpine::GenerateVertexData(file->m_VertexBuffer, file->m_SkeletonInstance, transform, &draw_descs); + + dmArray merged_draw_descs; + MergeDrawDescs(draw_descs, merged_draw_descs); - dmSpinePlugin::RenderObject& ro = file->m_RenderObjects[0]; - ro.Init(); - ro.m_VertexStart = 0; // byte offset - ro.m_VertexCount = file->m_VertexBuffer.Size(); - ro.m_SetStencilTest = 0; - ro.m_UseIndexBuffer = 0; - ro.m_IsTriangleStrip = 0; // 0 == GL_TRIANGLES, 1 == GL_TRIANGLE_STRIP + file->m_RenderObjects.SetSize(merged_draw_descs.Size()); - ro.m_SetFaceWinding = 0; - ro.m_FaceWindingCCW = dmGraphics::FACE_WINDING_CCW; + for (int i = 0; i < merged_draw_descs.Size(); ++i) + { + dmSpinePlugin::RenderObject& ro = file->m_RenderObjects[i]; + ro.Init(); + ro.m_VertexStart = merged_draw_descs[i].m_VertexStart; // byte offset + ro.m_VertexCount = merged_draw_descs[i].m_VertexCount; + ro.m_SetStencilTest = 0; + ro.m_UseIndexBuffer = 0; + ro.m_IsTriangleStrip = 0; // 0 == GL_TRIANGLES, 1 == GL_TRIANGLE_STRIP + ro.m_BlendFactor = merged_draw_descs[i].m_BlendMode; + ro.m_SetFaceWinding = 0; + ro.m_FaceWindingCCW = dmGraphics::FACE_WINDING_CCW; - //ro.AddConstant(UNIFORM_TINT, dmVMath::Vector4(1.0f, 1.0f, 1.0f, 1.0f)); + //ro.AddConstant(UNIFORM_TINT, dmVMath::Vector4(1.0f, 1.0f, 1.0f, 1.0f)); - ro.m_WorldTransform = transform; + ro.m_WorldTransform = transform; + } } diff --git a/defold-spine/pluginsrc/renderobject.h b/defold-spine/pluginsrc/renderobject.h index c2908cd..348cc20 100644 --- a/defold-spine/pluginsrc/renderobject.h +++ b/defold-spine/pluginsrc/renderobject.h @@ -64,7 +64,7 @@ namespace dmSpinePlugin uint32_t m_NumConstants; uint32_t m_VertexStart; uint32_t m_VertexCount; - uint32_t : 32; + uint32_t m_BlendFactor; bool m_SetBlendFactors; bool m_SetStencilTest; diff --git a/defold-spine/src/comp_spine_model.cpp b/defold-spine/src/comp_spine_model.cpp index 73ba6e4..41829ce 100644 --- a/defold-spine/src/comp_spine_model.cpp +++ b/defold-spine/src/comp_spine_model.cpp @@ -69,7 +69,6 @@ namespace dmSpine static void ResourceReloadedCallback(const dmResource::ResourceReloadedParams& params); static void DestroyComponent(struct SpineModelWorld* world, uint32_t index); - struct SpineModelWorld { dmObjectPool m_Components; @@ -78,6 +77,7 @@ namespace dmSpine dmGraphics::HVertexDeclaration m_VertexDeclaration; dmGraphics::HVertexBuffer m_VertexBuffer; dmArray m_VertexBufferData; + dmArray m_DrawDescBuffer; dmResource::HFactory m_Factory; }; @@ -782,58 +782,51 @@ namespace dmSpine return dmGameObject::UPDATE_RESULT_OK; } - - static void RenderBatch(SpineModelWorld* world, dmRender::HRenderContext render_context, dmRender::RenderListEntry *buf, uint32_t* begin, uint32_t* end) + static inline dmGameSystemDDF::SpineModelDesc::BlendMode SpineBlendModeToRenderBlendMode(spBlendMode sp_blend_mode) { - //DM_PROFILE(SpineModel, "RenderBatch"); - - dmArray& components = world->m_Components.GetRawObjects(); - - uint32_t component_index = (uint32_t)buf[*begin].m_UserData; - const SpineModelComponent* first = (const SpineModelComponent*) components[component_index]; - const SpineModelResource* resource = first->m_Resource; - - uint32_t vertex_start = world->m_VertexBufferData.Size(); - uint32_t vertex_count = 0; - - for (uint32_t *i = begin; i != end; ++i) - { - component_index = (uint32_t)buf[*i].m_UserData; - const SpineModelComponent* component = (const SpineModelComponent*) components[component_index]; - vertex_count += dmSpine::CalcVertexBufferSize(component->m_SkeletonInstance, 0); - } - - if (vertex_count > world->m_VertexBufferData.Capacity()) - world->m_VertexBufferData.SetCapacity(vertex_count); - - vertex_count = 0; - for (uint32_t *i = begin; i != end; ++i) + switch(sp_blend_mode) { - component_index = (uint32_t)buf[*i].m_UserData; - const SpineModelComponent* component = (const SpineModelComponent*) components[component_index]; - vertex_count += dmSpine::GenerateVertexData(world->m_VertexBufferData, component->m_SkeletonInstance, component->m_World); + case SP_BLEND_MODE_NORMAL: + return dmGameSystemDDF::SpineModelDesc::BLEND_MODE_ALPHA; + case SP_BLEND_MODE_ADDITIVE: + return dmGameSystemDDF::SpineModelDesc::BLEND_MODE_ADD; + case SP_BLEND_MODE_MULTIPLY: + return dmGameSystemDDF::SpineModelDesc::BLEND_MODE_MULT; + case SP_BLEND_MODE_SCREEN: + return dmGameSystemDDF::SpineModelDesc::BLEND_MODE_SCREEN; + default:break; } + return dmGameSystemDDF::SpineModelDesc::BLEND_MODE_ALPHA; + } - world->m_RenderObjects.SetSize(world->m_RenderObjects.Size()+1); - dmRender::RenderObject& ro = world->m_RenderObjects.Back(); - + static void FillRenderObject(SpineModelWorld* world, + dmRender::HRenderContext render_context, + dmRender::RenderObject& ro, + dmGameSystem::HComponentRenderConstants constants, + dmGraphics::HTexture texture, + dmRender::HMaterial material, + dmGameSystemDDF::SpineModelDesc::BlendMode blend_mode, + uint32_t vertex_start, + uint32_t vertex_count) + { ro.Init(); ro.m_VertexDeclaration = world->m_VertexDeclaration; - ro.m_VertexBuffer = world->m_VertexBuffer; - ro.m_PrimitiveType = dmGraphics::PRIMITIVE_TRIANGLES; - ro.m_VertexStart = vertex_start; - ro.m_VertexCount = vertex_count; - ro.m_Textures[0] = resource->m_SpineScene->m_TextureSet->m_Texture->m_Texture; // spine - texture set resource - texture resource - texture - ro.m_Material = GetMaterial(first); - - if (first->m_RenderConstants) + ro.m_VertexBuffer = world->m_VertexBuffer; + ro.m_PrimitiveType = dmGraphics::PRIMITIVE_TRIANGLES; + ro.m_VertexStart = vertex_start; + ro.m_VertexCount = vertex_count; + ro.m_Textures[0] = texture; + ro.m_Material = material; + + if (constants) { - dmGameSystem::EnableRenderObjectConstants(&ro, first->m_RenderConstants); + dmGameSystem::EnableRenderObjectConstants(&ro, constants); } - dmGameSystemDDF::SpineModelDesc::BlendMode blend_mode = resource->m_Ddf->m_BlendMode; + ro.m_SetBlendFactors = 1; + switch (blend_mode) - { + { case dmGameSystemDDF::SpineModelDesc::BLEND_MODE_ALPHA: ro.m_SourceBlendFactor = dmGraphics::BLEND_FACTOR_ONE; ro.m_DestinationBlendFactor = dmGraphics::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; @@ -860,11 +853,90 @@ namespace dmSpine break; } - ro.m_SetBlendFactors = 1; - dmRender::AddToRender(render_context, &ro); } + static void RenderBatch(SpineModelWorld* world, dmRender::HRenderContext render_context, dmRender::RenderListEntry *buf, uint32_t* begin, uint32_t* end) + { + //DM_PROFILE(SpineModel, "RenderBatch"); + + dmArray& components = world->m_Components.GetRawObjects(); + + uint32_t component_index = (uint32_t)buf[*begin].m_UserData; + const SpineModelComponent* first = (const SpineModelComponent*) components[component_index]; + const SpineModelResource* resource = first->m_Resource; + + dmGameSystemDDF::SpineModelDesc::BlendMode blend_mode = resource->m_Ddf->m_BlendMode; + bool use_inherit_blend = blend_mode == dmGameSystemDDF::SpineModelDesc::BLEND_MODE_INHERIT; + + uint32_t vertex_start = world->m_VertexBufferData.Size(); + uint32_t vertex_count = 0; + uint32_t draw_desc_buffer_count = 0; + + // This is a temporary scratch buffer just used for this batch call, so we make sure to reset it. + world->m_DrawDescBuffer.SetSize(0); + + for (uint32_t *i = begin; i != end; ++i) + { + component_index = (uint32_t)buf[*i].m_UserData; + const SpineModelComponent* component = (const SpineModelComponent*) components[component_index]; + vertex_count += dmSpine::CalcVertexBufferSize(component->m_SkeletonInstance, 0); + + if (use_inherit_blend) + { + draw_desc_buffer_count += dmSpine::CalcDrawDescCount(component->m_SkeletonInstance); + } + } + + if (draw_desc_buffer_count && draw_desc_buffer_count > world->m_DrawDescBuffer.Capacity()) + { + world->m_DrawDescBuffer.SetCapacity(draw_desc_buffer_count); + } + + if (vertex_count > world->m_VertexBufferData.Capacity()) + { + world->m_VertexBufferData.SetCapacity(vertex_count); + } + + vertex_count = 0; + for (uint32_t *i = begin; i != end; ++i) + { + component_index = (uint32_t)buf[*i].m_UserData; + const SpineModelComponent* component = (const SpineModelComponent*) components[component_index]; + vertex_count += dmSpine::GenerateVertexData(world->m_VertexBufferData, component->m_SkeletonInstance, component->m_World, use_inherit_blend ? &world->m_DrawDescBuffer : 0); + } + + dmGraphics::HTexture texture = resource->m_SpineScene->m_TextureSet->m_Texture->m_Texture; // spine - texture set resource - texture resource - texture + dmRender::HMaterial material = GetMaterial(first); + + if (use_inherit_blend) + { + uint32_t draw_desc_count = world->m_DrawDescBuffer.Size(); + dmArray scratch_draw_descs; + MergeDrawDescs(world->m_DrawDescBuffer, scratch_draw_descs); + + uint32_t merged_size = scratch_draw_descs.Size(); + uint32_t ro_count_begin = world->m_RenderObjects.Size(); + world->m_RenderObjects.SetSize(world->m_RenderObjects.Size() + merged_size); + + for (int i = 0; i < merged_size; ++i) + { + dmRender::RenderObject& ro = world->m_RenderObjects[ro_count_begin + i]; + FillRenderObject(world, render_context, ro, first->m_RenderConstants, texture, material, + SpineBlendModeToRenderBlendMode((spBlendMode) scratch_draw_descs[i].m_BlendMode), + scratch_draw_descs[i].m_VertexStart, + scratch_draw_descs[i].m_VertexCount); + } + } + else + { + uint32_t ro_index = world->m_RenderObjects.Size(); + world->m_RenderObjects.SetSize(ro_index + 1); + dmRender::RenderObject& ro = world->m_RenderObjects[ro_index]; + FillRenderObject(world, render_context, ro, first->m_RenderConstants, texture, material, blend_mode, vertex_start, vertex_count); + } + } + static void RenderListFrustumCulling(dmRender::RenderListVisibilityParams const ¶ms) { DM_PROFILE("SpineModel"); diff --git a/defold-spine/src/gui_node_spine.cpp b/defold-spine/src/gui_node_spine.cpp index ef3ce94..f63a6d1 100644 --- a/defold-spine/src/gui_node_spine.cpp +++ b/defold-spine/src/gui_node_spine.cpp @@ -834,7 +834,7 @@ static void GuiGetVertices(const dmGameSystem::CustomNodeCtx* nodectx, uint32_t // We currently know it's xyz-uv-rgba dmArray* vbdata = (dmArray*)&vertices; - uint32_t num_vertices = dmSpine::GenerateVertexData(*vbdata, node->m_SkeletonInstance, node->m_Transform); + uint32_t num_vertices = dmSpine::GenerateVertexData(*vbdata, node->m_SkeletonInstance, node->m_Transform, 0); (void)num_vertices; }