Files

223 lines
5.0 KiB
C++
Raw Permalink Normal View History

2019-01-18 15:55:06 +01:00
#include "texture.hpp"
#include "cachedtexture.hpp"
2019-01-18 17:04:17 +01:00
#include "geom.hpp"
2014-01-31 08:23:00 +13:00
2019-01-18 21:26:42 +01:00
#include <gxgraphics.hpp>
#include <gxcanvas.hpp>
#include <stdutil.hpp>
2014-01-31 08:23:00 +13:00
2019-01-18 17:04:17 +01:00
extern gxScene* gx_scene;
extern gxGraphics* gx_graphics;
2014-01-31 08:23:00 +13:00
struct Filter {
2019-01-18 21:26:42 +01:00
std::string t;
int flags;
Filter(const std::string& t, int flags) : t(t), flags(flags) {}
2014-01-31 08:23:00 +13:00
};
2019-01-18 21:26:42 +01:00
static std::vector<Filter> filters;
2014-01-31 08:23:00 +13:00
2019-01-18 21:26:42 +01:00
static int filterFile(const std::string& t, int flags)
2019-01-18 17:04:17 +01:00
{
2014-01-31 08:23:00 +13:00
//check filters...
2019-01-18 21:26:42 +01:00
std::string l = tolower(t);
for (size_t k = 0; k < filters.size(); ++k) {
2019-01-18 21:26:42 +01:00
if (l.find(filters[k].t) != std::string::npos) {
flags |= filters[k].flags;
2014-01-31 08:23:00 +13:00
}
}
return flags;
}
struct Texture::Rep {
2019-01-18 21:26:42 +01:00
int ref_cnt;
CachedTexture cached_tex;
std::vector<gxCanvas*> tex_frames;
2014-01-31 08:23:00 +13:00
2019-01-18 17:04:17 +01:00
int tex_blend, tex_flags;
2014-01-31 08:23:00 +13:00
bool transparent;
2019-01-18 17:04:17 +01:00
float sx, sy, tx, ty, rot;
bool mat_used, mat_valid;
2014-01-31 08:23:00 +13:00
gxScene::Matrix matrix;
2019-01-18 17:04:17 +01:00
Rep(int w, int h, int flags, int cnt)
: ref_cnt(1), cached_tex(w, h, flags, cnt), tex_blend(gxScene::BLEND_MULTIPLY), tex_flags(0), sx(1), sy(1),
tx(0), ty(0), rot(0), mat_used(false)
{
tex_frames = cached_tex.getFrames();
transparent = (flags & gxCanvas::CANVAS_TEX_ALPHA) && !(flags & gxCanvas::CANVAS_TEX_MASK);
memset(&matrix, 0, sizeof(matrix));
2014-01-31 08:23:00 +13:00
}
2019-01-18 21:26:42 +01:00
Rep(const std::string& f, int flags, int w, int h, int first, int cnt)
2019-01-18 17:04:17 +01:00
: ref_cnt(1), cached_tex(f, flags, w, h, first, cnt), tex_blend(gxScene::BLEND_MULTIPLY), tex_flags(0), sx(1),
sy(1), tx(0), ty(0), rot(0), mat_used(false)
{
tex_frames = cached_tex.getFrames();
transparent = (flags & gxCanvas::CANVAS_TEX_ALPHA) && !(flags & gxCanvas::CANVAS_TEX_MASK);
memset(&matrix, 0, sizeof(matrix));
2014-01-31 08:23:00 +13:00
}
2019-01-18 17:04:17 +01:00
Rep(const Rep& t)
: ref_cnt(1), cached_tex(t.cached_tex), tex_frames(t.tex_frames), tex_blend(t.tex_blend),
tex_flags(t.tex_flags), sx(t.sx), sy(t.sy), tx(t.tx), ty(t.ty), rot(t.rot), mat_used(t.mat_used),
mat_valid(t.mat_valid), matrix(t.matrix), transparent(t.transparent)
{}
2014-01-31 08:23:00 +13:00
};
2019-01-18 17:04:17 +01:00
Texture::Texture() : rep(0) {}
2014-01-31 08:23:00 +13:00
2019-01-18 21:26:42 +01:00
Texture::Texture(const std::string& f, int flags)
2019-01-18 17:04:17 +01:00
{
flags = filterFile(f, flags) | gxCanvas::CANVAS_TEXTURE;
2019-01-18 17:04:17 +01:00
if (flags & gxCanvas::CANVAS_TEX_MASK)
flags |= gxCanvas::CANVAS_TEX_RGB | gxCanvas::CANVAS_TEX_ALPHA;
2016-10-03 17:11:15 +02:00
rep = new Rep(f, flags, 0, 0, 0, 1);
2014-01-31 08:23:00 +13:00
}
2019-01-18 21:26:42 +01:00
Texture::Texture(const std::string& f, int flags, int w, int h, int first, int cnt)
2019-01-18 17:04:17 +01:00
{
flags = filterFile(f, flags) | gxCanvas::CANVAS_TEXTURE;
2019-01-18 17:04:17 +01:00
if (flags & gxCanvas::CANVAS_TEX_MASK)
flags |= gxCanvas::CANVAS_TEX_RGB | gxCanvas::CANVAS_TEX_ALPHA;
2016-10-03 17:11:15 +02:00
rep = new Rep(f, flags, w, h, first, cnt);
2014-01-31 08:23:00 +13:00
}
2019-01-18 17:04:17 +01:00
Texture::Texture(int w, int h, int flags, int cnt)
{
flags |= gxCanvas::CANVAS_TEXTURE;
2019-01-18 17:04:17 +01:00
if (flags & gxCanvas::CANVAS_TEX_MASK)
flags |= gxCanvas::CANVAS_TEX_RGB | gxCanvas::CANVAS_TEX_ALPHA;
2016-10-03 17:11:15 +02:00
rep = new Rep(w, h, flags, cnt);
2014-01-31 08:23:00 +13:00
}
2019-01-18 17:04:17 +01:00
Texture::Texture(const Texture& t) : rep(t.rep)
{
if (rep)
++rep->ref_cnt;
2014-01-31 08:23:00 +13:00
}
2019-01-18 17:04:17 +01:00
Texture::~Texture()
{
if (rep && !--rep->ref_cnt)
delete rep;
2014-01-31 08:23:00 +13:00
}
2019-01-18 17:04:17 +01:00
Texture& Texture::operator=(const Texture& t)
{
if (t.rep)
++t.rep->ref_cnt;
if (rep && !--rep->ref_cnt)
delete rep;
rep = t.rep;
2014-01-31 08:23:00 +13:00
return *this;
}
2019-01-18 17:04:17 +01:00
void Texture::setScale(float u_scale, float v_scale)
{
if (!rep)
return;
rep->sx = u_scale;
rep->sy = v_scale;
rep->mat_valid = false;
2019-01-18 17:04:17 +01:00
rep->mat_used = true;
2014-01-31 08:23:00 +13:00
}
2019-01-18 17:04:17 +01:00
void Texture::setRotation(float angle)
{
if (!rep)
return;
rep->rot = angle;
rep->mat_valid = false;
2019-01-18 17:04:17 +01:00
rep->mat_used = true;
2014-01-31 08:23:00 +13:00
}
2019-01-18 17:04:17 +01:00
void Texture::setPosition(float u_pos, float v_pos)
{
if (!rep)
return;
rep->tx = u_pos;
rep->ty = v_pos;
rep->mat_valid = false;
2019-01-18 17:04:17 +01:00
rep->mat_used = true;
2014-01-31 08:23:00 +13:00
}
2019-01-18 17:04:17 +01:00
void Texture::setBlend(int blend)
{
if (!rep)
return;
rep->tex_blend = blend;
2014-01-31 08:23:00 +13:00
}
2019-01-18 17:04:17 +01:00
void Texture::setFlags(int flags)
{
if (!rep)
return;
rep->tex_flags = flags;
2014-01-31 08:23:00 +13:00
}
2019-01-18 17:04:17 +01:00
bool Texture::isTransparent() const
{
2014-01-31 08:23:00 +13:00
return rep ? rep->transparent : false;
}
2019-01-18 17:04:17 +01:00
gxCanvas* Texture::getCanvas(int n) const
{
return rep && n >= 0 && n < rep->tex_frames.size() ? rep->tex_frames[n] : 0;
2014-01-31 08:23:00 +13:00
}
2019-01-18 17:04:17 +01:00
int Texture::getCanvasFlags() const
{
2014-01-31 08:23:00 +13:00
return rep && rep->tex_frames.size() ? rep->tex_frames[0]->getFlags() : 0;
}
2019-01-18 21:26:42 +01:00
CachedTexture* Texture::getCachedTexture() const
2019-01-18 17:04:17 +01:00
{
2014-01-31 08:23:00 +13:00
return rep ? &rep->cached_tex : 0;
}
2019-01-18 17:04:17 +01:00
int Texture::getBlend() const
{
2014-01-31 08:23:00 +13:00
return rep ? rep->tex_blend : 0;
}
2019-01-18 17:04:17 +01:00
int Texture::getFlags() const
{
2014-01-31 08:23:00 +13:00
return rep ? rep->tex_flags : 0;
}
2019-01-18 17:04:17 +01:00
const gxScene::Matrix* Texture::getMatrix() const
{
if (!rep || !rep->mat_used)
return 0;
if (!rep->mat_valid) {
float c = cos(rep->rot), s = sin(rep->rot);
2019-01-18 17:04:17 +01:00
rep->matrix.elements[0][0] = c * rep->sx;
rep->matrix.elements[1][0] = s * rep->sx;
rep->matrix.elements[0][1] = -s * rep->sy;
rep->matrix.elements[1][1] = c * rep->sy;
rep->matrix.elements[2][0] = rep->tx;
rep->matrix.elements[2][1] = rep->ty;
2019-01-18 17:04:17 +01:00
rep->mat_valid = true;
2014-01-31 08:23:00 +13:00
}
return &rep->matrix;
}
2019-01-18 17:04:17 +01:00
bool Texture::operator<(const Texture& t) const
{
if (rep && t.rep)
return rep->cached_tex < t.rep->cached_tex;
return rep < t.rep;
2014-01-31 08:23:00 +13:00
}
2019-01-18 17:04:17 +01:00
void Texture::clearFilters()
{
2014-01-31 08:23:00 +13:00
filters.clear();
}
2019-01-18 21:26:42 +01:00
void Texture::addFilter(const std::string& t, int flags)
2019-01-18 17:04:17 +01:00
{
filters.push_back(Filter(tolower(t), flags));
2014-01-31 08:23:00 +13:00
}