From 7bda30aca46dcd6bda0fa9e0e6fd4d0d8cfaedcb Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 24 May 2016 08:40:02 +0000 Subject: [PATCH] Refactor SS.bgImage to use Pixmap. --- src/draw.cpp | 45 ++++++------------------------ src/glhelper.cpp | 38 ++++++++++++++++++-------- src/solvespace.h | 7 ++--- src/style.cpp | 71 +++++++++--------------------------------------- src/textwin.cpp | 8 ++---- src/toolbar.cpp | 9 +++--- 6 files changed, 58 insertions(+), 120 deletions(-) diff --git a/src/draw.cpp b/src/draw.cpp index d8576d35..b422f14f 100644 --- a/src/draw.cpp +++ b/src/draw.cpp @@ -517,26 +517,9 @@ void GraphicsWindow::Paint() { glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT); - if(SS.bgImage.fromFile) { - // If a background image is loaded, then we draw it now as a texture. - // This handles the resizing for us nicely. - glBindTexture(GL_TEXTURE_2D, TEXTURE_BACKGROUND_IMG); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, - SS.bgImage.rw, SS.bgImage.rh, - 0, - GL_RGB, GL_UNSIGNED_BYTE, - SS.bgImage.fromFile); - - double tw = ((double)SS.bgImage.w) / SS.bgImage.rw, - th = ((double)SS.bgImage.h) / SS.bgImage.rh; - - double mmw = SS.bgImage.w / SS.bgImage.scale, - mmh = SS.bgImage.h / SS.bgImage.scale; + if(!SS.bgImage.pixmap.IsEmpty()) { + double mmw = SS.bgImage.pixmap.width / SS.bgImage.scale, + mmh = SS.bgImage.pixmap.height / SS.bgImage.scale; Vector origin = SS.bgImage.origin; origin = origin.DotInToCsys(projRight, projUp, n); @@ -548,22 +531,12 @@ void GraphicsWindow::Paint() { // Place the background at the very back of the Z order, though, by // mucking with the depth range. glDepthRange(1, 1); - glEnable(GL_TEXTURE_2D); - glBegin(GL_QUADS); - glTexCoord2d(0, 0); - ssglVertex3v(origin); - - glTexCoord2d(0, th); - ssglVertex3v(origin.Plus(projUp.ScaledBy(mmh))); - - glTexCoord2d(tw, th); - ssglVertex3v(origin.Plus(projRight.ScaledBy(mmw).Plus( - projUp. ScaledBy(mmh)))); - - glTexCoord2d(tw, 0); - ssglVertex3v(origin.Plus(projRight.ScaledBy(mmw))); - glEnd(); - glDisable(GL_TEXTURE_2D); + ssglDrawPixmap(SS.bgImage.pixmap, + origin, + origin.Plus(projUp.ScaledBy(mmh)), + origin.Plus(projRight.ScaledBy(mmw).Plus( + projUp. ScaledBy(mmh))), + origin.Plus(projRight.ScaledBy(mmw))); } ssglDepthRangeOffset(0); diff --git a/src/glhelper.cpp b/src/glhelper.cpp index 40179b1f..f895101b 100644 --- a/src/glhelper.cpp +++ b/src/glhelper.cpp @@ -564,7 +564,7 @@ void ssglDepthRangeLockToFront(bool yes) } } -void ssglDrawPixmap(const Pixmap &pixmap, bool flip) { +void ssglDrawPixmap(const Pixmap &pixmap, Vector a, Vector b, Vector c, Vector d) { glBindTexture(GL_TEXTURE_2D, TEXTURE_DRAW_PIXELS); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -578,21 +578,35 @@ void ssglDrawPixmap(const Pixmap &pixmap, bool flip) { glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); - glTexCoord2d(0.0, flip ? 0.0 : 1.0); - glVertex2d(0.0, (double)pixmap.height); - - glTexCoord2d(1.0, flip ? 0.0 : 1.0); - glVertex2d((double)pixmap.width, (double)pixmap.height); - - glTexCoord2d(1.0, flip ? 1.0 : 0.0); - glVertex2d((double)pixmap.width, 0.0); - - glTexCoord2d(0.0, flip ? 1.0 : 0.0); - glVertex2d(0.0, 0.0); + glTexCoord2d(0.0, 0.0); + glVertex3d(CO(a)); + glTexCoord2d(0.0, 1.0); + glVertex3d(CO(b)); + glTexCoord2d(1.0, 1.0); + glVertex3d(CO(c)); + glTexCoord2d(1.0, 0.0); + glVertex3d(CO(d)); glEnd(); glDisable(GL_TEXTURE_2D); } +void ssglDrawPixmap(const Pixmap &pixmap, Point2d o, bool flip) { + double w = (double)pixmap.width, h = (double)pixmap.height; + if(!flip) { + Vector a = { o.x, o.y, 0.0 }, + b = { o.x, o.y + h, 0.0 }, + c = { o.x + w, o.y + h, 0.0 }, + d = { o.x + w, o.y, 0.0 }; + ssglDrawPixmap(pixmap, a, b, c, d); + } else { + Vector a = { o.x, o.y + h, 0.0 }, + b = { o.x, o.y, 0.0 }, + c = { o.x + w, o.y, 0.0 }, + d = { o.x + w, o.y + h, 0.0 }; + ssglDrawPixmap(pixmap, a, b, c, d); + } +} + //----------------------------------------------------------------------------- // Bitmap font rendering //----------------------------------------------------------------------------- diff --git a/src/solvespace.h b/src/solvespace.h index 3c29344f..36b2b0b0 100644 --- a/src/solvespace.h +++ b/src/solvespace.h @@ -371,7 +371,8 @@ void ssglColorRGB(RgbaColor rgb); void ssglColorRGBa(RgbaColor rgb, double a); void ssglDepthRangeOffset(int units); void ssglDepthRangeLockToFront(bool yes); -void ssglDrawPixmap(const Pixmap &pixmap, bool flip = false); +void ssglDrawPixmap(const Pixmap &pixmap, Vector a, Vector b, Vector c, Vector d); +void ssglDrawPixmap(const Pixmap &pixmap, Point2d o, bool flip = false); void ssglInitializeBitmapFont(); void ssglBitmapText(const std::string &str, Vector p); double ssglBitmapCharQuad(char32_t chr, double x, double y); @@ -875,9 +876,7 @@ public: Vector ptB; } extraLine; struct { - uint8_t *fromFile; - int w, h; - int rw, rh; + Pixmap pixmap; double scale; // pixels per mm Vector origin; } bgImage; diff --git a/src/style.cpp b/src/style.cpp index 2f33721e..d9e3119e 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -109,8 +109,7 @@ void Style::LoadFactoryDefaults() { FillDefaultStyle(s, d); } SS.backgroundColor = RGBi(0, 0, 0); - if(SS.bgImage.fromFile) MemFree(SS.bgImage.fromFile); - SS.bgImage.fromFile = NULL; + SS.bgImage.pixmap.Clear(); } void Style::FreezeDefaultStyles() { @@ -382,62 +381,18 @@ static int RoundUpToPowerOfTwo(int v) } void TextWindow::ScreenBackgroundImage(int link, uint32_t v) { - if(SS.bgImage.fromFile) MemFree(SS.bgImage.fromFile); - SS.bgImage.fromFile = NULL; + SS.bgImage.pixmap.Clear(); if(link == 'l') { - FILE *f = NULL; - png_struct *png_ptr = NULL; - png_info *info_ptr = NULL; - - std::string importFile; - if(!GetOpenFile(&importFile, "", PngFileFilter)) goto err; - f = ssfopen(importFile, "rb"); - if(!f) goto err; - - uint8_t header[8]; - if (fread(header, 1, 8, f) != 8) - goto err; - if(png_sig_cmp(header, 0, 8)) goto err; - - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, - NULL, NULL, NULL); - if(!png_ptr) goto err; - - info_ptr = png_create_info_struct(png_ptr); - if(!info_ptr) goto err; - - if(setjmp(png_jmpbuf(png_ptr))) goto err; - - png_init_io(png_ptr, f); - png_set_sig_bytes(png_ptr, 8); - - png_read_png(png_ptr, info_ptr, - PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_STRIP_ALPHA, NULL); - - int w; w = (int)png_get_image_width(png_ptr, info_ptr); - int h; h = (int)png_get_image_height(png_ptr, info_ptr); - uint8_t **rows; rows = png_get_rows(png_ptr, info_ptr); - - // Round to next-highest powers of two, since the textures require - // that. And round up to 4, to guarantee 32-bit alignment. - int rw; rw = max(4, RoundUpToPowerOfTwo(w)); - int rh; rh = max(4, RoundUpToPowerOfTwo(h)); - - SS.bgImage.fromFile = (uint8_t *)MemAlloc(rw*rh*3); - {for(int i = 0; i < h; i++) { - memcpy(SS.bgImage.fromFile + ((h - 1) - i)*(rw*3), rows[i], w*3); - }} - SS.bgImage.w = w; - SS.bgImage.h = h; - SS.bgImage.rw = rw; - SS.bgImage.rh = rh; - SS.bgImage.scale = SS.GW.scale; - SS.bgImage.origin = SS.GW.offset.ScaledBy(-1); - -err: - if(png_ptr) png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - if(f) fclose(f); + std::string bgImageFile; + if(GetOpenFile(&bgImageFile, "", PngFileFilter)) { + FILE *f = ssfopen(bgImageFile, "rb"); + if(f) { + SS.bgImage.pixmap = Pixmap::FromPNG(f); + SS.bgImage.scale = SS.GW.scale; + SS.bgImage.origin = SS.GW.offset.ScaledBy(-1); + } + } } SS.ScheduleShowTW(); } @@ -476,9 +431,9 @@ void TextWindow::ShowListOfStyles() { Printf(false, ""); Printf(false, "%Ft background bitmap image%E"); - if(SS.bgImage.fromFile) { + if(!SS.bgImage.pixmap.IsEmpty()) { Printf(false, "%Ba %Ftwidth:%E %dpx %Ftheight:%E %dpx", - SS.bgImage.w, SS.bgImage.h); + SS.bgImage.pixmap.width, SS.bgImage.pixmap.height); Printf(false, " %Ftscale:%E %# px/%s %Fl%Ll%f%D[change]%E", SS.bgImage.scale*SS.MmPerUnit(), diff --git a/src/textwin.cpp b/src/textwin.cpp index 1676a8a4..bb88471d 100644 --- a/src/textwin.cpp +++ b/src/textwin.cpp @@ -383,11 +383,9 @@ void TextWindow::DrawOrHitTestIcons(int how, double mx, double my) } if(how == PAINT) { - glPushMatrix(); - glTranslated(x, y-24, 0); - glColor3d(0, 0, 0); - ssglDrawPixmap(hsi->icon); - glPopMatrix(); + glColor4d(0, 0, 0, 1.0); + Point2d o = { (double)x, (double)(y - 24) }; + ssglDrawPixmap(hsi->icon, o); if(hsi == hoveredIcon) { glColor4d(1, 1, 0, 0.3); diff --git a/src/toolbar.cpp b/src/toolbar.cpp index 872f5f5a..120bb2ff 100644 --- a/src/toolbar.cpp +++ b/src/toolbar.cpp @@ -170,11 +170,10 @@ bool GraphicsWindow::ToolbarDrawOrHitTest(int mx, int my, } if(paint) { - glPushMatrix(); - glTranslated(x - Toolbar[i].icon.width / 2, y - Toolbar[i].icon.height / 2, 0); - glColor4d(0, 0, 0, 1.0); - ssglDrawPixmap(Toolbar[i].icon, /*flip=*/true); - glPopMatrix(); + glColor4d(0, 0, 0, 1.0); + Point2d o = { (double)(x - Toolbar[i].icon.width / 2), + (double)(y - Toolbar[i].icon.height / 2) }; + ssglDrawPixmap(Toolbar[i].icon, o, /*flip=*/true); if(toolbarHovered == Toolbar[i].menu || pending.operation == Toolbar[i].menu) {