feat: Added basic 3D visualizer, moved visualizers to separate file

This commit is contained in:
WerWolv
2023-01-20 21:16:28 +01:00
parent a9cebed903
commit 8e759d9b5f
15 changed files with 7107 additions and 265 deletions

View File

@@ -24,6 +24,7 @@ set(LIBIMHEX_SOURCES
source/helpers/magic.cpp
source/helpers/crypto.cpp
source/helpers/net.cpp
source/helpers/opengl.cpp
source/helpers/file.cpp
source/helpers/socket.cpp
source/helpers/patches.cpp

View File

@@ -117,6 +117,8 @@ namespace hex {
/* Pattern Language Function Registry. Allows adding of new functions that may be used inside the pattern language */
namespace PatternLanguage {
using VisualizerFunctionCallback = std::function<void(pl::ptrn::Pattern&, pl::ptrn::Iteratable&, bool, const std::vector<pl::core::Token::Literal> &)>;
namespace impl {
struct FunctionDefinition {
@@ -129,6 +131,13 @@ namespace hex {
bool dangerous;
};
struct Visualizer {
u32 parameterCount;
VisualizerFunctionCallback callback;
};
std::map<std::string, Visualizer> &getVisualizers();
}
void configureRuntime(pl::PatternLanguage &runtime, prv::Provider *provider);
@@ -138,6 +147,8 @@ namespace hex {
void addFunction(const pl::api::Namespace &ns, const std::string &name, pl::api::FunctionParameterCount parameterCount, const pl::api::FunctionCallback &func);
void addDangerousFunction(const pl::api::Namespace &ns, const std::string &name, pl::api::FunctionParameterCount parameterCount, const pl::api::FunctionCallback &func);
void addVisualizer(const std::string &name, const VisualizerFunctionCallback &func, u32 parameterCount);
std::map<std::string, pl::api::PragmaHandler> &getPragmas();
std::vector<impl::FunctionDefinition> &getFunctions();

View File

@@ -0,0 +1,120 @@
#pragma once
#include <hex.hpp>
#include <hex/helpers/concepts.hpp>
#include <span>
#include <string>
#include <imgui_impl_opengl3_loader.h>
namespace hex::gl {
namespace {
template<typename T>
GLuint getType() {
if constexpr (std::is_same_v<T, float>)
return GL_FLOAT;
else if constexpr (std::is_same_v<T, u32>)
return GL_UNSIGNED_INT;
else
static_assert(hex::always_false<T>::value, "Unsupported type");
}
}
class Shader {
public:
Shader(const std::string &vertexSource, const std::string &fragmentSource);
~Shader();
void bind() const;
void unbind() const;
private:
void compile(GLuint shader, const std::string &source);
private:
GLuint m_program;
};
enum class BufferType {
Vertex = GL_ARRAY_BUFFER,
Index = GL_ELEMENT_ARRAY_BUFFER
};
template<typename T>
class Buffer {
public:
Buffer(BufferType type, std::span<T> data);
~Buffer();
void bind() const;
void unbind() const;
void draw() const;
size_t getSize() const;
private:
GLuint m_buffer;
size_t m_size;
GLuint m_type;
};
extern template class Buffer<float>;
extern template class Buffer<u32>;
class VertexArray {
public:
VertexArray();
~VertexArray();
template<typename T>
void addBuffer(const Buffer<T> &buffer) const {
glVertexAttribPointer(0, buffer.getSize() / sizeof(T), getType<T>(), GL_FALSE, 3 * sizeof(T), nullptr);
glEnableVertexAttribArray(0);
}
void bind() const;
void unbind() const;
private:
GLuint m_array;
};
class Texture {
public:
Texture(u32 width, u32 height);
~Texture();
void bind() const;
void unbind() const;
GLuint getTexture() const;
u32 getWidth() const;
u32 getHeight() const;
void release();
private:
GLuint m_texture;
u32 m_width, m_height;
};
class FrameBuffer {
public:
FrameBuffer();
~FrameBuffer();
void bind() const;
void unbind() const;
void attachTexture(const Texture &texture) const;
private:
GLuint m_frameBuffer, m_renderBuffer;
};
}

View File

@@ -36,6 +36,7 @@ namespace ImGui {
Texture() = default;
Texture(const ImU8 *buffer, int size, int width = 0, int height = 0);
explicit Texture(const char *path);
Texture(unsigned int texture, int width, int height);
Texture(const Texture&) = delete;
Texture(Texture&& other) noexcept;

View File

@@ -299,6 +299,18 @@ namespace hex {
});
}
std::map<std::string, impl::Visualizer> &impl::getVisualizers() {
static std::map<std::string, impl::Visualizer> visualizers;
return visualizers;
}
void addVisualizer(const std::string &name, const VisualizerFunctionCallback &function, u32 parameterCount) {
log::debug("Registered new pattern visualizer function: {}", name);
impl::getVisualizers()[name] = impl::Visualizer { parameterCount, function };
}
std::map<std::string, pl::api::PragmaHandler> &getPragmas() {
static std::map<std::string, pl::api::PragmaHandler> pragmas;

View File

@@ -0,0 +1,190 @@
#include <hex/helpers/opengl.hpp>
#include <hex/helpers/utils.hpp>
#include <hex/helpers/logger.hpp>
namespace hex::gl {
Shader::Shader(const std::string &vertexSource, const std::string &fragmentSource) {
auto vertexShader = glCreateShader(GL_VERTEX_SHADER);
this->compile(vertexShader, vertexSource);
auto fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
this->compile(fragmentShader, fragmentSource);
ON_SCOPE_EXIT { glDeleteShader(vertexShader); glDeleteShader(fragmentShader); };
this->m_program = glCreateProgram();
glAttachShader(this->m_program, vertexShader);
glAttachShader(this->m_program, fragmentShader);
glLinkProgram(this->m_program);
int result = false;
glGetProgramiv(this->m_program, GL_LINK_STATUS, &result);
if (!result) {
std::vector<char> log(512);
glGetShaderInfoLog(this->m_program, log.size(), nullptr, log.data());
log::error("Failed to link shader: {}", log.data());
}
}
Shader::~Shader() {
glDeleteProgram(this->m_program);
}
void Shader::bind() const {
glUseProgram(this->m_program);
}
void Shader::unbind() const {
glUseProgram(0);
}
void Shader::compile(GLuint shader, const std::string &source) {
auto sourcePtr = source.c_str();
glShaderSource(shader, 1, &sourcePtr, nullptr);
glCompileShader(shader);
int result = false;
glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
if (!result) {
std::vector<char> log(512);
glGetShaderInfoLog(shader, log.size(), nullptr, log.data());
log::error("Failed to compile shader: {}", log.data());
}
}
template<typename T>
Buffer<T>::Buffer(BufferType type, std::span<T> data) : m_size(data.size()), m_type(GLuint(type)) {
glGenBuffers(1, &this->m_buffer);
glBindBuffer(this->m_type, this->m_buffer);
glBufferData(this->m_type, data.size_bytes(), data.data(), GL_STATIC_DRAW);
}
template<typename T>
Buffer<T>::~Buffer() {
glDeleteBuffers(1, &this->m_buffer);
}
template<typename T>
void Buffer<T>::bind() const {
glBindBuffer(this->m_type, this->m_buffer);
}
template<typename T>
void Buffer<T>::unbind() const {
glBindBuffer(this->m_type, 0);
}
template<typename T>
size_t Buffer<T>::getSize() const {
return this->m_size;
}
template<typename T>
void Buffer<T>::draw() const {
glDrawElements(GL_TRIANGLES, this->m_size, getType<T>(), nullptr);
}
template class Buffer<float>;
template class Buffer<u32>;
VertexArray::VertexArray() {
glGenVertexArrays(1, &this->m_array);
}
VertexArray::~VertexArray() {
glDeleteVertexArrays(1, &this->m_array);
}
void VertexArray::bind() const {
glBindVertexArray(this->m_array);
}
void VertexArray::unbind() const {
glBindVertexArray(0);
}
Texture::Texture(u32 width, u32 height) : m_texture(0), m_width(width), m_height(height) {
glGenTextures(1, &this->m_texture);
glBindTexture(GL_TEXTURE_2D, this->m_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
}
Texture::~Texture() {
if (this->m_texture != 0)
glDeleteTextures(1, &this->m_texture);
}
void Texture::bind() const {
glBindTexture(GL_TEXTURE_2D, this->m_texture);
}
void Texture::unbind() const {
glBindTexture(GL_TEXTURE_2D, 0);
}
GLuint Texture::getTexture() const {
return this->m_texture;
}
u32 Texture::getWidth() const {
return this->m_width;
}
u32 Texture::getHeight() const {
return this->m_height;
}
void Texture::release() {
this->m_texture = 0;
}
FrameBuffer::FrameBuffer() {
glGenFramebuffers(1, &this->m_frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, this->m_frameBuffer);
glGenRenderbuffers(1, &this->m_renderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, this->m_renderBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 1280, 720);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, this->m_renderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
FrameBuffer::~FrameBuffer() {
glDeleteFramebuffers(1, &this->m_frameBuffer);
glDeleteRenderbuffers(1, &this->m_renderBuffer);
}
void FrameBuffer::bind() const {
glBindFramebuffer(GL_FRAMEBUFFER, this->m_frameBuffer);
}
void FrameBuffer::unbind() const {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void FrameBuffer::attachTexture(const Texture &texture) const {
glBindFramebuffer(GL_FRAMEBUFFER, this->m_frameBuffer);
texture.bind();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.getTexture(), 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
}

View File

@@ -69,7 +69,12 @@ namespace ImGui {
this->m_textureId = reinterpret_cast<ImTextureID>(static_cast<intptr_t>(texture));
}
Texture::Texture(unsigned int texture, int width, int height) : m_textureId(reinterpret_cast<ImTextureID>(static_cast<intptr_t>(texture))), m_width(width), m_height(height) {
}
Texture::Texture(Texture&& other) noexcept {
glDeleteTextures(1, reinterpret_cast<GLuint*>(&this->m_textureId));
this->m_textureId = other.m_textureId;
this->m_width = other.m_width;
this->m_height = other.m_height;
@@ -78,6 +83,7 @@ namespace ImGui {
}
Texture& Texture::operator=(Texture&& other) noexcept {
glDeleteTextures(1, reinterpret_cast<GLuint*>(&this->m_textureId));
this->m_textureId = other.m_textureId;
this->m_width = other.m_width;
this->m_height = other.m_height;