diff --git a/example/example_gl2.c b/example/example_gl2.c index f21263b..6c9d974 100644 --- a/example/example_gl2.c +++ b/example/example_gl2.c @@ -23,8 +23,8 @@ #include #include "nanovg.h" #define NANOVG_GL2_IMPLEMENTATION -#include "nanovg_gl2.h" -//#include "nanovg_gl3buf.h" // This version does not work correctly yet. +//#include "nanovg_gl2.h" +#include "nanovg_gl3buf.h" // This version does not work correctly yet. #include "demo.h" #include "perf.h" diff --git a/src/nanovg_gl3buf.h b/src/nanovg_gl3buf.h index 2a07eed..ee97353 100644 --- a/src/nanovg_gl3buf.h +++ b/src/nanovg_gl3buf.h @@ -25,17 +25,18 @@ extern "C" { #define NVG_ANTIALIAS 1 #if defined NANOVG_GL2_IMPLEMENTATION -# define NANOVG_GL2 -# define NANOVG_GL_IMPLEMENTATION +# define NANOVG_GL2 1 +# define NANOVG_GL_IMPLEMENTATION 1 #elif defined NANOVG_GL3_IMPLEMENTATION -# define NANOVG_GL3 -# define NANOVG_GL_IMPLEMENTATION +# define NANOVG_GL3 1 +# define NANOVG_GL_IMPLEMENTATION 1 +# define NANOVG_GL_USE_UNIFORMBUFFER 1 #elif defined NANOVG_GLES2_IMPLEMENTATION -# define NANOVG_GLES2 -# define NANOVG_GL_IMPLEMENTATION +# define NANOVG_GLES2 1 +# define NANOVG_GL_IMPLEMENTATION 1 #elif defined NANOVG_GLES3_IMPLEMENTATION -# define NANOVG_GLES3 -# define NANOVG_GL_IMPLEMENTATION +# define NANOVG_GLES3 1 +# define NANOVG_GL_IMPLEMENTATION 1 #endif @@ -76,7 +77,7 @@ void nvgDeleteGLES3(struct NVGcontext* ctx); #include "nanovg.h" enum GLNVGuniformLoc { -#if defined NANOVG_GL3 +#if NANOVG_GL_USE_UNIFORMBUFFER GLNVG_LOC_VIEW, GLNVG_LOC_FRAG, #else @@ -105,10 +106,12 @@ enum GLNVGshaderType { NSVG_SHADER_IMG }; +#if NANOVG_GL_USE_UNIFORMBUFFER enum GLNVGuniformBindings { GLNVG_VIEW_BINDING = 0, GLNVG_FRAG_BINDING = 1, }; +#endif struct GLNVGshader { GLuint prog; @@ -152,7 +155,7 @@ struct GLNVGfragUniforms { float scissorMat[12]; // matrices are actually 3 vec4s float paintMat[12]; struct NVGcolor innerCol; - struct NVGcolor outerCol; + struct NVGcolor outerCol; float scissorExt[2]; float scissorScale[2]; float extent[2]; @@ -173,6 +176,8 @@ struct GLNVGcontext { GLuint vertBuf; #if defined NANOVG_GL3 GLuint vertArr; +#endif +#if NANOVG_GL_USE_UNIFORMBUFFER GLuint viewBuf; GLuint fragBuf; #endif @@ -338,7 +343,7 @@ static void glnvg__deleteShader(struct GLNVGshader* shader) static void glnvg__getUniforms(struct GLNVGshader* shader) { -#if defined NANOVG_GL3 +#if NANOVG_GL_USE_UNIFORMBUFFER shader->loc[GLNVG_LOC_VIEW] = glGetUniformBlockIndex(shader->prog, "view"); shader->loc[GLNVG_LOC_FRAG] = glGetUniformBlockIndex(shader->prog, "frag"); #else @@ -369,6 +374,9 @@ static int glnvg__renderCreate(void* uptr) "#define NANOVG_GL2 1\n"; #elif defined NANOVG_GL3 "#version 150 core\n" +#if NANOVG_GL_USE_UNIFORMBUFFER + "#define USE_UNIFORMBUFFER 1\n" +#endif "#define NANOVG_GL3 1\n"; #elif defined NANOVG_GLES2 "#version 100\n" @@ -382,9 +390,13 @@ static int glnvg__renderCreate(void* uptr) static const char* fillVertShader = "#ifdef NANOVG_GL3\n" + "#ifdef USE_UNIFORMBUFFER\n" " layout(std140) uniform view {\n" " vec2 viewSize;\n" " };\n" + "#else\n" + " uniform vec2 viewSize;\n" + "#endif\n" " in vec2 vertex;\n" " in vec2 tcoord;\n" " out vec2 ftcoord;\n" @@ -404,6 +416,7 @@ static int glnvg__renderCreate(void* uptr) static const char* fillFragShader = "#ifdef NANOVG_GL3\n" + "#ifdef USE_UNIFORMBUFFER\n" " layout(std140) uniform frag {\n" " mat3 scissorMat;\n" " mat3 paintMat;\n" @@ -418,6 +431,20 @@ static int glnvg__renderCreate(void* uptr) " int texType;\n" " int type;\n" " };\n" + "#else\n" + " uniform mat3 scissorMat;\n" + " uniform mat3 paintMat;\n" + " uniform vec4 innerCol;\n" + " uniform vec4 outerCol;\n" + " uniform vec2 scissorExt;\n" + " uniform vec2 scissorScale;\n" + " uniform vec2 extent;\n" + " uniform float radius;\n" + " uniform float feather;\n" + " uniform float strokeMult;\n" + " uniform int texType;\n" + " uniform int type;\n" + "#endif\n" " uniform sampler2D tex;\n" " in vec2 ftcoord;\n" " in vec2 fpos;\n" @@ -461,13 +488,13 @@ static int glnvg__renderCreate(void* uptr) "\n" "void main(void) {\n" " vec4 result;\n" - " if (type == 0) { // Gradient\n" - " float scissor = scissorMask(fpos);\n" + " float scissor = scissorMask(fpos);\n" "#ifdef EDGE_AA\n" - " float strokeAlpha = strokeMask();\n" + " float strokeAlpha = strokeMask();\n" "#else\n" - " float strokeAlpha = 1.0;\n" + " float strokeAlpha = 1.0;\n" "#endif\n" + " if (type == 0) { // Gradient\n" " // Calculate gradient color using box gradient\n" " vec2 pt = (paintMat * vec3(fpos,1.0)).xy;\n" " float d = clamp((sdroundrect(pt, extent, radius) + feather*0.5) / feather, 0.0, 1.0);\n" @@ -476,12 +503,6 @@ static int glnvg__renderCreate(void* uptr) " color.w *= strokeAlpha * scissor;\n" " result = color;\n" " } else if (type == 1) { // Image\n" - " float scissor = scissorMask(fpos);\n" - "#ifdef EDGE_AA\n" - " float strokeAlpha = strokeMask();\n" - "#else\n" - " float strokeAlpha = 1.0;\n" - "#endif\n" " // Calculate color fron texture\n" " vec2 pt = (paintMat * vec3(fpos,1.0)).xy / extent;\n" "#ifdef NANOVG_GL3\n" @@ -496,7 +517,6 @@ static int glnvg__renderCreate(void* uptr) " } else if (type == 2) { // Stencil fill\n" " result = vec4(1,1,1,1);\n" " } else if (type == 3) { // Textured tris\n" - " float scissor = scissorMask(fpos);\n" "#ifdef NANOVG_GL3\n" " vec4 color = texture(tex, ftcoord);\n" "#else\n" @@ -532,7 +552,7 @@ static int glnvg__renderCreate(void* uptr) #endif glGenBuffers(1, &gl->vertBuf); -#if defined NANOVG_GL3 +#if NANOVG_GL_USE_UNIFORMBUFFER // Create UBOs glUniformBlockBinding(gl->shader.prog, gl->shader.loc[GLNVG_LOC_VIEW], GLNVG_VIEW_BINDING); glGenBuffers(1, &gl->viewBuf); @@ -544,6 +564,8 @@ static int glnvg__renderCreate(void* uptr) glnvg__checkError("create done"); + glFinish(); + return 1; } @@ -551,10 +573,6 @@ static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, const { struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr; struct GLNVGtexture* tex = glnvg__allocTexture(gl); - int align; -#ifndef NANOVG_GLES2 - int length, pixels, rows; -#endif if (tex == NULL) return 0; glGenTextures(1, &tex->tex); @@ -563,13 +581,6 @@ static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, const tex->type = type; glBindTexture(GL_TEXTURE_2D, tex->tex); - glGetIntegerv(GL_UNPACK_ALIGNMENT, &align); -#ifndef NANOVG_GLES2 - glGetIntegerv(GL_UNPACK_ROW_LENGTH, &length); - glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &pixels); - glGetIntegerv(GL_UNPACK_SKIP_ROWS, &rows); -#endif - glPixelStorei(GL_UNPACK_ALIGNMENT,1); #ifndef NANOVG_GLES2 glPixelStorei(GL_UNPACK_ROW_LENGTH, tex->width); @@ -585,16 +596,18 @@ static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, const glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glPixelStorei(GL_UNPACK_ALIGNMENT, align); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); #ifndef NANOVG_GLES2 - glPixelStorei(GL_UNPACK_ROW_LENGTH, length); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, pixels); - glPixelStorei(GL_UNPACK_SKIP_ROWS, rows); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); #endif if (glnvg__checkError("create tex")) return 0; + glBindTexture(GL_TEXTURE_2D, 0); + return tex->id; } @@ -609,22 +622,13 @@ static int glnvg__renderUpdateTexture(void* uptr, int image, int x, int y, int w { struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr; struct GLNVGtexture* tex = glnvg__findTexture(gl, image); - int align; -#ifndef NANOVG_GLES2 - int length, pixels, rows; -#endif if (tex == NULL) return 0; glBindTexture(GL_TEXTURE_2D, tex->tex); - glGetIntegerv(GL_UNPACK_ALIGNMENT, &align); glPixelStorei(GL_UNPACK_ALIGNMENT,1); #ifndef NANOVG_GLES2 - glGetIntegerv(GL_UNPACK_ROW_LENGTH, &length); - glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &pixels); - glGetIntegerv(GL_UNPACK_SKIP_ROWS, &rows); - glPixelStorei(GL_UNPACK_ROW_LENGTH, tex->width); glPixelStorei(GL_UNPACK_SKIP_PIXELS, x); glPixelStorei(GL_UNPACK_SKIP_ROWS, y); @@ -643,13 +647,15 @@ static int glnvg__renderUpdateTexture(void* uptr, int image, int x, int y, int w else glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_RED, GL_UNSIGNED_BYTE, data); - glPixelStorei(GL_UNPACK_ALIGNMENT, align); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); #ifndef NANOVG_GLES2 - glPixelStorei(GL_UNPACK_ROW_LENGTH, length); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, pixels); - glPixelStorei(GL_UNPACK_SKIP_ROWS, rows); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); #endif + glBindTexture(GL_TEXTURE_2D, 0); + return 1; } @@ -748,7 +754,7 @@ static int glnvg__convertPaint(struct GLNVGcontext* gl, struct GLNVGfragUniforms static struct GLNVGfragUniforms* nvg__fragUniformPtr(struct GLNVGcontext* gl, int i); -#if defined NANOVG_GL2 || defined NANOVG_GLES2 || defined NANOVG_GLES3 +#if !NANOVG_GL_USE_UNIFORMBUFFER static void glnvg__mat3(float* dst, float* src) { dst[0] = src[0]; @@ -767,7 +773,7 @@ static void glnvg__mat3(float* dst, float* src) static void glnvg__setUniforms(struct GLNVGcontext* gl, int uniformOffset, int image) { -#if defined NANOVG_GL3 +#if NANOVG_GL_USE_UNIFORMBUFFER glBindBufferRange(GL_UNIFORM_BUFFER, GLNVG_FRAG_BINDING, gl->fragBuf, uniformOffset, sizeof(struct GLNVGfragUniforms)); #else struct GLNVGfragUniforms* frag = nvg__fragUniformPtr(gl, uniformOffset); @@ -912,8 +918,9 @@ static void glnvg__renderFlush(void* uptr, int alphaBlend) glStencilMask(0xffffffff); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_ALWAYS, 0, 0xffffffff); + glActiveTexture(GL_TEXTURE0); -#if defined NANOVG_GL3 +#if NANOVG_GL_USE_UNIFORMBUFFER // Upload ubo for frag shaders glBindBuffer(GL_UNIFORM_BUFFER, gl->fragBuf); glBufferData(GL_UNIFORM_BUFFER, gl->nuniforms * gl->fragSize, gl->uniforms, GL_STREAM_DRAW); @@ -930,7 +937,7 @@ static void glnvg__renderFlush(void* uptr, int alphaBlend) 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))); -#if defined NANOVG_GL3 +#if NANOVG_GL_USE_UNIFORMBUFFER // once per frame set ubo for view glBindBuffer(GL_UNIFORM_BUFFER, gl->viewBuf); glBufferData(GL_UNIFORM_BUFFER, sizeof(gl->view), 0, GL_STREAM_DRAW); @@ -1062,20 +1069,20 @@ static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscis call->type = GLNVG_CONVEXFILL; // Allocate vertices for all the paths. - maxverts = glnvg__maxVertCount(paths, npaths); - offset = glnvg__allocVerts(gl, maxverts + 6); + maxverts = glnvg__maxVertCount(paths, npaths) + 6; + offset = glnvg__allocVerts(gl, maxverts); for (i = 0; i < npaths; i++) { struct GLNVGpath* copy = &gl->paths[call->pathOffset + i]; const struct NVGpath* path = &paths[i]; memset(copy, 0, sizeof(struct GLNVGpath)); - if (path->nfill) { + if (path->nfill > 0) { copy->fillOffset = offset; copy->fillCount = path->nfill; memcpy(&gl->verts[offset], path->fill, sizeof(struct NVGvertex) * path->nfill); offset += path->nfill; } - if (path->nstroke) { + if (path->nstroke > 0) { copy->strokeOffset = offset; copy->strokeCount = path->nstroke; memcpy(&gl->verts[offset], path->stroke, sizeof(struct NVGvertex) * path->nstroke); @@ -1125,7 +1132,7 @@ static void glnvg__renderStroke(void* uptr, struct NVGpaint* paint, struct NVGsc // Allocate vertices for all the paths. maxverts = glnvg__maxVertCount(paths, npaths); - offset = glnvg__allocVerts(gl, maxverts + 6); + offset = glnvg__allocVerts(gl, maxverts); for (i = 0; i < npaths; i++) { struct GLNVGpath* copy = &gl->paths[call->pathOffset + i]; @@ -1174,11 +1181,13 @@ static void glnvg__renderDelete(void* uptr) glnvg__deleteShader(&gl->shader); -#if defined NANOVG_GL3 +#if NANOVG_GL3 +#if NANOVG_GL_USE_UNIFORMBUFFER if (gl->viewBuf != 0) glDeleteBuffers(1, &gl->viewBuf); if (gl->fragBuf != 0) - glDeleteBuffers(1, &gl->fragBuf); + glDeleteBuffers(1, &gl->fragBuf); +#endif if (gl->vertArr != 0) glDeleteVertexArrays(1, &gl->vertArr); #endif @@ -1241,13 +1250,13 @@ error: return NULL; } -#if defined NANOVG_GL2 +#if NANOVG_GL2 void nvgDeleteGL2(struct NVGcontext* ctx) -#elif defined NANOVG_GL3 +#elif NANOVG_GL3 void nvgDeleteGL3(struct NVGcontext* ctx) -#elif defined NANOVG_GLES2 +#elif NANOVG_GLES2 void nvgDeleteGLES2(struct NVGcontext* ctx) -#elif defined NANOVG_GLES3 +#elif NANOVG_GLES3 void nvgDeleteGLES3(struct NVGcontext* ctx) #endif {