Refactor SS.bgImage to use Pixmap.
parent
274233fe08
commit
7bda30aca4
45
src/draw.cpp
45
src/draw.cpp
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue