Browse Source

Event+Asset+Keycodes: Add keybind for taking screenshots

master
Riyyi 4 months ago
parent
commit
03e8210165
  1. 5
      src/inferno/application.cpp
  2. 47
      src/inferno/asset/texture.cpp
  3. 3
      src/inferno/asset/texture.h
  4. 31
      src/inferno/event/keyevent.h
  5. 19
      src/inferno/keycodes.cpp
  6. 4
      src/inferno/keycodes.h
  7. 6
      src/inferno/window.cpp

5
src/inferno/application.cpp

@ -274,6 +274,11 @@ bool Application::onKeyPress(KeyPressEvent& e)
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;
}

47
src/inferno/asset/texture.cpp

@ -13,6 +13,8 @@
#include "ruc/meta/assert.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb/stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb/stb_image_write.h"
#include "inferno/asset/texture.h"
@ -23,6 +25,51 @@ Texture::~Texture()
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)
{
init(width, height,

3
src/inferno/asset/texture.h

@ -22,6 +22,9 @@ class Texture : public Asset {
public:
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, uint32_t internalFormat, uint32_t dataFormat, uint32_t dataType);

31
src/inferno/event/keyevent.h

@ -14,24 +14,27 @@ namespace Inferno {
class KeyEvent : public Event {
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)
protected:
KeyEvent(int key)
KeyEvent(int key, int mods)
: m_key(key)
, m_mods(mods)
{
}
private:
int m_key;
int m_key { 0 };
int m_mods { 0 };
};
class KeyPressEvent : public KeyEvent {
class KeyPressEvent final : public KeyEvent {
public:
KeyPressEvent(int key)
: KeyEvent(key)
KeyPressEvent(int key, int mods)
: KeyEvent(key, mods)
{
}
@ -45,10 +48,10 @@ public:
EVENT_CLASS_TYPE(KeyPress)
};
class KeyReleaseEvent : public KeyEvent {
class KeyReleaseEvent final : public KeyEvent {
public:
KeyReleaseEvent(int key)
: KeyEvent(key)
KeyReleaseEvent(int key, int mods)
: KeyEvent(key, mods)
{
}
@ -59,13 +62,13 @@ public:
return ss.str();
}
EVENT_CLASS_TYPE(KeyPress)
EVENT_CLASS_TYPE(KeyRelease)
};
class KeyRepeatEvent : public KeyEvent {
class KeyRepeatEvent final : public KeyEvent {
public:
KeyRepeatEvent(int key)
: KeyEvent(key)
KeyRepeatEvent(int key, int mods)
: KeyEvent(key, mods)
{
}
@ -76,7 +79,7 @@ public:
return ss.str();
}
EVENT_CLASS_TYPE(KeyPress)
EVENT_CLASS_TYPE(KeyRepeat)
};
} // namespace Inferno

19
src/inferno/keycodes.cpp

@ -139,14 +139,33 @@ static std::unordered_map<std::string_view, int> keys({
{ 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)
{
VERIFY(keys.find(name) != keys.end(), "could not find key code: {}", 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)
{
auto it = std::find_if(keys.begin(), keys.end(), [key](const auto& keybind) {

4
src/inferno/keycodes.h

@ -13,6 +13,8 @@
namespace Inferno {
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

6
src/inferno/window.cpp

@ -122,17 +122,17 @@ void Window::initialize()
switch (action) {
case GLFW_PRESS: {
KeyPressEvent event(key);
KeyPressEvent event(key, mods);
w.m_eventCallback(event);
break;
}
case GLFW_RELEASE: {
KeyReleaseEvent event(key);
KeyReleaseEvent event(key, mods);
w.m_eventCallback(event);
break;
}
case GLFW_REPEAT: {
KeyRepeatEvent event(key);
KeyRepeatEvent event(key, mods);
w.m_eventCallback(event);
break;
}

Loading…
Cancel
Save