Refactor SS.bgImage to use Pixmap.

pull/10/head
whitequark 2016-05-24 08:40:02 +00:00
parent 274233fe08
commit 7bda30aca4
6 changed files with 58 additions and 120 deletions

View File

@ -517,26 +517,9 @@ void GraphicsWindow::Paint() {
glClearDepth(1.0); glClearDepth(1.0);
glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT);
if(SS.bgImage.fromFile) { if(!SS.bgImage.pixmap.IsEmpty()) {
// If a background image is loaded, then we draw it now as a texture. double mmw = SS.bgImage.pixmap.width / SS.bgImage.scale,
// This handles the resizing for us nicely. mmh = SS.bgImage.pixmap.height / SS.bgImage.scale;
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;
Vector origin = SS.bgImage.origin; Vector origin = SS.bgImage.origin;
origin = origin.DotInToCsys(projRight, projUp, n); 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 // Place the background at the very back of the Z order, though, by
// mucking with the depth range. // mucking with the depth range.
glDepthRange(1, 1); glDepthRange(1, 1);
glEnable(GL_TEXTURE_2D); ssglDrawPixmap(SS.bgImage.pixmap,
glBegin(GL_QUADS); origin,
glTexCoord2d(0, 0); origin.Plus(projUp.ScaledBy(mmh)),
ssglVertex3v(origin); origin.Plus(projRight.ScaledBy(mmw).Plus(
projUp. ScaledBy(mmh))),
glTexCoord2d(0, th); origin.Plus(projRight.ScaledBy(mmw)));
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);
} }
ssglDepthRangeOffset(0); ssglDepthRangeOffset(0);

View File

@ -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); glBindTexture(GL_TEXTURE_2D, TEXTURE_DRAW_PIXELS);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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); glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS); glBegin(GL_QUADS);
glTexCoord2d(0.0, flip ? 0.0 : 1.0); glTexCoord2d(0.0, 0.0);
glVertex2d(0.0, (double)pixmap.height); glVertex3d(CO(a));
glTexCoord2d(0.0, 1.0);
glTexCoord2d(1.0, flip ? 0.0 : 1.0); glVertex3d(CO(b));
glVertex2d((double)pixmap.width, (double)pixmap.height); glTexCoord2d(1.0, 1.0);
glVertex3d(CO(c));
glTexCoord2d(1.0, flip ? 1.0 : 0.0); glTexCoord2d(1.0, 0.0);
glVertex2d((double)pixmap.width, 0.0); glVertex3d(CO(d));
glTexCoord2d(0.0, flip ? 1.0 : 0.0);
glVertex2d(0.0, 0.0);
glEnd(); glEnd();
glDisable(GL_TEXTURE_2D); 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 // Bitmap font rendering
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -371,7 +371,8 @@ void ssglColorRGB(RgbaColor rgb);
void ssglColorRGBa(RgbaColor rgb, double a); void ssglColorRGBa(RgbaColor rgb, double a);
void ssglDepthRangeOffset(int units); void ssglDepthRangeOffset(int units);
void ssglDepthRangeLockToFront(bool yes); 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 ssglInitializeBitmapFont();
void ssglBitmapText(const std::string &str, Vector p); void ssglBitmapText(const std::string &str, Vector p);
double ssglBitmapCharQuad(char32_t chr, double x, double y); double ssglBitmapCharQuad(char32_t chr, double x, double y);
@ -875,9 +876,7 @@ public:
Vector ptB; Vector ptB;
} extraLine; } extraLine;
struct { struct {
uint8_t *fromFile; Pixmap pixmap;
int w, h;
int rw, rh;
double scale; // pixels per mm double scale; // pixels per mm
Vector origin; Vector origin;
} bgImage; } bgImage;

View File

@ -109,8 +109,7 @@ void Style::LoadFactoryDefaults() {
FillDefaultStyle(s, d); FillDefaultStyle(s, d);
} }
SS.backgroundColor = RGBi(0, 0, 0); SS.backgroundColor = RGBi(0, 0, 0);
if(SS.bgImage.fromFile) MemFree(SS.bgImage.fromFile); SS.bgImage.pixmap.Clear();
SS.bgImage.fromFile = NULL;
} }
void Style::FreezeDefaultStyles() { void Style::FreezeDefaultStyles() {
@ -382,62 +381,18 @@ static int RoundUpToPowerOfTwo(int v)
} }
void TextWindow::ScreenBackgroundImage(int link, uint32_t v) { void TextWindow::ScreenBackgroundImage(int link, uint32_t v) {
if(SS.bgImage.fromFile) MemFree(SS.bgImage.fromFile); SS.bgImage.pixmap.Clear();
SS.bgImage.fromFile = NULL;
if(link == 'l') { if(link == 'l') {
FILE *f = NULL; std::string bgImageFile;
png_struct *png_ptr = NULL; if(GetOpenFile(&bgImageFile, "", PngFileFilter)) {
png_info *info_ptr = NULL; FILE *f = ssfopen(bgImageFile, "rb");
if(f) {
std::string importFile; SS.bgImage.pixmap = Pixmap::FromPNG(f);
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.scale = SS.GW.scale;
SS.bgImage.origin = SS.GW.offset.ScaledBy(-1); 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);
} }
SS.ScheduleShowTW(); SS.ScheduleShowTW();
} }
@ -476,9 +431,9 @@ void TextWindow::ShowListOfStyles() {
Printf(false, ""); Printf(false, "");
Printf(false, "%Ft background bitmap image%E"); 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", 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", Printf(false, " %Ftscale:%E %# px/%s %Fl%Ll%f%D[change]%E",
SS.bgImage.scale*SS.MmPerUnit(), SS.bgImage.scale*SS.MmPerUnit(),

View File

@ -383,11 +383,9 @@ void TextWindow::DrawOrHitTestIcons(int how, double mx, double my)
} }
if(how == PAINT) { if(how == PAINT) {
glPushMatrix(); glColor4d(0, 0, 0, 1.0);
glTranslated(x, y-24, 0); Point2d o = { (double)x, (double)(y - 24) };
glColor3d(0, 0, 0); ssglDrawPixmap(hsi->icon, o);
ssglDrawPixmap(hsi->icon);
glPopMatrix();
if(hsi == hoveredIcon) { if(hsi == hoveredIcon) {
glColor4d(1, 1, 0, 0.3); glColor4d(1, 1, 0, 0.3);

View File

@ -170,11 +170,10 @@ bool GraphicsWindow::ToolbarDrawOrHitTest(int mx, int my,
} }
if(paint) { if(paint) {
glPushMatrix();
glTranslated(x - Toolbar[i].icon.width / 2, y - Toolbar[i].icon.height / 2, 0);
glColor4d(0, 0, 0, 1.0); glColor4d(0, 0, 0, 1.0);
ssglDrawPixmap(Toolbar[i].icon, /*flip=*/true); Point2d o = { (double)(x - Toolbar[i].icon.width / 2),
glPopMatrix(); (double)(y - Toolbar[i].icon.height / 2) };
ssglDrawPixmap(Toolbar[i].icon, o, /*flip=*/true);
if(toolbarHovered == Toolbar[i].menu || if(toolbarHovered == Toolbar[i].menu ||
pending.operation == Toolbar[i].menu) { pending.operation == Toolbar[i].menu) {