Browse Source

Added MSAA option for backends

- added option to turn off AA fringe generation
- added examples which use no AA fringes and  MSAA
shared-context
Mikko Mononen 11 years ago
parent
commit
cd376082ba
8 changed files with 315 additions and 87 deletions
  1. +8
    -1
      example/example_gl2.c
  2. +8
    -1
      example/example_gl3.c
  3. +1
    -1
      example/example_gles2.c
  4. +56
    -0
      premake4.lua
  5. +39
    -26
      src/nanovg.c
  6. +1
    -0
      src/nanovg.h
  7. +98
    -27
      src/nanovg_gl2.h
  8. +104
    -31
      src/nanovg_gl3.h

+ 8
- 1
example/example_gl2.c View File

@@ -61,6 +61,9 @@ int main()

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
#ifdef DEMO_MSAA
glfwWindowHint(GLFW_SAMPLES, 4);
#endif

window = glfwCreateWindow(1000, 600, "NanoVG", NULL, NULL);
// window = glfwCreateWindow(1000, 600, "NanoVG", glfwGetPrimaryMonitor(), NULL);
@@ -79,7 +82,11 @@ int main()
}
#endif

vg = nvgCreateGL2(512,512);
#ifdef DEMO_MSAA
vg = nvgCreateGL2(512, 512, 0);
#else
vg = nvgCreateGL2(512, 512, NVG_ANTIALIAS);
#endif
if (vg == NULL) {
printf("Could not init nanovg.\n");
return -1;


+ 8
- 1
example/example_gl3.c View File

@@ -65,6 +65,9 @@ int main()
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef DEMO_MSAA
glfwWindowHint(GLFW_SAMPLES, 4);
#endif

window = glfwCreateWindow(1000, 600, "NanoVG", NULL, NULL);
// window = glfwCreateWindow(1000, 600, "NanoVG", glfwGetPrimaryMonitor(), NULL);
@@ -84,7 +87,11 @@ int main()
}
#endif

vg = nvgCreateGL3(512,512);
#ifdef DEMO_MSAA
vg = nvgCreateGL3(512, 512, 0);
#else
vg = nvgCreateGL3(512, 512, NVG_ANTIALIAS);
#endif
if (vg == NULL) {
printf("Could not init nanovg.\n");
return -1;


+ 1
- 1
example/example_gles2.c View File

@@ -83,7 +83,7 @@ int main()
}
#endif

