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);
|
||||
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);
|
||||
|
||||
|
|
|
@ -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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue