add <image ...> atlases support
This commit is contained in:
parent
c0dca31e98
commit
2dffdf757c
@ -235,7 +235,6 @@ std::unique_ptr<ImageData> _png_load(const char* file){
|
|||||||
FILE *png = nullptr;
|
FILE *png = nullptr;
|
||||||
char *pngbuf = nullptr;
|
char *pngbuf = nullptr;
|
||||||
spng_ctx *ctx = nullptr;
|
spng_ctx *ctx = nullptr;
|
||||||
unsigned char *out = nullptr;
|
|
||||||
|
|
||||||
png = fopen(file, "rb");
|
png = fopen(file, "rb");
|
||||||
if (png == nullptr){
|
if (png == nullptr){
|
||||||
@ -297,27 +296,24 @@ std::unique_ptr<ImageData> _png_load(const char* file){
|
|||||||
logger.error() << "spng_decoded_image_size(): " << spng_strerror(r);
|
logger.error() << "spng_decoded_image_size(): " << spng_strerror(r);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
out = new unsigned char[out_size];
|
auto out = std::make_unique<ubyte[]>(out_size);
|
||||||
r = spng_decode_image(ctx, out, out_size, SPNG_FMT_RGBA8, 0);
|
r = spng_decode_image(ctx, out.get(), out_size, SPNG_FMT_RGBA8, 0);
|
||||||
if (r != SPNG_SUCCESS){
|
if (r != SPNG_SUCCESS){
|
||||||
delete[] out;
|
|
||||||
delete[] pngbuf;
|
delete[] pngbuf;
|
||||||
spng_ctx_free(ctx);
|
spng_ctx_free(ctx);
|
||||||
logger.error() << "spng_decode_image(): " << spng_strerror(r);
|
logger.error() << "spng_decode_image(): " << spng_strerror(r);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* flipped = new unsigned char[out_size];
|
auto flipped = std::make_unique<ubyte[]>(out_size);
|
||||||
|
|
||||||
for (size_t i = 0; i < ihdr.height; i+=1){
|
for (size_t i = 0; i < ihdr.height; i+=1){
|
||||||
size_t rowsize = ihdr.width*4;
|
size_t rowsize = ihdr.width*4;
|
||||||
for (size_t j = 0; j < rowsize; j++){
|
for (size_t j = 0; j < rowsize; j++){
|
||||||
flipped[(ihdr.height-i-1)*rowsize+j] = out[i*rowsize+j];
|
flipped[(ihdr.height-i-1)*rowsize+j] = out[i*rowsize+j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete[] out; // <- finally delete out // no, delete spng usage
|
|
||||||
|
|
||||||
auto image = std::make_unique<ImageData>(ImageFormat::rgba8888, ihdr.width, ihdr.height, (void*)flipped);
|
auto image = std::make_unique<ImageData>(ImageFormat::rgba8888, ihdr.width, ihdr.height, std::move(flipped));
|
||||||
|
|
||||||
delete[] pngbuf;
|
delete[] pngbuf;
|
||||||
spng_ctx_free(ctx);
|
spng_ctx_free(ctx);
|
||||||
|
|||||||
@ -39,6 +39,7 @@ void Batch2D::setPrimitive(DrawPrimitive primitive) {
|
|||||||
void Batch2D::begin(){
|
void Batch2D::begin(){
|
||||||
currentTexture = nullptr;
|
currentTexture = nullptr;
|
||||||
blank->bind();
|
blank->bind();
|
||||||
|
region = blank->getUVRegion();
|
||||||
color = glm::vec4(1.0f);
|
color = glm::vec4(1.0f);
|
||||||
primitive = DrawPrimitive::triangle;
|
primitive = DrawPrimitive::triangle;
|
||||||
}
|
}
|
||||||
@ -50,8 +51,8 @@ void Batch2D::vertex(
|
|||||||
) {
|
) {
|
||||||
buffer[index++] = x;
|
buffer[index++] = x;
|
||||||
buffer[index++] = y;
|
buffer[index++] = y;
|
||||||
buffer[index++] = u;
|
buffer[index++] = u * region.getWidth() + region.u1;
|
||||||
buffer[index++] = v;
|
buffer[index++] = v * region.getHeight() + region.v1;
|
||||||
buffer[index++] = r;
|
buffer[index++] = r;
|
||||||
buffer[index++] = g;
|
buffer[index++] = g;
|
||||||
buffer[index++] = b;
|
buffer[index++] = b;
|
||||||
@ -64,8 +65,8 @@ void Batch2D::vertex(
|
|||||||
) {
|
) {
|
||||||
buffer[index++] = point.x;
|
buffer[index++] = point.x;
|
||||||
buffer[index++] = point.y;
|
buffer[index++] = point.y;
|
||||||
buffer[index++] = uvpoint.x;
|
buffer[index++] = uvpoint.x * region.getWidth() + region.u1;
|
||||||
buffer[index++] = uvpoint.y;
|
buffer[index++] = uvpoint.y * region.getHeight() + region.v1;
|
||||||
buffer[index++] = r;
|
buffer[index++] = r;
|
||||||
buffer[index++] = g;
|
buffer[index++] = g;
|
||||||
buffer[index++] = b;
|
buffer[index++] = b;
|
||||||
@ -80,8 +81,10 @@ void Batch2D::texture(Texture* new_texture){
|
|||||||
currentTexture = new_texture;
|
currentTexture = new_texture;
|
||||||
if (new_texture == nullptr) {
|
if (new_texture == nullptr) {
|
||||||
blank->bind();
|
blank->bind();
|
||||||
|
region = blank->getUVRegion();
|
||||||
} else {
|
} else {
|
||||||
new_texture->bind();
|
new_texture->bind();
|
||||||
|
region = currentTexture->getUVRegion();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,6 +92,10 @@ void Batch2D::untexture() {
|
|||||||
texture(nullptr);
|
texture(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Batch2D::setRegion(UVRegion region) {
|
||||||
|
this->region = region;
|
||||||
|
}
|
||||||
|
|
||||||
void Batch2D::point(float x, float y, float r, float g, float b, float a){
|
void Batch2D::point(float x, float y, float r, float g, float b, float a){
|
||||||
if (index + 6*B2D_VERTEX_SIZE >= capacity)
|
if (index + 6*B2D_VERTEX_SIZE >= capacity)
|
||||||
flush();
|
flush();
|
||||||
|
|||||||
@ -6,10 +6,10 @@
|
|||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
#include "commons.hpp"
|
#include "commons.hpp"
|
||||||
|
#include "../../maths/UVRegion.hpp"
|
||||||
|
|
||||||
class Mesh;
|
class Mesh;
|
||||||
class Texture;
|
class Texture;
|
||||||
struct UVRegion;
|
|
||||||
|
|
||||||
class Batch2D {
|
class Batch2D {
|
||||||
std::unique_ptr<float[]> buffer;
|
std::unique_ptr<float[]> buffer;
|
||||||
@ -20,6 +20,7 @@ class Batch2D {
|
|||||||
glm::vec4 color;
|
glm::vec4 color;
|
||||||
Texture* currentTexture;
|
Texture* currentTexture;
|
||||||
DrawPrimitive primitive = DrawPrimitive::triangle;
|
DrawPrimitive primitive = DrawPrimitive::triangle;
|
||||||
|
UVRegion region {0.0f, 0.0f, 1.0f, 1.0f};
|
||||||
|
|
||||||
void setPrimitive(DrawPrimitive primitive);
|
void setPrimitive(DrawPrimitive primitive);
|
||||||
|
|
||||||
@ -42,6 +43,7 @@ public:
|
|||||||
void begin();
|
void begin();
|
||||||
void texture(Texture* texture);
|
void texture(Texture* texture);
|
||||||
void untexture();
|
void untexture();
|
||||||
|
void setRegion(UVRegion region);
|
||||||
void sprite(float x, float y, float w, float h, const UVRegion& region, glm::vec4 tint);
|
void sprite(float x, float y, float w, float h, const UVRegion& region, glm::vec4 tint);
|
||||||
void sprite(float x, float y, float w, float h, int atlasRes, int index, glm::vec4 tint);
|
void sprite(float x, float y, float w, float h, int atlasRes, int index, glm::vec4 tint);
|
||||||
void point(float x, float y, float r, float g, float b, float a);
|
void point(float x, float y, float r, float g, float b, float a);
|
||||||
|
|||||||
@ -20,6 +20,10 @@ public:
|
|||||||
virtual std::unique_ptr<ImageData> readData() override;
|
virtual std::unique_ptr<ImageData> readData() override;
|
||||||
virtual uint getId() const override;
|
virtual uint getId() const override;
|
||||||
|
|
||||||
|
virtual UVRegion getUVRegion() const override {
|
||||||
|
return UVRegion(0.0f, 0.0f, 1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
static std::unique_ptr<GLTexture> from(const ImageData* image);
|
static std::unique_ptr<GLTexture> from(const ImageData* image);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#define GRAPHICS_CORE_TEXTURE_HPP_
|
#define GRAPHICS_CORE_TEXTURE_HPP_
|
||||||
|
|
||||||
#include "../../typedefs.hpp"
|
#include "../../typedefs.hpp"
|
||||||
|
#include "../../maths/UVRegion.hpp"
|
||||||
#include "ImageData.hpp"
|
#include "ImageData.hpp"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -28,6 +29,7 @@ public:
|
|||||||
virtual uint getHeight() const {
|
virtual uint getHeight() const {
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
virtual UVRegion getUVRegion() const = 0;
|
||||||
|
|
||||||
virtual uint getId() const = 0;
|
virtual uint getId() const = 0;
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include "../../core/DrawContext.hpp"
|
#include "../../core/DrawContext.hpp"
|
||||||
#include "../../core/Batch2D.hpp"
|
#include "../../core/Batch2D.hpp"
|
||||||
#include "../../core/Texture.hpp"
|
#include "../../core/Texture.hpp"
|
||||||
|
#include "../../core/Atlas.hpp"
|
||||||
#include "../../../assets/Assets.hpp"
|
#include "../../../assets/Assets.hpp"
|
||||||
#include "../../../maths/UVRegion.hpp"
|
#include "../../../maths/UVRegion.hpp"
|
||||||
|
|
||||||
@ -18,11 +19,28 @@ void Image::draw(const DrawContext* pctx, Assets* assets) {
|
|||||||
glm::vec2 pos = calcPos();
|
glm::vec2 pos = calcPos();
|
||||||
auto batch = pctx->getBatch2D();
|
auto batch = pctx->getBatch2D();
|
||||||
|
|
||||||
auto texture = assets->get<Texture>(this->texture);
|
Texture* texture = nullptr;
|
||||||
|
auto separator = this->texture.find(':');
|
||||||
|
if (separator == std::string::npos) {
|
||||||
|
texture = assets->get<Texture>(this->texture);
|
||||||
|
batch->texture(texture);
|
||||||
if (texture && autoresize) {
|
if (texture && autoresize) {
|
||||||
setSize(glm::vec2(texture->getWidth(), texture->getHeight()));
|
setSize(glm::vec2(texture->getWidth(), texture->getHeight()));
|
||||||
}
|
}
|
||||||
batch->texture(texture);
|
} else {
|
||||||
|
auto atlasName = this->texture.substr(0, separator);
|
||||||
|
if (auto atlas = assets->get<Atlas>(atlasName)) {
|
||||||
|
texture = atlas->getTexture();
|
||||||
|
batch->texture(atlas->getTexture());
|
||||||
|
auto& region = atlas->get(this->texture.substr(separator+1));
|
||||||
|
batch->setRegion(region);
|
||||||
|
if (autoresize) {
|
||||||
|
setSize(glm::vec2(
|
||||||
|
texture->getWidth()*region.getWidth(),
|
||||||
|
texture->getHeight()*region.getHeight()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
batch->rect(
|
batch->rect(
|
||||||
pos.x, pos.y, size.x, size.y,
|
pos.x, pos.y, size.x, size.y,
|
||||||
0, 0, 0, UVRegion(), false, true, calcColor()
|
0, 0, 0, UVRegion(), false, true, calcColor()
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
#ifndef MATHS_UVREGION_HPP_
|
#ifndef MATHS_UVREGION_HPP_
|
||||||
#define MATHS_UVREGION_HPP_
|
#define MATHS_UVREGION_HPP_
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
struct UVRegion {
|
struct UVRegion {
|
||||||
float u1;
|
float u1;
|
||||||
float v1;
|
float v1;
|
||||||
@ -11,6 +13,14 @@ struct UVRegion {
|
|||||||
: u1(u1), v1(v1), u2(u2), v2(v2){}
|
: u1(u1), v1(v1), u2(u2), v2(v2){}
|
||||||
|
|
||||||
UVRegion() : u1(0.0f), v1(0.0f), u2(1.0f), v2(1.0f){}
|
UVRegion() : u1(0.0f), v1(0.0f), u2(1.0f), v2(1.0f){}
|
||||||
|
|
||||||
|
inline float getWidth() const {
|
||||||
|
return fabs(u2-u1);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float getHeight() const {
|
||||||
|
return fabs(v2-v1);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MATHS_UVREGION_HPP_
|
#endif // MATHS_UVREGION_HPP_
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user