Added screenshot feature (F2 key)
This commit is contained in:
parent
d42d2dc294
commit
3723cf491f
@ -201,12 +201,12 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data,
|
||||
|
||||
spng_set_ihdr(ctx, &ihdr);
|
||||
fmt = SPNG_FMT_PNG;
|
||||
|
||||
ret = spng_encode_image(ctx, data, width * height , fmt, SPNG_ENCODE_FINALIZE);
|
||||
|
||||
ret = spng_encode_image(ctx, data, (size_t)width * (size_t)height * pixsize , fmt, SPNG_ENCODE_FINALIZE);
|
||||
if (ret) {
|
||||
printf("spng_encode_image() error: %s\n", spng_strerror(ret));
|
||||
goto encode_error;
|
||||
fflush(stdout);
|
||||
spng_ctx_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t png_size;
|
||||
@ -218,9 +218,7 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data,
|
||||
else {
|
||||
files::write_bytes(filename, (const char*)png_buf, png_size);
|
||||
}
|
||||
free(png_buf);
|
||||
|
||||
encode_error:
|
||||
fflush(stdout);
|
||||
spng_ctx_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#include "window/Camera.h"
|
||||
#include "window/input.h"
|
||||
#include "graphics/Batch2D.h"
|
||||
#include "graphics/ImageData.h"
|
||||
#include "world/World.h"
|
||||
#include "world/Level.h"
|
||||
#include "voxels/Chunk.h"
|
||||
@ -23,8 +24,10 @@
|
||||
#include "frontend/world_render.h"
|
||||
#include "frontend/hud.h"
|
||||
#include "frontend/gui/GUI.h"
|
||||
#include "util/platform.h"
|
||||
|
||||
#include "coders/json.h"
|
||||
#include "coders/png.h"
|
||||
#include "files/files.h"
|
||||
|
||||
using std::shared_ptr;
|
||||
@ -73,6 +76,14 @@ void Engine::updateHotkeys() {
|
||||
if (Events::jpressed(keycode::O)) {
|
||||
occlusion = !occlusion;
|
||||
}
|
||||
if (Events::jpressed(keycode::F2)) {
|
||||
ImageData* image = Window::takeScreenshot();
|
||||
image->flipY();
|
||||
std::string filename = platform::get_screenshot_file("png");
|
||||
png::write_image(filename, image);
|
||||
delete image;
|
||||
std::cout << "saved screenshot as " << filename << std::endl;
|
||||
}
|
||||
if (Events::jpressed(keycode::F3)) {
|
||||
level->player->debug = !level->player->debug;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "ImageData.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdexcept>
|
||||
|
||||
inline int min(int a, int b) {
|
||||
return (a < b) ? a : b;
|
||||
@ -23,7 +24,52 @@ ImageData::~ImageData() {
|
||||
}
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
void ImageData::flipX() {
|
||||
uint size;
|
||||
switch (format) {
|
||||
case ImageFormat::rgb888:
|
||||
case ImageFormat::rgba8888: {
|
||||
size = (format == ImageFormat::rgba8888) ? 4 : 3;
|
||||
ubyte* pixels = (ubyte*)data;
|
||||
for (uint y = 0; y < height; y++) {
|
||||
for (uint x = 0; x < width/2; x++) {
|
||||
for (uint c = 0; c < size; c++) {
|
||||
ubyte temp = pixels[(y * width + x) * size + c];
|
||||
pixels[(y * width + x) * size + c] = pixels[(y * width + (width - x - 1)) * size + c];
|
||||
pixels[(y * width + (width - x - 1)) * size + c] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw std::runtime_error("format is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
void ImageData::flipY() {
|
||||
uint size;
|
||||
switch (format) {
|
||||
case ImageFormat::rgb888:
|
||||
case ImageFormat::rgba8888: {
|
||||
size = (format == ImageFormat::rgba8888) ? 4 : 3;
|
||||
ubyte* pixels = (ubyte*)data;
|
||||
for (uint y = 0; y < height/2; y++) {
|
||||
for (uint x = 0; x < width; x++) {
|
||||
for (uint c = 0; c < size; c++) {
|
||||
ubyte temp = pixels[(y * width + x) * size + c];
|
||||
pixels[(y * width + x) * size + c] = pixels[((height-y-1) * width + x) * size + c];
|
||||
pixels[((height-y-1) * width + x) * size + c] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw std::runtime_error("format is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
ImageData* add_atlas_margins(ImageData* image, int grid_size) {
|
||||
// RGBA is only supported
|
||||
assert(image->getFormat() == ImageFormat::rgba8888);
|
||||
|
||||
@ -17,6 +17,9 @@ public:
|
||||
ImageData(ImageFormat format, uint width, uint height, void* data);
|
||||
~ImageData();
|
||||
|
||||
void flipX();
|
||||
void flipY();
|
||||
|
||||
void* getData() const {
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ struct DisplaySettings {
|
||||
/* GLFW swap interval value, 0 - unlimited fps, 1 - vsync*/
|
||||
int swapInterval = 1;
|
||||
/* Window title */
|
||||
const char* title = "VoxelEngine-Cpp v0.13";
|
||||
const char* title = "VoxelEngine-Cpp v0.14";
|
||||
};
|
||||
|
||||
struct ChunksSettings {
|
||||
|
||||
@ -1,12 +1,46 @@
|
||||
#include "platform.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <filesystem>
|
||||
#include <iomanip>
|
||||
#include <time.h>
|
||||
|
||||
#include "../typedefs.h"
|
||||
|
||||
#define SETTINGS_FILE "settings.json"
|
||||
#define SCREENSHOTS_FOLDER "screenshots"
|
||||
|
||||
using std::string;
|
||||
|
||||
|
||||
std::string platform::get_settings_file() {
|
||||
string platform::get_settings_file() {
|
||||
return SETTINGS_FILE;
|
||||
}
|
||||
|
||||
string platform::get_screenshot_file(string ext) {
|
||||
std::string folder = SCREENSHOTS_FOLDER;
|
||||
if (!std::filesystem::is_directory(folder)) {
|
||||
std::filesystem::create_directory(folder);
|
||||
}
|
||||
|
||||
auto t = std::time(nullptr);
|
||||
auto tm = *std::localtime(&t);
|
||||
|
||||
const char* format = "%d-%m-%Y_%H-%M-%S";
|
||||
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(&tm, format);
|
||||
string datetimestr = ss.str();
|
||||
|
||||
string filename = folder+"/screenshot-"+datetimestr+"."+ext;
|
||||
uint index = 0;
|
||||
while (std::filesystem::exists(filename)) {
|
||||
filename = folder+"/screenshot-"+datetimestr+"-"+std::to_string(index)+"."+ext;
|
||||
index++;
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
namespace platform {
|
||||
extern void configure_encoding();
|
||||
extern std::string get_settings_file();
|
||||
extern std::string get_screenshot_file(std::string ext);
|
||||
}
|
||||
|
||||
#endif // UTIL_PLATFORM_H_
|
||||
@ -1,6 +1,7 @@
|
||||
#include <iostream>
|
||||
#include "Window.h"
|
||||
#include "Events.h"
|
||||
#include "../graphics/ImageData.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
@ -181,3 +182,9 @@ void Window::swapBuffers(){
|
||||
double Window::time() {
|
||||
return glfwGetTime();
|
||||
}
|
||||
|
||||
ImageData* Window::takeScreenshot() {
|
||||
ubyte* data = new ubyte[width * height * 3];
|
||||
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
return new ImageData(ImageFormat::rgb888, width, height, data);
|
||||
}
|
||||
@ -10,6 +10,7 @@
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
class GLFWwindow;
|
||||
class ImageData;
|
||||
|
||||
class Window {
|
||||
static GLFWwindow* window;
|
||||
@ -33,8 +34,9 @@ public:
|
||||
static void resetScissor();
|
||||
|
||||
static void clear();
|
||||
|
||||
static double time();
|
||||
|
||||
static ImageData* takeScreenshot();
|
||||
};
|
||||
|
||||
#endif /* WINDOW_WINDOW_H_ */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user