Skip to content

Commit

Permalink
Refactor the "File → Export Image" command.
Browse files Browse the repository at this point in the history
The existing code is horrible and needlessly platform-dependent.
Even worse, it causes a freeze on GTK. Instead of propping that up
with a few more crutches, just fix the root cause.
  • Loading branch information
whitequark committed Jan 23, 2017
1 parent bb2cc4a commit 495a7ac
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 47 deletions.
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ set(solvespace_core_SOURCES
drawconstraint.cpp
drawentity.cpp
entity.cpp
export.cpp
exportstep.cpp
exportvector.cpp
expr.cpp
Expand Down Expand Up @@ -191,7 +192,6 @@ set(solvespace_core_SOURCES
srf/triangulate.cpp)

set(solvespace_core_gl_SOURCES
export.cpp
solvespace.cpp)

add_library(solvespace-core STATIC
Expand Down
34 changes: 21 additions & 13 deletions src/draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -885,26 +885,34 @@ void GraphicsWindow::Paint() {
/*outlineColor=*/Style::Color(Style::HOVERED));
}

// If we've had a screenshot requested, take it now, before the UI is overlaid.
if(!SS.screenshotFile.empty()) {
FILE *f = ssfopen(SS.screenshotFile, "wb");
if(!f || !canvas->ReadFrame()->WritePng(f, /*flip=*/true)) {
Error("Couldn't write to '%s'", SS.screenshotFile.c_str());
}
if(f) fclose(f);
SS.screenshotFile.clear();
}

// And finally the toolbar.
if(SS.showToolbar) {
canvas->SetCamera(camera);
ToolbarDraw(&uiCanvas);
}

// If we display UI elements, also display an fps counter.
if(SS.showToolbar) {
RgbaColor renderTimeColor;
if(1000 / renderTime.count() < 60) {
// We aim for a steady 60fps; draw the counter in red when we're slower.
renderTimeColor = { 255, 0, 0, 255 };
} else {
renderTimeColor = { 255, 255, 255, 255 };
}
uiCanvas.DrawBitmapText(ssprintf("rendered in %ld ms (%ld 1/s)",
(long)renderTime.count(),
(long)(1000/renderTime.count())),
5, 5, renderTimeColor);
// Also display an fps counter.
RgbaColor renderTimeColor;
if(1000 / renderTime.count() < 60) {
// We aim for a steady 60fps; draw the counter in red when we're slower.
renderTimeColor = { 255, 0, 0, 255 };
} else {
renderTimeColor = { 255, 255, 255, 255 };
}
uiCanvas.DrawBitmapText(ssprintf("rendered in %ld ms (%ld 1/s)",
(long)renderTime.count(),
(long)(1000/renderTime.count())),
5, 5, renderTimeColor);

canvas->FlushFrame();
canvas->Clear();
Expand Down
35 changes: 2 additions & 33 deletions src/export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1117,39 +1117,8 @@ void SolveSpaceUI::ExportMeshAsThreeJsTo(FILE *f, const std::string &filename,
// rendering the view in the usual way and then copying the pixels.
//-----------------------------------------------------------------------------
void SolveSpaceUI::ExportAsPngTo(const std::string &filename) {
#if !defined(HEADLESS)
// No guarantee that the back buffer contains anything valid right now,
// so repaint the scene. And hide the toolbar too.
bool prevShowToolbar = SS.showToolbar;
SS.showToolbar = false;

// Somewhat hacky way to invoke glReadPixels without dragging in all OpenGL headers.
std::shared_ptr<ViewportCanvas> canvas = CreateRenderer();
canvas->SetCamera(SS.GW.GetCamera());
std::shared_ptr<Pixmap> screenshot;
#if !defined(WIN32)
GlOffscreen offscreen;
offscreen.Render((int)SS.GW.width, (int)SS.GW.height, [&] {
SS.GW.Paint();
screenshot = canvas->ReadFrame();
});
#else
screenshotFile = filename;
// The rest of the work is done in the next redraw.
SS.GW.Paint();
screenshot = canvas->ReadFrame();
#endif
SS.showToolbar = prevShowToolbar;

FILE *f = ssfopen(filename, "wb");
if(!f || !screenshot->WritePng(f, /*flip=*/true)) {
Error("Couldn't write to '%s'", filename.c_str());
}
if(f) fclose(f);

#if !defined(WIN32)
offscreen.Clear();
#endif

return;
#endif
}

1 change: 1 addition & 0 deletions src/solvespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,7 @@ class SolveSpaceUI {
bool drawBackFaces;
bool checkClosedContour;
bool showToolbar;
std::string screenshotFile;
RgbaColor backgroundColor;
bool exportShadedTriangles;
bool exportPwlCurves;
Expand Down

0 comments on commit 495a7ac

Please sign in to comment.