GLPainter: draw text

git-svn-id: svn://ultimatepp.org/upp/trunk@12399 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2018-10-23 10:34:47 +00:00
parent 46e486ff48
commit 63fc0da2cc
7 changed files with 125 additions and 29 deletions

View file

@ -35,24 +35,21 @@ GLTexture GLTextureDraw::GetResult()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
GLCHK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture2, 0));
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture2, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glGenRenderbuffers(1, &rbo2);
glBindRenderbuffer(GL_RENDERBUFFER, rbo2);
GLCHK(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, sz.cx, sz.cy));
GLCHK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo2));
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, sz.cx, sz.cy);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo2);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
NEVER_("Failed to create final texture draw framebuffer");
GLCHK(glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer));
DLOG((const char *)gluErrorString(glGetError()));
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer2);
DLOG((const char *)gluErrorString(glGetError()));
glBlitFramebuffer(0, 0, sz.cx, sz.cy, 0, 0, sz.cx, sz.cy, GL_COLOR_BUFFER_BIT, GL_NEAREST);
DLOG((const char *)gluErrorString(glGetError()));
t.Set(texture2, sz);
@ -95,16 +92,16 @@ void GLTextureDraw::Create(Size sz_, int msaa_)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
GLCHK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, msaa > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D, texture, 0));
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, msaa > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D, texture, 0);
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
if(msaa > 1)
GLCHK(glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_DEPTH24_STENCIL8, sz.cx, sz.cy));
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_DEPTH24_STENCIL8, sz.cx, sz.cy);
else
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, sz.cx, sz.cy);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
GLCHK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo));
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
NEVER_("Failed to create texture draw framebuffer");

View file

@ -2,16 +2,20 @@
#define _GLDrawDemo_Ugl_h_
#include <GLDraw/GLDraw.h>
#include <plugin/tess2/tess2.h>
#include <Painter/Painter.h>
namespace Upp {
#define GL_TIMING(x) RTIMING(x)
#ifdef _DEBUG
#define GLCHK(x) do { \
x; \
int err = glGetError(); \
if(err) LOG("ERROR " << err << " (" << __LINE__ << "): " << #x); \
LOG((const char *)gluErrorString(err)); \
} while(0)
#endif
struct GLContext2D { // TODO: This should be changed to regular matrix (later)
Sizef vs;
@ -58,12 +62,13 @@ class GLTexture {
struct Data {
int refcount = 1;
GLuint textureid = 0;
Point hotspot = Point(0, 0);
Size sz = Size(0, 0);
};
Data *data = NULL;
void Set(GLuint texture, Size sz);
void Set(GLuint texture, Size sz, Point hotspot = Point(0, 0));
friend class GLTextureDraw;
@ -75,6 +80,7 @@ public:
int GetID() const { return data ? data->textureid : 0; }
operator GLuint() const { return GetID(); }
Size GetSize() const { return data ? data->sz : Size(0, 0); }
Point GetHotSpot() const { return data ? data->hotspot : Point(0, 0); }
GLTexture() {}
GLTexture(const Image& img, dword flags = TEXTURE_LINEAR|TEXTURE_MIPMAP) { Set(img, flags); }
@ -86,13 +92,13 @@ public:
void GLBind(const Image& img, dword style = TEXTURE_LINEAR|TEXTURE_MIPMAP);
void GLDrawTexture(const GLContext2D& dd, const Rect& rect, int textureid, double alpha = 1);
void GLDrawTexture(const GLContext2D& dd, const Rect& rect, const Image& img, double alpha = 1);
void GLDrawImage(const GLContext2D& dd, const Rect& rect, const Image& img, double alpha = 1);
void GLDrawTexture(const GLContext2D& dd, const Rectf& rect, int textureid, double alpha = 1);
void GLDrawTexture(const GLContext2D& dd, const Rectf& rect, const Image& img, double alpha = 1);
void GLDrawImage(const GLContext2D& dd, const Rectf& rect, const Image& img, double alpha = 1);
void GLDrawTexture(const GLContext2D& dd, const Rect& rect, int textureid, Size tsz, const Rect& src, double alpha);
void GLDrawTexture(const GLContext2D& dd, const Rect& rect, const GLTexture& img, const Rect& src, double alpha);
void GLDrawImage(const GLContext2D& dd, const Rect& rect, const Image& img, const Rect& src, double alpha);
void GLDrawTexture(const GLContext2D& dd, const Rectf& rect, int textureid, Size tsz, const Rect& src, double alpha);
void GLDrawTexture(const GLContext2D& dd, const Rectf& rect, const GLTexture& img, const Rect& src, double alpha);
void GLDrawImage(const GLContext2D& dd, const Rectf& rect, const Image& img, const Rect& src, double alpha);
class GLTextureDraw {
GLuint framebuffer = 0;
@ -178,6 +184,11 @@ void GLDrawArc(const GLContext2D& dd, Pointf center, Sizef radius, Color color,
virtual void DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color) = 0;
*/
GLTexture GetGlyphGLTextureCached(double angle, int chr, Font font, Color color);
void GLDrawText(const GLContext2D& dd, Pointf pos, double angle, const wchar *text, Font font,
Color ink, int n = -1, const int *dx = NULL, double alpha = 1);
#include "GLPainter.hpp"
};

View file

@ -54,7 +54,6 @@ void GLPolylines(GLVertexData& data, const Src& polygon)
<< ii - 4 + 2 << ii - 4 + 3 << ii0;
}
DDUMP(vertex);
data.Add(vertex, 4).Index(ndx);
}

View file

@ -11,10 +11,12 @@ file
GLPainter.hpp,
Code.cpp,
VertexData.cpp,
Image.cpp,
Texture.cpp,
DrawTexture.cpp,
TessPolygon.cpp,
StencilPolygon.cpp,
Line.cpp,
Ellipse.cpp;
Ellipse.cpp,
Text.cpp,
todo.txt;

82
bazaar/GLPainter/Text.cpp Normal file
View file

@ -0,0 +1,82 @@
#include "GLPainter.h"
namespace Upp {
Image RenderGlyphByPainter2(Point at, double angle, int chr, Font font, Color color, Size sz)
{
ImageBuffer ib(sz);
BufferPainter sw(ib);
sw.Clear(RGBAZero());
sw.EvenOdd(true);
sw.Translate(at.x, at.y);
if(angle)
sw.Rotate(angle);
wchar text = chr;
sw.Text(0, 0, &text, font, 1);
sw.Fill(color);
Image h = ib;
return Premultiply(h);
}
int texture_glyph_cache_max = 64*1024*1024;
struct sGlyphTextureMaker : LRUCache<GLTexture>::Maker {
double angle;
int chr;
Font font;
Color color;
virtual String Key() const {
StringBuffer h;
RawCat(h, chr);
RawCat(h, font);
RawCat(h, angle);
RawCat(h, color);
return h;
}
virtual int Make(GLTexture& object) const {
GL_TIMING("Do glyph");
Point at(font[chr], font.GetLineHeight());
int n = 2 * (at.x + at.y);
at.x = max(at.x, at.y);
at.y = max(at.x, at.y);
Image img = AutoCrop(WithHotSpot(RenderGlyphByPainter2(at, angle, chr, font, color, Size(n, n)), at.x, at.y), RGBAZero());
object = GLTexture(img, 0);
return 4 * img.GetLength();
}
};
GLTexture GetGlyphGLTextureCached(double angle, int chr, Font font, Color color)
{
GL_TIMING("GetGlyphGLTextureCached");
static LRUCache<GLTexture> cache;
sGlyphTextureMaker cm;
cm.angle = angle;
cm.chr = chr;
cm.font = font;
cm.color = color;
cache.Shrink(texture_glyph_cache_max, 20000);
return cache.Get(cm);
}
void GLDrawText(const GLContext2D& dd, Pointf pos, double angle, const wchar *text, Font font,
Color ink, int n, const int *dx, double alpha)
{
GL_TIMING("GLDrawText");
int x = 0;
Pointf u;
if(angle)
u = Polar(-angle);
if(n < 0)
n = wstrlen(text);
for(int i = 0; i < n; i++) {
GLTexture m = GetGlyphGLTextureCached(-angle, text[i], font, ink);
Point h = m.GetHotSpot();
Pointf p = (angle ? pos + x * u : Pointf(x + pos.x, pos.y)) - (Pointf)m.GetHotSpot();
GLDrawTexture(dd, Rectf((Point)p, m.GetSize()), m, alpha);
x += dx ? *dx++ : font[text[i]];
}
}
};

View file

@ -11,17 +11,18 @@ void GLTexture::Clear()
data = NULL;
}
void GLTexture::Set(GLuint id, Size sz)
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());
Set(CreateGLTexture(img, flags), img.GetSize(), img.GetHotSpot());
}
GLTexture::GLTexture(const GLTexture& src)
@ -63,7 +64,7 @@ const GLVertexData& GLRectMesh()
return mesh;
}
void GLDrawTexture(const GLContext2D& dd, const Rect& rect, int textureid, double alpha)
void GLDrawTexture(const GLContext2D& dd, const Rectf& rect, int textureid, double alpha)
{
static GLCode program(R"(
#version 330 core
@ -102,17 +103,17 @@ void GLDrawTexture(const GLContext2D& dd, const Rect& rect, int textureid, doubl
);
}
void GLDrawTexture(const GLContext2D& dd, const Rect& rect, const GLTexture& img, double alpha)
void GLDrawTexture(const GLContext2D& dd, const Rectf& rect, const GLTexture& img, double alpha)
{
GLDrawTexture(dd, rect, img.GetID(), alpha);
}
void GLDrawImage(const GLContext2D& dd, const Rect& rect, const Image& img, double alpha)
void GLDrawImage(const GLContext2D& dd, const Rectf& rect, const Image& img, double alpha)
{
GLDrawTexture(dd, rect, GetTextureForImage(img), alpha);
}
void GLDrawTexture(const GLContext2D& dd, const Rect& rect, int textureid, Size tsz, const Rect& src, double alpha)
void GLDrawTexture(const GLContext2D& dd, const Rectf& rect, int textureid, Size tsz, const Rect& src, double alpha)
{
static GLCode program(R"(
#version 330 core
@ -159,12 +160,12 @@ void GLDrawTexture(const GLContext2D& dd, const Rect& rect, int textureid, Size
);
}
void GLDrawTexture(const GLContext2D& dd, const Rect& rect, const GLTexture& img, const Rect& src, double alpha)
void GLDrawTexture(const GLContext2D& dd, const Rectf& rect, const GLTexture& img, const Rect& src, double alpha)
{
GLDrawTexture(dd, rect, img.GetID(), img.GetSize(), src, alpha);
}
void GLDrawImage(const GLContext2D& dd, const Rect& rect, const Image& img, const Rect& src, double alpha)
void GLDrawImage(const GLContext2D& dd, const Rectf& rect, const Image& img, const Rect& src, double alpha)
{
GLDrawTexture(dd, rect, GetTextureForImage(img), img.GetSize(), src, alpha);
}

View file

@ -0,0 +1,4 @@
- make banded glyphs
- make alpha textures
- colored texture paints
- Texture change Rect -> Rectf