Browse Source

Merge pull request #123 from starwing/master

Auto detect and resize text altas texture.
shared-context
Mikko Mononen 11 years ago
parent
commit
7d1ec4ddd8
8 changed files with 159 additions and 56 deletions
  1. +2
    -2
      example/example_fbo.c
  2. +2
    -2
      example/example_gl2.c
  3. +2
    -2
      example/example_gl3.c
  4. +1
    -1
      example/example_gles2.c
  5. +1
    -1
      example/example_gles3.c
  6. +143
    -37
      src/nanovg.c
  7. +0
    -1
      src/nanovg.h
  8. +8
    -10
      src/nanovg_gl.h

+ 2
- 2
example/example_fbo.c View File

@@ -153,9 +153,9 @@ int main()
#endif #endif


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


+ 2
- 2
example/example_gl2.c View File

@@ -92,9 +92,9 @@ int main()
#endif #endif


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


+ 2
- 2
example/example_gl3.c View File

@@ -105,9 +105,9 @@ int main()
#endif #endif


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


+ 1
- 1
example/example_gles2.c View File

@@ -82,7 +82,7 @@ int main()


glfwMakeContextCurrent(window); glfwMakeContextCurrent(window);


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


+ 1
- 1
example/example_gles3.c View File

@@ -82,7 +82,7 @@ int main()


glfwMakeContextCurrent(window); glfwMakeContextCurrent(window);


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


+ 143
- 37
src/nanovg.c View File

@@ -31,6 +31,10 @@
#pragma warning(disable: 4706) // assignment within conditional expression #pragma warning(disable: 4706) // assignment within conditional expression
#endif #endif


#define NVG_INIT_FONTIMAGE_SIZE 512
#define NVG_MAX_FONTIMAGE_SIZE 2048
#define NVG_MAX_FONTIMAGES 4

