|
@@ -60,7 +60,7 @@ void nvgDeleteGL3(struct NVGcontext* ctx); |
|
|
#include "nanovg.h" |
|
|
#include "nanovg.h" |
|
|
|
|
|
|
|
|
enum GLNVGuniformLoc { |
|
|
enum GLNVGuniformLoc { |
|
|
GLNVG_LOC_VIEWSIZE, |
|
|
|
|
|
|
|
|
GLNVG_LOC_UBOVIEW, |
|
|
GLNVG_LOC_SCISSORMAT, |
|
|
GLNVG_LOC_SCISSORMAT, |
|
|
GLNVG_LOC_SCISSOREXT, |
|
|
GLNVG_LOC_SCISSOREXT, |
|
|
GLNVG_LOC_SCISSORSCALE, |
|
|
GLNVG_LOC_SCISSORSCALE, |
|
@@ -84,6 +84,10 @@ enum GLNVGshaderType { |
|
|
NSVG_SHADER_IMG |
|
|
NSVG_SHADER_IMG |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
enum GLNVGuniformBindings { |
|
|
|
|
|
GLNVG_UBO_VIEW_BINDING = 0, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
struct GLNVGshader { |
|
|
struct GLNVGshader { |
|
|
GLuint prog; |
|
|
GLuint prog; |
|
|
GLuint frag; |
|
|
GLuint frag; |
|
@@ -126,12 +130,13 @@ struct GLNVGpath { |
|
|
struct GLNVGcontext { |
|
|
struct GLNVGcontext { |
|
|
struct GLNVGshader shader; |
|
|
struct GLNVGshader shader; |
|
|
struct GLNVGtexture* textures; |
|
|
struct GLNVGtexture* textures; |
|
|
float viewWidth, viewHeight; |
|
|
|
|
|
|
|
|
float view[2]; |
|
|
int ntextures; |
|
|
int ntextures; |
|
|
int ctextures; |
|
|
int ctextures; |
|
|
int textureId; |
|
|
int textureId; |
|
|
GLuint vertArr; |
|
|
GLuint vertArr; |
|
|
GLuint vertBuf; |
|
|
GLuint vertBuf; |
|
|
|
|
|
GLuint uboViewBuf; |
|
|
int edgeAntiAlias; |
|
|
int edgeAntiAlias; |
|
|
|
|
|
|
|
|
struct GLNVGcall* calls; |
|
|
struct GLNVGcall* calls; |
|
@@ -145,6 +150,8 @@ struct GLNVGcontext { |
|
|
int nverts; |
|
|
int nverts; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static struct GLNVGtexture* glnvg__allocTexture(struct GLNVGcontext* gl) |
|
|
static struct GLNVGtexture* glnvg__allocTexture(struct GLNVGcontext* gl) |
|
|
{ |
|
|
{ |
|
|
struct GLNVGtexture* tex = NULL; |
|
|
struct GLNVGtexture* tex = NULL; |
|
@@ -283,7 +290,7 @@ static void glnvg__deleteShader(struct GLNVGshader* shader) |
|
|
|
|
|
|
|
|
static void glnvg__getUniforms(struct GLNVGshader* shader) |
|
|
static void glnvg__getUniforms(struct GLNVGshader* shader) |
|
|
{ |
|
|
{ |
|
|
shader->loc[GLNVG_LOC_VIEWSIZE] = glGetUniformLocation(shader->prog, "viewSize"); |
|
|
|
|
|
|
|
|
shader->loc[GLNVG_LOC_UBOVIEW] = glGetUniformBlockIndex(shader->prog, "uboView"); |
|
|
shader->loc[GLNVG_LOC_SCISSORMAT] = glGetUniformLocation(shader->prog, "scissorMat"); |
|
|
shader->loc[GLNVG_LOC_SCISSORMAT] = glGetUniformLocation(shader->prog, "scissorMat"); |
|
|
shader->loc[GLNVG_LOC_SCISSOREXT] = glGetUniformLocation(shader->prog, "scissorExt"); |
|
|
shader->loc[GLNVG_LOC_SCISSOREXT] = glGetUniformLocation(shader->prog, "scissorExt"); |
|
|
shader->loc[GLNVG_LOC_SCISSORSCALE] = glGetUniformLocation(shader->prog, "scissorScale"); |
|
|
shader->loc[GLNVG_LOC_SCISSORSCALE] = glGetUniformLocation(shader->prog, "scissorScale"); |
|
@@ -310,7 +317,9 @@ static int glnvg__renderCreate(void* uptr) |
|
|
#else |
|
|
#else |
|
|
"#version 150 core\n" |
|
|
"#version 150 core\n" |
|
|
#endif |
|
|
#endif |
|
|
"uniform vec2 viewSize;\n" |
|
|
|
|
|
|
|
|
"layout(std140) uniform uboView {\n" |
|
|
|
|
|
" vec2 viewSize;\n" |
|
|
|
|
|
"};\n" |
|
|
"in vec2 vertex;\n" |
|
|
"in vec2 vertex;\n" |
|
|
"in vec2 tcoord;\n" |
|
|
"in vec2 tcoord;\n" |
|
|
"out vec2 ftcoord;\n" |
|
|
"out vec2 ftcoord;\n" |
|
@@ -475,6 +484,10 @@ static int glnvg__renderCreate(void* uptr) |
|
|
glGenVertexArrays(1, &gl->vertArr); |
|
|
glGenVertexArrays(1, &gl->vertArr); |
|
|
glGenBuffers(1, &gl->vertBuf); |
|
|
glGenBuffers(1, &gl->vertBuf); |
|
|
|
|
|
|
|
|
|
|
|
// Create UBOs |
|
|
|
|
|
glUniformBlockBinding(gl->shader.prog, gl->shader.loc[GLNVG_LOC_UBOVIEW], GLNVG_UBO_VIEW_BINDING); |
|
|
|
|
|
glGenBuffers(1, &gl->uboViewBuf); |
|
|
|
|
|
|
|
|
glnvg__checkError("done"); |
|
|
glnvg__checkError("done"); |
|
|
|
|
|
|
|
|
return 1; |
|
|
return 1; |
|
@@ -628,7 +641,6 @@ static int glnvg__setupPaint(struct GLNVGcontext* gl, struct NVGpaint* paint, st |
|
|
tex = glnvg__findTexture(gl, paint->image); |
|
|
tex = glnvg__findTexture(gl, paint->image); |
|
|
if (tex == NULL) return 0; |
|
|
if (tex == NULL) return 0; |
|
|
glUniform1i(gl->shader.loc[GLNVG_LOC_TYPE], NSVG_SHADER_FILLIMG); |
|
|
glUniform1i(gl->shader.loc[GLNVG_LOC_TYPE], NSVG_SHADER_FILLIMG); |
|
|
glUniform2f(gl->shader.loc[GLNVG_LOC_VIEWSIZE], gl->viewWidth, gl->viewHeight); |
|
|
|
|
|
glUniformMatrix3fv(gl->shader.loc[GLNVG_LOC_SCISSORMAT], 1, GL_FALSE, scissorMat); |
|
|
glUniformMatrix3fv(gl->shader.loc[GLNVG_LOC_SCISSORMAT], 1, GL_FALSE, scissorMat); |
|
|
glUniform2f(gl->shader.loc[GLNVG_LOC_SCISSOREXT], scissorx, scissory); |
|
|
glUniform2f(gl->shader.loc[GLNVG_LOC_SCISSOREXT], scissorx, scissory); |
|
|
glUniform2f(gl->shader.loc[GLNVG_LOC_SCISSORSCALE], scissorsx, scissorsy); |
|
|
glUniform2f(gl->shader.loc[GLNVG_LOC_SCISSORSCALE], scissorsx, scissorsy); |
|
@@ -642,7 +654,6 @@ static int glnvg__setupPaint(struct GLNVGcontext* gl, struct NVGpaint* paint, st |
|
|
glnvg__checkError("tex paint tex"); |
|
|
glnvg__checkError("tex paint tex"); |
|
|
} else { |
|
|
} else { |
|
|
glUniform1i(gl->shader.loc[GLNVG_LOC_TYPE], NSVG_SHADER_FILLGRAD); |
|
|
glUniform1i(gl->shader.loc[GLNVG_LOC_TYPE], NSVG_SHADER_FILLGRAD); |
|
|
glUniform2f(gl->shader.loc[GLNVG_LOC_VIEWSIZE], gl->viewWidth, gl->viewHeight); |
|
|
|
|
|
glUniformMatrix3fv(gl->shader.loc[GLNVG_LOC_SCISSORMAT], 1, GL_FALSE, scissorMat); |
|
|
glUniformMatrix3fv(gl->shader.loc[GLNVG_LOC_SCISSORMAT], 1, GL_FALSE, scissorMat); |
|
|
glUniform2f(gl->shader.loc[GLNVG_LOC_SCISSOREXT], scissorx, scissory); |
|
|
glUniform2f(gl->shader.loc[GLNVG_LOC_SCISSOREXT], scissorx, scissory); |
|
|
glUniform2f(gl->shader.loc[GLNVG_LOC_SCISSORSCALE], scissorsx, scissorsy); |
|
|
glUniform2f(gl->shader.loc[GLNVG_LOC_SCISSORSCALE], scissorsx, scissorsy); |
|
@@ -661,8 +672,8 @@ static int glnvg__setupPaint(struct GLNVGcontext* gl, struct NVGpaint* paint, st |
|
|
static void glnvg__renderViewport(void* uptr, int width, int height) |
|
|
static void glnvg__renderViewport(void* uptr, int width, int height) |
|
|
{ |
|
|
{ |
|
|
struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr; |
|
|
struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr; |
|
|
gl->viewWidth = (float)width; |
|
|
|
|
|
gl->viewHeight = (float)height; |
|
|
|
|
|
|
|
|
gl->view[0] = (float)width; |
|
|
|
|
|
gl->view[1] = (float)height; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static void glnvg__fill(struct GLNVGcontext* gl, struct GLNVGcall* call) |
|
|
static void glnvg__fill(struct GLNVGcontext* gl, struct GLNVGcall* call) |
|
@@ -702,7 +713,6 @@ static void glnvg__fill(struct GLNVGcontext* gl, struct GLNVGcall* call) |
|
|
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); |
|
|
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); |
|
|
|
|
|
|
|
|
glUniform1i(gl->shader.loc[GLNVG_LOC_TYPE], NSVG_SHADER_SIMPLE); |
|
|
glUniform1i(gl->shader.loc[GLNVG_LOC_TYPE], NSVG_SHADER_SIMPLE); |
|
|
glUniform2f(gl->shader.loc[GLNVG_LOC_VIEWSIZE], gl->viewWidth, gl->viewHeight); |
|
|
|
|
|
glnvg__checkError("fill solid loc"); |
|
|
glnvg__checkError("fill solid loc"); |
|
|
|
|
|
|
|
|
glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP); |
|
|
glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP); |
|
@@ -765,7 +775,6 @@ static void glnvg__triangles(struct GLNVGcontext* gl, struct GLNVGcall* call) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
glUniform1i(gl->shader.loc[GLNVG_LOC_TYPE], NSVG_SHADER_IMG); |
|
|
glUniform1i(gl->shader.loc[GLNVG_LOC_TYPE], NSVG_SHADER_IMG); |
|
|
glUniform2f(gl->shader.loc[GLNVG_LOC_VIEWSIZE], gl->viewWidth, gl->viewHeight); |
|
|
|
|
|
glUniform1i(gl->shader.loc[GLNVG_LOC_TEX], 0); |
|
|
glUniform1i(gl->shader.loc[GLNVG_LOC_TEX], 0); |
|
|
glUniform1i(gl->shader.loc[GLNVG_LOC_TEXTYPE], tex->type == NVG_TEXTURE_RGBA ? 0 : 1); |
|
|
glUniform1i(gl->shader.loc[GLNVG_LOC_TEXTYPE], tex->type == NVG_TEXTURE_RGBA ? 0 : 1); |
|
|
glnvg__toFloatColor(color, call->paint.innerColor); |
|
|
glnvg__toFloatColor(color, call->paint.innerColor); |
|
@@ -793,6 +802,11 @@ static void glnvg__renderFlush(void* uptr) |
|
|
glEnableVertexAttribArray(1); |
|
|
glEnableVertexAttribArray(1); |
|
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(size_t)0); |
|
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(size_t)0); |
|
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(0 + 2*sizeof(float))); |
|
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(0 + 2*sizeof(float))); |
|
|
|
|
|
// once per frame set ubo for view |
|
|
|
|
|
glBindBuffer(GL_UNIFORM_BUFFER, gl->uboViewBuf); |
|
|
|
|
|
glBufferData(GL_UNIFORM_BUFFER, sizeof(gl->view), 0, GL_STREAM_DRAW); |
|
|
|
|
|
glBufferData(GL_UNIFORM_BUFFER, sizeof(gl->view), gl->view, GL_STREAM_DRAW); |
|
|
|
|
|
glBindBufferBase(GL_UNIFORM_BUFFER, GLNVG_UBO_VIEW_BINDING, gl->uboViewBuf); |
|
|
|
|
|
|
|
|
for (i = 0; i < gl->ncalls; i++) { |
|
|
for (i = 0; i < gl->ncalls; i++) { |
|
|
struct GLNVGcall* call = &gl->calls[i]; |
|
|
struct GLNVGcall* call = &gl->calls[i]; |
|
|