Event+Asset+Keycodes: Add keybind for taking screenshots

This commit is contained in:
Riyyi
2024-08-17 21:05:43 +02:00
parent dcf2a85208
commit 03e8210165
7 changed files with 97 additions and 18 deletions
+5
View File
@@ -274,6 +274,11 @@ bool Application::onKeyPress(KeyPressEvent& e)
m_window->setShouldClose(true); m_window->setShouldClose(true);
} }
if (e.getKey() == keyCode("GLFW_KEY_F12")) {
ruc::info("Taking screenshot..");
Texture::saveScreenshotPNG("screenshot.png", m_window->getWidth(), m_window->getHeight());
}
return true; return true;
} }
+47
View File
@@ -13,6 +13,8 @@
#include "ruc/meta/assert.h" #include "ruc/meta/assert.h"
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "stb/stb_image.h" #include "stb/stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb/stb_image_write.h"
#include "inferno/asset/texture.h" #include "inferno/asset/texture.h"
@@ -23,6 +25,51 @@ Texture::~Texture()
glDeleteTextures(1, &m_id); glDeleteTextures(1, &m_id);
} }
// -----------------------------------------
void Texture::savePNG(std::string_view path, std::shared_ptr<Texture> texture)
{
texture->bind();
// Allocate memory
uint32_t dataFormat = texture->m_dataFormat == GL_RGBA ? 4 : 3;
size_t dataSize = texture->m_width * texture->m_height * dataFormat;
std::vector<unsigned char> data(dataSize);
// Read texture data from the GPU
glGetTexImage(GL_TEXTURE_2D, 0, texture->m_dataFormat, texture->m_dataType, data.data());
// Write image to a file
stbi_flip_vertically_on_write(1);
stbi_write_png(
path.data(),
texture->m_width,
texture->m_height,
dataFormat,
data.data(),
texture->m_width * dataFormat);
texture->unbind();
}
void Texture::saveScreenshotPNG(std::string_view path, uint32_t width, uint32_t height)
{
// Allocate memory
size_t dataSize = width * height * 4;
std::vector<unsigned char> data(dataSize);
// Set the pack alignment to 1 (to avoid row alignment issues)
glPixelStorei(GL_PACK_ALIGNMENT, 1);
// Read the pixels from the default framebuffer
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
stbi_flip_vertically_on_write(1);
stbi_write_png(path.data(), width, height, 4, data.data(), width * 4);
}
// -----------------------------------------
void Texture::init(uint32_t width, uint32_t height, uint8_t channels) void Texture::init(uint32_t width, uint32_t height, uint8_t channels)
{ {
init(width, height, init(width, height,
+3
View File
@@ -22,6 +22,9 @@ class Texture : public Asset {
public: public:
virtual ~Texture(); virtual ~Texture();
static void savePNG(std::string_view path, std::shared_ptr<Texture> texture);
static void saveScreenshotPNG(std::string_view path, uint32_t width, uint32_t height);
void init(uint32_t width, uint32_t height, uint8_t channels); void init(uint32_t width, uint32_t height, uint8_t channels);
void init(uint32_t width, uint32_t height, uint32_t internalFormat, uint32_t dataFormat, uint32_t dataType); void init(uint32_t width, uint32_t height, uint32_t internalFormat, uint32_t dataFormat, uint32_t dataType);
+17 -14
View File
@@ -14,24 +14,27 @@ namespace Inferno {
class KeyEvent : public Event { class KeyEvent : public Event {
public: public:
inline int getKey() const { return m_key; } int getKey() const { return m_key; }
int getMods() const { return m_mods; }
EVENT_CLASS_CATEGORY(InputEventCategory | KeyEventCategory) EVENT_CLASS_CATEGORY(InputEventCategory | KeyEventCategory)
protected: protected:
KeyEvent(int key) KeyEvent(int key, int mods)
: m_key(key) : m_key(key)
, m_mods(mods)
{ {
} }
private: private:
int m_key; int m_key { 0 };
int m_mods { 0 };
}; };
class KeyPressEvent : public KeyEvent { class KeyPressEvent final : public KeyEvent {
public: public:
KeyPressEvent(int key) KeyPressEvent(int key, int mods)
: KeyEvent(key) : KeyEvent(key, mods)
{ {
} }
@@ -45,10 +48,10 @@ public:
EVENT_CLASS_TYPE(KeyPress) EVENT_CLASS_TYPE(KeyPress)
}; };
class KeyReleaseEvent : public KeyEvent { class KeyReleaseEvent final : public KeyEvent {
public: public:
KeyReleaseEvent(int key) KeyReleaseEvent(int key, int mods)
: KeyEvent(key) : KeyEvent(key, mods)
{ {
} }
@@ -59,13 +62,13 @@ public:
return ss.str(); return ss.str();
} }
EVENT_CLASS_TYPE(KeyPress) EVENT_CLASS_TYPE(KeyRelease)
}; };
class KeyRepeatEvent : public KeyEvent { class KeyRepeatEvent final : public KeyEvent {
public: public:
KeyRepeatEvent(int key) KeyRepeatEvent(int key, int mods)
: KeyEvent(key) : KeyEvent(key, mods)
{ {
} }
@@ -76,7 +79,7 @@ public:
return ss.str(); return ss.str();
} }
EVENT_CLASS_TYPE(KeyPress) EVENT_CLASS_TYPE(KeyRepeat)
}; };
} // namespace Inferno } // namespace Inferno
+19
View File
@@ -139,14 +139,33 @@ static std::unordered_map<std::string_view, int> keys({
{ MAP_KEY(GLFW_KEY_MENU) }, { MAP_KEY(GLFW_KEY_MENU) },
}); });
static std::unordered_map<std::string_view, int> modifiers({
{ MAP_KEY(GLFW_MOD_SHIFT) },
{ MAP_KEY(GLFW_MOD_CONTROL) },
{ MAP_KEY(GLFW_MOD_ALT) },
{ MAP_KEY(GLFW_MOD_SUPER) },
{ MAP_KEY(GLFW_MOD_CAPS_LOCK) }, // State, not really a modifier
{ MAP_KEY(GLFW_MOD_NUM_LOCK) }, // State, not really a modifier
});
// ----------------------------------------- // -----------------------------------------
// Example usage:
// event.getKey() == keyCode("GLFW_KEY_ESCAPE")
int keyCode(std::string_view name) int keyCode(std::string_view name)
{ {
VERIFY(keys.find(name) != keys.end(), "could not find key code: {}", name); VERIFY(keys.find(name) != keys.end(), "could not find key code: {}", name);
return keys.at(name); return keys.at(name);
} }
// Example usage:
// event.getMods() & keyMod("GLFW_MOD_SHIFT")
int keyMod(std::string_view name)
{
VERIFY(modifiers.find(name) != modifiers.end(), "could not find key modifier: {}", name);
return modifiers.at(name);
}
std::string_view keyName(int key) std::string_view keyName(int key)
{ {
auto it = std::find_if(keys.begin(), keys.end(), [key](const auto& keybind) { auto it = std::find_if(keys.begin(), keys.end(), [key](const auto& keybind) {
+3 -1
View File
@@ -13,6 +13,8 @@
namespace Inferno { namespace Inferno {
int keyCode(std::string_view name); int keyCode(std::string_view name);
std::string_view keyName(int); int keyMod(std::string_view name);
std::string_view keyName(int key);
} // namespace Inferno } // namespace Inferno
+3 -3
View File
@@ -122,17 +122,17 @@ void Window::initialize()
switch (action) { switch (action) {
case GLFW_PRESS: { case GLFW_PRESS: {
KeyPressEvent event(key); KeyPressEvent event(key, mods);
w.m_eventCallback(event); w.m_eventCallback(event);
break; break;
} }
case GLFW_RELEASE: { case GLFW_RELEASE: {
KeyReleaseEvent event(key); KeyReleaseEvent event(key, mods);
w.m_eventCallback(event); w.m_eventCallback(event);
break; break;
} }
case GLFW_REPEAT: { case GLFW_REPEAT: {
KeyRepeatEvent event(key); KeyRepeatEvent event(key, mods);
w.m_eventCallback(event); w.m_eventCallback(event);
break; break;
} }