mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-06-13 22:04:36 -06:00
GLPainter: draw text
git-svn-id: svn://ultimatepp.org/upp/trunk@12399 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
46e486ff48
commit
63fc0da2cc
7 changed files with 125 additions and 29 deletions
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
82
bazaar/GLPainter/Text.cpp
Normal 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]];
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
4
bazaar/GLPainter/todo.txt
Normal file
4
bazaar/GLPainter/todo.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
- make banded glyphs
|
||||
- make alpha textures
|
||||
- colored texture paints
|
||||
- Texture change Rect -> Rectf
|
||||
Loading…
Add table
Add a link
Reference in a new issue