Added image capture capability.

ver1_5_1
Chris Laurel 2001-11-22 19:07:42 +00:00
parent 20f2036ac5
commit 5cd22a6714
3 changed files with 291 additions and 20 deletions

View File

@ -94,7 +94,7 @@ bin_PROGRAMS = celestia
@ENABLE_GTK_TRUE@FRONTENDSOURCE = gtkmain.cpp
@ENABLE_GTK_FALSE@FRONTENDSOURCE = glutmain.cpp
COMMONSOURCES = 3dsmesh.cpp 3dsmodel.cpp 3dsread.cpp asterism.cpp astro.cpp bigfix.cpp body.cpp celestiacore.cpp cmdparser.cpp color.cpp command.cpp configfile.cpp constellation.cpp customorbit.cpp debug.cpp destination.cpp dispmap.cpp execution.cpp favorites.cpp filetype.cpp frustum.cpp galaxy.cpp glext.cpp lodspheremesh.cpp meshmanager.cpp observer.cpp octree.cpp orbit.cpp overlay.cpp parser.cpp perlin.cpp regcombine.cpp render.cpp selection.cpp simulation.cpp solarsys.cpp spheremesh.cpp star.cpp stardb.cpp starname.cpp stellarclass.cpp texmanager.cpp texture.cpp texturefont.cpp tokenizer.cpp univcoord.cpp unixtimer.cpp util.cpp vertexlist.cpp vertexprog.cpp
COMMONSOURCES = 3dsmesh.cpp 3dsmodel.cpp 3dsread.cpp asterism.cpp astro.cpp bigfix.cpp body.cpp celestiacore.cpp cmdparser.cpp color.cpp command.cpp configfile.cpp constellation.cpp customorbit.cpp debug.cpp destination.cpp dispmap.cpp execution.cpp favorites.cpp filetype.cpp frustum.cpp galaxy.cpp glext.cpp imagecapture.cpp lodspheremesh.cpp meshmanager.cpp observer.cpp octree.cpp orbit.cpp overlay.cpp parser.cpp perlin.cpp regcombine.cpp render.cpp selection.cpp simulation.cpp solarsys.cpp spheremesh.cpp star.cpp stardb.cpp starname.cpp stellarclass.cpp texmanager.cpp texture.cpp texturefont.cpp tokenizer.cpp univcoord.cpp unixtimer.cpp util.cpp vertexlist.cpp vertexprog.cpp
celestia_SOURCES = $(COMMONSOURCES) $(FRONTENDSOURCE)
@ -120,9 +120,9 @@ X_PRE_LIBS = @X_PRE_LIBS@
@ENABLE_GTK_TRUE@cmdparser.o color.o command.o configfile.o \
@ENABLE_GTK_TRUE@constellation.o customorbit.o debug.o destination.o \
@ENABLE_GTK_TRUE@dispmap.o execution.o favorites.o filetype.o frustum.o \
@ENABLE_GTK_TRUE@galaxy.o glext.o lodspheremesh.o meshmanager.o \
@ENABLE_GTK_TRUE@observer.o octree.o orbit.o overlay.o parser.o \
@ENABLE_GTK_TRUE@perlin.o regcombine.o render.o selection.o \
@ENABLE_GTK_TRUE@galaxy.o glext.o imagecapture.o lodspheremesh.o \
@ENABLE_GTK_TRUE@meshmanager.o observer.o octree.o orbit.o overlay.o \
@ENABLE_GTK_TRUE@parser.o perlin.o regcombine.o render.o selection.o \
@ENABLE_GTK_TRUE@simulation.o solarsys.o spheremesh.o star.o stardb.o \
@ENABLE_GTK_TRUE@starname.o stellarclass.o texmanager.o texture.o \
@ENABLE_GTK_TRUE@texturefont.o tokenizer.o univcoord.o unixtimer.o \
@ -132,13 +132,14 @@ X_PRE_LIBS = @X_PRE_LIBS@
@ENABLE_GTK_FALSE@cmdparser.o color.o command.o configfile.o \
@ENABLE_GTK_FALSE@constellation.o customorbit.o debug.o destination.o \
@ENABLE_GTK_FALSE@dispmap.o execution.o favorites.o filetype.o \
@ENABLE_GTK_FALSE@frustum.o galaxy.o glext.o lodspheremesh.o \
@ENABLE_GTK_FALSE@meshmanager.o observer.o octree.o orbit.o overlay.o \
@ENABLE_GTK_FALSE@parser.o perlin.o regcombine.o render.o selection.o \
@ENABLE_GTK_FALSE@simulation.o solarsys.o spheremesh.o star.o stardb.o \
@ENABLE_GTK_FALSE@starname.o stellarclass.o texmanager.o texture.o \
@ENABLE_GTK_FALSE@texturefont.o tokenizer.o univcoord.o unixtimer.o \
@ENABLE_GTK_FALSE@util.o vertexlist.o vertexprog.o glutmain.o
@ENABLE_GTK_FALSE@frustum.o galaxy.o glext.o imagecapture.o \
@ENABLE_GTK_FALSE@lodspheremesh.o meshmanager.o observer.o octree.o \
@ENABLE_GTK_FALSE@orbit.o overlay.o parser.o perlin.o regcombine.o \
@ENABLE_GTK_FALSE@render.o selection.o simulation.o solarsys.o \
@ENABLE_GTK_FALSE@spheremesh.o star.o stardb.o starname.o \
@ENABLE_GTK_FALSE@stellarclass.o texmanager.o texture.o texturefont.o \
@ENABLE_GTK_FALSE@tokenizer.o univcoord.o unixtimer.o util.o \
@ENABLE_GTK_FALSE@vertexlist.o vertexprog.o glutmain.o
celestia_LDADD = $(LDADD)
celestia_DEPENDENCIES =
celestia_LDFLAGS =
@ -161,13 +162,13 @@ DEP_FILES = .deps/3dsmesh.P .deps/3dsmodel.P .deps/3dsread.P \
.deps/configfile.P .deps/constellation.P .deps/customorbit.P \
.deps/debug.P .deps/destination.P .deps/dispmap.P .deps/execution.P \
.deps/favorites.P .deps/filetype.P .deps/frustum.P .deps/galaxy.P \
.deps/glext.P .deps/glutmain.P .deps/gtkmain.P .deps/lodspheremesh.P \
.deps/meshmanager.P .deps/observer.P .deps/octree.P .deps/orbit.P \
.deps/overlay.P .deps/parser.P .deps/perlin.P .deps/regcombine.P \
.deps/render.P .deps/selection.P .deps/simulation.P .deps/solarsys.P \
.deps/spheremesh.P .deps/star.P .deps/stardb.P .deps/starname.P \
.deps/stellarclass.P .deps/texmanager.P .deps/texture.P \
.deps/texturefont.P .deps/tokenizer.P .deps/univcoord.P \
.deps/glext.P .deps/glutmain.P .deps/gtkmain.P .deps/imagecapture.P \
.deps/lodspheremesh.P .deps/meshmanager.P .deps/observer.P \
.deps/octree.P .deps/orbit.P .deps/overlay.P .deps/parser.P \
.deps/perlin.P .deps/regcombine.P .deps/render.P .deps/selection.P \
.deps/simulation.P .deps/solarsys.P .deps/spheremesh.P .deps/star.P \
.deps/stardb.P .deps/starname.P .deps/stellarclass.P .deps/texmanager.P \
.deps/texture.P .deps/texturefont.P .deps/tokenizer.P .deps/univcoord.P \
.deps/unixtimer.P .deps/util.P .deps/vertexlist.P .deps/vertexprog.P
SOURCES = $(celestia_SOURCES)
OBJECTS = $(celestia_OBJECTS)

