Refactor the "File → Export Image" command.
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.pull/168/merge
parent
bb2cc4aa56
commit
495a7ac166
|
@ -154,6 +154,7 @@ set(solvespace_core_SOURCES
|
||||||
drawconstraint.cpp
|
drawconstraint.cpp
|
||||||
drawentity.cpp
|
drawentity.cpp
|
||||||
entity.cpp
|
entity.cpp
|
||||||
|
export.cpp
|
||||||
exportstep.cpp
|
exportstep.cpp
|
||||||
exportvector.cpp
|
exportvector.cpp
|
||||||
expr.cpp
|
expr.cpp
|
||||||
|
@ -191,7 +192,6 @@ set(solvespace_core_SOURCES
|
||||||
srf/triangulate.cpp)
|
srf/triangulate.cpp)
|
||||||
|
|
||||||
set(solvespace_core_gl_SOURCES
|
set(solvespace_core_gl_SOURCES
|
||||||
export.cpp
|
|
||||||
solvespace.cpp)
|
solvespace.cpp)
|
||||||
|
|
||||||
add_library(solvespace-core STATIC
|
add_library(solvespace-core STATIC
|
||||||
|
|
34
src/draw.cpp
34
src/draw.cpp
|
@ -885,26 +885,34 @@ void GraphicsWindow::Paint() {
|
||||||
/*outlineColor=*/Style::Color(Style::HOVERED));
|
/*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.
|
// And finally the toolbar.
|
||||||
if(SS.showToolbar) {
|
if(SS.showToolbar) {
|
||||||
canvas->SetCamera(camera);
|
canvas->SetCamera(camera);
|
||||||
ToolbarDraw(&uiCanvas);
|
ToolbarDraw(&uiCanvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we display UI elements, also display an fps counter.
|
// Also display an fps counter.
|
||||||
if(SS.showToolbar) {
|
RgbaColor renderTimeColor;
|
||||||
RgbaColor renderTimeColor;
|
if(1000 / renderTime.count() < 60) {
|
||||||
if(1000 / renderTime.count() < 60) {
|
// We aim for a steady 60fps; draw the counter in red when we're slower.
|
||||||
// We aim for a steady 60fps; draw the counter in red when we're slower.
|
renderTimeColor = { 255, 0, 0, 255 };
|
||||||
renderTimeColor = { 255, 0, 0, 255 };
|
} else {
|
||||||
} else {
|
renderTimeColor = { 255, 255, 255, 255 };
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
uiCanvas.DrawBitmapText(ssprintf("rendered in %ld ms (%ld 1/s)",
|
||||||
|
(long)renderTime.count(),
|
||||||
|
(long)(1000/renderTime.count())),
|
||||||
|
5, 5, renderTimeColor);
|
||||||
|
|
||||||
canvas->FlushFrame();
|
canvas->FlushFrame();
|
||||||
canvas->Clear();
|
canvas->Clear();
|
||||||
|
|
|
@ -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.
|
// rendering the view in the usual way and then copying the pixels.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void SolveSpaceUI::ExportAsPngTo(const std::string &filename) {
|
void SolveSpaceUI::ExportAsPngTo(const std::string &filename) {
|
||||||
#if !defined(HEADLESS)
|
screenshotFile = filename;
|
||||||
// No guarantee that the back buffer contains anything valid right now,
|
// The rest of the work is done in the next redraw.
|
||||||
// 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
|
|
||||||
SS.GW.Paint();
|
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -676,6 +676,7 @@ public:
|
||||||
bool drawBackFaces;
|
bool drawBackFaces;
|
||||||
bool checkClosedContour;
|
bool checkClosedContour;
|
||||||
bool showToolbar;
|
bool showToolbar;
|
||||||
|
std::string screenshotFile;
|
||||||
RgbaColor backgroundColor;
|
RgbaColor backgroundColor;
|
||||||
bool exportShadedTriangles;
|
bool exportShadedTriangles;
|
||||||
bool exportPwlCurves;
|
bool exportPwlCurves;
|
||||||
|
|
Loading…
Reference in New Issue