Skip to content

Commit

Permalink
Done spine runtimes
Browse files Browse the repository at this point in the history
  • Loading branch information
ducphamhong committed Oct 3, 2024
1 parent cbd797f commit ad0573b
Show file tree
Hide file tree
Showing 9 changed files with 258 additions and 21 deletions.
4 changes: 4 additions & 0 deletions Projects/Irrlicht/Include/EMaterialTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ namespace video
//! Makes the material transparent based on the vertex alpha value.
EMT_TRANSPARENT_VERTEX_ALPHA,

//! Skylicht engine update
EMT_TRANSPARENT_MULTIPLY,
EMT_TRANSPARENT_SCREEN,

//! This value is not used. It only forces this enumeration to compile to 32 bit.
EMT_FORCE_32BIT = 0x7fffffff
};
Expand Down
101 changes: 97 additions & 4 deletions Projects/SpineCpp/CSkeletonDrawable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ This file is part of the "Skylicht Engine".

#include "pch.h"
#include "CSkeletonDrawable.h"
#include "CSpineResource.h"

#include "Graphics2D/CGraphics2D.h"
#include "Graphics2D/CCanvas.h"
#include "Graphics2D/GUI/CGUIElement.h"

using namespace Skylicht;

Expand All @@ -36,7 +41,6 @@ namespace spine
CSkeletonDrawable::CSkeletonDrawable(spine::SkeletonData* skeletonData, spine::AnimationStateData* animationStateData) :
m_skeleton(NULL),
m_animationState(NULL),
m_usePremultipliedAlpha(false),
m_ownsAnimationStateData(false)
{
m_skeleton = new spine::Skeleton(skeletonData);
Expand All @@ -59,14 +63,103 @@ namespace spine

void CSkeletonDrawable::update(float delta, spine::Physics physics)
{
m_animationState->update(delta);
m_animationState->update(delta * 0.001f);
m_animationState->apply(*m_skeleton);
m_skeleton->update(delta);
m_skeleton->updateWorldTransform(physics);
}

void CSkeletonDrawable::render()
void CSkeletonDrawable::render(CGUIElement* insideElement)
{

if (insideElement == NULL)
return;

spine::SkeletonRenderer* renderer = CSpineResource::getRenderer();
if (renderer == NULL)
return;

CCanvas* canvas = insideElement->getCanvas();
float canvasHeight = canvas->getRootElement()->getHeight();

// move to center of element
core::vector3df pos = insideElement->getAbsoluteTransform().getTranslation();
pos.X = pos.X + insideElement->getWidth() * 0.5f + m_drawOffset.X;
pos.Y = pos.Y + insideElement->getHeight() * 0.5f + m_drawOffset.Y;

// set position (flip Y)
m_skeleton->setPosition(pos.X, canvasHeight - pos.Y);

// flush the current buffer
CGraphics2D* graphics = CGraphics2D::getInstance();
video::SMaterial& material = graphics->getMaterial();
graphics->flush();

RenderCommand* command = renderer->render(*m_skeleton);
while (command)
{
IMeshBuffer* meshBuffer = graphics->getCurrentBuffer();

scene::IVertexBuffer* vtxBuffer = meshBuffer->getVertexBuffer();
scene::IIndexBuffer* idxBuffer = meshBuffer->getIndexBuffer();

float* positions = command->positions;
float* uvs = command->uvs;
uint32_t* colors = command->colors;

// alloc vertex buffer
vtxBuffer->set_used(command->numVertices);
S3DVertex* vertices = (S3DVertex*)vtxBuffer->getVertices();

for (int ii = 0; ii < command->numVertices << 1; ii += 2)
{
S3DVertex* v = &vertices[ii >> 1];

v->Pos.X = positions[ii];
// warning: flip Y
v->Pos.Y = canvasHeight - positions[ii + 1];
v->Pos.Z = 0.0f;

v->TCoords.X = uvs[ii];
v->TCoords.Y = uvs[ii + 1];

v->Color.set(colors[ii >> 1]);
}

// alloc index buffer
idxBuffer->set_used(command->numIndices);
u16* index = (u16*)idxBuffer->getIndices();
uint16_t* indices = command->indices;

for (int ii = 0; ii < command->numIndices; ii++)
{
index[ii] = indices[ii];
}

// texture
material.setTexture(0, (ITexture*)command->texture);

// blendmode
BlendMode blendMode = command->blendMode;
switch (blendMode)
{
case BlendMode_Normal:
material.MaterialType = CSpineResource::getTextureColorBlend();
break;
case BlendMode_Multiply:
material.MaterialType = CSpineResource::getTextureColorMultiply();
break;
case BlendMode_Additive:
material.MaterialType = CSpineResource::getTextureColorAddtive();
break;
case BlendMode_Screen:
material.MaterialType = CSpineResource::getTextureColorScreen();
break;
}

// draw this command
graphics->flush();

command = command->next;
}
}
}
26 changes: 23 additions & 3 deletions Projects/SpineCpp/CSkeletonDrawable.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ This file is part of the "Skylicht Engine".
#pragma once

#include <spine/spine.h>
#include "Graphics2D/GUI/CGUIElement.h"

namespace Skylicht
{
class CGUIElement;
}

namespace spine
{
Expand All @@ -35,16 +39,32 @@ namespace spine
spine::Skeleton* m_skeleton;
spine::AnimationState* m_animationState;

bool m_usePremultipliedAlpha;
bool m_ownsAnimationStateData;

core::vector2df m_drawOffset;

public:
CSkeletonDrawable(spine::SkeletonData* skeletonData, spine::AnimationStateData* animationStateData = NULL);

virtual ~CSkeletonDrawable();

void update(float delta, spine::Physics physics);

void render();
void render(Skylicht::CGUIElement* insideElement);

inline spine::Skeleton* getSkeleton()
{
return m_skeleton;
}

inline spine::AnimationState* getAnimationState()
{
return m_animationState;
}

inline void setDrawOffset(const core::vector2df& offset)
{
m_drawOffset = offset;
}
};
}
61 changes: 60 additions & 1 deletion Projects/SpineCpp/CSpineResource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,68 @@ This file is part of the "Skylicht Engine".

#include "pch.h"
#include "CSpineResource.h"
#include "Material/Shader/CShaderManager.h"

using namespace Skylicht;

namespace spine
{
spine::SkeletonRenderer* g_renderer = NULL;

spine::SkeletonRenderer* CSpineResource::initRenderer()
{
if (g_renderer == NULL)
g_renderer = new spine::SkeletonRenderer();
return g_renderer;
}

void CSpineResource::releaseRenderer()
{
if (g_renderer)
{
delete g_renderer;
g_renderer = NULL;
}
}

spine::SkeletonRenderer* CSpineResource::getRenderer()
{
return g_renderer;
}

int g_textColorBlend = 0;
int g_textColorAddtive = 0;
int g_textColorMultiply = 0;
int g_textColorScreen = 0;

int CSpineResource::getTextureColorBlend()
{
if (g_textColorBlend == 0)
g_textColorBlend = CShaderManager::getInstance()->getShaderIDByName("TextureColorAlpha");
return g_textColorBlend;
}

int CSpineResource::getTextureColorAddtive()
{
if (g_textColorAddtive == 0)
g_textColorAddtive = CShaderManager::getInstance()->getShaderIDByName("TextureColorAdditive");
return g_textColorAddtive;
}

int CSpineResource::getTextureColorMultiply()
{
if (g_textColorMultiply == 0)
g_textColorMultiply = CShaderManager::getInstance()->getShaderIDByName("TextureColorAlpha");
return g_textColorMultiply;
}

int CSpineResource::getTextureColorScreen()
{
if (g_textColorScreen == 0)
g_textColorScreen = CShaderManager::getInstance()->getShaderIDByName("TextureColorAlpha");
return g_textColorScreen;
}

CSpineResource::CSpineResource() :
m_textureLoader(NULL),
m_drawable(NULL),
Expand Down Expand Up @@ -70,7 +127,7 @@ namespace spine
return true;
}

bool CSpineResource::loadSkeletonJson(const char* path)
bool CSpineResource::loadSkeletonJson(const char* path, float scale)
{
if (m_atlas == NULL)
{
Expand All @@ -89,7 +146,9 @@ namespace spine

if (m_skeletonJson)
delete m_skeletonJson;

m_skeletonJson = new spine::SkeletonJson(m_attachmentLoader);
m_skeletonJson->setScale(scale);

if (m_drawable)
{
Expand Down
20 changes: 18 additions & 2 deletions Projects/SpineCpp/CSpineResource.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ This file is part of the "Skylicht Engine".

#pragma once

#include "CTextureLoader.h"
#include "CSkeletonDrawable.h"
#include "CTextureLoader.h"

namespace spine
{
Expand All @@ -40,14 +40,30 @@ namespace spine
spine::SkeletonJson* m_skeletonJson;
spine::SkeletonData* m_skeletonData;

public:

static spine::SkeletonRenderer* initRenderer();

static void releaseRenderer();

static spine::SkeletonRenderer* getRenderer();

static int getTextureColorBlend();

static int getTextureColorAddtive();

static int getTextureColorMultiply();

static int getTextureColorScreen();

public:
CSpineResource();

virtual ~CSpineResource();

bool loadAtlas(const char* path, const char* folder);

bool loadSkeletonJson(const char* path);
bool loadSkeletonJson(const char* path, float scale);

void free();

Expand Down
7 changes: 6 additions & 1 deletion Projects/SpineCpp/CTextureLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ This file is part of the "Skylicht Engine".
*/

#include "pch.h"
#include "CTextureLoader.h"
#include <spine/spine.h>

#include "CTextureLoader.h"
#include "TextureManager/CTextureManager.h"

using namespace Skylicht;
Expand All @@ -42,6 +43,10 @@ namespace spine
if (!texture)
return;
page.texture = texture;

const core::dimension2du& size = texture->getSize();
page.width = (int)size.Width;
page.height = (int)size.Height;
}

void CTextureLoader::unload(void* texture)
Expand Down
3 changes: 3 additions & 0 deletions Projects/SpineCpp/CTextureLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ This file is part of the "Skylicht Engine".

namespace spine
{
class AtlasPage;
class String;

class CTextureLoader : public spine::TextureLoader
{
public:
Expand Down
Loading

0 comments on commit ad0573b

Please sign in to comment.