Browse Source

Fixed rendering artefacts when not using uniform buffers

- made uniform buffer support behind separate define for easier toggling
- calculate scissor and stroke alpha outside type selection to simplify
the shader (or else it produces rendering artefacts)
- restore default pixel store settings instead of restoring old state
- set active texture to 0 when starting to render a frame
shared-context
Mikko Mononen 11 years ago
parent
commit
407cd75a98
2 changed files with 77 additions and 68 deletions
  1. +2
    -2
      example/example_gl2.c
  2. +75
    -66
      src/nanovg_gl3buf.h

+ 2
- 2
example/example_gl2.c View File

@@ -23,8 +23,8 @@
#include <GLFW/glfw3.h>
#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"



+ 75
- 66
src/nanovg_gl3buf.h View File

@@ -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
{


Loading…
Cancel
Save