mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-06-13 22:04:36 -06:00
GLPainter
git-svn-id: svn://ultimatepp.org/upp/trunk@12370 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
6e8d1aed0c
commit
6d0c7ce353
7 changed files with 466 additions and 0 deletions
82
bazaar/GLPainter/Code.cpp
Normal file
82
bazaar/GLPainter/Code.cpp
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
#include "GLPainter.h"
|
||||
|
||||
namespace Upp {
|
||||
|
||||
GLCode::GLCode(const char *vertex_shader, const char *pixel_shader)
|
||||
{
|
||||
Create(vertex_shader, pixel_shader);
|
||||
Vector<Tuple2<int, const char *>> ins;
|
||||
CParser p(vertex_shader);
|
||||
int ii = 0;
|
||||
while(!p.IsEof() && !p.Char('{'))
|
||||
if(p.Id("attribute") || p.Id("in")) {
|
||||
String id;
|
||||
while(!p.IsEof() && !p.Char(';'))
|
||||
if(p.IsId())
|
||||
id = p.ReadId();
|
||||
else
|
||||
p.SkipTerm();
|
||||
if(id.GetCount())
|
||||
glBindAttribLocation(program, ii++, id);
|
||||
}
|
||||
else
|
||||
p.SkipTerm();
|
||||
}
|
||||
|
||||
GLCode& GLCode::Uniform(int i, double a)
|
||||
{
|
||||
Use();
|
||||
glUniform1f(i, (float)a);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GLCode& GLCode::Uniform(int i, double a, double b)
|
||||
{
|
||||
Use();
|
||||
glUniform2f(i, (float)a, (float)b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GLCode& GLCode::Uniform(int i, double a, double b, double c)
|
||||
{
|
||||
Use();
|
||||
glUniform3f(i, (float)a, (float)b, (float)c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GLCode& GLCode::Uniform(int i, double a, double b, double c, double d)
|
||||
{
|
||||
Use();
|
||||
glUniform4f(i, (float)a, (float)b, (float)c, (float)d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GLCode& GLCode::Uniform(const char *id, double a)
|
||||
{
|
||||
Use();
|
||||
glUniform1f(GetUniform(id), (float)a);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GLCode& GLCode::Uniform(const char *id, double a, double b)
|
||||
{
|
||||
Use();
|
||||
glUniform2f(GetUniform(id), (float)a, (float)b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GLCode& GLCode::Uniform(const char *id, double a, double b, double c)
|
||||
{
|
||||
Use();
|
||||
glUniform3f(GetUniform(id), (float)a, (float)b, (float)c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GLCode& GLCode::Uniform(const char *id, double a, double b, double c, double d)
|
||||
{
|
||||
Use();
|
||||
glUniform4f(GetUniform(id), (float)a, (float)b, (float)c, (float)d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
95
bazaar/GLPainter/GLPainter.h
Normal file
95
bazaar/GLPainter/GLPainter.h
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
#ifndef _GLDrawDemo_Ugl_h_
|
||||
#define _GLDrawDemo_Ugl_h_
|
||||
|
||||
#include <GLDraw/GLDraw.h>
|
||||
#include <plugin/tess2/tess2.h>
|
||||
|
||||
namespace Upp {
|
||||
|
||||
struct GLCode : GLProgram {
|
||||
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); }
|
||||
};
|
||||
|
||||
/*
|
||||
class GLTexture {
|
||||
int textureid = 0;
|
||||
|
||||
public:
|
||||
void Clear() { if(textureid)
|
||||
void Set(const Image& img, dword flags);
|
||||
|
||||
operator GLuint() const { return textureid; }
|
||||
GLuint operator~() const { return textureid; }
|
||||
void Bind() const {
|
||||
|
||||
GLTexture();
|
||||
GLTexture(const Image& img) { Set(img); }
|
||||
~GLTexture() { Clear(); }
|
||||
}
|
||||
*/
|
||||
|
||||
Sizef GLMakeViewScale(Size view_size);
|
||||
|
||||
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;
|
||||
int elements;
|
||||
|
||||
Vector<GLuint> VBO;
|
||||
|
||||
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 Vector<Pointf>& pt);
|
||||
GLMesh& Index(const int *indices, int count);
|
||||
GLMesh& 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;
|
||||
|
||||
GLMesh();
|
||||
~GLMesh();
|
||||
};
|
||||
|
||||
const GLMesh& GLRectMesh();
|
||||
|
||||
void GLMakePolygon(GLMesh& mesh, const Vector<Vector<Pointf>>& polygon);
|
||||
void GLDrawPolygon(Sizef vs, Point at, const GLMesh& mesh, Sizef scale, Color color, double alpha);
|
||||
|
||||
void GLStencilPolygon(GLMesh& mesh, const Vector<Vector<Pointf>>& polygon);
|
||||
void GLDrawStencilPolygon(Sizef vs, Point at, const GLMesh& mesh, Sizef scale, Color color, double alpha);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
17
bazaar/GLPainter/GLPainter.upp
Normal file
17
bazaar/GLPainter/GLPainter.upp
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
description "OpenGL based GLDraw demo\377";
|
||||
|
||||
uses
|
||||
CtrlLib,
|
||||
GLDraw,
|
||||
GLCtrl,
|
||||
plugin/jpg,
|
||||
plugin/tess2;
|
||||
|
||||
file
|
||||
GLPainter.h,
|
||||
Code.cpp,
|
||||
Mesh.cpp,
|
||||
Image.cpp,
|
||||
Polygon.cpp,
|
||||
StencilPolygon.cpp;
|
||||
|
||||
74
bazaar/GLPainter/Image.cpp
Normal file
74
bazaar/GLPainter/Image.cpp
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
#include "GLPainter.h"
|
||||
|
||||
namespace Upp {
|
||||
|
||||
void GLBind(const Image& img, dword style)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, GetTextureForImage(style, img));
|
||||
}
|
||||
|
||||
Sizef GLMakeViewScale(Size view_size)
|
||||
{
|
||||
return Sizef(2.0 / view_size.cx, -2.0 / view_size.cy);
|
||||
}
|
||||
|
||||
const GLMesh& GLRectMesh()
|
||||
{
|
||||
static GLMesh mesh;
|
||||
ONCELOCK {
|
||||
static const float box[] = {
|
||||
0, 0, // 0
|
||||
0, 1, // 1
|
||||
1, 0, // 2
|
||||
1, 1, // 3
|
||||
};
|
||||
static const int ndx[] = {
|
||||
0, 1, 2, 1, 2, 3
|
||||
};
|
||||
mesh.Add(box, 2, 4).Index(ndx, 6);
|
||||
}
|
||||
return mesh;
|
||||
}
|
||||
|
||||
void GLDrawImage(Sizef vs, const Rect& rect, const Image& img, double alpha)
|
||||
{
|
||||
static GLCode program(R"(
|
||||
#version 330 core
|
||||
uniform vec2 offset;
|
||||
uniform vec2 scale;
|
||||
in vec2 aPos;
|
||||
out vec2 tPos;
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(scale * aPos + offset, 0, 1);
|
||||
tPos = aPos;
|
||||
}
|
||||
)", R"(
|
||||
#version 330 core
|
||||
in vec2 tPos;
|
||||
uniform float alpha;
|
||||
uniform sampler2D s_texture;
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = alpha * texture2D(s_texture, tPos);
|
||||
}
|
||||
)");
|
||||
|
||||
static int offset = program["offset"];
|
||||
static int scale = program["scale"];
|
||||
static int ialpha = program["alpha"];
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
GLBind(img);
|
||||
GLRectMesh().Draw(
|
||||
program(offset, vs * rect.TopLeft() + Sizef(-1, 1))
|
||||
(scale, vs * rect.GetSize())
|
||||
(ialpha, alpha)
|
||||
);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
77
bazaar/GLPainter/Mesh.cpp
Normal file
77
bazaar/GLPainter/Mesh.cpp
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
#include "GLPainter.h"
|
||||
|
||||
namespace Upp {
|
||||
|
||||
GLMesh::GLMesh()
|
||||
{
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &EBO);
|
||||
}
|
||||
|
||||
GLMesh::~GLMesh()
|
||||
{
|
||||
glDeleteVertexArrays(1, &VAO);
|
||||
glDeleteBuffers(1, &EBO);
|
||||
for(auto h : VBO)
|
||||
glDeleteBuffers(1, &h);
|
||||
}
|
||||
|
||||
GLMesh& GLMesh::Add(const void *data, int type, int ntuple, int count)
|
||||
{
|
||||
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));
|
||||
glBufferData(GL_ARRAY_BUFFER, sz * ntuple * count, data, GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(ii, ntuple, type, GL_FALSE, ntuple * sz, (void*)0);
|
||||
glEnableVertexAttribArray(ii);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GLMesh& GLMesh::Index(const int *indices, int count)
|
||||
{
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * count, indices, GL_STATIC_DRAW);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
elements = count;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void GLMesh::Draw(int mode) const
|
||||
{
|
||||
glBindVertexArray(VAO);
|
||||
glDrawElements(mode, elements, GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void GLMesh::Draw(GLCode& shaders, int mode) const
|
||||
{
|
||||
shaders.Use();
|
||||
Draw(mode);
|
||||
}
|
||||
|
||||
GLMesh& GLMesh::Add(const Vector<Pointf>& pt)
|
||||
{
|
||||
Buffer<float> f(2 * pt.GetCount());
|
||||
float *t = f;
|
||||
for(const Pointf& p : pt) {
|
||||
*t++ = (float)p.x;
|
||||
*t++ = (float)p.y;
|
||||
}
|
||||
return Add(f, GL_FLOAT, 2, pt.GetCount());
|
||||
}
|
||||
|
||||
};
|
||||
46
bazaar/GLPainter/Polygon.cpp
Normal file
46
bazaar/GLPainter/Polygon.cpp
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#include "GLPainter.h"
|
||||
|
||||
namespace Upp {
|
||||
|
||||
void GLMakePolygon(GLMesh& mesh, const Vector<Vector<Pointf>>& polygon)
|
||||
{
|
||||
Vector<Pointf> vertex;
|
||||
Vector<int> ndx;
|
||||
Tesselate(polygon, vertex, ndx);
|
||||
|
||||
mesh.Add(vertex).Index(ndx);
|
||||
}
|
||||
|
||||
void GLDrawPolygon(Sizef vs, Point at, const GLMesh& mesh, Sizef scale, Color color, double alpha)
|
||||
{
|
||||
static GLCode program(R"(
|
||||
#version 330 core
|
||||
in vec2 aPos;
|
||||
uniform vec2 offset;
|
||||
uniform vec2 scale;
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(scale * aPos + offset, 0, 1);
|
||||
}
|
||||
)", R"(
|
||||
#version 330 core
|
||||
uniform vec4 color;
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = color;
|
||||
}
|
||||
)");
|
||||
|
||||
RTIMING("Poly");
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
mesh.Draw(
|
||||
program("offset", vs * at + Sizef(-1, 1))
|
||||
("scale", vs * scale)
|
||||
("color", color.GetR() / 255.0f, color.GetG() / 255.0f, color.GetB() / 255.0f, alpha)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
75
bazaar/GLPainter/StencilPolygon.cpp
Normal file
75
bazaar/GLPainter/StencilPolygon.cpp
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
#include "GLPainter.h"
|
||||
|
||||
namespace Upp {
|
||||
|
||||
void GLStencilPolygon(GLMesh& mesh, const Vector<Vector<Pointf>>& polygon)
|
||||
{
|
||||
Vector<Pointf> vertex;
|
||||
Vector<int> 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)
|
||||
{
|
||||
static GLCode program(R"(
|
||||
#version 330 core
|
||||
in vec2 aPos;
|
||||
uniform vec2 offset;
|
||||
uniform vec2 scale;
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(scale * aPos + offset, 0, 1);
|
||||
}
|
||||
)", R"(
|
||||
#version 330 core
|
||||
uniform vec4 color;
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = color;
|
||||
}
|
||||
)");
|
||||
|
||||
RTIMING("Stencil");
|
||||
|
||||
|
||||
program("offset", vs * at + Sizef(-1, 1))
|
||||
("scale", vs * scale)
|
||||
("color", color.GetR() / 255.0f, color.GetG() / 255.0f, color.GetB() / 255.0f, alpha);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
// glClearStencil(0);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
glStencilFunc(GL_NEVER, 0, 1);
|
||||
glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
|
||||
|
||||
mesh.Draw(program);
|
||||
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glStencilFunc(GL_EQUAL, 1, 1);
|
||||
glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
GLRectMesh().Draw(
|
||||
program("offset", -1, -1)
|
||||
("scale", 2, 2)
|
||||
);
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue