ultimatepp/uppsrc/GLDraw/GLPainter.h
cxl a783cffdfa GLDraw: GLCode::Mat4
git-svn-id: svn://ultimatepp.org/upp/trunk@12742 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2019-02-04 15:34:29 +00:00

319 lines
12 KiB
C++

#ifndef _GLDrawDemo_Ugl_h_
#define _GLDrawDemo_Ugl_h_
namespace Upp {
#define GL_TIMING(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;
Sizef off = Sizef(-1, 1);
double alpha = 1;
void Set(Size sz) { vs = Sizef(2.0 / sz.cx, -2.0 / sz.cy); }
GLContext2D(Size sz) { Set(sz); }
GLContext2D() {}
};
struct GLCode : GLProgram {
int64 serialid;
GLCode(const char *vertex_shader, const char *pixel_shader);
int operator[](const char *id) { return GetUniform(id); }
GLCode& Uniform(int i, double a);
GLCode& Uniform(int i, double a, double b);
GLCode& Uniform(int i, double a, double b, double c);
GLCode& Uniform(int i, double a, double b, double c, double d);
GLCode& Uniform(const char *id, double a);
GLCode& Uniform(const char *id, double a, double b);
GLCode& Uniform(const char *id, double a, double b, double c);
GLCode& Uniform(const char *id, double a, double b, double c, double d);
GLCode& operator()(const char *id, double a) { return Uniform(id, a); }
GLCode& operator()(const char *id, double a, double b) { return Uniform(id, a, b); }
GLCode& operator()(const char *id, double a, double b, double c) { return Uniform(id, a, b, c); }
GLCode& operator()(const char *id, double a, double b, double c, double d) { return Uniform(id, a, b, c, d); }
GLCode& operator()(int i, double a) { return Uniform(i, a); }
GLCode& operator()(int i, double a, double b) { return Uniform(i, a, b); }
GLCode& operator()(int i, double a, double b, double c) { return Uniform(i, a, b, c); }
GLCode& operator()(int i, double a, double b, double c, double d) { return Uniform(i, a, b, c, d); }
GLCode& operator()(const char *id, Pointf p) { return Uniform(id, p.x, p.y); }
GLCode& operator()(int i, Pointf p) { return Uniform(i, p.x, p.y); }
GLCode& operator()(const char *id, Sizef sz) { return Uniform(id, sz.cx, sz.cy); }
GLCode& operator()(int i, Sizef sz) { return Uniform(i, sz.cx, sz.cy); }
GLCode& operator()(const char *id, Color c, double alpha = 1);
GLCode& operator()(int i, Color c, double alpha = 1);
GLCode& Mat4(int i, float *mat4);
GLCode& Mat4(const char *id, float *mat4);
};
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, Point hotspot = Point(0, 0));
friend class GLTextureDraw;
public:
void Clear();
void Set(const Image& img, dword flags = TEXTURE_LINEAR|TEXTURE_MIPMAP);
void Bind(int ii = 0) const;
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); }
~GLTexture() { Clear(); }
GLTexture(const GLTexture& src);
GLTexture& operator=(const GLTexture& src);
};
void GLBind(int ii, const Image& img, dword style = TEXTURE_LINEAR|TEXTURE_MIPMAP);
void GLBind(const Image& img, dword style = TEXTURE_LINEAR|TEXTURE_MIPMAP);
void GLDrawTexture(const GLContext2D& dd, const Rectf& rect, int textureid, Size tsz, const Rect& src);
void GLDrawTexture(const GLContext2D& dd, const Rectf& rect, const GLTexture& img, const Rect& src);
void GLDrawImage(const GLContext2D& dd, const Rectf& rect, const Image& img, const Rect& src);
void GLDrawTexture(const GLContext2D& dd, const Rectf& rect, const GLTexture& img);
void GLDrawImage(const GLContext2D& dd, const Rectf& rect, const Image& img);
class GLVertexData {
struct Data {
int refcount = 1;
GLuint VAO = 0;
GLuint EBO = 0;
int elements = 0;
Vector<GLuint> VBO;
};
Data *data = NULL;
void Do();
public:
void Clear();
GLVertexData& Add(const void *data, int type, int ntuple, int count);
GLVertexData& Add(const float *data, int ntuple, int count) { return Add(data, GL_FLOAT, ntuple, count); }
GLVertexData& Add(const byte *data, int ntuple, int count) { return Add(data, GL_UNSIGNED_BYTE, ntuple, count); }
GLVertexData& Add(const dword *data, int ntuple, int count) { return Add(data, GL_UNSIGNED_INT, ntuple, count); }
GLVertexData& Add(const Vector<float>& data, int ntuple) { return Add(data, ntuple, data.GetCount() / ntuple); }
GLVertexData& Add(const Vector<byte>& data, int ntuple) { return Add(data, ntuple, data.GetCount() / ntuple); }
GLVertexData& Add(const Vector<dword>& data, int ntuple) { return Add(data, ntuple, data.GetCount() / ntuple); }
GLVertexData& Add(const Vector<Pointf>& pt);
GLVertexData& Index(const int *indices, int count);
GLVertexData& Index(const Vector<int>& indices) { return Index(indices, indices.GetCount()); }
void Draw(int mode = GL_TRIANGLES) const;
void Draw(GLCode& shaders, int mode = GL_TRIANGLES) const;
operator bool() const { return data; }
bool IsEmpty() const { return !data; }
GLVertexData() {}
~GLVertexData() { Clear(); }
GLVertexData(const GLVertexData& src);
GLVertexData& operator=(const GLVertexData& src);
};
const GLVertexData& GLRectMesh();
template <typename Src>
void GLPolygons(GLVertexData& mesh, const Src& polygon);
void GLDrawPolygons(const GLContext2D& dd, Pointf at, const GLVertexData& mesh, Sizef scale, Color color);
void GLDrawConvexPolygons(const GLContext2D& dd, Pointf at, const GLVertexData& mesh, Sizef scale, Color color);
template <typename Src>
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);
void GLDrawPolylines(const GLContext2D& dd, Pointf at, const GLVertexData& mesh, Sizef scale, double width, Color color);
void GLDrawStencil(Color color, double alpha);
void GLDrawEllipse(const GLContext2D& dd, Pointf center, Sizef radius, Color fill_color,
double width, Color line_color, const Vector<double>& dash, double distance);
void GLDrawEllipse(const GLContext2D& dd, Pointf center, Sizef radius, Color fill_color,
double width, Color line_color);
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);
void GLArc(Vector<Vector<Pointf>>& line, const Rectf& rc, Pointf start, Pointf end);
class GLTriangles {
Vector<float> pos;
Vector<byte> color;
Vector<GLint> elements;
int ii = 0;
public:
int Vertex(float x, float y, byte r, byte g, byte b, double alpha) {
pos << x << y << (float)alpha;
color << r << g << b;
return ii++;
}
int Vertex(float x, float y, Color c, double alpha) { return Vertex(x, y, c.GetR(), c.GetG(), c.GetB(), alpha); }
int Vertex(Pointf p, Color c, double alpha) { return Vertex((float)p.x, (float)p.y, c, alpha); }
int Vertex(int x, int y, Color c, double alpha) { return Vertex((float)x, (float)y, c, alpha); }
void Triangle(int a, int b, int c) { elements << a << b << c; }
void Clear() { elements.Clear(); pos.Clear(); color.Clear(); ii = 0; }
void Draw(const GLContext2D& dd);
};
void Ellipse(GLTriangles& tr, Pointf center, Sizef radius, Color color, double width, Color line_color, double alpha);
void Polyline(GLTriangles& tr, const Vector<Pointf>& p, double width, Color color, double alpha, bool close);
#include "GLPainter.hpp"
class DrawGL : public NilPainter, GLTriangles {
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 DrawRectOp(int x, int y, int cx, int cy, Color color);
virtual void DrawImageOp(int x, int y, int cx, int cy, const Image& image, const Rect& src, 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);
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> {
Rect clip;
Pointf offset;
};
struct State {
double alpha;
double dash_start;
Vector<double> dash;
};
Vector<Cloff> cloff;
Array<State> state;
GLContext2D dd;
Size view_size;
Rect scissor;
Pointf prev;
Vector<Vector<Pointf>> path;
bool path_done;
bool close_path;
double dash_start;
Vector<double> dash, path_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);
void ApplyDash(Vector<Vector<Pointf>>& polyline, int& width);
void DoDrawPolylines(Vector<Vector<Pointf>>& poly, int width, Color color, bool close = false);
void DoDrawPolygons(const Vector<Vector<Pointf>>& path, Color color);
friend class GLTextureDraw;
public:
using Draw::Clip;
void Init(Size sz, double alpha = 1);
void Flush();
operator const GLContext2D&() { Flush(); return dd; }
DrawGL() {}
DrawGL(Size sz, double alpha = 1) { Init(sz, alpha); }
~DrawGL();
};
class GLTextureDraw : public DrawGL {
GLuint framebuffer = 0;
GLuint texture = 0;
GLuint rbo = 0;
Size sz;
int msaa = 0;
public:
void Clear();
void Create(Size sz, int msaa = 0);
GLTexture GetResult();
operator GLTexture() { return GetResult(); }
GLTextureDraw() {}
GLTextureDraw(Size sz, int msaa = 0) { Create(sz, msaa); }
~GLTextureDraw() { Clear(); }
};
void GLClearCounters();
int GLElementCounter();
int GLTextureCounter();
int GLProgramCounter();
int GLDrawCounter();
int GLTesselateCounter();
};
#endif