vg = nvgCreateGL2(512,512);
vg = nvgCreateGL2(512, 512, NVG_ANTIALIAS);
if (vg == NULL) {
printf("Could not init nanovg.\n");
return -1;


+ 56
- 0
premake4.lua View File

@@ -67,6 +67,62 @@ solution "nanovg"
defines { "NDEBUG" }
flags { "Optimize", "ExtraWarnings"}

project "example_gl2_msaa"
kind "ConsoleApp"
language "C"
defines { "DEMO_MSAA" }
files { "example/example_gl2.c", "example/demo.c" }
includedirs { "src", "example" }
targetdir("build")
links { "nanovg" }
configuration { "linux" }
links { "X11","Xrandr", "rt", "GL", "GLU", "pthread", "m", "glfw3", "GLEW" }
defines { "NANOVG_GLEW" }

configuration { "windows" }
links { "glu32","opengl32", "gdi32", "winmm", "user32" }

configuration { "macosx" }
links { "glfw3" }
linkoptions { "-framework OpenGL", "-framework Cocoa", "-framework IOKit", "-framework CoreVideo" }

configuration "Debug"
defines { "DEBUG" }
flags { "Symbols", "ExtraWarnings"}

configuration "Release"
defines { "NDEBUG" }
flags { "Optimize", "ExtraWarnings"}

project "example_gl3_msaa"
kind "ConsoleApp"
language "C"
defines { "DEMO_MSAA" }
files { "example/example_gl3.c", "example/demo.c" }
includedirs { "src", "example" }
targetdir("build")
links { "nanovg" }
configuration { "linux" }
links { "X11","Xrandr", "rt", "GL", "GLU", "pthread", "m", "glfw3", "GLEW" }
defines { "NANOVG_GLEW" }

configuration { "windows" }
links { "glu32","opengl32", "gdi32", "winmm", "user32" }

configuration { "macosx" }
links { "glfw3" }
linkoptions { "-framework OpenGL", "-framework Cocoa", "-framework IOKit", "-framework CoreVideo" }

configuration "Debug"
defines { "DEBUG" }
flags { "Symbols", "ExtraWarnings"}

configuration "Release"
defines { "NDEBUG" }
flags { "Optimize", "ExtraWarnings"}

project "example_gles2"
kind "ConsoleApp"
language "C"


+ 39
- 26
src/nanovg.c View File

@@ -1114,31 +1114,38 @@ static int nvg__expandStrokeAndFill(struct NVGcontext* ctx, int feats, float w)
dst = verts;
path->fill = dst;

// Looping
p0 = &pts[path->count-1];
p1 = &pts[0];
for (j = 0; j < path->count; ++j) {
if (p1->flags & NVG_BEVEL) {
float dlx0 = p0->dy;
float dly0 = -p0->dx;
float dlx1 = p1->dy;
float dly1 = -p1->dx;
if (p1->flags & NVG_LEFT) {
float lx = p1->x - p1->dmx * wo;
float ly = p1->y - p1->dmy * wo;
nvg__vset(dst, lx, ly, 0.5f,1); dst++;
if (w == 0.0f) {
for (j = 0; j < path->count; ++j) {
nvg__vset(dst, pts[j].x, pts[j].y, 0.5f,1);
dst++;
}
} else {
// Looping
p0 = &pts[path->count-1];
p1 = &pts[0];
for (j = 0; j < path->count; ++j) {
if (p1->flags & NVG_BEVEL) {
float dlx0 = p0->dy;
float dly0 = -p0->dx;
float dlx1 = p1->dy;
float dly1 = -p1->dx;
if (p1->flags & NVG_LEFT) {
float lx = p1->x - p1->dmx * wo;
float ly = p1->y - p1->dmy * wo;
nvg__vset(dst, lx, ly, 0.5f,1); dst++;
} else {
float lx0 = p1->x - dlx0 * wo;
float ly0 = p1->y - dly0 * wo;
float lx1 = p1->x - dlx1 * wo;
float ly1 = p1->y - dly1 * wo;
nvg__vset(dst, lx0, ly0, 0.5f,1); dst++;
nvg__vset(dst, lx1, ly1, 0.5f,1); dst++;
}
} else {
float lx0 = p1->x - dlx0 * wo;
float ly0 = p1->y - dly0 * wo;
float lx1 = p1->x - dlx1 * wo;
float ly1 = p1->y - dly1 * wo;
nvg__vset(dst, lx0, ly0, 0.5f,1); dst++;
nvg__vset(dst, lx1, ly1, 0.5f,1); dst++;
nvg__vset(dst, p1->x - (p1->dmx * wo), p1->y - (p1->dmy * wo), 0.5f,1); dst++;
}
} else {
nvg__vset(dst, p1->x - (p1->dmx * wo), p1->y - (p1->dmy * wo), 0.5f,1); dst++;
p0 = p1++;
}
p0 = p1++;
}

path->nfill = (int)(dst - verts);
@@ -1480,7 +1487,10 @@ void nvgFill(struct NVGcontext* ctx)
int i;

nvg__flattenPaths(ctx, state->miterLimit);
nvg__expandStrokeAndFill(ctx, NVG_FILL|NVG_STROKE, NVG_AA);
if (ctx->params.edgeAntiAlias)
nvg__expandStrokeAndFill(ctx, NVG_FILL|NVG_STROKE, NVG_AA);
else
nvg__expandStrokeAndFill(ctx, NVG_FILL, 0.0f);

ctx->params.renderFill(ctx->params.userPtr, &state->fill, &state->scissor, NVG_AA,
ctx->cache->bounds, ctx->cache->paths, ctx->cache->npaths);
@@ -1503,7 +1513,10 @@ void nvgStroke(struct NVGcontext* ctx)
int i;

nvg__flattenPaths(ctx, state->miterLimit);
nvg__expandStrokeAndFill(ctx, NVG_STROKE|NVG_CAPS, strokeWidth*0.5f + NVG_AA/2.0f);
if (ctx->params.edgeAntiAlias)
nvg__expandStrokeAndFill(ctx, NVG_STROKE|NVG_CAPS, strokeWidth*0.5f + NVG_AA/2.0f);
else
nvg__expandStrokeAndFill(ctx, NVG_STROKE|NVG_CAPS, strokeWidth*0.5f);

ctx->params.renderStroke(ctx->params.userPtr, &state->stroke, &state->scissor, NVG_AA,
strokeWidth, ctx->cache->paths, ctx->cache->npaths);
@@ -1651,7 +1664,7 @@ float nvgText(struct NVGcontext* ctx, float x, float y, const char* string, cons
float nvgTextBounds(struct NVGcontext* ctx, const char* string, const char* end, float* bounds)
{
struct NVGstate* state = nvg__getState(ctx);
float scale = nvg__getFontScale(state);
float scale = 1.0f; // nvg__getFontScale(state);

if (state->fontId == FONS_INVALID) return 0;

@@ -1667,7 +1680,7 @@ float nvgTextBounds(struct NVGcontext* ctx, const char* string, const char* end,
void nvgVertMetrics(struct NVGcontext* ctx, float* ascender, float* descender, float* lineh)
{
struct NVGstate* state = nvg__getState(ctx);
float scale = nvg__getFontScale(state);
float scale = 1.0f; // nvg__getFontScale(state);

if (state->fontId == FONS_INVALID) return;



+ 1
- 0
src/nanovg.h View File

@@ -396,6 +396,7 @@ struct NVGpath {
struct NVGparams {
void* userPtr;
int atlasWidth, atlasHeight;
int edgeAntiAlias;
int (*renderCreate)(void* uptr);
int (*renderCreateTexture)(void* uptr, int type, int w, int h, const unsigned char* data);
int (*renderDeleteTexture)(void* uptr, int image);


+ 98
- 27
src/nanovg_gl2.h View File

@@ -22,7 +22,9 @@
extern "C" {
#endif

struct NVGcontext* nvgCreateGL2();
#define NVG_ANTIALIAS 1

struct NVGcontext* nvgCreateGL2(int atlasw, int atlash, int edgeaa);
void nvgDeleteGL2(struct NVGcontext* ctx);

#ifdef __cplusplus
@@ -83,6 +85,7 @@ struct GLNVGcontext {
int ctextures;
int textureId;
GLuint vertBuf;
int edgeAntiAlias;
};

static struct GLNVGtexture* glnvg__allocTexture(struct GLNVGcontext* gl)
@@ -258,7 +261,7 @@ static int glnvg__renderCreate(void* uptr)
" gl_Position = vec4(2.0*vertex.x/viewSize.x - 1.0, 1.0 - 2.0*vertex.y/viewSize.y, 0, 1);\n"
"}\n";

static const char* fillFragShader =
static const char* fillFragShaderEdgeAA =
"uniform mat3 scissorMat;\n"
"uniform vec2 scissorExt;\n"
"uniform mat3 paintMat;\n"
@@ -322,10 +325,72 @@ static int glnvg__renderCreate(void* uptr)
" }\n"
"}\n";

static const char* fillFragShader =
"uniform mat3 scissorMat;\n"
"uniform vec2 scissorExt;\n"
"uniform mat3 paintMat;\n"
"uniform vec2 extent;\n"
"uniform float radius;\n"
"uniform float feather;\n"
"uniform vec4 innerCol;\n"
"uniform vec4 outerCol;\n"
"uniform float strokeMult;\n"
"uniform sampler2D tex;\n"
"uniform int texType;\n"
"uniform int type;\n"
"varying vec2 ftcoord;\n"
"varying vec4 fcolor;\n"
"varying vec2 fpos;\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"
"void main(void) {\n"
" if (type == 0) {\n"
" float scissor = scissorMask(fpos);\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 *= scissor;\n"
" gl_FragColor = color;\n"
" } else if (type == 1) {\n"
" float scissor = scissorMask(fpos);\n"
" // Calculate color fron texture\n"
" vec2 pt = (paintMat * vec3(fpos,1.0)).xy / extent;\n"
" vec4 color = texture2D(tex, pt);\n"
" color = texType == 0 ? color : vec4(1,1,1,color.x);\n"
" // Combine alpha\n"
" color.w *= scissor;\n"
" gl_FragColor = color;\n"
" } else if (type == 2) {\n"
" gl_FragColor = vec4(1,1,1,1);\n"
" } else if (type == 3) {\n"
" vec4 color = texture2D(tex, ftcoord);\n"
" color = texType == 0 ? color : vec4(1,1,1,color.x);\n"
" gl_FragColor = color * fcolor;\n"
" }\n"
"}\n";

glnvg__checkError("init");

if (glnvg__createShader(&gl->shader, "shader", fillVertShader, fillFragShader) == 0)
return 0;
if (gl->edgeAntiAlias) {
if (glnvg__createShader(&gl->shader, "shader", fillVertShader, fillFragShaderEdgeAA) == 0)
return 0;
} else {
if (glnvg__createShader(&gl->shader, "shader", fillVertShader, fillFragShader) == 0)
return 0;
}

glnvg__checkError("uniform locations");
glnvg__getUniforms(&gl->shader);
@@ -578,15 +643,17 @@ static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscis

glEnable(GL_CULL_FACE);

// Draw fringes
n = 0;
for (i = 0; i < npaths; i++) {
path = &paths[i];
offset = (n + path->nfill) * sizeof(struct NVGvertex);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(size_t)offset);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(offset + 2*sizeof(float)));
glDrawArrays(GL_TRIANGLE_STRIP, 0, path->nstroke);
n += path->nfill + path->nstroke;
if (gl->edgeAntiAlias) {
// Draw fringes
n = 0;
for (i = 0; i < npaths; i++) {
path = &paths[i];
offset = (n + path->nfill) * sizeof(struct NVGvertex);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(size_t)offset);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(offset + 2*sizeof(float)));
glDrawArrays(GL_TRIANGLE_STRIP, 0, path->nstroke);
n += path->nfill + path->nstroke;
}
}

glUseProgram(0);
@@ -631,22 +698,23 @@ static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscis
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glEnable(GL_BLEND);

glStencilFunc(GL_EQUAL, 0x00, 0xff);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

glEnableVertexAttribArray(1);

glnvg__setupPaint(gl, paint, scissor, 1.0001f, aasize);

// Draw fringes
n = 0;
for (i = 0; i < npaths; i++) {
path = &paths[i];
offset = (n + path->nfill) * sizeof(struct NVGvertex);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(size_t)offset);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(offset + 2*sizeof(float)));
glDrawArrays(GL_TRIANGLE_STRIP, 0, path->nstroke);
n += path->nfill + path->nstroke;
if (gl->edgeAntiAlias) {
glStencilFunc(GL_EQUAL, 0x00, 0xff);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

// Draw fringes
n = 0;
for (i = 0; i < npaths; i++) {
path = &paths[i];
offset = (n + path->nfill) * sizeof(struct NVGvertex);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(size_t)offset);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(offset + 2*sizeof(float)));
glDrawArrays(GL_TRIANGLE_STRIP, 0, path->nstroke);
n += path->nfill + path->nstroke;
}
}

// Draw fill
@@ -767,7 +835,7 @@ static void glnvg__renderDelete(void* uptr)
}


struct NVGcontext* nvgCreateGL2(int atlasw, int atlash)
struct NVGcontext* nvgCreateGL2(int atlasw, int atlash, int edgeaa)
{
struct NVGparams params;
struct NVGcontext* ctx = NULL;
@@ -789,6 +857,9 @@ struct NVGcontext* nvgCreateGL2(int atlasw, int atlash)
params.userPtr = gl;
params.atlasWidth = atlasw;
params.atlasHeight = atlash;
params.edgeAntiAlias = edgeaa;

gl->edgeAntiAlias = edgeaa;

ctx = nvgCreateInternal(&params);
if (ctx == NULL) goto error;


+ 104
- 31
src/nanovg_gl3.h View File

@@ -22,7 +22,9 @@
extern "C" {
#endif

struct NVGcontext* nvgCreateGL3();
#define NVG_ANTIALIAS 1

struct NVGcontext* nvgCreateGL3(int atlasw, int atlash, int edgeaa);
void nvgDeleteGL3(struct NVGcontext* ctx);

#ifdef __cplusplus
@@ -84,6 +86,7 @@ struct GLNVGcontext {
int textureId;
GLuint vertArr;
GLuint vertBuf;
int edgeAntiAlias;
};

static struct GLNVGtexture* glnvg__allocTexture(struct GLNVGcontext* gl)
@@ -260,7 +263,7 @@ static int glnvg__renderCreate(void* uptr)
" gl_Position = vec4(2.0*vertex.x/viewSize.x - 1.0, 1.0 - 2.0*vertex.y/viewSize.y, 0, 1);\n"
"}\n";

static const char* fillFragShader =
static const char* fillFragShaderEdgeAA =
"#version 150 core\n"
"uniform mat3 scissorMat;\n"
"uniform vec2 scissorExt;\n"
@@ -297,7 +300,7 @@ static int glnvg__renderCreate(void* uptr)
"}\n"
"\n"
"void main(void) {\n"
" if (type == 0) {\n"
" if (type == 0) { // Gradient\n"
" float scissor = scissorMask(fpos);\n"
" float strokeAlpha = strokeMask();\n"
" // Calculate gradient color using box gradient\n"
@@ -307,7 +310,7 @@ static int glnvg__renderCreate(void* uptr)
" // Combine alpha\n"
" color.w *= strokeAlpha * scissor;\n"
" outColor = color;\n"
" } else if (type == 1) {\n"
" } else if (type == 1) { // Image\n"
" float scissor = scissorMask(fpos);\n"
" float strokeAlpha = strokeMask();\n"
" // Calculate color fron texture\n"
@@ -317,9 +320,68 @@ static int glnvg__renderCreate(void* uptr)
" // Combine alpha\n"
" color.w *= strokeAlpha * scissor;\n"
" outColor = color;\n"
" } else if (type == 2) {\n"
" } else if (type == 2) { // Stencil fill\n"
" outColor = vec4(1,1,1,1);\n"
" } else if (type == 3) {\n"
" } else if (type == 3) { // Textured tris\n"
" vec4 color = texture(tex, ftcoord);\n"
" color = texType == 0 ? color : vec4(1,1,1,color.x);\n"
" outColor = color * fcolor;\n"
" }\n"
"}\n";

static const char* fillFragShader =
"#version 150 core\n"
"uniform mat3 scissorMat;\n"
"uniform vec2 scissorExt;\n"
"uniform mat3 paintMat;\n"
"uniform vec2 extent;\n"
"uniform float radius;\n"
"uniform float feather;\n"
"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"
"void main(void) {\n"
" if (type == 0) { // Gradient\n"
" float scissor = scissorMask(fpos);\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 *= scissor;\n"
" outColor = color;\n"
" } else if (type == 1) { // Image\n"
" float scissor = scissorMask(fpos);\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 *= scissor;\n"
" outColor = color;\n"
" } else if (type == 2) { // Stencil fill\n"
" outColor = vec4(1,1,1,1);\n"
" } else if (type == 3) { // Textured tris\n"
" vec4 color = texture(tex, ftcoord);\n"
" color = texType == 0 ? color : vec4(1,1,1,color.x);\n"
" outColor = color * fcolor;\n"
@@ -328,8 +390,13 @@ static int glnvg__renderCreate(void* uptr)

glnvg__checkError("init");

if (glnvg__createShader(&gl->shader, "shader", fillVertShader, fillFragShader) == 0)
return 0;
if (gl->edgeAntiAlias) {
if (glnvg__createShader(&gl->shader, "shader", fillVertShader, fillFragShaderEdgeAA) == 0)
return 0;
} else {
if (glnvg__createShader(&gl->shader, "shader", fillVertShader, fillFragShader) == 0)
return 0;
}

glnvg__checkError("uniform locations");
glnvg__getUniforms(&gl->shader);
@@ -584,15 +651,17 @@ static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscis

glEnable(GL_CULL_FACE);

// Draw fringes
n = 0;
for (i = 0; i < npaths; i++) {
path = &paths[i];
offset = (n + path->nfill) * sizeof(struct NVGvertex);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(size_t)offset);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(offset + 2*sizeof(float)));
glDrawArrays(GL_TRIANGLE_STRIP, 0, path->nstroke);
n += path->nfill + path->nstroke;
if (gl->edgeAntiAlias) {
// Draw fringes
n = 0;
for (i = 0; i < npaths; i++) {
path = &paths[i];
offset = (n + path->nfill) * sizeof(struct NVGvertex);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(size_t)offset);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(offset + 2*sizeof(float)));
glDrawArrays(GL_TRIANGLE_STRIP, 0, path->nstroke);
n += path->nfill + path->nstroke;
}
}

glUseProgram(0);
@@ -638,22 +707,23 @@ static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscis
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glEnable(GL_BLEND);

glStencilFunc(GL_EQUAL, 0x00, 0xff);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

glEnableVertexAttribArray(1);

glnvg__setupPaint(gl, paint, scissor, 1.0001f, aasize);

// Draw fringes
n = 0;
for (i = 0; i < npaths; i++) {
path = &paths[i];
offset = (n + path->nfill) * sizeof(struct NVGvertex);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(size_t)offset);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(offset + 2*sizeof(float)));
glDrawArrays(GL_TRIANGLE_STRIP, 0, path->nstroke);
n += path->nfill + path->nstroke;
if (gl->edgeAntiAlias) {
glStencilFunc(GL_EQUAL, 0x00, 0xff);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

// Draw fringes
n = 0;
for (i = 0; i < npaths; i++) {
path = &paths[i];
offset = (n + path->nfill) * sizeof(struct NVGvertex);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(size_t)offset);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(offset + 2*sizeof(float)));
glDrawArrays(GL_TRIANGLE_STRIP, 0, path->nstroke);
n += path->nfill + path->nstroke;
}
}

// Draw fill
@@ -776,7 +846,7 @@ static void glnvg__renderDelete(void* uptr)
}


struct NVGcontext* nvgCreateGL3(int atlasw, int atlash)
struct NVGcontext* nvgCreateGL3(int atlasw, int atlash, int edgeaa)
{
struct NVGparams params;
struct NVGcontext* ctx = NULL;
@@ -798,6 +868,9 @@ struct NVGcontext* nvgCreateGL3(int atlasw, int atlash)
params.userPtr = gl;
params.atlasWidth = atlasw;
params.atlasHeight = atlash;
params.edgeAntiAlias = edgeaa;

gl->edgeAntiAlias = edgeaa;

ctx = nvgCreateInternal(&params);
if (ctx == NULL) goto error;


Loading…
Cancel
Save