mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 14:16:09 -06:00
158 lines
3.5 KiB
C++
158 lines
3.5 KiB
C++
#include "GLDraw.h"
|
|
|
|
namespace Upp {
|
|
|
|
void GLTexture::Clear()
|
|
{
|
|
if(data && --data->refcount == 0) {
|
|
glDeleteTextures(1, &data->textureid);
|
|
delete data;
|
|
}
|
|
data = NULL;
|
|
}
|
|
|
|
void GLTexture::Set(GLuint id, Size sz, Point hotspot)
|
|
{
|
|
Clear();
|
|
data = new Data;
|
|
data->sz = sz;
|
|
data->hotspot = hotspot;
|
|
data->textureid = id;
|
|
}
|
|
|
|
void GLTexture::Set(const Image& img, dword flags)
|
|
{
|
|
Set(CreateGLTexture(img, flags), img.GetSize(), img.GetHotSpot());
|
|
}
|
|
|
|
extern int sTextureCounter;
|
|
|
|
void GLTexture::Bind(int ii) const
|
|
{
|
|
if(data) {
|
|
glActiveTexture(GL_TEXTURE0 + ii);
|
|
glBindTexture(GL_TEXTURE_2D, data->textureid);
|
|
sTextureCounter++;
|
|
}
|
|
}
|
|
|
|
GLTexture::GLTexture(const GLTexture& src)
|
|
{
|
|
data = src.data;
|
|
if(data)
|
|
data->refcount++;
|
|
}
|
|
|
|
GLTexture& GLTexture::operator=(const GLTexture& src)
|
|
{
|
|
Clear();
|
|
data = src.data;
|
|
if(data)
|
|
data->refcount++;
|
|
return *this;
|
|
}
|
|
|
|
void GLBind(int ii, const Image& img, dword style)
|
|
{
|
|
extern int sTextureCounter;
|
|
glActiveTexture(GL_TEXTURE0 + ii);
|
|
glBindTexture(GL_TEXTURE_2D, GetTextureForImage(style, img));
|
|
sTextureCounter++;
|
|
}
|
|
|
|
void GLBind(const Image& img, dword style)
|
|
{
|
|
GLBind(0, img, style);
|
|
}
|
|
|
|
const GLVertexData& GLRectMesh()
|
|
{
|
|
static GLVertexData mesh;
|
|
ONCELOCK {
|
|
static const float box[] = {
|
|
0, 0, // 0
|
|
0, 1, // 1
|
|
1, 0, // 2
|
|
1, 1, // 3
|
|
};
|
|
static const int ndx[] = {
|
|
0, 1, 2, 1, 2, 3
|
|
};
|
|
mesh.Add(box, 2, 4).Index(ndx, 6);
|
|
}
|
|
return mesh;
|
|
}
|
|
|
|
void GLDrawTexture(const GLContext2D& dd, const Rectf& rect, int textureid, Size tsz, const Rect& src)
|
|
{
|
|
static GLCode program(R"(
|
|
// #version 330 core
|
|
uniform vec2 offset;
|
|
uniform vec2 scale;
|
|
|
|
uniform vec2 toffset;
|
|
uniform vec2 tscale;
|
|
|
|
attribute vec2 aPos;
|
|
varying vec2 tPos;
|
|
void main()
|
|
{
|
|
gl_Position = vec4(scale * aPos + offset, 0, 1);
|
|
tPos = tscale * aPos + toffset;
|
|
}
|
|
)", R"(
|
|
// #version 330 core
|
|
varying vec2 tPos;
|
|
uniform float alpha;
|
|
uniform sampler2D s_texture;
|
|
void main()
|
|
{
|
|
vec4 v = texture2D(s_texture, tPos);
|
|
gl_FragColor = alpha * clamp(v, vec4(0, 0, 0, 0), v.aaaa); // clamp fixes non-premultiplied textures
|
|
}
|
|
)");
|
|
|
|
if(tsz.cx * tsz.cy == 0)
|
|
return;
|
|
|
|
static int ioffset = program["offset"];
|
|
static int iscale = program["scale"];
|
|
static int ialpha = program["alpha"];
|
|
static int itscale = program["tscale"];
|
|
static int itoffset = program["toffset"];
|
|
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, textureid);
|
|
sTextureCounter++;
|
|
GLRectMesh().Draw(
|
|
program(ioffset, dd.vs * rect.TopLeft() + dd.off)
|
|
(iscale, dd.vs * rect.GetSize())
|
|
(ialpha, dd.alpha)
|
|
(itoffset, Sizef((float)src.left / tsz.cx, (float)src.top / tsz.cy))
|
|
(itscale, Sizef((float)src.GetWidth() / tsz.cx, (float)src.GetHeight() / tsz.cy))
|
|
);
|
|
}
|
|
|
|
void GLDrawTexture(const GLContext2D& dd, const Rectf& rect, const GLTexture& img, const Rect& src)
|
|
{
|
|
GLDrawTexture(dd, rect, img.GetID(), img.GetSize(), src);
|
|
}
|
|
|
|
void GLDrawImage(const GLContext2D& dd, const Rectf& rect, const Image& img, const Rect& src)
|
|
{
|
|
GLDrawTexture(dd, rect, GetTextureForImage(img), img.GetSize(), src);
|
|
}
|
|
|
|
void GLDrawTexture(const GLContext2D& dd, const Rectf& rect, const GLTexture& img)
|
|
{
|
|
GLDrawTexture(dd, rect, img, img.GetSize());
|
|
}
|
|
|
|
void GLDrawImage(const GLContext2D& dd, const Rectf& rect, const Image& img)
|
|
{
|
|
GLDrawTexture(dd, rect, img, img.GetSize());
|
|
}
|
|
|
|
};
|