From 3d3c302e6ceab3190a7cb932f5a9034b27d38fca Mon Sep 17 00:00:00 2001 From: Mikko Mononen Date: Thu, 13 Feb 2014 22:12:18 +0200 Subject: [PATCH] GL3 uber shader - added milliseconds to fps counter - smooth fps reading a bit more - changed GL3 to uber shader --- example/demo.c | 15 ++- example/example_gl2.c | 1 + example/example_gl3.c | 3 +- src/nanovg_gl3.h | 206 +++++++++++++++++++----------------------- 4 files changed, 106 insertions(+), 119 deletions(-) diff --git a/example/demo.c b/example/demo.c index 132f7db..d8d3d4c 100644 --- a/example/demo.c +++ b/example/demo.c @@ -801,6 +801,8 @@ void updateFPS(struct FPScounter* fps, float frameTime) fps->values[fps->head] = frameTime; } +#define AVG_SIZE 20 + void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps) { int i, head; @@ -809,11 +811,11 @@ void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps) avg = 0; head = fps->head; - for (i = 0; i < 10; i++) { + for (i = 0; i < AVG_SIZE; i++) { avg += fps->values[head]; head = (head+FPS_HISTORY_COUNT-1) % FPS_HISTORY_COUNT; } - avg /= 10.0f; + avg /= (float)AVG_SIZE; w = 200; h = 30; @@ -836,11 +838,18 @@ void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps) nvgFillColor(vg, nvgRGBA(255,192,0,128)); nvgFill(vg); - nvgFontSize(vg, 18.0f); nvgFontFace(vg, "sans"); + nvgFontSize(vg, 18.0f); nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_MIDDLE); nvgFillColor(vg, nvgRGBA(240,240,240,255)); sprintf(str, "%.2f FPS", 1.0f / avg); nvgText(vg, x+w-5,y+h/2, str, NULL); + + nvgFontSize(vg, 15.0f); + nvgTextAlign(vg,NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE); + nvgFillColor(vg, nvgRGBA(240,240,240,160)); + sprintf(str, "%.2f ms", avg * 1000.0f); + nvgText(vg, x+5,y+h/2, str, NULL); + } diff --git a/example/example_gl2.c b/example/example_gl2.c index 4627882..5a76717 100644 --- a/example/example_gl2.c +++ b/example/example_gl2.c @@ -63,6 +63,7 @@ int main() glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); window = glfwCreateWindow(1000, 600, "NanoVG", NULL, NULL); +// window = glfwCreateWindow(1000, 600, "NanoVG", glfwGetPrimaryMonitor(), NULL); if (!window) { glfwTerminate(); return -1; diff --git a/example/example_gl3.c b/example/example_gl3.c index 3f077e6..b76f224 100644 --- a/example/example_gl3.c +++ b/example/example_gl3.c @@ -66,7 +66,8 @@ int main() glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - window = glfwCreateWindow(1000, 600, "NanoVG", NULL, NULL); + window = glfwCreateWindow(1000, 600, "NanoVG", NULL, NULL); +// window = glfwCreateWindow(1000, 600, "NanoVG", glfwGetPrimaryMonitor(), NULL); if (!window) { glfwTerminate(); return -1; diff --git a/src/nanovg_gl3.h b/src/nanovg_gl3.h index 84c9dd6..b6e7bee 100644 --- a/src/nanovg_gl3.h +++ b/src/nanovg_gl3.h @@ -51,6 +51,7 @@ enum GLNVGuniformLoc { GLNVG_LOC_STROKEMULT, GLNVG_LOC_TEX, GLNVG_LOC_TEXTYPE, + GLNVG_LOC_TYPE, GLNVG_MAX_LOCS }; @@ -69,10 +70,11 @@ struct GLNVGtexture { }; struct GLNVGcontext { - struct GLNVGshader gradShader; + struct GLNVGshader shader; +/* struct GLNVGshader gradShader; struct GLNVGshader imgShader; struct GLNVGshader solidShader; - struct GLNVGshader solidImgShader; + struct GLNVGshader solidImgShader;*/ struct GLNVGtexture* textures; float viewWidth, viewHeight; int ntextures; @@ -235,6 +237,7 @@ static void glnvg__getUniforms(struct GLNVGshader* shader) shader->loc[GLNVG_LOC_STROKEMULT] = glGetUniformLocation(shader->prog, "strokeMult"); shader->loc[GLNVG_LOC_TEX] = glGetUniformLocation(shader->prog, "tex"); shader->loc[GLNVG_LOC_TEXTYPE] = glGetUniformLocation(shader->prog, "texType"); + shader->loc[GLNVG_LOC_TYPE] = glGetUniformLocation(shader->prog, "type"); } static int glnvg__renderCreate(void* uptr) @@ -258,7 +261,7 @@ static int glnvg__renderCreate(void* uptr) " gl_Position = vec4(2.0*(vertex.x+viewPos.x)/viewSize.x - 1.0, 1.0 - 2.0*(vertex.y+viewPos.y)/viewSize.y, 0, 1);\n" "}\n"; - static const char* fillFragGradShader = + static const char* fillFragShader = "#version 150 core\n" "uniform mat3 scissorMat;\n" "uniform vec2 scissorExt;\n" @@ -269,101 +272,68 @@ static int glnvg__renderCreate(void* uptr) "uniform vec4 innerCol;\n" "uniform vec4 outerCol;\n" "uniform float strokeMult;\n" + "uniform sampler2D tex;\n" + "uniform int texType;\n" + "uniform int type;\n" "in vec2 ftcoord;\n" "in vec4 fcolor;\n" "in vec2 fpos;\n" "out vec4 outColor;\n" + "\n" "float sdroundrect(vec2 pt, vec2 ext, float rad) {\n" " vec2 ext2 = ext - vec2(rad,rad);\n" " vec2 d = abs(pt) - ext2;\n" " return min(max(d.x,d.y),0.0) + length(max(d,0.0)) - rad;\n" "}\n" + "\n" + "// Scissoring\n" + "float scissorMask(vec2 p) {\n" + " vec2 sc = vec2(0.5,0.5) - (abs((scissorMat * vec3(p,1.0)).xy) - scissorExt);\n" + " return clamp(sc.x,0.0,1.0) * clamp(sc.y,0.0,1.0);\n" + "}\n" + "\n" + "// Stroke - from [0..1] to clipped pyramid, where the slope is 1px.\n" + "float strokeMask() {\n" + " return min(1.0, (1.0-abs(ftcoord.x*2.0-1.0))*strokeMult) * ftcoord.y;\n" + "}\n" + "\n" "void main(void) {\n" - " // Scissoring\n" - " vec2 sc = vec2(0.5,0.5) - (abs((scissorMat * vec3(fpos,1.0)).xy) - scissorExt);\n" - " float scissor = clamp(sc.x,0.0,1.0) * clamp(sc.y,0.0,1.0);\n" -// " if (scissor < 0.001) discard;\n" - " // Stroke - from [0..1] to clipped pyramid, where the slope is 1px.\n" - " float strokeAlpha = min(1.0, (1.0-abs(ftcoord.x*2.0-1.0))*strokeMult) * ftcoord.y;\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" - " vec4 color = mix(innerCol,outerCol,d);\n" - " // Combine alpha\n" - " color.w *= strokeAlpha * scissor;\n" - " outColor = color;\n" - "}\n"; - - static const char* fillFragImgShader = - "#version 150 core\n" - "uniform mat3 scissorMat;\n" - "uniform vec2 scissorExt;\n" - "uniform mat3 paintMat;\n" - "uniform vec2 extent;\n" - "uniform float strokeMult;\n" - "uniform sampler2D tex;\n" - "uniform int texType;\n" - "in vec2 ftcoord;\n" - "in vec4 fcolor;\n" - "in vec2 fpos;\n" - "out vec4 outColor;\n" - "void main(void) {\n" - " // Scissoring\n" - " vec2 sc = vec2(0.5,0.5) - (abs((scissorMat * vec3(fpos,1.0)).xy) - scissorExt);\n" - " float scissor = clamp(sc.x,0.0,1.0) * clamp(sc.y,0.0,1.0);\n" -// " if (scissor < 0.001) discard;\n" - " // Stroke - from [0..1] to clipped pyramid, where the slope is 1px.\n" - " float strokeAlpha = min(1.0, (1.0-abs(ftcoord.x*2.0-1.0))*strokeMult) * ftcoord.y;\n" - " // Calculate color fron texture\n" - " vec2 pt = (paintMat * vec3(fpos,1.0)).xy;\n" - " pt /= extent;\n" - " vec4 color = texture(tex, pt);\n" - " color = texType == 0 ? color : vec4(1,1,1,color.x);\n" - " // Combine alpha\n" - " color.w *= strokeAlpha * scissor;\n" - " outColor = color;\n" - "}\n"; - - static const char* fillFragSolidShader = - "#version 150 core\n" - "in vec2 ftcoord;\n" - "in vec4 fcolor;\n" - "in vec2 fpos;\n" - "out vec4 outColor;\n" - "void main(void) {\n" - " outColor = vec4(1,1,1,1);\n" - "}\n"; - - static const char* fillFragSolidImgShader = - "#version 150 core\n" - "uniform sampler2D tex;\n" - "uniform int texType;\n" - "in vec2 ftcoord;\n" - "in vec4 fcolor;\n" - "in vec2 fpos;\n" - "out vec4 outColor;\n" - "void main(void) {\n" - " vec4 color = texture(tex, ftcoord);\n" - " color = texType == 0 ? color : vec4(1,1,1,color.x);\n" - " outColor = color * fcolor;\n" + " if (type == 0) {\n" + " float scissor = scissorMask(fpos);\n" + " float strokeAlpha = strokeMask();\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" + " vec4 color = mix(innerCol,outerCol,d);\n" + " // Combine alpha\n" + " color.w *= strokeAlpha * scissor;\n" + " outColor = color;\n" + " } else if (type == 1) {\n" + " float scissor = scissorMask(fpos);\n" + " float strokeAlpha = strokeMask();\n" + " // Calculate color fron texture\n" + " vec2 pt = (paintMat * vec3(fpos,1.0)).xy / extent;\n" + " vec4 color = texture(tex, pt);\n" + " color = texType == 0 ? color : vec4(1,1,1,color.x);\n" + " // Combine alpha\n" + " color.w *= strokeAlpha * scissor;\n" + " outColor = color;\n" + " } else if (type == 2) {\n" + " outColor = vec4(1,1,1,1);\n" + " } else if (type == 3) {\n" + " vec4 color = texture(tex, ftcoord);\n" + " color = texType == 0 ? color : vec4(1,1,1,color.x);\n" + " outColor = color * fcolor;\n" + " }\n" "}\n"; glnvg__checkError("init"); - if (glnvg__createShader(&gl->gradShader, "grad", fillVertShader, fillFragGradShader) == 0) - return 0; - if (glnvg__createShader(&gl->imgShader, "image", fillVertShader, fillFragImgShader) == 0) - return 0; - if (glnvg__createShader(&gl->solidShader, "solid", fillVertShader, fillFragSolidShader) == 0) - return 0; - if (glnvg__createShader(&gl->solidImgShader, "solid-img", fillVertShader, fillFragSolidImgShader) == 0) + if (glnvg__createShader(&gl->shader, "shader", fillVertShader, fillFragShader) == 0) return 0; glnvg__checkError("uniform locations"); - glnvg__getUniforms(&gl->gradShader); - glnvg__getUniforms(&gl->imgShader); - glnvg__getUniforms(&gl->solidShader); - glnvg__getUniforms(&gl->solidImgShader); + glnvg__getUniforms(&gl->shader); // Create dynamic vertex array glGenVertexArrays(1, &gl->vertArr); @@ -514,32 +484,34 @@ static int glnvg__setupPaint(struct GLNVGcontext* gl, struct NVGpaint* paint, st if (paint->image != 0) { tex = glnvg__findTexture(gl, paint->image); if (tex == NULL) return 0; - glUseProgram(gl->imgShader.prog); - glUniform2f(gl->imgShader.loc[GLNVG_LOC_VIEWPOS], 0, 0); - glUniform2f(gl->imgShader.loc[GLNVG_LOC_VIEWSIZE], gl->viewWidth, gl->viewHeight); - glUniformMatrix3fv(gl->imgShader.loc[GLNVG_LOC_SCISSORMAT], 1, GL_FALSE, scissorMat); - glUniform2f(gl->imgShader.loc[GLNVG_LOC_SCISSOREXT], scissorx, scissory); - glUniformMatrix3fv(gl->imgShader.loc[GLNVG_LOC_PAINTMAT], 1, GL_FALSE, paintMat); - glUniform2f(gl->imgShader.loc[GLNVG_LOC_EXTENT], paint->extent[0], paint->extent[1]); - glUniform1f(gl->imgShader.loc[GLNVG_LOC_STROKEMULT], width*0.5f + aasize*0.5f); - glUniform1i(gl->imgShader.loc[GLNVG_LOC_TEX], 0); - glUniform1i(gl->imgShader.loc[GLNVG_LOC_TEXTYPE], tex->type == NVG_TEXTURE_RGBA ? 0 : 1); + glUseProgram(gl->shader.prog); + glUniform1i(gl->shader.loc[GLNVG_LOC_TYPE], 1); + glUniform2f(gl->shader.loc[GLNVG_LOC_VIEWPOS], 0, 0); + glUniform2f(gl->shader.loc[GLNVG_LOC_VIEWSIZE], gl->viewWidth, gl->viewHeight); + glUniformMatrix3fv(gl->shader.loc[GLNVG_LOC_SCISSORMAT], 1, GL_FALSE, scissorMat); + glUniform2f(gl->shader.loc[GLNVG_LOC_SCISSOREXT], scissorx, scissory); + glUniformMatrix3fv(gl->shader.loc[GLNVG_LOC_PAINTMAT], 1, GL_FALSE, paintMat); + glUniform2f(gl->shader.loc[GLNVG_LOC_EXTENT], paint->extent[0], paint->extent[1]); + glUniform1f(gl->shader.loc[GLNVG_LOC_STROKEMULT], width*0.5f + aasize*0.5f); + glUniform1i(gl->shader.loc[GLNVG_LOC_TEX], 0); + glUniform1i(gl->shader.loc[GLNVG_LOC_TEXTYPE], tex->type == NVG_TEXTURE_RGBA ? 0 : 1); glnvg__checkError("tex paint loc"); glBindTexture(GL_TEXTURE_2D, tex->tex); glnvg__checkError("tex paint tex"); } else { - glUseProgram(gl->gradShader.prog); - glUniform2f(gl->gradShader.loc[GLNVG_LOC_VIEWPOS], 0, 0); - glUniform2f(gl->gradShader.loc[GLNVG_LOC_VIEWSIZE], gl->viewWidth, gl->viewHeight); - glUniformMatrix3fv(gl->gradShader.loc[GLNVG_LOC_SCISSORMAT], 1, GL_FALSE, scissorMat); - glUniform2f(gl->gradShader.loc[GLNVG_LOC_SCISSOREXT], scissorx, scissory); - glUniformMatrix3fv(gl->gradShader.loc[GLNVG_LOC_PAINTMAT], 1, GL_FALSE, paintMat); - glUniform2f(gl->gradShader.loc[GLNVG_LOC_EXTENT], paint->extent[0], paint->extent[1]); - glUniform1f(gl->gradShader.loc[GLNVG_LOC_RADIUS], paint->radius); - glUniform1f(gl->gradShader.loc[GLNVG_LOC_FEATHER], paint->feather); - glUniform4fv(gl->gradShader.loc[GLNVG_LOC_INNERCOL], 1, innerCol); - glUniform4fv(gl->gradShader.loc[GLNVG_LOC_OUTERCOL], 1, outerCol); - glUniform1f(gl->gradShader.loc[GLNVG_LOC_STROKEMULT], width*0.5f + aasize*0.5f); + glUseProgram(gl->shader.prog); + glUniform1i(gl->shader.loc[GLNVG_LOC_TYPE], 0); + glUniform2f(gl->shader.loc[GLNVG_LOC_VIEWPOS], 0, 0); + glUniform2f(gl->shader.loc[GLNVG_LOC_VIEWSIZE], gl->viewWidth, gl->viewHeight); + glUniformMatrix3fv(gl->shader.loc[GLNVG_LOC_SCISSORMAT], 1, GL_FALSE, scissorMat); + glUniform2f(gl->shader.loc[GLNVG_LOC_SCISSOREXT], scissorx, scissory); + glUniformMatrix3fv(gl->shader.loc[GLNVG_LOC_PAINTMAT], 1, GL_FALSE, paintMat); + glUniform2f(gl->shader.loc[GLNVG_LOC_EXTENT], paint->extent[0], paint->extent[1]); + glUniform1f(gl->shader.loc[GLNVG_LOC_RADIUS], paint->radius); + glUniform1f(gl->shader.loc[GLNVG_LOC_FEATHER], paint->feather); + glUniform4fv(gl->shader.loc[GLNVG_LOC_INNERCOL], 1, innerCol); + glUniform4fv(gl->shader.loc[GLNVG_LOC_OUTERCOL], 1, outerCol); + glUniform1f(gl->shader.loc[GLNVG_LOC_STROKEMULT], width*0.5f + aasize*0.5f); glnvg__checkError("grad paint loc"); } return 1; @@ -586,7 +558,7 @@ static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscis const struct NVGpath* path; int i, n, offset, maxCount; - if (gl->gradShader.prog == 0) + if (gl->shader.prog == 0) return; maxCount = glnvg__maxVertCount(paths, npaths); @@ -645,9 +617,10 @@ static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscis glStencilFunc(GL_ALWAYS, 0, ~0); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - glUseProgram(gl->solidShader.prog); - glUniform2f(gl->solidShader.loc[GLNVG_LOC_VIEWPOS], 0, 0); - glUniform2f(gl->solidShader.loc[GLNVG_LOC_VIEWSIZE], gl->viewWidth, gl->viewHeight); + glUseProgram(gl->shader.prog); + glUniform1i(gl->shader.loc[GLNVG_LOC_TYPE], 2); + glUniform2f(gl->shader.loc[GLNVG_LOC_VIEWPOS], 0, 0); + glUniform2f(gl->shader.loc[GLNVG_LOC_VIEWSIZE], gl->viewWidth, gl->viewHeight); glnvg__checkError("fill solid loc"); glEnableVertexAttribArray(0); @@ -718,7 +691,7 @@ static void glnvg__renderStroke(void* uptr, struct NVGpaint* paint, struct NVGsc const struct NVGpath* path; int i, n, offset, maxCount; - if (gl->gradShader.prog == 0) + if (gl->shader.prog == 0) return; glnvg__setupPaint(gl, paint, scissor, width, aasize); @@ -758,15 +731,19 @@ static void glnvg__renderTriangles(void* uptr, struct NVGpaint* paint, struct NV struct GLNVGtexture* tex = glnvg__findTexture(gl, image); float color[4]; + if (gl->shader.prog == 0) + return; + if (tex != NULL) { glBindTexture(GL_TEXTURE_2D, tex->tex); } - glUseProgram(gl->solidImgShader.prog); - glUniform2f(gl->solidImgShader.loc[GLNVG_LOC_VIEWPOS], 0, 0); - glUniform2f(gl->solidImgShader.loc[GLNVG_LOC_VIEWSIZE], gl->viewWidth, gl->viewHeight); - glUniform1i(gl->solidImgShader.loc[GLNVG_LOC_TEX], 0); - glUniform1i(gl->solidImgShader.loc[GLNVG_LOC_TEXTYPE], tex->type == NVG_TEXTURE_RGBA ? 0 : 1); + glUseProgram(gl->shader.prog); + glUniform1i(gl->shader.loc[GLNVG_LOC_TYPE], 3); + glUniform2f(gl->shader.loc[GLNVG_LOC_VIEWPOS], 0, 0); + 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_TEXTYPE], tex->type == NVG_TEXTURE_RGBA ? 0 : 1); glnvg__checkError("tris solid img loc"); glBindVertexArray(gl->vertArr); @@ -793,8 +770,7 @@ static void glnvg__renderDelete(void* uptr) int i; if (gl == NULL) return; - glnvg__deleteShader(&gl->gradShader); - glnvg__deleteShader(&gl->imgShader); + glnvg__deleteShader(&gl->shader); for (i = 0; i < gl->ntextures; i++) { if (gl->textures[i].tex != 0)