diff --git a/bazaar/GLPainter/GLPainter.h b/bazaar/GLPainter/GLPainter.h index 04fa58adb..c4aeee289 100644 --- a/bazaar/GLPainter/GLPainter.h +++ b/bazaar/GLPainter/GLPainter.h @@ -62,21 +62,28 @@ void GLBind(const Image& img, dword style = TEXTURE_LINEAR|TEXTURE_MIPMAP); void GLDrawImage(Sizef vs, const Rect& rect, const Image& img, double alpha); class GLMesh { - GLuint VAO, EBO; + GLuint VAO = 0; + GLuint EBO = 0; int elements; Vector VBO; + + void Make(); public: GLMesh& Add(const void *data, int type, int ntuple, int count); - GLMesh& Add(const float *data, int ntuple, int count) { return Add(data, GL_FLOAT, ntuple, count); } + GLMesh& Add(const float *data, int ntuple, int count) { return Add(data, GL_FLOAT, ntuple, count); } GLMesh& Add(const Vector& pt); GLMesh& Index(const int *indices, int count); - GLMesh& Index(const Vector& indices) { return Index(indices, indices.GetCount()); } + GLMesh& Index(const Vector& indices) { return Index(indices, indices.GetCount()); } - void Draw(int mode = GL_TRIANGLES) const; + void Draw(int mode = GL_TRIANGLES) const; - void Draw(GLCode& shaders, int mode = GL_TRIANGLES) const; + void Draw(GLCode& shaders, int mode = GL_TRIANGLES) const; + + void Clear(); + + bool IsEmpty() const { return VAO == 0; } GLMesh(); ~GLMesh(); @@ -87,8 +94,25 @@ const GLMesh& GLRectMesh(); void GLMakePolygon(GLMesh& mesh, const Vector>& polygon); void GLDrawPolygon(Sizef vs, Point at, const GLMesh& mesh, Sizef scale, Color color, double alpha); -void GLStencilPolygon(GLMesh& mesh, const Vector>& polygon); -void GLDrawStencilPolygon(Sizef vs, Point at, const GLMesh& mesh, Sizef scale, Color color, double alpha); +template +void GLStencilPolygon(GLMesh& mesh, const Src& polygon) +{ + Vector vertex; // todo: Optimize! + Vector ndx; + + for(const auto& p: polygon) { + int i0 = vertex.GetCount(); + for(int i = 0; i < p.GetCount(); i++) { + if(i > 1) + ndx << i0 << i0 + i - 1 << i0 + i; + vertex.Add(p[i]); + } + } + + mesh.Add(vertex).Index(ndx); +} + +void GLDrawStencilPolygon(Sizef vs, Pointf at, const GLMesh& mesh, Sizef scale, Color color, double alpha); }; diff --git a/bazaar/GLPainter/Mesh.cpp b/bazaar/GLPainter/Mesh.cpp index 3c53b72a9..b8145cccc 100644 --- a/bazaar/GLPainter/Mesh.cpp +++ b/bazaar/GLPainter/Mesh.cpp @@ -2,35 +2,47 @@ namespace Upp { -GLMesh::GLMesh() +GLMesh::GLMesh() {} + +void GLMesh::Make() { - glGenVertexArrays(1, &VAO); - glGenBuffers(1, &EBO); + if(!VAO) { + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &EBO); + } } -GLMesh::~GLMesh() +void GLMesh::Clear() { glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &EBO); for(auto h : VBO) glDeleteBuffers(1, &h); + VAO = EBO = 0; + VBO.Clear(); +} + +GLMesh::~GLMesh() +{ + Clear(); } GLMesh& GLMesh::Add(const void *data, int type, int ntuple, int count) { + Make(); glBindVertexArray(VAO); int ii = VBO.GetCount(); GLuint& vbo = VBO.Add(); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); - int sz = decode(type, GL_FLOAT, sizeof(float), - GL_BYTE, sizeof(byte), - GL_UNSIGNED_BYTE, sizeof(byte), - GL_SHORT, sizeof(int16), - GL_UNSIGNED_SHORT, sizeof(uint16), - GL_INT, sizeof(int32), - GL_UNSIGNED_INT, sizeof(uint32), - (int)sizeof(double)); + int sz = (int)decode(type, GL_FLOAT, sizeof(float), + GL_BYTE, sizeof(byte), + GL_UNSIGNED_BYTE, sizeof(byte), + GL_SHORT, sizeof(int16), + GL_UNSIGNED_SHORT, sizeof(uint16), + GL_INT, sizeof(int32), + GL_UNSIGNED_INT, sizeof(uint32), + sizeof(double)); glBufferData(GL_ARRAY_BUFFER, sz * ntuple * count, data, GL_STATIC_DRAW); glVertexAttribPointer(ii, ntuple, type, GL_FALSE, ntuple * sz, (void*)0); glEnableVertexAttribArray(ii); @@ -41,6 +53,7 @@ GLMesh& GLMesh::Add(const void *data, int type, int ntuple, int count) GLMesh& GLMesh::Index(const int *indices, int count) { + Make(); glBindVertexArray(VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * count, indices, GL_STATIC_DRAW); @@ -52,7 +65,8 @@ GLMesh& GLMesh::Index(const int *indices, int count) void GLMesh::Draw(int mode) const { - glBindVertexArray(VAO); + if(VAO) + glBindVertexArray(VAO); glDrawElements(mode, elements, GL_UNSIGNED_INT, 0); glBindVertexArray(0); } diff --git a/bazaar/GLPainter/StencilPolygon.cpp b/bazaar/GLPainter/StencilPolygon.cpp index cccb2c175..3cb176ca7 100644 --- a/bazaar/GLPainter/StencilPolygon.cpp +++ b/bazaar/GLPainter/StencilPolygon.cpp @@ -2,24 +2,7 @@ namespace Upp { -void GLStencilPolygon(GLMesh& mesh, const Vector>& polygon) -{ - Vector vertex; - Vector ndx; - - for(const auto& p: polygon) { - int i0 = vertex.GetCount(); - for(int i = 0; i < p.GetCount(); i++) { - if(i > 1) - ndx << i0 << i0 + i - 1 << i0 + i; - vertex.Add(p[i]); - } - } - - mesh.Add(vertex).Index(ndx); -} - -void GLDrawStencilPolygon(Sizef vs, Point at, const GLMesh& mesh, Sizef scale, Color color, double alpha) +void GLDrawStencilPolygon(Sizef vs, Pointf at, const GLMesh& mesh, Sizef scale, Color color, double alpha) { static GLCode program(R"( #version 330 core @@ -42,7 +25,7 @@ void GLDrawStencilPolygon(Sizef vs, Point at, const GLMesh& mesh, Sizef scale, C RTIMING("Stencil"); - program("offset", vs * at + Sizef(-1, 1)) + program("offset", Pointf(vs) * at + Sizef(-1, 1)) ("scale", vs * scale) ("color", color.GetR() / 255.0f, color.GetG() / 255.0f, color.GetB() / 255.0f, alpha);