mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-22 10:16:01 +08:00
[sdl] Fix up texture loader in C implementation.
This commit is contained in:
parent
6fb0ebdc7a
commit
2b69bb2af5
@ -118,6 +118,65 @@ extern "C" {
|
|||||||
return self->items[self->size - 1]; \
|
return self->items[self->size - 1]; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define _SP_ARRAY_IMPLEMENT_TYPE_NO_CONTAINS(name, itemType) \
|
||||||
|
name* name##_create(int initialCapacity) { \
|
||||||
|
name* array = CALLOC(name, 1); \
|
||||||
|
array->size = 0; \
|
||||||
|
array->capacity = initialCapacity; \
|
||||||
|
array->items = CALLOC(itemType, initialCapacity); \
|
||||||
|
return array; \
|
||||||
|
} \
|
||||||
|
void name##_dispose(name* self) { \
|
||||||
|
FREE(self->items); \
|
||||||
|
FREE(self); \
|
||||||
|
} \
|
||||||
|
void name##_clear(name* self) { \
|
||||||
|
self->size = 0; \
|
||||||
|
} \
|
||||||
|
name* name##_setSize(name* self, int newSize) { \
|
||||||
|
self->size = newSize; \
|
||||||
|
if (self->capacity < newSize) { \
|
||||||
|
self->capacity = MAX(8, (int)(self->size * 1.75f)); \
|
||||||
|
self->items = REALLOC(self->items, itemType, self->capacity); \
|
||||||
|
} \
|
||||||
|
return self; \
|
||||||
|
} \
|
||||||
|
void name##_ensureCapacity(name* self, int newCapacity) { \
|
||||||
|
if (self->capacity >= newCapacity) return; \
|
||||||
|
self->capacity = newCapacity; \
|
||||||
|
self->items = REALLOC(self->items, itemType, self->capacity); \
|
||||||
|
} \
|
||||||
|
void name##_add(name* self, itemType value) { \
|
||||||
|
if (self->size == self->capacity) { \
|
||||||
|
self->capacity = MAX(8, (int)(self->size * 1.75f)); \
|
||||||
|
self->items = REALLOC(self->items, itemType, self->capacity); \
|
||||||
|
} \
|
||||||
|
self->items[self->size++] = value; \
|
||||||
|
} \
|
||||||
|
void name##_addAll(name* self, name* other) { \
|
||||||
|
int i = 0; \
|
||||||
|
for (; i < other->size; i++) { \
|
||||||
|
name##_add(self, other->items[i]); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
void name##_addAllValues(name* self, itemType* values, int offset, int count) { \
|
||||||
|
int i = offset, n = offset + count; \
|
||||||
|
for (; i < n; i++) { \
|
||||||
|
name##_add(self, values[i]); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
void name##_removeAt(name* self, int index) { \
|
||||||
|
self->size--; \
|
||||||
|
memmove(self->items + index, self->items + index + 1, sizeof(itemType) * (self->size - index)); \
|
||||||
|
} \
|
||||||
|
itemType name##_pop(name* self) { \
|
||||||
|
itemType item = self->items[--self->size]; \
|
||||||
|
return item; \
|
||||||
|
} \
|
||||||
|
itemType name##_peek(name* self) { \
|
||||||
|
return self->items[self->size - 1]; \
|
||||||
|
}
|
||||||
|
|
||||||
_SP_ARRAY_DECLARE_TYPE(spFloatArray, float)
|
_SP_ARRAY_DECLARE_TYPE(spFloatArray, float)
|
||||||
|
|
||||||
_SP_ARRAY_DECLARE_TYPE(spIntArray, int)
|
_SP_ARRAY_DECLARE_TYPE(spIntArray, int)
|
||||||
|
|||||||
@ -1,3 +1,88 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Spine Runtimes License Agreement
|
||||||
|
* Last updated September 24, 2021. Replaces all prior versions.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2021, Esoteric Software LLC
|
||||||
|
*
|
||||||
|
* Integration of the Spine Runtimes into software or otherwise creating
|
||||||
|
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||||
|
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||||
|
* http://esotericsoftware.com/spine-editor-license
|
||||||
|
*
|
||||||
|
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||||
|
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||||
|
* "Products"), provided that each user of the Products must obtain their own
|
||||||
|
* Spine Editor license and redistribution of the Products in any form must
|
||||||
|
* include this license and copyright notice.
|
||||||
|
*
|
||||||
|
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||||
|
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <spine-sdl-c.h>
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO)) {
|
||||||
|
printf("Error: %s", SDL_GetError());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
SDL_Window *window = SDL_CreateWindow("Spine SDL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, 0);
|
||||||
|
if (!window) {
|
||||||
|
printf("Error: %s", SDL_GetError());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||||
|
if (!renderer) {
|
||||||
|
printf("Error: %s", SDL_GetError());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
spAtlas *atlas = spAtlas_createFromFile("/Users/badlogic/workspaces/spine-runtimes/examples/spineboy/export/spineboy.atlas", renderer);
|
||||||
|
spSkeletonJson *json = spSkeletonJson_create(atlas);
|
||||||
|
json->scale = 0.5f;
|
||||||
|
spSkeletonData *skeletonData = spSkeletonJson_readSkeletonDataFile(json, "/Users/badlogic/workspaces/spine-runtimes/examples/spineboy/export/spineboy-pro.json");
|
||||||
|
spAnimationStateData *animationStateData = spAnimationStateData_create(skeletonData);
|
||||||
|
spSkeletonDrawable *drawable = spSkeletonDrawable_create(skeletonData, animationStateData);
|
||||||
|
|
||||||
|
drawable->skeleton->x = 400; drawable->skeleton->y = 500;
|
||||||
|
spSkeleton_setToSetupPose(drawable->skeleton);
|
||||||
|
spSkeletonDrawable_update(drawable, 0);
|
||||||
|
spAnimationState_setAnimationByName(drawable->animationState, 0, "run", -1);
|
||||||
|
|
||||||
|
int quit = 0;
|
||||||
|
uint64_t lastFrameTime = SDL_GetPerformanceCounter();
|
||||||
|
while (!quit) {
|
||||||
|
SDL_Event event;
|
||||||
|
while (SDL_PollEvent(&event) != 0) {
|
||||||
|
if (event.type == SDL_QUIT) {
|
||||||
|
quit = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_SetRenderDrawColor(renderer, 94, 93, 96, 255);
|
||||||
|
SDL_RenderClear(renderer);
|
||||||
|
|
||||||
|
uint64_t now = SDL_GetPerformanceCounter();
|
||||||
|
double deltaTime = (now - lastFrameTime) / (double) SDL_GetPerformanceFrequency();
|
||||||
|
lastFrameTime = now;
|
||||||
|
|
||||||
|
spSkeletonDrawable_update(drawable, deltaTime);
|
||||||
|
spSkeletonDrawable_draw(drawable, renderer);
|
||||||
|
|
||||||
|
SDL_RenderPresent(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
SDL_Quit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1,3 +1,32 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Spine Runtimes License Agreement
|
||||||
|
* Last updated September 24, 2021. Replaces all prior versions.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2021, Esoteric Software LLC
|
||||||
|
*
|
||||||
|
* Integration of the Spine Runtimes into software or otherwise creating
|
||||||
|
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||||
|
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||||
|
* http://esotericsoftware.com/spine-editor-license
|
||||||
|
*
|
||||||
|
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||||
|
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||||
|
* "Products"), provided that each user of the Products must obtain their own
|
||||||
|
* Spine Editor license and redistribution of the Products in any form must
|
||||||
|
* include this license and copyright notice.
|
||||||
|
*
|
||||||
|
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||||
|
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <spine-sdl-cpp.h>
|
#include <spine-sdl-cpp.h>
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
|
|||||||
@ -36,7 +36,10 @@
|
|||||||
|
|
||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
|
|
||||||
|
_SP_ARRAY_IMPLEMENT_TYPE_NO_CONTAINS(spSdlVertexArray, SDL_Vertex)
|
||||||
|
|
||||||
spSkeletonDrawable *spSkeletonDrawable_create(spSkeletonData *skeletonData, spAnimationStateData *animationStateData) {
|
spSkeletonDrawable *spSkeletonDrawable_create(spSkeletonData *skeletonData, spAnimationStateData *animationStateData) {
|
||||||
|
spBone_setYDown(-1);
|
||||||
spSkeletonDrawable *self = NEW(spSkeletonDrawable);
|
spSkeletonDrawable *self = NEW(spSkeletonDrawable);
|
||||||
self->skeleton = spSkeleton_create(skeletonData);
|
self->skeleton = spSkeleton_create(skeletonData);
|
||||||
self->animationState = spAnimationState_create(animationStateData);
|
self->animationState = spAnimationState_create(animationStateData);
|
||||||
@ -69,7 +72,7 @@ void spSkeletonDrawable_draw(spSkeletonDrawable *self, struct SDL_Renderer *rend
|
|||||||
spSkeletonClipping *clipper = self->clipper;
|
spSkeletonClipping *clipper = self->clipper;
|
||||||
SDL_Texture *texture;
|
SDL_Texture *texture;
|
||||||
SDL_Vertex sdlVertex;
|
SDL_Vertex sdlVertex;
|
||||||
for (unsigned i = 0; i < skeleton->slotsCount; ++i) {
|
for (int i = 0; i < skeleton->slotsCount; ++i) {
|
||||||
spSlot *slot = skeleton->drawOrder[i];
|
spSlot *slot = skeleton->drawOrder[i];
|
||||||
spAttachment *attachment = slot->attachment;
|
spAttachment *attachment = slot->attachment;
|
||||||
if (!attachment) continue;
|
if (!attachment) continue;
|
||||||
@ -100,8 +103,8 @@ void spSkeletonDrawable_draw(spSkeletonDrawable *self, struct SDL_Renderer *rend
|
|||||||
spFloatArray_setSize(vertices, 8);
|
spFloatArray_setSize(vertices, 8);
|
||||||
spRegionAttachment_computeWorldVertices(region, slot, vertices->items, 0, 2);
|
spRegionAttachment_computeWorldVertices(region, slot, vertices->items, 0, 2);
|
||||||
verticesCount = 4;
|
verticesCount = 4;
|
||||||
uvs = ®ion->uvs;
|
uvs = region->uvs;
|
||||||
indices = &quadIndices;
|
indices = quadIndices;
|
||||||
indicesCount = 6;
|
indicesCount = 6;
|
||||||
texture = (SDL_Texture *) ((spAtlasRegion*)region->rendererObject)->page->rendererObject;
|
texture = (SDL_Texture *) ((spAtlasRegion*)region->rendererObject)->page->rendererObject;
|
||||||
} else if (attachment->type == SP_ATTACHMENT_MESH) {
|
} else if (attachment->type == SP_ATTACHMENT_MESH) {
|
||||||
@ -115,7 +118,7 @@ void spSkeletonDrawable_draw(spSkeletonDrawable *self, struct SDL_Renderer *rend
|
|||||||
}
|
}
|
||||||
|
|
||||||
spFloatArray_setSize(vertices, mesh->super.worldVerticesLength);
|
spFloatArray_setSize(vertices, mesh->super.worldVerticesLength);
|
||||||
spVertexAttachment_computeWorldVertices(SUPER(mesh), slot, 0, mesh->super.worldVerticesLength, vertices, 0, 2);
|
spVertexAttachment_computeWorldVertices(SUPER(mesh), slot, 0, mesh->super.worldVerticesLength, vertices->items, 0, 2);
|
||||||
verticesCount = mesh->super.worldVerticesLength >> 1;
|
verticesCount = mesh->super.worldVerticesLength >> 1;
|
||||||
uvs = mesh->uvs;
|
uvs = mesh->uvs;
|
||||||
indices = mesh->triangles;
|
indices = mesh->triangles;
|
||||||
@ -138,8 +141,8 @@ void spSkeletonDrawable_draw(spSkeletonDrawable *self, struct SDL_Renderer *rend
|
|||||||
sdlVertex.color.a = a;
|
sdlVertex.color.a = a;
|
||||||
|
|
||||||
if (spSkeletonClipping_isClipping(clipper)) {
|
if (spSkeletonClipping_isClipping(clipper)) {
|
||||||
spSkeletonClipping_clipTriangles(clipper, vertices, verticesCount << 1, indices, indicesCount, uvs, 2);
|
spSkeletonClipping_clipTriangles(clipper, vertices->items, verticesCount << 1, indices, indicesCount, uvs, 2);
|
||||||
vertices = clipper->clippedVertices->items;
|
vertices = clipper->clippedVertices;
|
||||||
verticesCount = clipper->clippedVertices->size >> 1;
|
verticesCount = clipper->clippedVertices->size >> 1;
|
||||||
uvs = clipper->clippedUVs->items;
|
uvs = clipper->clippedUVs->items;
|
||||||
indices = clipper->clippedTriangles->items;
|
indices = clipper->clippedTriangles->items;
|
||||||
@ -184,7 +187,7 @@ void _spAtlasPage_createTexture(spAtlasPage *self, const char *path) {
|
|||||||
int width, height, components;
|
int width, height, components;
|
||||||
stbi_uc *imageData = stbi_load(path, &width, &height, &components, 4);
|
stbi_uc *imageData = stbi_load(path, &width, &height, &components, 4);
|
||||||
if (!imageData) return;
|
if (!imageData) return;
|
||||||
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STATIC, width,
|
SDL_Texture *texture = SDL_CreateTexture((SDL_Renderer*)self->atlas->rendererObject, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STATIC, width,
|
||||||
height);
|
height);
|
||||||
if (!texture) {
|
if (!texture) {
|
||||||
stbi_image_free(imageData);
|
stbi_image_free(imageData);
|
||||||
@ -195,6 +198,7 @@ void _spAtlasPage_createTexture(spAtlasPage *self, const char *path) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
stbi_image_free(imageData);
|
stbi_image_free(imageData);
|
||||||
|
self->rendererObject = texture;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -39,7 +39,7 @@ extern "C" {
|
|||||||
struct SDL_Renderer;
|
struct SDL_Renderer;
|
||||||
struct SDL_Texture;
|
struct SDL_Texture;
|
||||||
struct SDL_Vertex;
|
struct SDL_Vertex;
|
||||||
_SP_ARRAY_DECLARE_TYPE(spSdlVertexArray, struct SDL_Vertex);
|
_SP_ARRAY_DECLARE_TYPE(spSdlVertexArray, struct SDL_Vertex)
|
||||||
|
|
||||||
typedef struct spSkeletonDrawable {
|
typedef struct spSkeletonDrawable {
|
||||||
spSkeleton *skeleton;
|
spSkeleton *skeleton;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user