mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-06-13 22:04:36 -06:00
GLPainter: DrawGL
git-svn-id: svn://ultimatepp.org/upp/trunk@12402 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
690713f57c
commit
4c776bd7f2
8 changed files with 345 additions and 14 deletions
27
bazaar/GLPainter/Arc.cpp
Normal file
27
bazaar/GLPainter/Arc.cpp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#include "GLPainter.h"
|
||||
|
||||
namespace Upp {
|
||||
|
||||
void GLDrawArc(const GLContext2D& dd, const Rectf& rc, Pointf start, Pointf end, int width, Color color, double alpha)
|
||||
{
|
||||
if(rc.Width() <= 0 || rc.Height() <= 0)
|
||||
return;
|
||||
Sizef radius = Sizef(rc.Size()) / 2.0;
|
||||
Pointf center = Pointf(rc.TopLeft()) + radius;
|
||||
double ang1 = Direction((Pointf(start) - center) / radius);
|
||||
double ang2 = Direction((Pointf(end) - center) / radius);
|
||||
if(ang1 > ang2)
|
||||
Swap(ang1, ang2);
|
||||
|
||||
Vector<Vector<Pointf>> line;
|
||||
line.Add();
|
||||
for(double a = ang1; a <= ang2 + M_PI / 200; a += M_PI / 200) {
|
||||
line.Top().Add(radius * Polar(min(a, ang2)) + center);
|
||||
}
|
||||
|
||||
GLVertexData l;
|
||||
GLPolylines(l, line);
|
||||
GLDrawPolylines(dd, Pointf(0, 0), l, Sizef(1, 1), width, color, alpha);
|
||||
}
|
||||
|
||||
};
|
||||
216
bazaar/GLPainter/DrawGL.cpp
Normal file
216
bazaar/GLPainter/DrawGL.cpp
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
#include "GLPainter.h"
|
||||
|
||||
namespace Upp {
|
||||
|
||||
void DrawGL::Init(Size sz, double alpha)
|
||||
{
|
||||
Cloff& c = cloff.Add();
|
||||
c.clip = view_size = sz;
|
||||
c.offset = Pointf(0.5, 0.5);
|
||||
dd.Set(sz);
|
||||
dd.alpha = alpha;
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
SyncScissor();
|
||||
}
|
||||
|
||||
DrawGL::~DrawGL()
|
||||
{
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
dword DrawGL::GetInfo() const
|
||||
{
|
||||
return DRAWTEXTLINES;
|
||||
}
|
||||
|
||||
void DrawGL::BeginOp()
|
||||
{
|
||||
Cloff c = cloff.Top();
|
||||
cloff.Add(c);
|
||||
}
|
||||
|
||||
bool DrawGL::ClipOp(const Rect& r)
|
||||
{
|
||||
Cloff c = cloff.Top();
|
||||
Cloff& c1 = cloff.Add();
|
||||
c1.clip = c.clip & (r + c.offset);
|
||||
c1.offset = c.offset;
|
||||
SyncScissor();
|
||||
return !c1.clip.IsEmpty();
|
||||
}
|
||||
|
||||
bool DrawGL::ClipoffOp(const Rect& r)
|
||||
{
|
||||
Cloff c = cloff.Top();
|
||||
Cloff& c1 = cloff.Add();
|
||||
c1.clip = c.clip & (r + c.offset);
|
||||
c1.offset = c.offset + (Pointf)r.TopLeft();
|
||||
SyncScissor();
|
||||
return !c1.clip.IsEmpty();
|
||||
}
|
||||
|
||||
bool DrawGL::IntersectClipOp(const Rect& r)
|
||||
{
|
||||
Cloff& c = cloff.Top();
|
||||
c.clip = c.clip & (r + c.offset);
|
||||
SyncScissor();
|
||||
return !c.clip.IsEmpty();
|
||||
}
|
||||
|
||||
bool DrawGL::ExcludeClipOp(const Rect& r)
|
||||
{
|
||||
// does not work with DrawGL
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DrawGL::IsPaintingOp(const Rect& r) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void DrawGL::OffsetOp(Point p)
|
||||
{
|
||||
Cloff c = cloff.Top();
|
||||
Cloff& c1 = cloff.Add();
|
||||
c1.clip = c.clip;
|
||||
c1.offset = c.offset + (Pointf)p;
|
||||
}
|
||||
|
||||
void DrawGL::EndOp()
|
||||
{
|
||||
ASSERT(cloff.GetCount());
|
||||
if(cloff.GetCount())
|
||||
cloff.Drop();
|
||||
SyncScissor();
|
||||
}
|
||||
|
||||
void DrawGL::SyncScissor()
|
||||
{
|
||||
Rect clip = cloff.Top().clip;
|
||||
Size sz = clip.GetSize();
|
||||
glScissor(clip.left, view_size.cy - sz.cy - clip.top, sz.cx, sz.cy);
|
||||
}
|
||||
|
||||
Pointf DrawGL::Offset(int x, int y)
|
||||
{
|
||||
Pointf o = cloff.Top().offset;
|
||||
return Pointf(x + o.x, y + o.y);
|
||||
}
|
||||
|
||||
Rectf DrawGL::Offset(int x, int y, int cx, int cy)
|
||||
{
|
||||
Point o = cloff.Top().offset;
|
||||
return RectfC(x + o.x, y + o.y, cx, cy);
|
||||
}
|
||||
|
||||
Rectf DrawGL::Offset(int x, int y, Size sz)
|
||||
{
|
||||
return Offset(x, y, sz.cx, sz.cy);
|
||||
}
|
||||
|
||||
void DrawGL::SysDrawImageOp(int x, int y, const Image& img, Color color)
|
||||
{
|
||||
GLDrawImage(dd, Offset(x, y, img.GetSize()),
|
||||
IsNull(color) ? img : CachedSetColorKeepAlpha(img, color));
|
||||
}
|
||||
|
||||
void DrawGL::SysDrawImageOp(int x, int y, const Image& img, const Rect& src, Color color)
|
||||
{
|
||||
GLDrawImage(dd, Offset(x, y, img.GetSize()), IsNull(color) ? img : CachedSetColorKeepAlpha(img, color),
|
||||
src);
|
||||
}
|
||||
|
||||
void DrawGL::DrawRectOp(int x, int y, int cx, int cy, Color color)
|
||||
{
|
||||
Vector<Vector<Pointf>> polygon;
|
||||
polygon.Add().Add(Offset(x, y));
|
||||
polygon.Top().Add(Offset(x + cx, y));
|
||||
polygon.Top().Add(Offset(x + cx, y + cy));
|
||||
polygon.Top().Add(Offset(x, y + cy));
|
||||
|
||||
GLVertexData data;
|
||||
GLPolygons(data, polygon);
|
||||
|
||||
GLDrawConvexPolygons(dd, Pointf(0, 0), data, Sizef(1, 1), color);
|
||||
}
|
||||
|
||||
void DrawGL::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx)
|
||||
{
|
||||
GLDrawText(dd, Offset(x, y), angle * M_2PI / 3600, text, font, ink, n, dx);
|
||||
}
|
||||
|
||||
void DrawGL::DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color)
|
||||
{
|
||||
// TODO...
|
||||
}
|
||||
|
||||
void DrawGL::DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor)
|
||||
{
|
||||
GLDrawEllipse(dd, Offset(r.CenterPoint()), Sizef(r.GetSize()) / 2, color, pen, pencolor);
|
||||
}
|
||||
|
||||
void DrawGL::DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color)
|
||||
{
|
||||
Vector<Vector<Pointf>> poly;
|
||||
poly.Add().Add(Offset(x1, y1));
|
||||
poly.Top().Add(Offset(x2, y2));
|
||||
|
||||
GLVertexData data;
|
||||
GLPolylines(data, poly);
|
||||
|
||||
GLDrawPolylines(dd, Pointf(0, 0), data, Sizef(1, 1), max(width, 1), color);
|
||||
}
|
||||
|
||||
void DrawGL::DoPath(Vector<Vector<Pointf>>& poly, const Point *pp, const Point *end)
|
||||
{
|
||||
poly.Add().Add(Offset(*pp++));
|
||||
while(pp < end)
|
||||
poly.Top().Add(Offset(*pp++));
|
||||
}
|
||||
|
||||
void DrawGL::DrawPolyPolylineOp(const Point *vertices, int vertex_count, const int *counts, int count_count, int width, Color color, Color doxor)
|
||||
{
|
||||
if(vertex_count < 2 || IsNull(color))
|
||||
return;
|
||||
Vector<Vector<Pointf>> poly;
|
||||
while(--count_count >= 0) {
|
||||
const Point *pp = vertices;
|
||||
vertices += *counts++;
|
||||
DoPath(poly, pp, vertices);
|
||||
}
|
||||
|
||||
GLVertexData data;
|
||||
GLPolylines(data, poly);
|
||||
GLDrawPolylines(dd, Pointf(0, 0), data, Sizef(1, 1), max(width, 1), color);
|
||||
}
|
||||
|
||||
void DrawGL::DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count, const int *subpolygon_counts, int scc,
|
||||
const int *disjunct_polygon_counts, int dpcc, Color color,
|
||||
int width, Color outline, uint64 pattern, Color doxor)
|
||||
{
|
||||
Vector<Vector<Pointf>> poly;
|
||||
while(--dpcc >= 0) {
|
||||
const Point *sp = vertices;
|
||||
vertices += *disjunct_polygon_counts++;
|
||||
while(sp < vertices) {
|
||||
const Point *pp = sp;
|
||||
sp += *subpolygon_counts++;
|
||||
DoPath(poly, pp, sp);
|
||||
}
|
||||
}
|
||||
|
||||
if(!IsNull(color)) {
|
||||
GLVertexData data;
|
||||
GLPolygons(data, poly);
|
||||
GLDrawPolygons(dd, Pointf(0, 0), data, Sizef(1, 1), color);
|
||||
}
|
||||
if(!IsNull(outline)) {
|
||||
GLVertexData data;
|
||||
for(auto& pl : poly)
|
||||
pl.Add(pl[0]);
|
||||
GLPolylines(data, poly);
|
||||
GLDrawPolylines(dd, Pointf(0, 0), data, Sizef(1, 1), max(width, 1), outline);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -13,7 +13,8 @@ void GLDrawEllipse(const GLContext2D& dd, Pointf center, Sizef radius, Color fil
|
|||
for(int i = 0; i < N; i++)
|
||||
p.Top().Add(Polar(i * M_2PI / N));
|
||||
GLPolygons(fill, p);
|
||||
p.Add(p[0]);
|
||||
Pointf f = p.Top()[0];
|
||||
p.Top().Add(f);
|
||||
GLPolylines(line, p);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ struct GLContext2D { // TODO: This should be changed to regular matrix (later)
|
|||
Sizef vs;
|
||||
double alpha = 1;
|
||||
|
||||
GLContext2D(Size sz) { vs = Sizef(2.0 / sz.cx, -2.0 / sz.cy); }
|
||||
void Set(Size sz) { vs = Sizef(2.0 / sz.cx, -2.0 / sz.cy); }
|
||||
|
||||
GLContext2D(Size sz) { Set(sz); }
|
||||
GLContext2D() {}
|
||||
};
|
||||
|
||||
|
|
@ -96,9 +98,9 @@ void GLDrawTexture(const GLContext2D& dd, const Rectf& rect, int textureid, doub
|
|||
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 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);
|
||||
void GLDrawTexture(const GLContext2D& dd, const Rectf& rect, int textureid, Size tsz, const Rect& src, double alpha = 1);
|
||||
void GLDrawTexture(const GLContext2D& dd, const Rectf& rect, const GLTexture& img, const Rect& src, double alpha = 1);
|
||||
void GLDrawImage(const GLContext2D& dd, const Rectf& rect, const Image& img, const Rect& src, double alpha = 1);
|
||||
|
||||
class GLTextureDraw {
|
||||
GLuint framebuffer = 0;
|
||||
|
|
@ -166,23 +168,24 @@ void GLDrawPolygon(Sizef vs, Point at, const GLVertexData& mesh, Sizef scale, Co
|
|||
template <typename Src>
|
||||
void GLPolygons(GLVertexData& mesh, const Src& polygon);
|
||||
|
||||
void GLDrawPolygons(const GLContext2D& dd, Pointf at, const GLVertexData& mesh, Sizef scale, Color color, double alpha);
|
||||
void GLDrawConvexPolygons(const GLContext2D& dd, Pointf at, const GLVertexData& mesh, Sizef scale, Color color, double alpha);
|
||||
void GLDrawPolygons(const GLContext2D& dd, Pointf at, const GLVertexData& mesh, Sizef scale, Color color, double alpha = 1);
|
||||
void GLDrawConvexPolygons(const GLContext2D& dd, Pointf at, const GLVertexData& mesh, Sizef scale, Color color, double alpha = 1);
|
||||
|
||||
template <typename Src>
|
||||
void GLPolylines(GLVertexData& data, const Src& polygon);
|
||||
|
||||
void GLDrawPolylines(const GLContext2D& dd, Pointf at, const GLVertexData& mesh, Sizef scale, double width, Color color, double alpha);
|
||||
void DashPolyline(Vector<Vector<Pointf>>& polyline, const Vector<Pointf>& line,
|
||||
const Vector<double>& pattern, double distance);
|
||||
|
||||
void GLDrawPolylines(const GLContext2D& dd, Pointf at, const GLVertexData& mesh, Sizef scale, double width, Color color, double alpha = 1);
|
||||
|
||||
void GLDrawStencil(Color color, double alpha);
|
||||
|
||||
void GLDrawEllipse(const GLContext2D& dd, Pointf center, Sizef radius, Color fill_color,
|
||||
double width = 0, Color line_color = Null, double alpha = 1);
|
||||
|
||||
/*
|
||||
void GLDrawArc(const GLContext2D& dd, Pointf center, Sizef radius, Color color, double alpha);
|
||||
virtual void DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color) = 0;
|
||||
*/
|
||||
void GLDrawArc(const GLContext2D& dd, const Rectf& rc, Pointf start, Pointf end, int width,
|
||||
Color color, double alpha = 1);
|
||||
|
||||
GLTexture GetGlyphGLTextureCached(double angle, int chr, Font font, Color color);
|
||||
|
||||
|
|
@ -191,6 +194,56 @@ void GLDrawText(const GLContext2D& dd, Pointf pos, double angle, const wchar *te
|
|||
|
||||
#include "GLPainter.hpp"
|
||||
|
||||
class DrawGL : public Draw {
|
||||
public:
|
||||
virtual dword GetInfo() const;
|
||||
|
||||
virtual void BeginOp();
|
||||
virtual bool ClipOp(const Rect& r);
|
||||
virtual bool ClipoffOp(const Rect& r);
|
||||
virtual bool IntersectClipOp(const Rect& r);
|
||||
virtual void OffsetOp(Point p);
|
||||
virtual bool ExcludeClipOp(const Rect& r);
|
||||
virtual void EndOp();
|
||||
virtual bool IsPaintingOp(const Rect& r) const;
|
||||
|
||||
virtual void SysDrawImageOp(int x, int y, const Image& img, Color color);
|
||||
virtual void SysDrawImageOp(int x, int y, const Image& img, const Rect& src, Color color);
|
||||
virtual void DrawRectOp(int x, int y, int cx, int cy, Color color);
|
||||
|
||||
virtual void DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx);
|
||||
|
||||
virtual void DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color);
|
||||
virtual void DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor);
|
||||
virtual void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color);
|
||||
virtual void DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count, const int *subpolygon_counts, int scc, const int *disjunct_polygon_counts, int dpcc, Color color, int width, Color outline, uint64 pattern, Color doxor);
|
||||
virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count, const int *counts, int count_count, int width, Color color, Color doxor);
|
||||
|
||||
private:
|
||||
struct Cloff : Moveable<Cloff> {
|
||||
Rect clip;
|
||||
Pointf offset;
|
||||
};
|
||||
|
||||
Vector<Cloff> cloff;
|
||||
GLContext2D dd;
|
||||
Size view_size;
|
||||
|
||||
Pointf Offset(int x, int y);
|
||||
Pointf Offset(Point p) { return Offset(p.x, p.y); }
|
||||
Rectf Offset(int x, int y, int cx, int cy);
|
||||
Rectf Offset(int x, int y, Size sz);
|
||||
void SyncScissor();
|
||||
void DoPath(Vector<Vector<Pointf>>& poly, const Point *pp, const Point *end);
|
||||
|
||||
public:
|
||||
void Init(Size sz, double alpha = 1);
|
||||
|
||||
DrawGL() {}
|
||||
DrawGL(Size sz, double alpha = 1) { Init(sz, alpha); }
|
||||
~DrawGL();
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ void GLPolylines(GLVertexData& data, const Src& polygon)
|
|||
ndx << ii << ii + 1 << ii + 2
|
||||
<< ii + 3 << ii + 2 << ii + 1;
|
||||
|
||||
if(ii) // if line is not first, draw bevel join between current and previous line
|
||||
if(i) // if line is not first, draw bevel join between current and previous line
|
||||
ndx << ii << ii + 1 << ii - 4 + 3
|
||||
<< ii - 4 + 2 << ii - 4 + 3 << ii;
|
||||
|
||||
|
|
@ -56,4 +56,3 @@ void GLPolylines(GLVertexData& data, const Src& polygon)
|
|||
|
||||
data.Add(vertex, 4).Index(ndx);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ file
|
|||
StencilPolygon.cpp,
|
||||
Line.cpp,
|
||||
Ellipse.cpp,
|
||||
Arc.cpp,
|
||||
Text.cpp,
|
||||
DrawGL.cpp,
|
||||
todo.txt;
|
||||
|
||||
|
|
|
|||
|
|
@ -60,4 +60,28 @@ void GLDrawPolylines(const GLContext2D& dd, Pointf at, const GLVertexData& mesh,
|
|||
}
|
||||
}
|
||||
|
||||
void DashPolyline(Vector<Vector<Pointf>>& polyline, const Vector<Pointf>& line,
|
||||
const Vector<double>& pattern, double distance = 0)
|
||||
{
|
||||
struct LineStore : LinearPathConsumer {
|
||||
Vector<Vector<Pointf>>& polyline;
|
||||
|
||||
void Move(const Pointf& p) override { DLOG("MOVE " << p); polyline.Add().Add(p); }
|
||||
void Line(const Pointf& p) override { DLOG("LINE " << p); polyline.Top().Add(p); }
|
||||
|
||||
LineStore(Vector<Vector<Pointf>>& polyline) : polyline(polyline) {}
|
||||
};
|
||||
|
||||
LineStore st(polyline);
|
||||
Dasher dasher;
|
||||
dasher.target = &st;
|
||||
dasher.Init(pattern, distance);
|
||||
for(int i = 0; i < line.GetCount(); i++)
|
||||
if(i)
|
||||
dasher.Line(line[i]);
|
||||
else
|
||||
dasher.Move(line[i]);
|
||||
dasher.End();
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -1,4 +1,13 @@
|
|||
- make banded glyphs
|
||||
- make alpha textures
|
||||
- colored texture paints
|
||||
- ARC
|
||||
- DASHER
|
||||
- optimize draw rect
|
||||
- circle pen should be able to 'dash'
|
||||
- arc pen should be able to 'dash'
|
||||
- polygon pen should be able to 'dash'
|
||||
|
||||
DONE:
|
||||
|
||||
- Texture change Rect -> Rectf
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue