Added screenshot feature (F2 key)

This commit is contained in:
MihailRis 2023-11-13 15:01:41 +03:00
parent d42d2dc294
commit 3723cf491f
9 changed files with 113 additions and 11 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -17,6 +17,9 @@ public:
ImageData(ImageFormat format, uint width, uint height, void* data);
~ImageData();
void flipX();
void flipY();
void* getData() const {
return data;
}

View File

@ -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 {

View File

@ -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>

View File

@ -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_

View File

@ -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);
}

View File

@ -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_ */