mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-06 07:14:55 +08:00
Texture atlas data loader, libgdx format.
This commit is contained in:
parent
1f8620f191
commit
5efed09862
62
spine-cpp/includes/spine/AtlasData.h
Normal file
62
spine-cpp/includes/spine/AtlasData.h
Normal file
@ -0,0 +1,62 @@
|
||||
#ifndef SPINE_ATLASDATA_H_
|
||||
#define SPINE_ATLASDATA_H_
|
||||
|
||||
#include <istream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace spine {
|
||||
|
||||
class AtlasPage;
|
||||
class AtlasRegion;
|
||||
|
||||
class AtlasData {
|
||||
public:
|
||||
std::vector<AtlasPage*> pages;
|
||||
std::vector<AtlasRegion*> regions;
|
||||
|
||||
AtlasData (const char *begin, const char *end);
|
||||
AtlasData (const std::string &json);
|
||||
AtlasData (std::istream &file);
|
||||
~AtlasData ();
|
||||
|
||||
private:
|
||||
void init (const char *begin, const char *end);
|
||||
};
|
||||
|
||||
enum Format {
|
||||
alpha, intensity, luminanceAlpha, rgb565, rgba4444, rgb888, rgba8888
|
||||
};
|
||||
|
||||
enum TextureFilter {
|
||||
nearest, linear, mipMap, mipMapNearestNearest, mipMapLinearNearest, mipMapNearestLinear, mipMapLinearLinear
|
||||
};
|
||||
|
||||
enum TextureWrap {
|
||||
mirroredRepeat, clampToEdge, repeat
|
||||
};
|
||||
|
||||
class AtlasPage {
|
||||
public:
|
||||
std::string name;
|
||||
Format format;
|
||||
TextureFilter minFilter, magFilter;
|
||||
TextureWrap uWrap, vWrap;
|
||||
};
|
||||
|
||||
class AtlasRegion {
|
||||
public:
|
||||
std::string name;
|
||||
AtlasPage *page;
|
||||
int x, y, width, height;
|
||||
float offsetX, offsetY;
|
||||
int originalWidth, originalHeight;
|
||||
int index;
|
||||
bool rotate;
|
||||
bool flip;
|
||||
int *splits;
|
||||
int *pads;
|
||||
};
|
||||
|
||||
} /* namespace spine */
|
||||
#endif /* SPINE_ATLASDATA_H_ */
|
||||
@ -1,6 +1,7 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <spine/BaseSkeleton.h>
|
||||
#include <spine/AtlasData.h>
|
||||
#include <spine-sfml/spine.h>
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
@ -25,6 +26,9 @@ int main () {
|
||||
}
|
||||
cout << flush;
|
||||
|
||||
ifstream file2("../uiskin.atlas");
|
||||
new AtlasData(file2);
|
||||
|
||||
sf::RenderWindow window(sf::VideoMode(640, 480), "Spine SFML");
|
||||
window.setFramerateLimit(60);
|
||||
|
||||
@ -32,7 +36,7 @@ int main () {
|
||||
shape.setFillColor(sf::Color::Green);
|
||||
|
||||
sf::Event event;
|
||||
while (window.isOpen()) {
|
||||
while (window.isOpen() && false) {
|
||||
while (window.pollEvent(event))
|
||||
if (event.type == sf::Event::Closed) window.close();
|
||||
window.clear();
|
||||
|
||||
169
spine-cpp/src/spine/AtlasData.cpp
Normal file
169
spine-cpp/src/spine/AtlasData.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <stdexcept>
|
||||
#include <spine/AtlasData.h>
|
||||
|
||||
using std::string;
|
||||
using std::runtime_error;
|
||||
|
||||
namespace spine {
|
||||
|
||||
static inline string& trim (string &s) {
|
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
|
||||
return s;
|
||||
}
|
||||
|
||||
static inline void readLine (const char *¤t, const char *end, string &value) {
|
||||
const char *begin = current;
|
||||
while (current != end) {
|
||||
char c = *current++;
|
||||
if (c == '\n') break;
|
||||
}
|
||||
value.clear();
|
||||
value.append(begin, current - 1);
|
||||
}
|
||||
|
||||
static inline string& readValue (const char *&begin, const char *end, string &value) {
|
||||
readLine(begin, end, value);
|
||||
int colon = value.find(':');
|
||||
if (colon == -1) throw runtime_error("Invalid line: " + value);
|
||||
value = value.substr(colon + 1);
|
||||
return trim(value);
|
||||
}
|
||||
|
||||
/** Returns the number of tuple values read (2 or 4). */
|
||||
static inline int readTuple (const char *&begin, const char *end, string &value, string tuple[4]) {
|
||||
readLine(begin, end, value);
|
||||
int colon = value.find(':');
|
||||
if (colon == -1) throw runtime_error("Invalid line: " + value);
|
||||
int i = 0, lastMatch = colon + 1;
|
||||
for (i = 0; i < 3; i++) {
|
||||
int comma = value.find(',', lastMatch);
|
||||
if (comma == -1) {
|
||||
if (i == 0) throw runtime_error("Invalid line: " + value);
|
||||
break;
|
||||
}
|
||||
tuple[i] = value.substr(lastMatch, comma - lastMatch);
|
||||
trim(tuple[i]);
|
||||
lastMatch = comma + 1;
|
||||
}
|
||||
tuple[i] = value.substr(lastMatch);
|
||||
trim(tuple[i]);
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
static inline int indexOf (const string *array, int count, const string &value) {
|
||||
for (int i = count - 1; i >= 0; i--)
|
||||
if (array[i] == value) return i;
|
||||
throw runtime_error("Invalid value: " + value);
|
||||
}
|
||||
|
||||
static string formatNames[] = {"Alpha", "Intensity", "LuminanceAlpha", "RGB565", "RGBA4444", "RGB888", "RGBA8888"};
|
||||
static string textureFilterNames[] = {"Nearest", "Linear", "MipMap", "MipMapNearestNearest", "MipMapLinearNearest",
|
||||
"MipMapNearestLinear", "MipMapLinearLinear"};
|
||||
|
||||
AtlasData::AtlasData (std::istream &file) {
|
||||
string text;
|
||||
std::getline(file, text, (char)EOF);
|
||||
const char *begin = text.c_str();
|
||||
const char *end = begin + text.length();
|
||||
init(begin, end);
|
||||
}
|
||||
|
||||
AtlasData::AtlasData (const string &text) {
|
||||
const char *begin = text.c_str();
|
||||
const char *end = begin + text.length();
|
||||
init(begin, end);
|
||||
}
|
||||
|
||||
AtlasData::AtlasData (const char *begin, const char *end) {
|
||||
init(begin, end);
|
||||
}
|
||||
|
||||
void AtlasData::init (const char *current, const char *end) {
|
||||
string value;
|
||||
string tuple[4];
|
||||
AtlasPage *page;
|
||||
while (current != end) {
|
||||
readLine(current, end, value);
|
||||
trim(value);
|
||||
if (value.length() == 0) {
|
||||
page = 0;
|
||||
} else if (!page) {
|
||||
page = new AtlasPage();
|
||||
pages.push_back(page);
|
||||
page->name = value;
|
||||
page->format = static_cast<Format>(indexOf(formatNames, 7, readValue(current, end, value)));
|
||||
|
||||
readTuple(current, end, value, tuple);
|
||||
page->minFilter = static_cast<TextureFilter>(indexOf(textureFilterNames, 7, tuple[0]));
|
||||
page->magFilter = static_cast<TextureFilter>(indexOf(textureFilterNames, 7, tuple[1]));
|
||||
|
||||
readValue(current, end, value);
|
||||
if (value == "x") {
|
||||
page->uWrap = repeat;
|
||||
page->vWrap = clampToEdge;
|
||||
} else if (value == "y") {
|
||||
page->uWrap = clampToEdge;
|
||||
page->vWrap = repeat;
|
||||
} else if (value == "xy") {
|
||||
page->uWrap = repeat;
|
||||
page->vWrap = repeat;
|
||||
}
|
||||
} else {
|
||||
AtlasRegion *region = new AtlasRegion();
|
||||
regions.push_back(region);
|
||||
region->name = value;
|
||||
region->page = page;
|
||||
|
||||
region->rotate = readValue(current, end, value) == "true";
|
||||
|
||||
readTuple(current, end, value, tuple);
|
||||
region->x = atoi(tuple[0].c_str());
|
||||
region->y = atoi(tuple[1].c_str());
|
||||
|
||||
readTuple(current, end, value, tuple);
|
||||
region->width = atoi(tuple[0].c_str());
|
||||
region->height = atoi(tuple[1].c_str());
|
||||
|
||||
if (readTuple(current, end, value, tuple) == 4) { // split is optional
|
||||
region->splits = new int[4];
|
||||
region->splits[0] = atoi(tuple[0].c_str());
|
||||
region->splits[1] = atoi(tuple[1].c_str());
|
||||
region->splits[2] = atoi(tuple[2].c_str());
|
||||
region->splits[3] = atoi(tuple[3].c_str());
|
||||
|
||||
if (readTuple(current, end, value, tuple) == 4) { // pad is optional, but only present with splits
|
||||
region->pads = new int[4];
|
||||
region->pads[0] = atoi(tuple[0].c_str());
|
||||
region->pads[1] = atoi(tuple[1].c_str());
|
||||
region->pads[2] = atoi(tuple[2].c_str());
|
||||
region->pads[3] = atoi(tuple[3].c_str());
|
||||
|
||||
readTuple(current, end, value, tuple);
|
||||
}
|
||||
}
|
||||
|
||||
region->originalWidth = atoi(tuple[0].c_str());
|
||||
region->originalHeight = atoi(tuple[1].c_str());
|
||||
|
||||
readTuple(current, end, value, tuple);
|
||||
region->offsetX = atoi(tuple[0].c_str());
|
||||
region->offsetY = atoi(tuple[1].c_str());
|
||||
|
||||
region->index = atoi(readValue(current, end, value).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AtlasData::~AtlasData () {
|
||||
for (int i = 0, n = pages.size(); i < n; i++)
|
||||
delete pages[i];
|
||||
for (int i = 0, n = regions.size(); i < n; i++)
|
||||
delete regions[i];
|
||||
}
|
||||
|
||||
} /* namespace spine */
|
||||
198
spine-cpp/uiskin.atlas
Normal file
198
spine-cpp/uiskin.atlas
Normal file
@ -0,0 +1,198 @@
|
||||
|
||||
uiskin.png
|
||||
format: RGBA8888
|
||||
filter: Nearest,Nearest
|
||||
repeat: none
|
||||
default
|
||||
rotate: false
|
||||
xy: 1, 50
|
||||
size: 254, 77
|
||||
orig: 254, 77
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
default-window
|
||||
rotate: false
|
||||
xy: 1, 20
|
||||
size: 27, 29
|
||||
split: 4, 3, 20, 3
|
||||
orig: 27, 29
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
default-select
|
||||
rotate: false
|
||||
xy: 29, 29
|
||||
size: 27, 20
|
||||
split: 4, 14, 4, 4
|
||||
orig: 27, 20
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
default-round-large
|
||||
rotate: false
|
||||
xy: 57, 29
|
||||
size: 20, 20
|
||||
split: 5, 5, 5, 4
|
||||
orig: 20, 20
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
default-scroll
|
||||
rotate: false
|
||||
xy: 78, 29
|
||||
size: 20, 20
|
||||
split: 2, 2, 2, 2
|
||||
orig: 20, 20
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
default-slider-knob
|
||||
rotate: false
|
||||
xy: 1, 1
|
||||
size: 9, 18
|
||||
orig: 9, 18
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
default-round-down
|
||||
rotate: false
|
||||
xy: 99, 29
|
||||
size: 12, 20
|
||||
split: 5, 5, 5, 4
|
||||
orig: 12, 20
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
default-round
|
||||
rotate: false
|
||||
xy: 112, 29
|
||||
size: 12, 20
|
||||
split: 5, 5, 5, 4
|
||||
pad: 4, 4, 1, 1
|
||||
orig: 12, 20
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
check-off
|
||||
rotate: false
|
||||
xy: 11, 5
|
||||
size: 14, 14
|
||||
orig: 14, 14
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
textfield
|
||||
rotate: false
|
||||
xy: 11, 5
|
||||
size: 14, 14
|
||||
split: 3, 3, 3, 3
|
||||
orig: 14, 14
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
check-on
|
||||
rotate: false
|
||||
xy: 125, 35
|
||||
size: 14, 14
|
||||
orig: 14, 14
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
tree-minus
|
||||
rotate: false
|
||||
xy: 140, 35
|
||||
size: 14, 14
|
||||
orig: 14, 14
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
tree-plus
|
||||
rotate: false
|
||||
xy: 155, 35
|
||||
size: 14, 14
|
||||
orig: 14, 14
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
default-slider
|
||||
rotate: false
|
||||
xy: 29, 20
|
||||
size: 8, 8
|
||||
split: 2, 2, 2, 2
|
||||
orig: 8, 8
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
default-pane
|
||||
rotate: false
|
||||
xy: 11, 1
|
||||
size: 5, 3
|
||||
split: 1, 1, 1, 1
|
||||
orig: 5, 3
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
default-rect-pad
|
||||
rotate: false
|
||||
xy: 11, 1
|
||||
size: 5, 3
|
||||
split: 1, 1, 1, 1
|
||||
orig: 5, 3
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
default-splitpane
|
||||
rotate: false
|
||||
xy: 17, 1
|
||||
size: 5, 3
|
||||
split: 0, 5, 0, 0
|
||||
orig: 5, 3
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
cursor
|
||||
rotate: false
|
||||
xy: 23, 1
|
||||
size: 3, 3
|
||||
split: 1, 1, 1, 1
|
||||
orig: 3, 3
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
default-splitpane-vertical
|
||||
rotate: false
|
||||
xy: 125, 29
|
||||
size: 3, 5
|
||||
split: 0, 0, 0, 5
|
||||
orig: 3, 5
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
default-rect-down
|
||||
rotate: false
|
||||
xy: 170, 46
|
||||
size: 3, 3
|
||||
split: 1, 1, 1, 1
|
||||
orig: 3, 3
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
default-rect
|
||||
rotate: false
|
||||
xy: 38, 25
|
||||
size: 3, 3
|
||||
split: 1, 1, 1, 1
|
||||
orig: 3, 3
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
default-select-selection
|
||||
rotate: false
|
||||
xy: 26, 16
|
||||
size: 3, 3
|
||||
split: 1, 1, 1, 1
|
||||
orig: 3, 3
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
default-pane-noborder
|
||||
rotate: false
|
||||
xy: 129, 33
|
||||
size: 1, 1
|
||||
split: 0, 0, 0, 0
|
||||
orig: 1, 1
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
selection
|
||||
rotate: false
|
||||
xy: 170, 44
|
||||
size: 1, 1
|
||||
orig: 1, 1
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
white
|
||||
rotate: false
|
||||
xy: 174, 48
|
||||
size: 1, 1
|
||||
orig: 1, 1
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
Loading…
x
Reference in New Issue
Block a user