From 89ec47f9619fa187cec575307cdc11ad836c40c5 Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Sep 07 2020 07:37:42 +0000 Subject: fix stroke and framebuffer --- diff --git a/src/drawing.c b/src/drawing.c index c3198c0..feb3a10 100644 --- a/src/drawing.c +++ b/src/drawing.c @@ -152,13 +152,18 @@ void noClip() void projectionByViewport() { + unsigned int framebuffer_id = 0; + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (int*)&framebuffer_id); int vp[4] = {}; glGetIntegerv(GL_VIEWPORT, vp); unsigned int mode; glGetIntegerv(GL_MATRIX_MODE, (int*)&mode); glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glOrtho(0, vp[2], vp[3], 0, -1.0, 1.0); + if (framebuffer_id) + glOrtho(0, vp[2], 0, vp[3], -1.0, 1.0); + else + glOrtho(0, vp[2], vp[3], 0, -1.0, 1.0); glMatrixMode(mode); } @@ -564,6 +569,8 @@ static void strokeAddCorner( double kl0 = 1/l0, kl1 = 1/l1; double nx0 = dx0*kl0, ny0 = dy0*kl0; double nx1 = dx1*kl1, ny1 = dy1*kl1; + assert(fabs(sqrt(nx0*nx0 + ny0*ny0) - 1) <= HELI_PRECISION); + assert(fabs(sqrt(nx1*nx1 + ny1*ny1) - 1) <= HELI_PRECISION); double dot = nx0*ny1 - ny0*nx1; if (dot > HELI_PRECISION) { @@ -571,7 +578,7 @@ static void strokeAddCorner( strokeAddPoint(stroke, x0, y0, ny0, -nx0); strokeAddCornerSub(stroke, ny1, -nx1, precisionSqr, 8); } else - if (dot < HELI_PRECISION) { + if (dot < -HELI_PRECISION) { // corner double dx = nx1 - nx0; double dy = ny1 - ny0; @@ -579,7 +586,7 @@ static void strokeAddCorner( double nx = dx*kl, ny = dy*kl; double c = nx*nx1 + ny*ny1; double cl = 1/sqrt(1 - c*c); - if (cl > 3) cl = 3; + if (cl > 3) cl = 3; strokeAddPoint(stroke, x0, y0, nx*cl, ny*cl); } else { // flat @@ -729,6 +736,8 @@ static void pushPathPoint(double x, double y) { } static void endPath(int close, int stroke, int fill, int fillSimple) { + int origPathSize = pathSize; + // remove duplicates int removed = 0; for(int i = 2; i < pathSize; i += 2) { @@ -752,13 +761,22 @@ static void endPath(int close, int stroke, int fill, int fillSimple) { pathSize -= 2; // draw + int isPoint = FALSE; + double px, py; if (pathSize >= 4) { if (fillSimple) drawFillSimple(); else if (fill) drawFill(); if (stroke) drawStroke(close); + } else + if (origPathSize >= 4 && stroke) { + px = path[0]; + py = path[1]; + isPoint = TRUE; } resetPath(); + + if (isPoint) point(px, py); } void closePath() @@ -859,7 +877,7 @@ void heliDrawingPrepareFrame() { glEnable(GL_BLEND); if (heliGLBlendFuncSeparatePtr) - heliGLBlendFuncSeparatePtr(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); + heliGLBlendFuncSeparatePtr(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE); else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_LINE_SMOOTH); diff --git a/src/framebuffer.c b/src/framebuffer.c index 06ead48..ea0e518 100644 --- a/src/framebuffer.c +++ b/src/framebuffer.c @@ -243,6 +243,9 @@ int imageFromViewport(int *outWidth, int *outHeight, unsigned char **outPixels) if (vp[2] <= 0 || vp[3] <= 0) return FALSE; + unsigned int prevR = 0, prevD = 0; + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (int*)&prevR); + unsigned char *buffer = malloc(vp[2]*vp[3]*4); glGetError(); glReadPixels(vp[0], vp[1], vp[2], vp[3], GL_RGBA, GL_UNSIGNED_BYTE, buffer); @@ -257,8 +260,6 @@ int imageFromViewport(int *outWidth, int *outHeight, unsigned char **outPixels) HeliFramebufferDesc fbd = {}; heliInitFramebuffer(&fbd, vp[2], vp[3], NULL, FALSE, FALSE, FALSE, 0, TRUE); - unsigned int prevR = 0, prevD = 0; - glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, (int*)&prevR); glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (int*)&prevD); heliGLBindFramebufferPtr(GL_DRAW_FRAMEBUFFER, fbd.framebuffer_id); heliGLBlitFramebufferPtr(vp[0], vp[1], vp[2], vp[3], 0, 0, vp[2], vp[3], GL_COLOR_BUFFER_BIT, GL_NEAREST); @@ -271,14 +272,16 @@ int imageFromViewport(int *outWidth, int *outHeight, unsigned char **outPixels) } // flip image - size_t rowSize = vp[2]*4; - unsigned char *row = malloc(rowSize); - for(int i = vp[3]/2 - 1; i >= 0; --i) { - unsigned char *r0 = buffer + rowSize*i; - unsigned char *r1 = buffer + rowSize*(vp[3]-i-1); - memcpy(row, r0, rowSize); - memcpy(r0, r1, rowSize); - memcpy(r1, row, rowSize); + if (!prevR) { + size_t rowSize = vp[2]*4; + unsigned char *row = malloc(rowSize); + for(int i = vp[3]/2 - 1; i >= 0; --i) { + unsigned char *r0 = buffer + rowSize*i; + unsigned char *r1 = buffer + rowSize*(vp[3]-i-1); + memcpy(row, r0, rowSize); + memcpy(r0, r1, rowSize); + memcpy(r1, row, rowSize); + } } *outWidth = vp[2]; diff --git a/src/gl.c b/src/gl.c index cdfbbba..98c95f2 100644 --- a/src/gl.c +++ b/src/gl.c @@ -186,7 +186,7 @@ void heliGLGetCommonState(HeliGLCommonState *state, unsigned int flags) { void heliGLSetCommonState(const HeliGLCommonState *state) { int loadClip = state->flags & STATE_CLIP; - int loadTransform = state->flags & STATE_CLIP; + int loadTransform = state->flags & STATE_TRANSFORM; if (loadClip) { unsigned int mode; glGetIntegerv(GL_MATRIX_MODE, (int*)&mode);