#define NVG_INIT_COMMANDS_SIZE 256 #define NVG_INIT_COMMANDS_SIZE 256
#define NVG_INIT_POINTS_SIZE 128 #define NVG_INIT_POINTS_SIZE 128
#define NVG_INIT_PATHS_SIZE 16 #define NVG_INIT_PATHS_SIZE 16
@@ -111,7 +115,8 @@ struct NVGcontext {
float fringeWidth; float fringeWidth;
float devicePxRatio; float devicePxRatio;
struct FONScontext* fs; struct FONScontext* fs;
int fontImage;
int fontImages[NVG_MAX_FONTIMAGES];
int fontImageIdx;
int drawCallCount; int drawCallCount;
int fillTriCount; int fillTriCount;
int strokeTriCount; int strokeTriCount;
@@ -196,10 +201,13 @@ struct NVGcontext* nvgCreateInternal(struct NVGparams* params)
{ {
struct FONSparams fontParams; struct FONSparams fontParams;
struct NVGcontext* ctx = (struct NVGcontext*)malloc(sizeof(struct NVGcontext)); struct NVGcontext* ctx = (struct NVGcontext*)malloc(sizeof(struct NVGcontext));
int i;
if (ctx == NULL) goto error; if (ctx == NULL) goto error;
memset(ctx, 0, sizeof(struct NVGcontext)); memset(ctx, 0, sizeof(struct NVGcontext));


ctx->params = *params; ctx->params = *params;
for (i = 0; i < NVG_MAX_FONTIMAGES; i++)
ctx->fontImages[i] = 0;


ctx->commands = (float*)malloc(sizeof(float)*NVG_INIT_COMMANDS_SIZE); ctx->commands = (float*)malloc(sizeof(float)*NVG_INIT_COMMANDS_SIZE);
if (!ctx->commands) goto error; if (!ctx->commands) goto error;
@@ -218,8 +226,8 @@ struct NVGcontext* nvgCreateInternal(struct NVGparams* params)


// Init font rendering // Init font rendering
memset(&fontParams, 0, sizeof(fontParams)); memset(&fontParams, 0, sizeof(fontParams));
fontParams.width = params->atlasWidth;
fontParams.height = params->atlasHeight;
fontParams.width = NVG_INIT_FONTIMAGE_SIZE;
fontParams.height = NVG_INIT_FONTIMAGE_SIZE;
fontParams.flags = FONS_ZERO_TOPLEFT; fontParams.flags = FONS_ZERO_TOPLEFT;
fontParams.renderCreate = NULL; fontParams.renderCreate = NULL;
fontParams.renderUpdate = NULL; fontParams.renderUpdate = NULL;
@@ -230,8 +238,9 @@ struct NVGcontext* nvgCreateInternal(struct NVGparams* params)
if (ctx->fs == NULL) goto error; if (ctx->fs == NULL) goto error;


// Create font texture // Create font texture
ctx->fontImage = ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_ALPHA, fontParams.width, fontParams.height, NULL);
if (ctx->fontImage == 0) goto error;
ctx->fontImages[0] = ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_ALPHA, fontParams.width, fontParams.height, NULL);
if (ctx->fontImages[0] == 0) goto error;
ctx->fontImageIdx = 0;


return ctx; return ctx;


@@ -247,6 +256,7 @@ struct NVGparams* nvgInternalParams(struct NVGcontext* ctx)


void nvgDeleteInternal(struct NVGcontext* ctx) void nvgDeleteInternal(struct NVGcontext* ctx)
{ {
int i;
if (ctx == NULL) return; if (ctx == NULL) return;
if (ctx->commands != NULL) free(ctx->commands); if (ctx->commands != NULL) free(ctx->commands);
if (ctx->cache != NULL) nvg__deletePathCache(ctx->cache); if (ctx->cache != NULL) nvg__deletePathCache(ctx->cache);
@@ -254,6 +264,13 @@ void nvgDeleteInternal(struct NVGcontext* ctx)
if (ctx->fs) if (ctx->fs)
fonsDeleteInternal(ctx->fs); fonsDeleteInternal(ctx->fs);


for (i = 0; i < NVG_MAX_FONTIMAGES; i++) {
if (ctx->fontImages[i] != 0) {
nvgDeleteImage(ctx, ctx->fontImages[i]);
ctx->fontImages[i] = 0;
}
}

if (ctx->params.renderDelete != NULL) if (ctx->params.renderDelete != NULL)
ctx->params.renderDelete(ctx->params.userPtr); ctx->params.renderDelete(ctx->params.userPtr);


@@ -283,6 +300,31 @@ void nvgBeginFrame(struct NVGcontext* ctx, int windowWidth, int windowHeight, fl
void nvgEndFrame(struct NVGcontext* ctx) void nvgEndFrame(struct NVGcontext* ctx)
{ {
ctx->params.renderFlush(ctx->params.userPtr); ctx->params.renderFlush(ctx->params.userPtr);
if (ctx->fontImageIdx != 0) {
int fontImage = ctx->fontImages[ctx->fontImageIdx];
int i, j, iw, ih;
// delete images that smaller than current one
if (fontImage == 0)
return;
nvgImageSize(ctx, fontImage, &iw, &ih);
for (i = j = 0; i < ctx->fontImageIdx; i++) {
if (ctx->fontImages[i] != 0) {
int nw, nh;
nvgImageSize(ctx, ctx->fontImages[i], &nw, &nh);
if (nw < iw || nh < ih)
nvgDeleteImage(ctx, ctx->fontImages[i]);
else
ctx->fontImages[j++] = ctx->fontImages[i];
}
}
// make current font image to first
ctx->fontImages[j++] = ctx->fontImages[0];
ctx->fontImages[0] = fontImage;
ctx->fontImageIdx = 0;
// clear all images after j
for (i = j; i < NVG_MAX_FONTIMAGES; i++)
ctx->fontImages[i] = 0;
}
} }


struct NVGcolor nvgRGB(unsigned char r, unsigned char g, unsigned char b) struct NVGcolor nvgRGB(unsigned char r, unsigned char g, unsigned char b)
@@ -337,7 +379,7 @@ struct NVGcolor nvgLerpRGBA(struct NVGcolor c0, struct NVGcolor c1, float u)


u = nvg__clampf(u, 0.0f, 1.0f); u = nvg__clampf(u, 0.0f, 1.0f);
oneminu = 1.0f - u; oneminu = 1.0f - u;
for( i = 0; i <4; ++i )
for( i = 0; i <4; i++ )
{ {
cint.rgba[i] = c0.rgba[i] * oneminu + c1.rgba[i] * u; cint.rgba[i] = c0.rgba[i] * oneminu + c1.rgba[i] * u;
} }
@@ -1197,7 +1239,7 @@ static void nvg__flattenPaths(struct NVGcontext* ctx)
nvg__polyReverse(pts, path->count); nvg__polyReverse(pts, path->count);
} }


for(i = 0; i < path->count; ++i) {
for(i = 0; i < path->count; i++) {
// Calculate segment direction and length // Calculate segment direction and length
p0->dx = p1->x - p0->x; p0->dx = p1->x - p0->x;
p0->dy = p1->y - p0->y; p0->dy = p1->y - p0->y;
@@ -2128,16 +2170,75 @@ static float nvg__getFontScale(struct NVGstate* state)
return nvg__minf(nvg__quantize(nvg__getAverageScale(state->xform), 0.01f), 4.0f); return nvg__minf(nvg__quantize(nvg__getAverageScale(state->xform), 0.01f), 4.0f);
} }


static void nvg__flushTextTexture(struct NVGcontext* ctx)
{
int dirty[4];

if (fonsValidateTexture(ctx->fs, dirty)) {
int fontImage = ctx->fontImages[ctx->fontImageIdx];
// Update texture
if (fontImage != 0) {
int iw, ih;
const unsigned char* data = fonsGetTextureData(ctx->fs, &iw, &ih);
int x = dirty[0];
int y = dirty[1];
int w = dirty[2] - dirty[0];
int h = dirty[3] - dirty[1];
ctx->params.renderUpdateTexture(ctx->params.userPtr, fontImage, x,y, w,h, data);
}
}
}

static int nvg__allocTextAtlas(struct NVGcontext* ctx)
{
int iw, ih;
nvg__flushTextTexture(ctx);
if (ctx->fontImageIdx >= NVG_MAX_FONTIMAGES-1)
return 0;
// if next fontImage already have a texture
if (ctx->fontImages[ctx->fontImageIdx+1] != 0)
nvgImageSize(ctx, ctx->fontImages[ctx->fontImageIdx+1], &iw, &ih);
else { // calculate the new font image size and create it.
nvgImageSize(ctx, ctx->fontImages[ctx->fontImageIdx], &iw, &ih);
if (iw > ih)
ih *= 2;
else
iw *= 2;
if (iw > NVG_MAX_FONTIMAGE_SIZE || ih > NVG_MAX_FONTIMAGE_SIZE)
iw = ih = NVG_MAX_FONTIMAGE_SIZE;
ctx->fontImages[ctx->fontImageIdx+1] = ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_ALPHA, iw, ih, NULL);
}
++ctx->fontImageIdx;
fonsResetAtlas(ctx->fs, iw, ih);
return 1;
}

static void nvg__renderText(struct NVGcontext* ctx, struct NVGvertex* verts, int nverts)
{
struct NVGstate* state = nvg__getState(ctx);
struct NVGpaint paint = state->fill;

// Render triangles.
paint.image = ctx->fontImages[ctx->fontImageIdx];

// Apply global alpha
paint.innerColor.a *= state->alpha;
paint.outerColor.a *= state->alpha;

ctx->params.renderTriangles(ctx->params.userPtr, &paint, &state->scissor, verts, nverts);

ctx->drawCallCount++;
ctx->textTriCount += nverts/3;
}

float nvgText(struct NVGcontext* ctx, float x, float y, const char* string, const char* end) float nvgText(struct NVGcontext* ctx, float x, float y, const char* string, const char* end)
{ {
struct NVGstate* state = nvg__getState(ctx); struct NVGstate* state = nvg__getState(ctx);
struct NVGpaint paint;
struct FONStextIter iter;
struct FONStextIter iter, prevIter;
struct FONSquad q; struct FONSquad q;
struct NVGvertex* verts; struct NVGvertex* verts;
float scale = nvg__getFontScale(state) * ctx->devicePxRatio; float scale = nvg__getFontScale(state) * ctx->devicePxRatio;
float invscale = 1.0f / scale; float invscale = 1.0f / scale;
int dirty[4];
int cverts = 0; int cverts = 0;
int nverts = 0; int nverts = 0;


@@ -2157,9 +2258,23 @@ float nvgText(struct NVGcontext* ctx, float x, float y, const char* string, cons
if (verts == NULL) return x; if (verts == NULL) return x;


fonsTextIterInit(ctx->fs, &iter, x*scale, y*scale, string, end); fonsTextIterInit(ctx->fs, &iter, x*scale, y*scale, string, end);
prevIter = iter;
while (fonsTextIterNext(ctx->fs, &iter, &q)) { while (fonsTextIterNext(ctx->fs, &iter, &q)) {
// Trasnform corners.
float c[4*2]; float c[4*2];
if (iter.prevGlyphIndex == -1) { // can not retrieve glyph?
if (!nvg__allocTextAtlas(ctx))
break; // no memory :(
if (nverts != 0) {
nvg__renderText(ctx, verts, nverts);
nverts = 0;
}
iter = prevIter;
fonsTextIterNext(ctx->fs, &iter, &q); // try again
if (iter.prevGlyphIndex == -1) // still can not find glyph?
break;
}
prevIter = iter;
// Trasnform corners.
nvgTransformPoint(&c[0],&c[1], state->xform, q.x0*invscale, q.y0*invscale); nvgTransformPoint(&c[0],&c[1], state->xform, q.x0*invscale, q.y0*invscale);
nvgTransformPoint(&c[2],&c[3], state->xform, q.x1*invscale, q.y0*invscale); nvgTransformPoint(&c[2],&c[3], state->xform, q.x1*invscale, q.y0*invscale);
nvgTransformPoint(&c[4],&c[5], state->xform, q.x1*invscale, q.y1*invscale); nvgTransformPoint(&c[4],&c[5], state->xform, q.x1*invscale, q.y1*invscale);
@@ -2176,31 +2291,9 @@ float nvgText(struct NVGcontext* ctx, float x, float y, const char* string, cons
} }


// TODO: add back-end bit to do this just once per frame. // TODO: add back-end bit to do this just once per frame.
if (fonsValidateTexture(ctx->fs, dirty)) {
// Update texture
if (ctx->fontImage != 0) {
int iw, ih;
const unsigned char* data = fonsGetTextureData(ctx->fs, &iw, &ih);
int x = dirty[0];
int y = dirty[1];
int w = dirty[2] - dirty[0];
int h = dirty[3] - dirty[1];
ctx->params.renderUpdateTexture(ctx->params.userPtr, ctx->fontImage, x,y, w,h, data);
}
}

// Render triangles.
paint = state->fill;
paint.image = ctx->fontImage;

// Apply global alpha
paint.innerColor.a *= state->alpha;
paint.outerColor.a *= state->alpha;
nvg__flushTextTexture(ctx);


ctx->params.renderTriangles(ctx->params.userPtr, &paint, &state->scissor, verts, nverts);

ctx->drawCallCount++;
ctx->textTriCount += nverts/3;
nvg__renderText(ctx, verts, nverts);


return iter.x; return iter.x;
} }
@@ -2243,7 +2336,7 @@ int nvgTextGlyphPositions(struct NVGcontext* ctx, float x, float y, const char*
struct NVGstate* state = nvg__getState(ctx); struct NVGstate* state = nvg__getState(ctx);
float scale = nvg__getFontScale(state) * ctx->devicePxRatio; float scale = nvg__getFontScale(state) * ctx->devicePxRatio;
float invscale = 1.0f / scale; float invscale = 1.0f / scale;
struct FONStextIter iter;
struct FONStextIter iter, prevIter;
struct FONSquad q; struct FONSquad q;
int npos = 0; int npos = 0;


@@ -2262,7 +2355,13 @@ int nvgTextGlyphPositions(struct NVGcontext* ctx, float x, float y, const char*
fonsSetFont(ctx->fs, state->fontId); fonsSetFont(ctx->fs, state->fontId);


fonsTextIterInit(ctx->fs, &iter, x*scale, y*scale, string, end); fonsTextIterInit(ctx->fs, &iter, x*scale, y*scale, string, end);
prevIter = iter;
while (fonsTextIterNext(ctx->fs, &iter, &q)) { while (fonsTextIterNext(ctx->fs, &iter, &q)) {
if (iter.prevGlyphIndex < 0 && nvg__allocTextAtlas(ctx)) { // can not retrieve glyph?
iter = prevIter;
fonsTextIterNext(ctx->fs, &iter, &q); // try again
}
prevIter = iter;
positions[npos].str = iter.str; positions[npos].str = iter.str;
positions[npos].x = iter.x * invscale; positions[npos].x = iter.x * invscale;
positions[npos].minx = nvg__minf(iter.x, q.x0) * invscale; positions[npos].minx = nvg__minf(iter.x, q.x0) * invscale;
@@ -2286,7 +2385,7 @@ int nvgTextBreakLines(struct NVGcontext* ctx, const char* string, const char* en
struct NVGstate* state = nvg__getState(ctx); struct NVGstate* state = nvg__getState(ctx);
float scale = nvg__getFontScale(state) * ctx->devicePxRatio; float scale = nvg__getFontScale(state) * ctx->devicePxRatio;
float invscale = 1.0f / scale; float invscale = 1.0f / scale;
struct FONStextIter iter;
struct FONStextIter iter, prevIter;
struct FONSquad q; struct FONSquad q;
int nrows = 0; int nrows = 0;
float rowStartX = 0; float rowStartX = 0;
@@ -2321,7 +2420,13 @@ int nvgTextBreakLines(struct NVGcontext* ctx, const char* string, const char* en
breakRowWidth *= scale; breakRowWidth *= scale;


fonsTextIterInit(ctx->fs, &iter, 0, 0, string, end); fonsTextIterInit(ctx->fs, &iter, 0, 0, string, end);
prevIter = iter;
while (fonsTextIterNext(ctx->fs, &iter, &q)) { while (fonsTextIterNext(ctx->fs, &iter, &q)) {
if (iter.prevGlyphIndex < 0 && nvg__allocTextAtlas(ctx)) { // can not retrieve glyph?
iter = prevIter;
fonsTextIterNext(ctx->fs, &iter, &q); // try again
}
prevIter = iter;
switch (iter.codepoint) { switch (iter.codepoint) {
case 9: // \t case 9: // \t
case 11: // \v case 11: // \v
@@ -2592,3 +2697,4 @@ void nvgTextMetrics(struct NVGcontext* ctx, float* ascender, float* descender, f
if (lineh != NULL) if (lineh != NULL)
*lineh *= invscale; *lineh *= invscale;
} }
// vim: ft=c nu noet ts=4

+ 0
- 1
src/nanovg.h View File

@@ -565,7 +565,6 @@ struct NVGpath {


struct NVGparams { struct NVGparams {
void* userPtr; void* userPtr;
int atlasWidth, atlasHeight;
int edgeAntiAlias; int edgeAntiAlias;
int (*renderCreate)(void* uptr); int (*renderCreate)(void* uptr);
int (*renderCreateTexture)(void* uptr, int type, int w, int h, const unsigned char* data); int (*renderCreateTexture)(void* uptr, int type, int w, int h, const unsigned char* data);


+ 8
- 10
src/nanovg_gl.h View File

@@ -52,28 +52,28 @@ extern "C" {


#if defined NANOVG_GL2 #if defined NANOVG_GL2


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


#endif #endif


#if defined NANOVG_GL3 #if defined NANOVG_GL3


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


#endif #endif


#if defined NANOVG_GLES2 #if defined NANOVG_GLES2


struct NVGcontext* nvgCreateGLES2(int atlasw, int atlash, int edgeaa);
struct NVGcontext* nvgCreateGLES2(int flags);
void nvgDeleteGLES2(struct NVGcontext* ctx); void nvgDeleteGLES2(struct NVGcontext* ctx);


#endif #endif


#if defined NANOVG_GLES3 #if defined NANOVG_GLES3


struct NVGcontext* nvgCreateGLES3(int atlasw, int atlash, int edgeaa);
struct NVGcontext* nvgCreateGLES3(int flags);
void nvgDeleteGLES3(struct NVGcontext* ctx); void nvgDeleteGLES3(struct NVGcontext* ctx);


#endif #endif
@@ -1348,13 +1348,13 @@ static void glnvg__renderDelete(void* uptr)




#if defined NANOVG_GL2 #if defined NANOVG_GL2
struct NVGcontext* nvgCreateGL2(int atlasw, int atlash, int flags)
struct NVGcontext* nvgCreateGL2(int flags)
#elif defined NANOVG_GL3 #elif defined NANOVG_GL3
struct NVGcontext* nvgCreateGL3(int atlasw, int atlash, int flags)
struct NVGcontext* nvgCreateGL3(int flags)
#elif defined NANOVG_GLES2 #elif defined NANOVG_GLES2
struct NVGcontext* nvgCreateGLES2(int atlasw, int atlash, int flags)
struct NVGcontext* nvgCreateGLES2(int flags)
#elif defined NANOVG_GLES3 #elif defined NANOVG_GLES3
struct NVGcontext* nvgCreateGLES3(int atlasw, int atlash, int flags)
struct NVGcontext* nvgCreateGLES3(int flags)
#endif #endif
{ {
struct NVGparams params; struct NVGparams params;
@@ -1376,8 +1376,6 @@ struct NVGcontext* nvgCreateGLES3(int atlasw, int atlash, int flags)
params.renderTriangles = glnvg__renderTriangles; params.renderTriangles = glnvg__renderTriangles;
params.renderDelete = glnvg__renderDelete; params.renderDelete = glnvg__renderDelete;
params.userPtr = gl; params.userPtr = gl;
params.atlasWidth = atlasw;
params.atlasHeight = atlash;
params.edgeAntiAlias = flags & NVG_ANTIALIAS ? 1 : 0; params.edgeAntiAlias = flags & NVG_ANTIALIAS ? 1 : 0;


gl->flags = flags; gl->flags = flags;


Loading…
Cancel
Save