View File

@ -19,6 +19,7 @@
#include <unistd.h>
#include "gl.h"
#include <GL/glut.h>
#include "../config.h"
#include "celestia.h"
#include "vecmath.h"
#include "quaternion.h"

View File

@ -31,6 +31,8 @@
#include "timer.h"
#include "mathlib.h"
#include "astro.h"
#include "filetype.h"
#include "imagecapture.h"
#include "celestiacore.h"
@ -226,6 +228,74 @@ static void menuAbout()
}
static GtkWidget* fileSelector = NULL;
static gchar* captureFilename = NULL;
void storeCaptureFilename(GtkFileSelection* selector, gpointer)
{
captureFilename = gtk_file_selection_get_filename(GTK_FILE_SELECTION(fileSelector));
if (captureFilename == NULL)
return;
string filename(captureFilename);
// Get the dimensions of the current viewport
int viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
bool success = false;
ContentType type = DetermineFileType(filename);
if (type == Content_JPEG)
{
success = CaptureGLBufferToJPEG(filename,
viewport[0], viewport[1],
viewport[2], viewport[3]);
}
else if (type == Content_PNG)
{
success = CaptureGLBufferToPNG(string(filename),
viewport[0], viewport[1],
viewport[2], viewport[3]);
}
else
{
DPRINTF("Unknown file type for screen capture.\n");
}
if (!success)
{
GtkWidget* errBox = gnome_message_box_new("Error writing captured image.",
GNOME_MESSAGE_BOX_ERROR,
GNOME_STOCK_BUTTON_OK,
NULL);
gtk_widget_show(errBox);
}
}
static void menuCaptureImage()
{
captureFilename = NULL;
fileSelector = gtk_file_selection_new("Select capture file.");
gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fileSelector)->ok_button),
"clicked",
GTK_SIGNAL_FUNC(storeCaptureFilename),
NULL);
gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(fileSelector)->ok_button),
"clicked",
GTK_SIGNAL_FUNC(gtk_widget_destroy),
GTK_OBJECT(fileSelector));
gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(fileSelector)->cancel_button),
"clicked",
GTK_SIGNAL_FUNC(gtk_widget_destroy),
GTK_OBJECT(fileSelector));
gtk_widget_show(fileSelector);
}
static void menuSelectObject()
{
GtkWidget* dialog = gnome_dialog_new("Find Object",
@ -273,6 +343,201 @@ static void menuSelectObject()
gnome_dialog_close(GNOME_DIALOG(dialog));
}
class GotoObjectDialog
{
public:
GotoObjectDialog();
~GotoObjectDialog();
bool init();
GtkWidget* dialog;
GtkWidget* nameEntry;
GtkWidget* latEntry;
GtkWidget* longEntry;
GtkWidget* distEntry;
};
static bool GetEntryFloat(GtkWidget* w, float& f)
{
GtkEntry* entry = GTK_ENTRY(w);
if (entry == NULL)
return false;
gchar* text = gtk_entry_get_text(entry);
if (text == NULL)
return false;
return sscanf(text, " %f", &f) == 1;
}
static gint GotoObject(GtkWidget* w, gpointer data)
{
GotoObjectDialog* gotoObjectDlg = reinterpret_cast<GotoObjectDialog*>(data);
if (gotoObjectDlg == NULL)
return FALSE;
Simulation* sim = appCore->getSimulation();
gchar* objectName = gtk_entry_get_text(GTK_ENTRY(gotoObjectDlg->nameEntry));
if (objectName != NULL)
{
Selection sel = sim->findObjectFromPath(objectName);
if (!sel.empty())
{
sim->setSelection(sel);
sim->follow();
float distance = (float) (sel.radius() * 5.0f);
if (GetEntryFloat(gotoObjectDlg->distEntry, distance))
{
distance += (float) sel.radius();
}
distance = astro::kilometersToLightYears(distance);
float longitude, latitude;
if (GetEntryFloat(gotoObjectDlg->latEntry, latitude) &&
GetEntryFloat(gotoObjectDlg->longEntry, longitude))
{
sim->gotoSelectionLongLat(5.0,
distance,
degToRad(longitude),
degToRad(latitude),
Vec3f(0, 1, 0));
}
else
{
sim->gotoSelection(5.0,
distance,
Vec3f(0, 1, 0),
astro::ObserverLocal);
}
}
}
return TRUE;
}
GotoObjectDialog::GotoObjectDialog() :
dialog(NULL),
nameEntry(NULL),
latEntry(NULL),
longEntry(NULL),
distEntry(NULL)
{
}
GotoObjectDialog::~GotoObjectDialog()
{
}
bool GotoObjectDialog::init()
{
dialog = gnome_dialog_new("Goto Object",
GNOME_STOCK_BUTTON_CANCEL,
NULL);
nameEntry = gtk_entry_new();
latEntry = gtk_entry_new();
longEntry = gtk_entry_new();
distEntry = gtk_entry_new();
if (dialog == NULL ||
nameEntry == NULL ||
latEntry == NULL ||
longEntry == NULL ||
distEntry == NULL)
{
// Potential memory leak here . . .
return false;
}
GtkWidget* hbox = NULL;
GtkWidget* label = NULL;
// Object name label and entry
hbox = gtk_hbox_new(FALSE, 6);
if (hbox == NULL)
return false;
label = gtk_label_new("Object name:");
if (label == NULL)
return false;
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), nameEntry, FALSE, TRUE, 0);
gtk_widget_show(label);
gtk_widget_show(nameEntry);
gtk_box_pack_start(GTK_BOX (GNOME_DIALOG (dialog)->vbox),
hbox, FALSE, TRUE, 0);
gtk_widget_show(hbox);
// Latitude and longitude
hbox = gtk_hbox_new(FALSE, 6);
if (hbox == NULL)
return false;
label = gtk_label_new("Latitude:");
if (label == NULL)
return false;
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), latEntry, FALSE, TRUE, 0);
gtk_widget_show(label);
gtk_widget_show(latEntry);
label = gtk_label_new("Longitude:");
if (label == NULL)
return false;
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), longEntry, FALSE, TRUE, 0);
gtk_widget_show(label);
gtk_widget_show(longEntry);
gtk_box_pack_start(GTK_BOX (GNOME_DIALOG (dialog)->vbox),
hbox, FALSE, TRUE, 0);
gtk_widget_show(hbox);
// Distance
hbox = gtk_hbox_new(FALSE, 6);
if (hbox == NULL)
return false;
label = gtk_label_new("Distance:");
if (label == NULL)
return false;
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), distEntry, FALSE, TRUE, 0);
gtk_widget_show(label);
gtk_widget_show(distEntry);
gtk_box_pack_start(GTK_BOX (GNOME_DIALOG (dialog)->vbox),
hbox, FALSE, TRUE, 0);
gtk_widget_show(hbox);
// Goto button
GtkWidget* gotoButton = gtk_button_new_with_label(" Go To ");
if (gotoButton == NULL)
return false;
gtk_widget_show(gotoButton);
gtk_box_pack_start(GTK_BOX (GNOME_DIALOG (dialog)->vbox),
gotoButton, FALSE, TRUE, 0);
gtk_signal_connect(GTK_OBJECT(gotoButton),
"pressed",
GTK_SIGNAL_FUNC(GotoObject),
this);
gnome_dialog_run_and_close(GNOME_DIALOG(dialog));
return true;
}
static void menuGotoObject()
{
GotoObjectDialog* gotoObjectDlg = new GotoObjectDialog();
gotoObjectDlg->init();
}
static Destination* selectedDest = NULL;
static gint TourGuideSelect(GtkWidget* w, gpointer data)
{
@ -442,11 +707,13 @@ static void menuTourGuide()
static GtkItemFactoryEntry menuItems[] =
{
{ "/_File", NULL, NULL, 0, "<Branch>" },
{ "/File/Capture Image...", "F10", menuCaptureImage, 0, NULL },
{ "/File/Quit", "<control>Q", gtk_main_quit, 0, NULL },
{ "/_Navigation", NULL, NULL, 0, "<Branch>" },
{ "/Navigation/Select Sol", "H", menuSelectSol, 0, NULL },
{ "/Navigation/Tour Guide", NULL, menuTourGuide, 0, NULL },
{ "/Navigation/Select Object...", NULL, menuSelectObject, 0, NULL },
{ "/Navigation/Goto Object...", NULL, menuGotoObject, 0, NULL },
{ "/Navigation/sep1", NULL, NULL, 0, "<Separator>" },
{ "/Navigation/Center Selection", "C", menuCenter, 0, NULL },
{ "/Navigation/Goto Selection", "G", menuGoto, 0, NULL },
@ -692,6 +959,10 @@ static bool handleSpecialKey(int key, bool down)
case GDK_F6:
k = CelestiaCore::Key_F6;
break;
case GDK_F10:
if (down)
menuCaptureImage();
break;
case GDK_KP_0:
k = CelestiaCore::Key_NumPad0;
break;
@ -749,7 +1020,6 @@ static bool handleSpecialKey(int key, bool down)
gint glarea_key_press(GtkWidget* widget, GdkEventKey* event)
{
cout << "down\n";
gtk_signal_emit_stop_by_name(GTK_OBJECT(widget),"key_press_event");
switch (event->keyval)
{
@ -779,7 +1049,6 @@ gint glarea_key_press(GtkWidget* widget, GdkEventKey* event)
gint glarea_key_release(GtkWidget* widget, GdkEventKey* event)
{
cout << "up\n";
gtk_signal_emit_stop_by_name(GTK_OBJECT(widget),"key_release_event");
return handleSpecialKey(event->keyval, false);
}