- fixed off-by-one pixels from demo - added device-pixel-ratio support (retina support) - added nvgEndFrame()shared-context
@@ -623,8 +623,8 @@ void drawColorwheel(struct NVGcontext* vg, float x, float y, float w, float h, f | |||||
} | } | ||||
nvgBeginPath(vg); | nvgBeginPath(vg); | ||||
nvgCircle(vg, cx,cy, r0-1); | |||||
nvgCircle(vg, cx,cy, r1+1); | |||||
nvgCircle(vg, cx,cy, r0-0.5f); | |||||
nvgCircle(vg, cx,cy, r1+0.5f); | |||||
nvgStrokeColor(vg, nvgRGBA(0,0,0,64)); | nvgStrokeColor(vg, nvgRGBA(0,0,0,64)); | ||||
nvgStrokeWidth(vg, 1.0f); | nvgStrokeWidth(vg, 1.0f); | ||||
nvgStroke(vg); | nvgStroke(vg); | ||||
@@ -643,8 +643,8 @@ void drawColorwheel(struct NVGcontext* vg, float x, float y, float w, float h, f | |||||
paint = nvgBoxGradient(vg, r0-3,-5,r1-r0+6,10, 2,4, nvgRGBA(0,0,0,128), nvgRGBA(0,0,0,0)); | paint = nvgBoxGradient(vg, r0-3,-5,r1-r0+6,10, 2,4, nvgRGBA(0,0,0,128), nvgRGBA(0,0,0,0)); | ||||
nvgBeginPath(vg); | nvgBeginPath(vg); | ||||
nvgRect(vg, r0-3-10,-5-10,r1-r0+6+20,10+20); | |||||
nvgRect(vg, r0-3,-5,r1-r0+6,10); | |||||
nvgRect(vg, r0-2-10,-4-10,r1-r0+4+20,8+20); | |||||
nvgRect(vg, r0-2,-4,r1-r0+4,8); | |||||
nvgPathWinding(vg, NVG_HOLE); | nvgPathWinding(vg, NVG_HOLE); | ||||
nvgFillPaint(vg, paint); | nvgFillPaint(vg, paint); | ||||
nvgFill(vg); | nvgFill(vg); | ||||
@@ -103,7 +103,9 @@ int main() | |||||
while (!glfwWindowShouldClose(window)) | while (!glfwWindowShouldClose(window)) | ||||
{ | { | ||||
double mx, my, t, dt; | double mx, my, t, dt; | ||||
int width, height; | |||||
int winWidth, winHeight; | |||||
int fbWidth, fbHeight; | |||||
float pxRatio; | |||||
t = glfwGetTime(); | t = glfwGetTime(); | ||||
dt = t - prevt; | dt = t - prevt; | ||||
@@ -111,25 +113,29 @@ int main() | |||||
updateFPS(&fps, dt); | updateFPS(&fps, dt); | ||||
glfwGetCursorPos(window, &mx, &my); | glfwGetCursorPos(window, &mx, &my); | ||||
glfwGetFramebufferSize(window, &width, &height); | |||||
glfwGetWindowSize(window, &winWidth, &winHeight); | |||||
glfwGetFramebufferSize(window, &fbWidth, &fbHeight); | |||||
// Calculate pixel ration for hi-dpi devices. | |||||
pxRatio = (float)fbWidth / (float)winWidth; | |||||
// Update and render | // Update and render | ||||
glViewport(0, 0, width, height); | |||||
glViewport(0, 0, fbWidth, fbHeight); | |||||
glClearColor(0.3f, 0.3f, 0.32f, 1.0f); | glClearColor(0.3f, 0.3f, 0.32f, 1.0f); | ||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); | glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); | ||||
glEnable(GL_BLEND); | glEnable(GL_BLEND); | ||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
glEnable(GL_CULL_FACE); | glEnable(GL_CULL_FACE); | ||||
glDisable(GL_TEXTURE_2D); | |||||
glDisable(GL_DEPTH_TEST); | glDisable(GL_DEPTH_TEST); | ||||
glColor4ub(255,255,255,255); | |||||
nvgBeginFrame(vg, width, height); | |||||
nvgBeginFrame(vg, winWidth, winHeight, pxRatio); | |||||
renderDemo(vg, mx,my, width,height, t, blowup, &data); | |||||
renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); | |||||
renderFPS(vg, 5,5, &fps); | renderFPS(vg, 5,5, &fps); | ||||
nvgEndFrame(vg); | |||||
glEnable(GL_DEPTH_TEST); | glEnable(GL_DEPTH_TEST); | ||||
glfwSwapBuffers(window); | glfwSwapBuffers(window); | ||||
@@ -108,7 +108,9 @@ int main() | |||||
while (!glfwWindowShouldClose(window)) | while (!glfwWindowShouldClose(window)) | ||||
{ | { | ||||
double mx, my, t, dt; | double mx, my, t, dt; | ||||
int width, height; | |||||
int winWidth, winHeight; | |||||
int fbWidth, fbHeight; | |||||
float pxRatio; | |||||
t = glfwGetTime(); | t = glfwGetTime(); | ||||
dt = t - prevt; | dt = t - prevt; | ||||
@@ -116,22 +118,28 @@ int main() | |||||
updateFPS(&fps, dt); | updateFPS(&fps, dt); | ||||
glfwGetCursorPos(window, &mx, &my); | glfwGetCursorPos(window, &mx, &my); | ||||
glfwGetFramebufferSize(window, &width, &height); | |||||
glfwGetWindowSize(window, &winWidth, &winHeight); | |||||
glfwGetFramebufferSize(window, &fbWidth, &fbHeight); | |||||
// Calculate pixel ration for hi-dpi devices. | |||||
pxRatio = (float)fbWidth / (float)winWidth; | |||||
// Update and render | // Update and render | ||||
glViewport(0, 0, width, height); | |||||
glViewport(0, 0, fbWidth, fbHeight); | |||||
glClearColor(0.3f, 0.3f, 0.32f, 1.0f); | glClearColor(0.3f, 0.3f, 0.32f, 1.0f); | ||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); | glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); | ||||
glEnable(GL_BLEND); | glEnable(GL_BLEND); | ||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
glEnable(GL_CULL_FACE); | glEnable(GL_CULL_FACE); | ||||
glDisable(GL_DEPTH_TEST); | glDisable(GL_DEPTH_TEST); | ||||
nvgBeginFrame(vg, width, height); | |||||
nvgBeginFrame(vg, winWidth, winHeight, pxRatio); | |||||
renderDemo(vg, mx,my, width,height, t, blowup, &data); | |||||
renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); | |||||
renderFPS(vg, 5,5, &fps); | renderFPS(vg, 5,5, &fps); | ||||
nvgEndFrame(vg); | |||||
glEnable(GL_DEPTH_TEST); | glEnable(GL_DEPTH_TEST); | ||||
glfwSwapBuffers(window); | glfwSwapBuffers(window); | ||||
@@ -90,7 +90,9 @@ int main() | |||||
while (!glfwWindowShouldClose(window)) | while (!glfwWindowShouldClose(window)) | ||||
{ | { | ||||
double mx, my, t, dt; | double mx, my, t, dt; | ||||
int width, height; | |||||
int winWidth, winHeight; | |||||
int fbWidth, fbHeight; | |||||
float pxRatio; | |||||
t = glfwGetTime(); | t = glfwGetTime(); | ||||
dt = t - prevt; | dt = t - prevt; | ||||
@@ -98,22 +100,28 @@ int main() | |||||
updateFPS(&fps, dt); | updateFPS(&fps, dt); | ||||
glfwGetCursorPos(window, &mx, &my); | glfwGetCursorPos(window, &mx, &my); | ||||
glfwGetFramebufferSize(window, &width, &height); | |||||
glfwGetWindowSize(window, &winWidth, &winHeight); | |||||
glfwGetFramebufferSize(window, &fbWidth, &fbHeight); | |||||
// Calculate pixel ration for hi-dpi devices. | |||||
pxRatio = (float)fbWidth / (float)winWidth; | |||||
// Update and render | // Update and render | ||||
glViewport(0, 0, width, height); | |||||
glViewport(0, 0, fbWidth, fbHeight); | |||||
glClearColor(0.3f, 0.3f, 0.32f, 1.0f); | glClearColor(0.3f, 0.3f, 0.32f, 1.0f); | ||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); | glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); | ||||
glEnable(GL_BLEND); | glEnable(GL_BLEND); | ||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
glEnable(GL_CULL_FACE); | glEnable(GL_CULL_FACE); | ||||
glDisable(GL_DEPTH_TEST); | glDisable(GL_DEPTH_TEST); | ||||
nvgBeginFrame(vg, width, height); | |||||
nvgBeginFrame(vg, winWidth, winHeight, pxRatio); | |||||
renderDemo(vg, mx,my, width,height, t, blowup, &data); | |||||
renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); | |||||
renderFPS(vg, 5,5, &fps); | renderFPS(vg, 5,5, &fps); | ||||
nvgEndFrame(vg); | |||||
glEnable(GL_DEPTH_TEST); | glEnable(GL_DEPTH_TEST); | ||||
glfwSwapBuffers(window); | glfwSwapBuffers(window); | ||||
@@ -90,7 +90,9 @@ int main() | |||||
while (!glfwWindowShouldClose(window)) | while (!glfwWindowShouldClose(window)) | ||||
{ | { | ||||
double mx, my, t, dt; | double mx, my, t, dt; | ||||
int width, height; | |||||
int winWidth, winHeight; | |||||
int fbWidth, fbHeight; | |||||
float pxRatio; | |||||
t = glfwGetTime(); | t = glfwGetTime(); | ||||
dt = t - prevt; | dt = t - prevt; | ||||
@@ -98,22 +100,28 @@ int main() | |||||
updateFPS(&fps, dt); | updateFPS(&fps, dt); | ||||
glfwGetCursorPos(window, &mx, &my); | glfwGetCursorPos(window, &mx, &my); | ||||
glfwGetFramebufferSize(window, &width, &height); | |||||
glfwGetWindowSize(window, &winWidth, &winHeight); | |||||
glfwGetFramebufferSize(window, &fbWidth, &fbHeight); | |||||
// Calculate pixel ration for hi-dpi devices. | |||||
pxRatio = (float)fbWidth / (float)winWidth; | |||||
// Update and render | // Update and render | ||||
glViewport(0, 0, width, height); | |||||
glViewport(0, 0, fbWidth, fbHeight); | |||||
glClearColor(0.3f, 0.3f, 0.32f, 1.0f); | glClearColor(0.3f, 0.3f, 0.32f, 1.0f); | ||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); | glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); | ||||
glEnable(GL_BLEND); | glEnable(GL_BLEND); | ||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
glEnable(GL_CULL_FACE); | glEnable(GL_CULL_FACE); | ||||
glDisable(GL_DEPTH_TEST); | glDisable(GL_DEPTH_TEST); | ||||
nvgBeginFrame(vg, width, height); | |||||
nvgBeginFrame(vg, winWidth, winHeight, pxRatio); | |||||
renderDemo(vg, mx,my, width,height, t, blowup, &data); | |||||
renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); | |||||
renderFPS(vg, 5,5, &fps); | renderFPS(vg, 5,5, &fps); | ||||
nvgEndFrame(vg); | |||||
glEnable(GL_DEPTH_TEST); | glEnable(GL_DEPTH_TEST); | ||||
glfwSwapBuffers(window); | glfwSwapBuffers(window); | ||||
@@ -28,7 +28,6 @@ | |||||
#define NVG_INIT_PATH_SIZE 256 | #define NVG_INIT_PATH_SIZE 256 | ||||
#define NVG_MAX_STATES 32 | #define NVG_MAX_STATES 32 | ||||
#define NVG_AA 1.0f | |||||
#define NVG_KAPPA90 0.5522847493f // Lenght proportional to radius of a cubic bezier handle for 90deg arcs. | #define NVG_KAPPA90 0.5522847493f // Lenght proportional to radius of a cubic bezier handle for 90deg arcs. | ||||
#define NVG_COUNTOF(arr) (sizeof(arr) / sizeof(0[arr])) | #define NVG_COUNTOF(arr) (sizeof(arr) / sizeof(0[arr])) | ||||
@@ -101,6 +100,8 @@ struct NVGcontext { | |||||
struct NVGpathCache* cache; | struct NVGpathCache* cache; | ||||
float tessTol; | float tessTol; | ||||
float distTol; | float distTol; | ||||
float fringeWidth; | |||||
float devicePxRatio; | |||||
struct FONScontext* fs; | struct FONScontext* fs; | ||||
int fontImage; | int fontImage; | ||||
int drawCallCount; | int drawCallCount; | ||||
@@ -173,6 +174,13 @@ error: | |||||
return NULL; | return NULL; | ||||
} | } | ||||
static void nvg__setDevicePixelRatio(struct NVGcontext* ctx, float ratio) | |||||
{ | |||||
ctx->tessTol = 0.3f * 4.0f / ratio; | |||||
ctx->distTol = 0.01f / ratio; | |||||
ctx->fringeWidth = 1.0f / ratio; | |||||
ctx->devicePxRatio = ratio; | |||||
} | |||||
struct NVGcontext* nvgCreateInternal(struct NVGparams* params) | struct NVGcontext* nvgCreateInternal(struct NVGparams* params) | ||||
{ | { | ||||
@@ -194,8 +202,7 @@ struct NVGcontext* nvgCreateInternal(struct NVGparams* params) | |||||
nvgSave(ctx); | nvgSave(ctx); | ||||
nvgReset(ctx); | nvgReset(ctx); | ||||
ctx->tessTol = 0.3f * 4.0f; | |||||
ctx->distTol = 0.01f; | |||||
nvg__setDevicePixelRatio(ctx, 1.0f); | |||||
if (ctx->params.renderCreate(ctx->params.userPtr) == 0) goto error; | if (ctx->params.renderCreate(ctx->params.userPtr) == 0) goto error; | ||||
@@ -238,13 +245,19 @@ void nvgDeleteInternal(struct NVGcontext* ctx) | |||||
free(ctx); | free(ctx); | ||||
} | } | ||||
void nvgBeginFrame(struct NVGcontext* ctx, int width, int height) | |||||
void nvgBeginFrame(struct NVGcontext* ctx, int windowWidth, int windowHeight, float devicePixelRatio) | |||||
{ | { | ||||
/* printf("Tris: draws:%d fill:%d stroke:%d text:%d TOT:%d\n", | /* printf("Tris: draws:%d fill:%d stroke:%d text:%d TOT:%d\n", | ||||
ctx->drawCallCount, ctx->fillTriCount, ctx->strokeTriCount, ctx->textTriCount, | ctx->drawCallCount, ctx->fillTriCount, ctx->strokeTriCount, ctx->textTriCount, | ||||
ctx->fillTriCount+ctx->strokeTriCount+ctx->textTriCount);*/ | ctx->fillTriCount+ctx->strokeTriCount+ctx->textTriCount);*/ | ||||
ctx->nstates = 0; | |||||
nvgSave(ctx); | |||||
nvgReset(ctx); | |||||
nvg__setDevicePixelRatio(ctx, devicePixelRatio); | |||||
ctx->params.renderViewport(ctx->params.userPtr, width, height); | |||||
ctx->params.renderViewport(ctx->params.userPtr, windowWidth, windowHeight); | |||||
ctx->drawCallCount = 0; | ctx->drawCallCount = 0; | ||||
ctx->fillTriCount = 0; | ctx->fillTriCount = 0; | ||||
@@ -252,6 +265,11 @@ void nvgBeginFrame(struct NVGcontext* ctx, int width, int height) | |||||
ctx->textTriCount = 0; | ctx->textTriCount = 0; | ||||
} | } | ||||
void nvgEndFrame(struct NVGcontext* ctx) | |||||
{ | |||||
ctx->params.renderFlush(ctx->params.userPtr); | |||||
} | |||||
unsigned int nvgRGB(unsigned char r, unsigned char g, unsigned char b) | unsigned int nvgRGB(unsigned char r, unsigned char g, unsigned char b) | ||||
{ | { | ||||
return nvgRGBA(r,g,b,255); | return nvgRGBA(r,g,b,255); | ||||
@@ -1084,6 +1102,7 @@ static int nvg__expandStrokeAndFill(struct NVGcontext* ctx, int feats, float w) | |||||
int convex = 0; | int convex = 0; | ||||
int i, j, s, e; | int i, j, s, e; | ||||
float wo = 0; | float wo = 0; | ||||
float aa = ctx->fringeWidth; | |||||
// Calculate max vertex usage. | // Calculate max vertex usage. | ||||
cverts = 0; | cverts = 0; | ||||
@@ -1110,7 +1129,7 @@ static int nvg__expandStrokeAndFill(struct NVGcontext* ctx, int feats, float w) | |||||
// Calculate shape vertices. | // Calculate shape vertices. | ||||
if (feats & NVG_FILL) { | if (feats & NVG_FILL) { | ||||
wo = 0.5f; | |||||
wo = 0.5f*aa; | |||||
dst = verts; | dst = verts; | ||||
path->fill = dst; | path->fill = dst; | ||||
@@ -1196,8 +1215,8 @@ static int nvg__expandStrokeAndFill(struct NVGcontext* ctx, int feats, float w) | |||||
nvg__normalize(&dx, &dy); | nvg__normalize(&dx, &dy); | ||||
dlx = dy; | dlx = dy; | ||||
dly = -dx; | dly = -dx; | ||||
nvg__vset(dst, p0->x + dlx*rw - dx*NVG_AA, p0->y + dly*rw - dy*NVG_AA, u0,0); dst++; | |||||
nvg__vset(dst, p0->x - dlx*lw - dx*NVG_AA, p0->y - dly*lw - dy*NVG_AA, u1,0); dst++; | |||||
nvg__vset(dst, p0->x + dlx*rw - dx*aa, p0->y + dly*rw - dy*aa, u0,0); dst++; | |||||
nvg__vset(dst, p0->x - dlx*lw - dx*aa, p0->y - dly*lw - dy*aa, u1,0); dst++; | |||||
nvg__vset(dst, p0->x + dlx*rw, p0->y + dly * rw, u0,1); dst++; | nvg__vset(dst, p0->x + dlx*rw, p0->y + dly * rw, u0,1); dst++; | ||||
nvg__vset(dst, p0->x - dlx*lw, p0->y - dly * lw, u1,1); dst++; | nvg__vset(dst, p0->x - dlx*lw, p0->y - dly * lw, u1,1); dst++; | ||||
} | } | ||||
@@ -1252,8 +1271,8 @@ static int nvg__expandStrokeAndFill(struct NVGcontext* ctx, int feats, float w) | |||||
dly = -dx; | dly = -dx; | ||||
nvg__vset(dst, p1->x + dlx*rw, p1->y + dly * rw, u0,1); dst++; | nvg__vset(dst, p1->x + dlx*rw, p1->y + dly * rw, u0,1); dst++; | ||||
nvg__vset(dst, p1->x - dlx*lw, p1->y - dly * lw, u1,1); dst++; | nvg__vset(dst, p1->x - dlx*lw, p1->y - dly * lw, u1,1); dst++; | ||||
nvg__vset(dst, p1->x + dlx*rw + dx*NVG_AA, p1->y + dly*rw + dy*NVG_AA, u0,0); dst++; | |||||
nvg__vset(dst, p1->x - dlx*lw + dx*NVG_AA, p1->y - dly*lw + dy*NVG_AA, u1,0); dst++; | |||||
nvg__vset(dst, p1->x + dlx*rw + dx*aa, p1->y + dly*rw + dy*aa, u0,0); dst++; | |||||
nvg__vset(dst, p1->x - dlx*lw + dx*aa, p1->y - dly*lw + dy*aa, u1,0); dst++; | |||||
} | } | ||||
path->nstroke = (int)(dst - verts); | path->nstroke = (int)(dst - verts); | ||||
@@ -1488,11 +1507,11 @@ void nvgFill(struct NVGcontext* ctx) | |||||
nvg__flattenPaths(ctx, state->miterLimit); | nvg__flattenPaths(ctx, state->miterLimit); | ||||
if (ctx->params.edgeAntiAlias) | if (ctx->params.edgeAntiAlias) | ||||
nvg__expandStrokeAndFill(ctx, NVG_FILL|NVG_STROKE, NVG_AA); | |||||
nvg__expandStrokeAndFill(ctx, NVG_FILL|NVG_STROKE, ctx->fringeWidth); | |||||
else | else | ||||
nvg__expandStrokeAndFill(ctx, NVG_FILL, 0.0f); | nvg__expandStrokeAndFill(ctx, NVG_FILL, 0.0f); | ||||
ctx->params.renderFill(ctx->params.userPtr, &state->fill, &state->scissor, NVG_AA, | |||||
ctx->params.renderFill(ctx->params.userPtr, &state->fill, &state->scissor, 1.0f, | |||||
ctx->cache->bounds, ctx->cache->paths, ctx->cache->npaths); | ctx->cache->bounds, ctx->cache->paths, ctx->cache->npaths); | ||||
// Count triangles | // Count triangles | ||||
@@ -1514,11 +1533,11 @@ void nvgStroke(struct NVGcontext* ctx) | |||||
nvg__flattenPaths(ctx, state->miterLimit); | nvg__flattenPaths(ctx, state->miterLimit); | ||||
if (ctx->params.edgeAntiAlias) | if (ctx->params.edgeAntiAlias) | ||||
nvg__expandStrokeAndFill(ctx, NVG_STROKE|NVG_CAPS, strokeWidth*0.5f + NVG_AA/2.0f); | |||||
nvg__expandStrokeAndFill(ctx, NVG_STROKE|NVG_CAPS, strokeWidth*0.5f + ctx->fringeWidth/2.0f); | |||||
else | else | ||||
nvg__expandStrokeAndFill(ctx, NVG_STROKE|NVG_CAPS, strokeWidth*0.5f); | nvg__expandStrokeAndFill(ctx, NVG_STROKE|NVG_CAPS, strokeWidth*0.5f); | ||||
ctx->params.renderStroke(ctx->params.userPtr, &state->stroke, &state->scissor, NVG_AA, | |||||
ctx->params.renderStroke(ctx->params.userPtr, &state->stroke, &state->scissor, 1.0f, | |||||
strokeWidth, ctx->cache->paths, ctx->cache->npaths); | strokeWidth, ctx->cache->paths, ctx->cache->npaths); | ||||
// Count triangles | // Count triangles | ||||
@@ -1599,7 +1618,7 @@ float nvgText(struct NVGcontext* ctx, float x, float y, const char* string, cons | |||||
struct FONStextIter iter; | struct FONStextIter iter; | ||||
struct FONSquad q; | struct FONSquad q; | ||||
struct NVGvertex* verts; | struct NVGvertex* verts; | ||||
float scale = nvg__getFontScale(state); | |||||
float scale = nvg__getFontScale(state) * ctx->devicePxRatio; | |||||
float invscale = 1.0f / scale; | float invscale = 1.0f / scale; | ||||
int dirty[4]; | int dirty[4]; | ||||
int cverts = 0; | int cverts = 0; | ||||
@@ -66,9 +66,18 @@ enum NVGaling { | |||||
}; | }; | ||||
// Called at the beginning of a frame. | |||||
// | |||||
void nvgBeginFrame(struct NVGcontext* ctx, int width, int height); | |||||
// Begin drawing a new frame | |||||
// Calls to nanovg drawing API should be wrapped in nvgBeginFrame() & nvgEndFrame() | |||||
// nvgBeginFrame() defines the size of the window to render to in relation currently | |||||
// set viewport (i.e. glViewport on GL backends). Device pixel ration allows to | |||||
// control the rendering on Hi-DPI devices. | |||||
// For example, GLFW returns two dimension for an opened window: window size and | |||||
// frame buffer size. In that case you would set windowWidth/Height to the window size | |||||
// devicePixelRatio to: frameBufferWidth / windowWidth. | |||||
void nvgBeginFrame(struct NVGcontext* ctx, int windowWidth, int windowHeight, float devicePixelRatio); | |||||
// Ends drawing flushing remaining render state. | |||||
void nvgEndFrame(struct NVGcontext* ctx); | |||||
// | // | ||||
// Color utils | // Color utils | ||||
@@ -405,6 +414,7 @@ struct NVGparams { | |||||
int (*renderUpdateTexture)(void* uptr, int image, int x, int y, int w, int h, const unsigned char* data); | int (*renderUpdateTexture)(void* uptr, int image, int x, int y, int w, int h, const unsigned char* data); | ||||
int (*renderGetTextureSize)(void* uptr, int image, int* w, int* h); | int (*renderGetTextureSize)(void* uptr, int image, int* w, int* h); | ||||
void (*renderViewport)(void* uptr, int width, int height); | void (*renderViewport)(void* uptr, int width, int height); | ||||
void (*renderFlush)(void* uptr); | |||||
void (*renderFill)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float aasize, const float* bounds, const struct NVGpath* paths, int npaths); | void (*renderFill)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float aasize, const float* bounds, const struct NVGpath* paths, int npaths); | ||||
void (*renderStroke)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float aasize, float strokeWidth, const struct NVGpath* paths, int npaths); | void (*renderStroke)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float aasize, float strokeWidth, const struct NVGpath* paths, int npaths); | ||||
void (*renderTriangles)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, int image, const struct NVGvertex* verts, int nverts); | void (*renderTriangles)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, int image, const struct NVGvertex* verts, int nverts); | ||||
@@ -609,6 +609,12 @@ static void glnvg__renderViewport(void* uptr, int width, int height) | |||||
gl->viewHeight = height; | gl->viewHeight = height; | ||||
} | } | ||||
static void glnvg__renderFlush(void* uptr) | |||||
{ | |||||
// struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr; | |||||
// empty | |||||
} | |||||
static int glnvg__maxVertCount(const struct NVGpath* paths, int npaths) | static int glnvg__maxVertCount(const struct NVGpath* paths, int npaths) | ||||
{ | { | ||||
int i, count = 0; | int i, count = 0; | ||||
@@ -883,6 +889,7 @@ struct NVGcontext* nvgCreateGL2(int atlasw, int atlash, int edgeaa) | |||||
params.renderUpdateTexture = glnvg__renderUpdateTexture; | params.renderUpdateTexture = glnvg__renderUpdateTexture; | ||||
params.renderGetTextureSize = glnvg__renderGetTextureSize; | params.renderGetTextureSize = glnvg__renderGetTextureSize; | ||||
params.renderViewport = glnvg__renderViewport; | params.renderViewport = glnvg__renderViewport; | ||||
params.renderFlush = glnvg__renderFlush; | |||||
params.renderFill = glnvg__renderFill; | params.renderFill = glnvg__renderFill; | ||||
params.renderStroke = glnvg__renderStroke; | params.renderStroke = glnvg__renderStroke; | ||||
params.renderTriangles = glnvg__renderTriangles; | params.renderTriangles = glnvg__renderTriangles; | ||||
@@ -611,6 +611,12 @@ static void glnvg__renderViewport(void* uptr, int width, int height) | |||||
gl->viewHeight = height; | gl->viewHeight = height; | ||||
} | } | ||||
static void glnvg__renderFlush(void* uptr) | |||||
{ | |||||
// struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr; | |||||
// empty | |||||
} | |||||
static int glnvg__maxVertCount(const struct NVGpath* paths, int npaths) | static int glnvg__maxVertCount(const struct NVGpath* paths, int npaths) | ||||
{ | { | ||||
int i, count = 0; | int i, count = 0; | ||||
@@ -889,6 +895,7 @@ struct NVGcontext* nvgCreateGL3(int atlasw, int atlash, int edgeaa) | |||||
params.renderUpdateTexture = glnvg__renderUpdateTexture; | params.renderUpdateTexture = glnvg__renderUpdateTexture; | ||||
params.renderGetTextureSize = glnvg__renderGetTextureSize; | params.renderGetTextureSize = glnvg__renderGetTextureSize; | ||||
params.renderViewport = glnvg__renderViewport; | params.renderViewport = glnvg__renderViewport; | ||||
params.renderFlush = glnvg__renderFlush; | |||||
params.renderFill = glnvg__renderFill; | params.renderFill = glnvg__renderFill; | ||||
params.renderStroke = glnvg__renderStroke; | params.renderStroke = glnvg__renderStroke; | ||||
params.renderTriangles = glnvg__renderTriangles; | params.renderTriangles = glnvg__renderTriangles; | ||||