mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
GLPainter
git-svn-id: svn://ultimatepp.org/upp/trunk@12423 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
df6c72f77f
commit
469bd30ffc
10 changed files with 251 additions and 30 deletions
|
|
@ -21,8 +21,11 @@ GLCode::GLCode(const char *vertex_shader, const char *pixel_shader)
|
|||
while(!p.IsEof() && !p.Char('{'))
|
||||
if(p.Id("attribute") || p.Id("in")) {
|
||||
String id = readID();
|
||||
if(id.GetCount())
|
||||
if(id.GetCount()) {
|
||||
DDUMP(ii);
|
||||
DDUMP(id);
|
||||
glBindAttribLocation(program, ii++, id);
|
||||
}
|
||||
}
|
||||
else
|
||||
p.SkipTerm();
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ void DrawGL::Init(Size sz, double alpha)
|
|||
dd.alpha = alpha;
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
SyncScissor();
|
||||
|
||||
prev = Point(0, 0);
|
||||
path_done = false;
|
||||
}
|
||||
|
||||
DrawGL::~DrawGL()
|
||||
|
|
@ -23,10 +26,19 @@ dword DrawGL::GetInfo() const
|
|||
return DRAWTEXTLINES;
|
||||
}
|
||||
|
||||
void DrawGL::Push()
|
||||
{
|
||||
auto& s = state.Add();
|
||||
s.dash = clone(dash);
|
||||
s.dash_start = clone(dash_start);
|
||||
s.alpha = dd.alpha;
|
||||
}
|
||||
|
||||
void DrawGL::BeginOp()
|
||||
{
|
||||
Cloff c = cloff.Top();
|
||||
cloff.Add(c);
|
||||
Push();
|
||||
}
|
||||
|
||||
bool DrawGL::ClipOp(const Rect& r)
|
||||
|
|
@ -36,6 +48,7 @@ bool DrawGL::ClipOp(const Rect& r)
|
|||
c1.clip = c.clip & (r + c.offset);
|
||||
c1.offset = c.offset;
|
||||
SyncScissor();
|
||||
Push();
|
||||
return !c1.clip.IsEmpty();
|
||||
}
|
||||
|
||||
|
|
@ -46,6 +59,7 @@ bool DrawGL::ClipoffOp(const Rect& r)
|
|||
c1.clip = c.clip & (r + c.offset);
|
||||
c1.offset = c.offset + (Pointf)r.TopLeft();
|
||||
SyncScissor();
|
||||
Push();
|
||||
return !c1.clip.IsEmpty();
|
||||
}
|
||||
|
||||
|
|
@ -54,6 +68,7 @@ bool DrawGL::IntersectClipOp(const Rect& r)
|
|||
Cloff& c = cloff.Top();
|
||||
c.clip = c.clip & (r + c.offset);
|
||||
SyncScissor();
|
||||
Push();
|
||||
return !c.clip.IsEmpty();
|
||||
}
|
||||
|
||||
|
|
@ -74,6 +89,7 @@ void DrawGL::OffsetOp(Point p)
|
|||
Cloff& c1 = cloff.Add();
|
||||
c1.clip = c.clip;
|
||||
c1.offset = c.offset + (Pointf)p;
|
||||
Push();
|
||||
}
|
||||
|
||||
void DrawGL::EndOp()
|
||||
|
|
@ -81,6 +97,13 @@ void DrawGL::EndOp()
|
|||
ASSERT(cloff.GetCount());
|
||||
if(cloff.GetCount())
|
||||
cloff.Drop();
|
||||
if(state.GetCount()) {
|
||||
auto& s = state.Top();
|
||||
dash = pick(s.dash);
|
||||
dash_start = s.dash_start;
|
||||
dd.alpha = s.alpha;
|
||||
state.Drop();
|
||||
}
|
||||
SyncScissor();
|
||||
}
|
||||
|
||||
|
|
@ -92,42 +115,42 @@ void DrawGL::SyncScissor()
|
|||
glScissor(clip.left, view_size.cy - sz.cy - clip.top, sz.cx, sz.cy);
|
||||
}
|
||||
|
||||
Pointf DrawGL::Offset(int x, int y)
|
||||
Pointf DrawGL::Off(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)
|
||||
Rectf DrawGL::Off(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)
|
||||
Rectf DrawGL::Off(int x, int y, Size sz)
|
||||
{
|
||||
return Offset(x, y, sz.cx, sz.cy);
|
||||
return Off(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()),
|
||||
GLDrawImage(dd, Off(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),
|
||||
GLDrawImage(dd, Off(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));
|
||||
polygon.Add().Add(Off(x, y));
|
||||
polygon.Top().Add(Off(x + cx, y));
|
||||
polygon.Top().Add(Off(x + cx, y + cy));
|
||||
polygon.Top().Add(Off(x, y + cy));
|
||||
|
||||
GLVertexData data;
|
||||
GLPolygons(data, polygon);
|
||||
|
|
@ -137,7 +160,7 @@ void DrawGL::DrawRectOp(int x, int y, int cx, int cy, Color 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);
|
||||
GLDrawText(dd, Off(x, y), angle * M_2PI / 3600, text, font, ink, n, dx);
|
||||
}
|
||||
|
||||
const Vector<double>& DrawGL::GetDash(int& width)
|
||||
|
|
@ -180,8 +203,8 @@ void DrawGL::ApplyDash(Vector<Vector<Pointf>>& polyline, int& width)
|
|||
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));
|
||||
poly.Add().Add(Off(x1, y1));
|
||||
poly.Top().Add(Off(x2, y2));
|
||||
|
||||
ApplyDash(poly, width);
|
||||
|
||||
|
|
@ -207,14 +230,14 @@ void DrawGL::DrawArcOp(const Rect& rc, Point start, Point end, int width, Color
|
|||
void DrawGL::DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor)
|
||||
{
|
||||
const Vector<double>& dash = GetDash(pen);
|
||||
GLDrawEllipse(dd, Offset(r.CenterPoint()), Sizef(r.GetSize()) / 2, color, pen, pencolor, dash, 0);
|
||||
GLDrawEllipse(dd, Off(r.CenterPoint()), Sizef(r.GetSize()) / 2, color, pen, pencolor, dash, 0);
|
||||
}
|
||||
|
||||
void DrawGL::DoPath(Vector<Vector<Pointf>>& poly, const Point *pp, const Point *end)
|
||||
{
|
||||
poly.Add().Add(Offset(*pp++));
|
||||
poly.Add().Add(Off(*pp++));
|
||||
while(pp < end)
|
||||
poly.Top().Add(Offset(*pp++));
|
||||
poly.Top().Add(Off(*pp++));
|
||||
}
|
||||
|
||||
void DrawGL::DrawPolyPolylineOp(const Point *vertices, int vertex_count, const int *counts, int count_count, int width, Color color, Color doxor)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ file
|
|||
Ellipse.cpp,
|
||||
Arc.cpp,
|
||||
Text.cpp,
|
||||
Triangles.cpp,
|
||||
DrawGL.cpp,
|
||||
PainterGL.cpp,
|
||||
todo.txt;
|
||||
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ void GLDrawPolygons(const GLContext2D& dd, Pointf at, const GLVertexData& mesh,
|
|||
void GLDrawConvexPolygons(const GLContext2D& dd, Pointf at, const GLVertexData& mesh, Sizef scale, Color color);
|
||||
|
||||
template <typename Src>
|
||||
void GLPolylines(GLVertexData& data, const Src& polygon);
|
||||
void GLPolylines(GLVertexData& data, const Src& polygon, bool close_loops = false);
|
||||
|
||||
void DashPolyline(Vector<Vector<Pointf>>& polyline, const Vector<Pointf>& line,
|
||||
const Vector<double>& pattern, double distance = 0);
|
||||
|
|
@ -188,9 +188,22 @@ void GLDrawText(const GLContext2D& dd, Pointf pos, double angle, const wchar *te
|
|||
|
||||
void GLArc(Vector<Vector<Pointf>>& line, const Rectf& rc, Pointf start, Pointf end);
|
||||
|
||||
class GLTriangles {
|
||||
Vector<float> pos;
|
||||
Vector<GLubyte> color;
|
||||
Vector<GLint> elements;
|
||||
int ii = 0;
|
||||
|
||||
public:
|
||||
int Vertex(Pointf p, Color c, double alpha = 1) { pos << (float)p.x << (float)p.y << (float)alpha; color << c.GetR() << c.GetG() << c.GetB(); return ii++; }
|
||||
void Triangle(int a, int b, int c) { elements << a << b << c; }
|
||||
|
||||
void Draw(const GLContext2D& dd);
|
||||
};
|
||||
|
||||
#include "GLPainter.hpp"
|
||||
|
||||
class DrawGL : public Draw {
|
||||
class DrawGL : public NilPainter {
|
||||
public:
|
||||
virtual dword GetInfo() const;
|
||||
|
||||
|
|
@ -214,6 +227,15 @@ public:
|
|||
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);
|
||||
|
||||
virtual void MoveOp(const Pointf& p, bool rel);
|
||||
virtual void LineOp(const Pointf& p, bool rel);
|
||||
virtual void OpacityOp(double o);
|
||||
virtual void CloseOp();
|
||||
virtual void StrokeOp(double width, const RGBA& rgba);
|
||||
virtual void FillOp(const RGBA& color);
|
||||
virtual void DashOp(const Vector<double>& dash, double start);
|
||||
|
||||
|
||||
private:
|
||||
struct Cloff : Moveable<Cloff> {
|
||||
|
|
@ -221,14 +243,28 @@ private:
|
|||
Pointf offset;
|
||||
};
|
||||
|
||||
struct State {
|
||||
double alpha;
|
||||
double dash_start;
|
||||
Vector<double> dash;
|
||||
};
|
||||
|
||||
Vector<Cloff> cloff;
|
||||
Array<State> state;
|
||||
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);
|
||||
|
||||
Pointf prev;
|
||||
Vector<Vector<Pointf>> path;
|
||||
bool path_done;
|
||||
double dash_start;
|
||||
Vector<double> dash;
|
||||
|
||||
void Push();
|
||||
Pointf Off(int x, int y);
|
||||
Pointf Off(Point p) { return Off(p.x, p.y); }
|
||||
Rectf Off(int x, int y, int cx, int cy);
|
||||
Rectf Off(int x, int y, Size sz);
|
||||
void SyncScissor();
|
||||
void DoPath(Vector<Vector<Pointf>>& poly, const Point *pp, const Point *end);
|
||||
static const Vector<double>& GetDash(int& width);
|
||||
|
|
@ -236,9 +272,11 @@ private:
|
|||
|
||||
public:
|
||||
void Init(Size sz, double alpha = 1);
|
||||
|
||||
operator const GLContext2D&() const { return dd; }
|
||||
|
||||
DrawGL() {}
|
||||
DrawGL(Size sz, double alpha = 1) { Init(sz, alpha); }
|
||||
DrawGL(Size sz, double alpha = 1) { Init(sz, alpha); }
|
||||
~DrawGL();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ void GLPolygons(GLVertexData& mesh, const Src& polygon)
|
|||
}
|
||||
|
||||
template <typename Src>
|
||||
void GLPolylines(GLVertexData& data, const Src& polygon)
|
||||
void GLPolylines(GLVertexData& data, const Src& polygon, bool close)
|
||||
{
|
||||
Vector<float> vertex;
|
||||
Vector<int> ndx;
|
||||
|
|
@ -33,7 +33,11 @@ void GLPolylines(GLVertexData& data, const Src& polygon)
|
|||
for(const auto& p: polygon) {
|
||||
int i0 = vertex.GetCount();
|
||||
int ii0 = ii;
|
||||
for(int i = 0; i < p.GetCount(); i++) {
|
||||
int m = 1;
|
||||
|
||||
if(p.GetCount() && close && p[0] != p.Top())
|
||||
m = 0;
|
||||
for(int i = 0; i < p.GetCount() - m; i++) {
|
||||
Pointf p1 = p[i];
|
||||
Pointf p2 = p[i + 1 < p.GetCount() ? i + 1 : 0];
|
||||
Pointf un = p1 - p2;
|
||||
|
|
@ -54,7 +58,7 @@ void GLPolylines(GLVertexData& data, const Src& polygon)
|
|||
ii += 4;
|
||||
}
|
||||
|
||||
if(p.GetCount() > 2 && p.Top() == p[0]) // Line loop is closed, draw bevel join
|
||||
if(p.GetCount() > 2 && (p.Top() == p[0] || close)) // Line loop is closed, draw bevel join
|
||||
ndx << ii0 << ii0 + 1 << ii - 4 + 3
|
||||
<< ii - 4 + 2 << ii - 4 + 3 << ii0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ void GLDrawPolylines(const GLContext2D& dd, Pointf at, const GLVertexData& mesh,
|
|||
double width, Color color)
|
||||
{
|
||||
GL_TIMING("GLDrawPolylines");
|
||||
|
||||
if(IsNull(color))
|
||||
return;
|
||||
|
||||
static GLCode program(R"(
|
||||
#version 330 core
|
||||
|
|
|
|||
77
uppsrc/GLDraw/PainterGL.cpp
Normal file
77
uppsrc/GLDraw/PainterGL.cpp
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
#include "GLDraw.h"
|
||||
|
||||
namespace Upp {
|
||||
|
||||
void DrawGL::MoveOp(const Pointf& p_, bool rel)
|
||||
{
|
||||
if(path_done) {
|
||||
path.Clear();
|
||||
path_done = false;
|
||||
}
|
||||
Pointf p = p_;
|
||||
if(rel)
|
||||
p = prev + p;
|
||||
path.Add().Add(Off(p));
|
||||
prev = p;
|
||||
}
|
||||
|
||||
void DrawGL::LineOp(const Pointf& p_, bool rel)
|
||||
{
|
||||
if(path_done) {
|
||||
path.Clear();
|
||||
path_done = false;
|
||||
}
|
||||
if(path.GetCount() == 0)
|
||||
path.Add();
|
||||
Pointf p = p_;
|
||||
if(rel)
|
||||
p = prev + p;
|
||||
path.Top().Add(Off(p));
|
||||
prev = p;
|
||||
}
|
||||
|
||||
void DrawGL::OpacityOp(double o)
|
||||
{
|
||||
dd.alpha *= o;
|
||||
}
|
||||
|
||||
void DrawGL::CloseOp()
|
||||
{
|
||||
if(path.GetCount() && path.Top().GetCount())
|
||||
if(path.Top().Top() != path.Top()[0])
|
||||
path.Add(path[0]);
|
||||
}
|
||||
|
||||
void DrawGL::StrokeOp(double width, const RGBA& rgba)
|
||||
{
|
||||
if(width > 0) {
|
||||
GLVertexData data;
|
||||
if(dash.GetCount()) {
|
||||
Vector<Vector<Pointf>> r;
|
||||
for(auto& l : path)
|
||||
DashPolyline(r, l, dash);
|
||||
GLPolylines(data, r);
|
||||
}
|
||||
else
|
||||
GLPolylines(data, path);
|
||||
GLDrawPolylines(dd, Pointf(0, 0), data, Sizef(1, 1), width, rgba);
|
||||
path_done = true;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawGL::FillOp(const RGBA& color)
|
||||
{
|
||||
GLVertexData data;
|
||||
GLPolygons(data, path);
|
||||
GLDrawPolygons(dd, Pointf(0, 0), data, Sizef(1, 1), color);
|
||||
CloseOp();
|
||||
path_done = true;
|
||||
}
|
||||
|
||||
void DrawGL::DashOp(const Vector<double>& dash_, double start)
|
||||
{
|
||||
dash = clone(dash_);
|
||||
dash_start = start;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -48,6 +48,9 @@ void GLDrawPolygons(const GLContext2D& dd, bool generic, Pointf at, const GLVert
|
|||
{
|
||||
GL_TIMING("GLDrawPolygons");
|
||||
|
||||
if(IsNull(color))
|
||||
return;
|
||||
|
||||
GLCode& program = GLSimpleCode();
|
||||
|
||||
static int ioffset = program["offset"];
|
||||
|
|
|
|||
68
uppsrc/GLDraw/Triangles.cpp
Normal file
68
uppsrc/GLDraw/Triangles.cpp
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
#include "GLDraw.h"
|
||||
|
||||
namespace Upp {
|
||||
|
||||
void GLTriangles::Draw(const GLContext2D& dd)
|
||||
{
|
||||
static GLCode program(R"(
|
||||
#version 330 core
|
||||
in vec4 p;
|
||||
in vec4 c;
|
||||
uniform vec2 offset;
|
||||
uniform vec2 scale;
|
||||
out vec4 v_color;
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(scale * p.xy + offset, 0, 1);
|
||||
v_color = vec4(c.r / 255.0, c.g / 255.0, c.b / 255.0, p.z);
|
||||
}
|
||||
)", R"(
|
||||
#version 330 core
|
||||
in vec4 v_color;
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = v_color;
|
||||
gl_FragColor = vec4(1, 0.5, 0.5, 1);
|
||||
}
|
||||
)");
|
||||
|
||||
static int ioffset = program["offset"];
|
||||
static int iscale = program["scale"];
|
||||
|
||||
#if 1
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), pos.begin());
|
||||
glVertexAttribPointer(1, 3, GL_UNSIGNED_BYTE, GL_FALSE, 3 * sizeof(GLubyte), color.begin());
|
||||
|
||||
program(ioffset, Sizef(-1, 1))
|
||||
(iscale, dd.vs)
|
||||
;
|
||||
|
||||
program.Use();
|
||||
|
||||
glDrawElements(GL_TRIANGLES, elements.GetCount(), GL_INT, elements);
|
||||
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
|
||||
#else
|
||||
GLVertexData va;
|
||||
va.Add(pos, 3);
|
||||
va.Add(color, GL_BYTE, 3, elements.GetCount());
|
||||
va.Index(elements);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
program(ioffset, Sizef(-1, 1))
|
||||
(iscale, dd.vs)
|
||||
;
|
||||
|
||||
va.Draw(program);
|
||||
#endif
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -409,7 +409,7 @@ protected:
|
|||
virtual void StrokeOp(double width, const RGBA& color1, const RGBA& color2,
|
||||
const Xform2D& transsrc,
|
||||
int style);
|
||||
virtual void StrokeOp(double width, const Pointf& f, const RGBA& color1,
|
||||
virtual void StrokeOp(double width, const Pointf& f, const RGBA& color1,
|
||||
const Pointf& c, double r, const RGBA& color2,
|
||||
int style);
|
||||
virtual void StrokeOp(double width, const Pointf& f,
|
||||
|
|
@ -419,7 +419,7 @@ protected:
|
|||
virtual void ClipOp();
|
||||
|
||||
virtual void CharacterOp(const Pointf& p, int ch, Font fnt);
|
||||
virtual void TextOp(const Pointf& p, const wchar *text, Font fnt, int n = -1,
|
||||
virtual void TextOp(const Pointf& p, const wchar *text, Font fnt, int n = -1,
|
||||
const double *dx = NULL);
|
||||
|
||||
virtual void ColorStopOp(double pos, const RGBA& color);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue