Provide a common method to save screenshots

pull/3/head
Hleb Valoshka 2019-10-19 15:38:04 +03:00
parent 2c2a17aa0a
commit 097d7113e2
6 changed files with 56 additions and 140 deletions

View File

@ -59,6 +59,7 @@
#include <celephem/scriptobject.h>
#endif
#include "imagecapture.h"
// TODO: proper gettext
#define C_(a, b) (b)
@ -4434,3 +4435,30 @@ View* CelestiaCore::getViewByObserver(const Observer *obs) const
return view;
return nullptr;
}
bool CelestiaCore::saveScreenShot(const fs::path& filename, ContentType type) const
{
if (type == Content_Unknown)
type = DetermineFileType(filename);
// Get the dimensions of the current viewport
array<int, 4> viewport;
getRenderer()->getViewport(viewport);
if (type == Content_JPEG)
{
return CaptureGLBufferToJPEG(filename,
viewport[0], viewport[1],
viewport[2], viewport[3],
getRenderer());
}
if (type == Content_PNG)
{
return CaptureGLBufferToPNG(filename,
viewport[0], viewport[1],
viewport[2], viewport[3],
getRenderer());
}
return false;
}

View File

@ -10,6 +10,7 @@
#ifndef _CELESTIACORE_H_
#define _CELESTIACORE_H_
#include <celutil/filetype.h>
#include <celutil/timer.h>
#include <celutil/watcher.h>
// #include <celutil/watchable.h>
@ -337,6 +338,8 @@ class CelestiaCore // : public Watchable<CelestiaCore>
void setScriptHook(std::unique_ptr<celestia::scripts::IScriptHook> &&hook) { m_scriptHook = std::move(hook); }
const std::shared_ptr<celestia::scripts::ScriptMaps>& scriptMaps() const { return m_scriptMaps; }
bool saveScreenShot(const fs::path&, ContentType = Content_Unknown) const;
protected:
bool readStars(const CelestiaConfig&, ProgressNotifier*);
void renderOverlay();

View File

@ -25,7 +25,6 @@
#include <celengine/simulation.h>
#include <celengine/render.h>
#include <celestia/celestiacore.h>
#include <celestia/imagecapture.h>
#include <celestia/url.h>
#include <celutil/filetype.h>
#ifdef THEORA
@ -1067,50 +1066,20 @@ static void openScript(const char* filename, AppData* app)
/* Image capturing helper called by actionCaptureImage() */
static void captureImage(const char* filename, AppData* app)
{
/* Get the dimensions of the current viewport */
array<int, 4> viewport;
app->renderer->getViewport(viewport);
bool success = false;
ContentType type = DetermineFileType(filename);
if (type == Content_Unknown)
if (type != Content_JPEG && type != Content_PNG)
{
GtkWidget* errBox = gtk_message_dialog_new(GTK_WINDOW(app->mainWindow),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
"Unable to determine image file type from name, please use a name ending in '.jpg' or '.png'.");
gtk_dialog_run(GTK_DIALOG(errBox));
gtk_widget_destroy(errBox);
return;
}
else if (type == Content_JPEG)
{
success = CaptureGLBufferToJPEG(filename,
viewport[0], viewport[1],
viewport[2], viewport[3],
app->renderer);
}
else if (type == Content_PNG)
{
success = CaptureGLBufferToPNG(filename,
viewport[0], viewport[1],
viewport[2], viewport[3],
app->renderer);
}
else
{
GtkWidget* errBox = gtk_message_dialog_new(GTK_WINDOW(app->mainWindow),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
"Currently screen capturing to only JPEG or PNG files is supported.");
_("Please use a name ending in '.jpg' or '.png'."));
gtk_dialog_run(GTK_DIALOG(errBox));
gtk_widget_destroy(errBox);
return;
}
if (!success)
if (!app->core->saveScreenShot(filename))
{
GtkWidget* errBox = gtk_message_dialog_new(GTK_WINDOW(app->mainWindow),
GTK_DIALOG_DESTROY_WITH_PARENT,

View File

@ -39,7 +39,6 @@
#include <GL/glew.h>
#include "celestia/celestiacore.h"
#include "celestia/imagecapture.h"
#include "celestia/avicapture.h"
#include "celestia/url.h"
#include "winstarbrowser.h"
@ -2681,81 +2680,38 @@ static void HandleCaptureImage(HWND hWnd)
// If you got here, a path and file has been specified.
// Ofn.lpstrFile contains full path to specified file
// Ofn.lpstrFileTitle contains just the filename with extension
// Get the dimensions of the current viewport
array<int,4> viewport;
appCore->getRenderer()->getViewport(viewport);
bool success = false;
DWORD nFileType=0;
char defaultExtensions[][4] = {"jpg", "png"};
if (Ofn.nFileExtension == 0)
{
// If no extension was specified, use the selection of filter to
// determine which type of file should be created, instead of
// just defaulting to JPEG.
nFileType = Ofn.nFilterIndex;
strcat(Ofn.lpstrFile, ".");
strcat(Ofn.lpstrFile, defaultExtensions[nFileType-1]);
strcat(Ofn.lpstrFile, defaultExtensions[Ofn.nFilterIndex-1]);
}
else if (*(Ofn.lpstrFile + Ofn.nFileExtension) == '\0')
{
// If just a period was specified for the extension, use the
// selection of filter to determine which type of file should be
// created instead of just defaulting to JPEG.
nFileType = Ofn.nFilterIndex;
strcat(Ofn.lpstrFile, defaultExtensions[nFileType-1]);
strcat(Ofn.lpstrFile, defaultExtensions[Ofn.nFilterIndex-1]);
}
else
ContentType type = DetermineFileType(Ofn.lpstrFile);
if (type != Content_JPEG && type != Content_PNG)
{
switch (DetermineFileType(Ofn.lpstrFile))
{
case Content_JPEG:
nFileType = 1;
break;
case Content_PNG:
nFileType = 2;
break;
default:
nFileType = 0;
break;
}
MessageBox(hWnd,
_("Please use a name ending in '.jpg' or '.png'."),
"Error",
MB_OK | MB_ICONERROR);
return;
}
// Redraw to make sure that the back buffer is up to date
appCore->draw();
if (nFileType == 1)
if (!appCore->saveScreenShot(Ofn.lpstrFile))
{
success = CaptureGLBufferToJPEG(string(Ofn.lpstrFile),
viewport[0], viewport[1],
viewport[2], viewport[3],
appCore->getRenderer());
}
else if (nFileType == 2)
{
success = CaptureGLBufferToPNG(string(Ofn.lpstrFile),
viewport[0], viewport[1],
viewport[2], viewport[3],
appCore->getRenderer());
}
else
{
// Invalid file extension specified.
DPRINTF(0, "WTF? Unknown file extension specified for screen capture.\n");
}
if (!success)
{
char errorMsg[64];
if(nFileType == 0)
sprintf(errorMsg, "Specified file extension is not recognized.");
else
sprintf(errorMsg, "Could not save image file.");
MessageBox(hWnd, errorMsg, "Error", MB_OK | MB_ICONERROR);
MessageBox(hWnd, "Could not save image file.", "Error", MB_OK | MB_ICONERROR);
}
}
}

View File

@ -15,8 +15,8 @@
#include <celengine/glcontext.h>
#endif
#include <celestia/celestiacore.h>
#include <celestia/imagecapture.h>
#include <celengine/multitexture.h>
#include <celutil/filetype.h>
#include <celutil/util.h>
#include <celmath/mathlib.h>
#include <iostream>
@ -639,30 +639,12 @@ CommandCapture::CommandCapture(std::string _type,
void CommandCapture::process(ExecutionEnvironment& env)
{
#ifndef __APPLE__
const Renderer* r = env.getRenderer();
if (r == nullptr)
return;
// Get the dimensions of the current viewport
array<int, 4> viewport;
r->getViewport(viewport);
if (compareIgnoringCase(type, "jpeg") == 0)
{
CaptureGLBufferToJPEG(filename,
viewport[0], viewport[1],
viewport[2], viewport[3],
r);
}
else if (compareIgnoringCase(type, "png") == 0)
{
CaptureGLBufferToPNG(filename,
viewport[0], viewport[1],
viewport[2], viewport[3],
r);
}
#endif
ContentType _type = Content_Unknown;
if (type == "jpeg" || type == "jpg")
_type = Content_JPEG;
else if (type == "png")
_type = Content_PNG;
env.getCelestiaCore()->saveScreenShot(filename, _type);
}

View File

@ -26,7 +26,6 @@
#include "celx_vector.h"
#include "celx_category.h"
#include <celestia/url.h>
#include <celestia/imagecapture.h>
#include <celestia/celestiacore.h>
#include <celestia/view.h>
#include <celscript/common/scriptmaps.h>
@ -1915,30 +1914,9 @@ static int celestia_takescreenshot(lua_State* l)
string filenamestem;
filenamestem = fmt::sprintf("screenshot-%s%06i", fileid, luastate->screenshotCount);
// Get the dimensions of the current viewport
array<GLint, 4> viewport;
appCore->getRenderer()->getViewport(viewport);
fs::path path = appCore->getConfig()->scriptScreenshotDirectory;
#ifndef __APPLE__
if (strncmp(filetype, "jpg", 3) == 0)
{
fs::path filepath = path / (filenamestem + ".jpg");
success = CaptureGLBufferToJPEG(filepath,
viewport[0], viewport[1],
viewport[2], viewport[3],
appCore->getRenderer());
}
else
{
fs::path filepath = path / (filenamestem + ".png");
success = CaptureGLBufferToPNG(filepath,
viewport[0], viewport[1],
viewport[2], viewport[3],
appCore->getRenderer());
}
#endif
fs::path filepath = path / fmt::sprintf("%s.%s", filenamestem, filetype);
success = appCore->saveScreenShot(filepath);
lua_pushboolean(l, success);
// no matter how long it really took, make it look like 0.1s to timeout check:
@ -2411,7 +2389,7 @@ static int celestia_newcategory(lua_State *l)
static int celestia_findcategory(lua_State *l)
{
CelxLua celx(l);
const char *emsg = "Argument of celestia:fndcategory must be a string.";
const char *name = celx.safeGetString(2, AllErrors, emsg);
if (name == nullptr)