Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-08-23 13:47:16 +0000
committerStijn Buys <ingar@osirion.org>2008-08-23 13:47:16 +0000
commit37bfbfbd234cce09b67c1d53e1ef7d91a46e53cc (patch)
tree3ed13293a1825009b6ef776fcca06ec542838953
parent02e9a70009f79064043033abc5e597930aa11079 (diff)
png screenshots
-rw-r--r--src/client/video.cc39
-rw-r--r--src/render/pngfile.cc69
2 files changed, 101 insertions, 7 deletions
diff --git a/src/client/video.cc b/src/client/video.cc
index 2c1fe6b..aed25ae 100644
--- a/src/client/video.cc
+++ b/src/client/video.cc
@@ -7,11 +7,13 @@
#include <fstream>
#include <sstream>
+#include "auxiliary/functions.h"
#include "client/video.h"
#include "client/view.h"
#include "render/camera.h"
#include "render/render.h"
#include "render/tga.h"
+#include "render/pngfile.h"
#include "core/core.h"
#include "filesystem/filesystem.h"
#include "sys/sys.h"
@@ -30,6 +32,8 @@ int height = 0;
int width_prev = 0;
int height_prev = 0;
+int screenshot_number = 0;
+
const int width_default = 1024;
const int height_default = 768;
@@ -39,6 +43,8 @@ core::Cvar *r_width;
core::Cvar *r_height;
core::Cvar *r_fullscreen;
+core::Cvar *screenshotformat;
+
void reset()
{
// setup our viewport.
@@ -65,6 +71,9 @@ bool init()
r_fullscreen = core::Cvar::get("r_fullscreen", "0", core::Cvar::Archive);
r_fullscreen->set_info("[bool] enable or disable fullscreen video");
+ screenshotformat = core::Cvar::get("screenshotformat", "tga", core::Cvar::Archive);
+ screenshotformat->set_info("[string] screenshot format: tga png");
+
int bpp = 0;
int flags = 0;
@@ -183,27 +192,39 @@ void shutdown()
void screenshot()
{
- int number = 0;
bool available = false;
std::string shortname;
std::string filename;
+ const int TYPETGA = 0;
+ const int TYPEPNG = 1;
+ int filetype = TYPETGA;
// make sure the screenshots folder exists
filename.assign(filesystem::writedir());
filename.append("screenshots/");
sys::mkdir(filename);
+ aux::lowercase(screenshotformat->str());
+
+ if (screenshotformat->str().compare("png") == 0) {
+ filetype = TYPEPNG;
+ } else {
+ filetype = TYPETGA;
+ (*screenshotformat) = "tga";
+ }
+
// find the first available screenshotxxx.tga
do {
std::stringstream nstr;
- nstr << number;
+ nstr << screenshot_number;
shortname.assign(nstr.str());
while(shortname.size() < 3)
shortname.insert(0, 1, '0');
shortname.insert(0, "screenshots/osirion");
- shortname.append(".tga");
+ shortname.append(".");
+ shortname.append(screenshotformat->str());
filename.assign(filesystem::writedir());
filename.append(shortname);
@@ -211,10 +232,10 @@ void screenshot()
FILE *handle = fopen(filename.c_str(), "r");
if (handle) {
fclose(handle);
- number++;
} else {
- available = true;
+ available = true;
}
+ screenshot_number++;
} while (!available);
render::Image image((unsigned int)video::width, (unsigned int)video::height, 3);
@@ -222,7 +243,13 @@ void screenshot()
glReadPixels(0, 0, (GLsizei) video::width, (GLsizei) video::height,
GL_RGB, GL_UNSIGNED_BYTE, (void *) image.data());
- render::TGA::save(filename.c_str(), image);
+ image.flip();
+
+ if (filetype == TYPEPNG) {
+ render::PNG::save(filename.c_str(), image);
+ } else if (filetype == TYPETGA) {
+ render::TGA::save(filename.c_str(), image);
+ }
}
diff --git a/src/render/pngfile.cc b/src/render/pngfile.cc
index 14884f0..27cfd8f 100644
--- a/src/render/pngfile.cc
+++ b/src/render/pngfile.cc
@@ -116,7 +116,74 @@ Image *PNG::load(const char *filename)
void PNG::save(const char *filename, Image & image)
{
- con_warn << "PNG::save stub" << std::endl;
+
+ FILE *png_file = fopen(filename, "wb");
+ if (!png_file) {
+ con_warn << "Could not write " << filename << std::endl;
+ return;
+ }
+
+ /* initialize stuff */
+ png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!png_ptr) {
+ fclose(png_file);
+ con_warn << "Error writing " << filename << ": png_create_write_struct failed!" << std::endl;
+ return;
+ }
+
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr) {
+ fclose(png_file);
+ con_warn << "Error writing " << filename << ": png_create_info_struct failed!" << std::endl;
+ return;
+ }
+
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ con_warn << "Error reading " << filename << ": error during init_io!" << std::endl;
+ fclose(png_file);
+ return;
+ }
+
+ png_init_io(png_ptr, png_file);
+
+ /* write header */
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ con_warn << "Error writing " << filename << ": error writing header!" << std::endl;
+ fclose(png_file);
+ return;
+ }
+
+ png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(), 8, PNG_COLOR_TYPE_RGB,
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ png_write_info(png_ptr, info_ptr);
+
+ /* write image data */
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ con_warn << "Error writing " << filename << ": error writing header!" << std::endl;
+ fclose(png_file);
+ return;
+ }
+
+ png_bytep row_pointers[image.height()];
+
+ for (size_t i = 0; i < image.height(); i++)
+ row_pointers[i] = (png_bytep) image[i * image.width() * image.channels()];
+
+ png_write_image(png_ptr, row_pointers);
+
+ /* end write */
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ con_warn << "Error writing " << filename << std::endl;
+ fclose(png_file);
+ return;
+ }
+
+ png_write_end(png_ptr, NULL);
+
+ fclose(png_file);
+
+ con_print << "Wrote " << filename << std::endl;
}
}