Texture atlas data loader, libgdx format.

This commit is contained in:
NathanSweet 2013-02-22 03:08:06 +01:00
parent 1f8620f191
commit 5efed09862
4 changed files with 434 additions and 1 deletions

View 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_ */

View File

@ -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();

View 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 *&current, 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
View 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