Improves renderer and adds shader support
Adds shader class to core and modifies the renderer to use it, while also adding profiling macros and fixing resize issues. The changes ensure the render target is resized only when the requested size is different from the current size and also clears the screen to a dark gray color.
This commit is contained in:
parent
4194764d7a
commit
f7e0882597
@ -99,6 +99,7 @@ add_library(Core STATIC
|
||||
src/core/systems/Asset.h
|
||||
src/core/systems/assets/Texture2D.cpp
|
||||
src/core/systems/assets/Texture2D.h
|
||||
src/core/systems/Shader.cpp
|
||||
)
|
||||
|
||||
target_include_directories(Core PUBLIC src/core)
|
||||
|
@ -3,41 +3,59 @@
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace OX {
|
||||
namespace OX
|
||||
{
|
||||
// ——— Camera2D implementation (unchanged) ———
|
||||
Camera2D::Camera2D(float left, float right, float bottom, float top)
|
||||
: _left(left), _right(right), _bottom(bottom), _top(top)
|
||||
{
|
||||
Recalculate();
|
||||
}
|
||||
|
||||
// ——— Camera2D implementation (unchanged) ———
|
||||
Camera2D::Camera2D(float left, float right, float bottom, float top)
|
||||
: _left(left), _right(right), _bottom(bottom), _top(top)
|
||||
{ Recalculate(); }
|
||||
void Camera2D::SetPosition(const glm::vec2 &pos)
|
||||
{
|
||||
_position = pos;
|
||||
Recalculate();
|
||||
}
|
||||
|
||||
void Camera2D::SetPosition(const glm::vec2& pos) { _position = pos; Recalculate(); }
|
||||
void Camera2D::SetZoom(float z) { _zoom = z; Recalculate(); }
|
||||
void Camera2D::SetZoom(float z)
|
||||
{
|
||||
_zoom = z;
|
||||
Recalculate();
|
||||
}
|
||||
|
||||
void Camera2D::Recalculate() {
|
||||
float halfW = (_right - _left) * 0.5f / _zoom;
|
||||
float halfH = (_top - _bottom) * 0.5f / _zoom;
|
||||
glm::mat4 proj = glm::ortho(-halfW, halfW, -halfH, halfH, -1.0f, 1.0f);
|
||||
glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(-_position, 0.0f));
|
||||
_viewProj = proj * view;
|
||||
}
|
||||
void Camera2D::Recalculate()
|
||||
{
|
||||
float halfW = (_right - _left) * 0.5f / _zoom;
|
||||
float halfH = (_top - _bottom) * 0.5f / _zoom;
|
||||
glm::mat4 proj = glm::ortho(-halfW, halfW, -halfH, halfH, -1.0f, 1.0f);
|
||||
glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(-_position, 0.0f));
|
||||
_viewProj = proj * view;
|
||||
}
|
||||
|
||||
const glm::mat4& Camera2D::GetViewProjection() const { return _viewProj; }
|
||||
const glm::mat4 &Camera2D::GetViewProjection() const { return _viewProj; }
|
||||
|
||||
// ——— Renderer ———
|
||||
Renderer::~Renderer() {
|
||||
if (m_quadVAO) glDeleteVertexArrays(1, &m_quadVAO);
|
||||
if (m_quadVBO) glDeleteBuffers(1, &m_quadVBO);
|
||||
if (m_fbo) glDeleteFramebuffers(1, &m_fbo);
|
||||
if (m_colorTex) glDeleteTextures(1, &m_colorTex);
|
||||
if (m_depthRBO) glDeleteRenderbuffers(1, &m_depthRBO);
|
||||
}
|
||||
// ——— Renderer ———
|
||||
Renderer::~Renderer()
|
||||
{
|
||||
if (m_quadVAO)
|
||||
glDeleteVertexArrays(1, &m_quadVAO);
|
||||
if (m_quadVBO)
|
||||
glDeleteBuffers(1, &m_quadVBO);
|
||||
if (m_fbo)
|
||||
glDeleteFramebuffers(1, &m_fbo);
|
||||
if (m_colorTex) glDeleteTextures(1, &m_colorTex);
|
||||
if (m_depthRBO)
|
||||
glDeleteRenderbuffers(1, &m_depthRBO);
|
||||
}
|
||||
|
||||
void Renderer::Init(int targetWidth, int targetHeight) {
|
||||
// create offscreen FBO & attachments
|
||||
CreateFramebuffer(targetWidth, targetHeight);
|
||||
void Renderer::Init(int targetWidth, int targetHeight)
|
||||
{
|
||||
// create offscreen FBO & attachments
|
||||
CreateFramebuffer(targetWidth, targetHeight);
|
||||
|
||||
// compile our sprite shader
|
||||
static const char* vs = R"GLSL(
|
||||
// compile our sprite shader
|
||||
static const char *vs = R"GLSL(
|
||||
#version 330 core
|
||||
layout(location = 0) in vec2 aPos;
|
||||
layout(location = 1) in vec2 aUV;
|
||||
@ -51,7 +69,7 @@ void Renderer::Init(int targetWidth, int targetHeight) {
|
||||
gl_Position = u_ViewProj * vec4(pos,0,1);
|
||||
}
|
||||
)GLSL";
|
||||
static const char* fs = R"GLSL(
|
||||
static const char *fs = R"GLSL(
|
||||
#version 330 core
|
||||
in vec2 vUV;
|
||||
out vec4 FragColor;
|
||||
@ -61,102 +79,116 @@ void Renderer::Init(int targetWidth, int targetHeight) {
|
||||
}
|
||||
)GLSL";
|
||||
|
||||
m_shader.LoadFromSource(vs, fs);
|
||||
m_shader.LoadFromSource(vs, fs);
|
||||
|
||||
CreateQuad();
|
||||
}
|
||||
CreateQuad();
|
||||
}
|
||||
|
||||
void Renderer::CreateFramebuffer(int width, int height) {
|
||||
// cleanup old
|
||||
if (m_fbo) glDeleteFramebuffers(1, &m_fbo);
|
||||
if (m_colorTex) glDeleteTextures(1, &m_colorTex);
|
||||
if (m_depthRBO) glDeleteRenderbuffers(1, &m_depthRBO);
|
||||
void Renderer::CreateFramebuffer(int width, int height)
|
||||
{
|
||||
size = {width, height};
|
||||
|
||||
// color texture
|
||||
glGenTextures(1, &m_colorTex);
|
||||
glBindTexture(GL_TEXTURE_2D, m_colorTex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 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);
|
||||
// cleanup old
|
||||
if (m_fbo)
|
||||
glDeleteFramebuffers(1, &m_fbo);
|
||||
if (m_colorTex) glDeleteTextures(1, &m_colorTex);
|
||||
if (m_depthRBO)
|
||||
glDeleteRenderbuffers(1, &m_depthRBO);
|
||||
|
||||
// depth renderbuffer
|
||||
glGenRenderbuffers(1, &m_depthRBO);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_depthRBO);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
|
||||
// color texture
|
||||
glGenTextures(1, &m_colorTex);
|
||||
glBindTexture(GL_TEXTURE_2D, m_colorTex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 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);
|
||||
|
||||
// framebuffer
|
||||
glGenFramebuffers(1, &m_fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_2D, m_colorTex, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
|
||||
GL_RENDERBUFFER, m_depthRBO);
|
||||
// depth renderbuffer
|
||||
glGenRenderbuffers(1, &m_depthRBO);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_depthRBO);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
std::cerr << "[Renderer] Framebuffer not complete!\n";
|
||||
// framebuffer
|
||||
glGenFramebuffers(1, &m_fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_2D, m_colorTex, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
|
||||
GL_RENDERBUFFER, m_depthRBO);
|
||||
|
||||
// unbind
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
std::cerr << "[Renderer] Framebuffer not complete!\n";
|
||||
|
||||
void Renderer::ResizeTarget(int width, int height) {
|
||||
CreateFramebuffer(width, height);
|
||||
}
|
||||
// unbind
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void Renderer::BeginScene(const Camera2D& camera) {
|
||||
// bind offscreen
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
// clear
|
||||
glViewport(0, 0, /*width*/0, /*height*/0); // you may want to track size
|
||||
glClearColor(0,0,0,1);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
void Renderer::ResizeTarget(int width, int height)
|
||||
{
|
||||
OX_PROFILE_FUNCTION();
|
||||
if (size == Vec2i{width, height}) {
|
||||
return;
|
||||
}
|
||||
CreateFramebuffer(width, height);
|
||||
}
|
||||
|
||||
// setup shader & camera
|
||||
m_viewProj = camera.GetViewProjection();
|
||||
m_shader.Use();
|
||||
m_shader.SetMat4("u_ViewProj", m_viewProj);
|
||||
m_shader.SetInt("u_Texture", 0);
|
||||
}
|
||||
void Renderer::BeginScene(const Camera2D &camera)
|
||||
{
|
||||
OX_PROFILE_FUNCTION();
|
||||
// bind offscreen
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
// clear
|
||||
glViewport(0, 0, size.x, size.y);
|
||||
glClearColor(0.1f, 0.1f, 0.1f, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
void Renderer::DrawSprite(const Sprite& s) {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, s.textureID);
|
||||
// setup shader & camera
|
||||
m_viewProj = camera.GetViewProjection();
|
||||
m_shader.Use();
|
||||
m_shader.SetMat4("u_ViewProj", m_viewProj);
|
||||
m_shader.SetInt("u_Texture", 0);
|
||||
}
|
||||
|
||||
m_shader.SetVec2("u_Offset", s.position);
|
||||
m_shader.SetVec2("u_Scale", s.size);
|
||||
void Renderer::DrawSprite(const Sprite &s)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, s.textureID);
|
||||
|
||||
glBindVertexArray(m_quadVAO);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
|
||||
}
|
||||
m_shader.SetVec2("u_Offset", s.position);
|
||||
m_shader.SetVec2("u_Scale", s.size);
|
||||
|
||||
void Renderer::EndScene() {
|
||||
// unbind FBO → subsequent draws go to default framebuffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
glBindVertexArray(m_quadVAO);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
|
||||
}
|
||||
|
||||
void Renderer::CreateQuad() {
|
||||
float verts[] = {
|
||||
-0.5f, -0.5f, 0,0,
|
||||
0.5f, -0.5f, 1,0,
|
||||
0.5f, 0.5f, 1,1,
|
||||
-0.5f, 0.5f, 0,1
|
||||
};
|
||||
unsigned int idx[] = {0,1,2, 2,3,0};
|
||||
void Renderer::EndScene()
|
||||
{
|
||||
// unbind FBO → subsequent draws go to default framebuffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
glGenVertexArrays(1, &m_quadVAO);
|
||||
glGenBuffers(1, &m_quadVBO);
|
||||
void Renderer::CreateQuad()
|
||||
{
|
||||
float verts[] = {
|
||||
-0.5f, -0.5f, 0, 0,
|
||||
0.5f, -0.5f, 1, 0,
|
||||
0.5f, 0.5f, 1, 1,
|
||||
-0.5f, 0.5f, 0, 1
|
||||
};
|
||||
unsigned int idx[] = {0, 1, 2, 2, 3, 0};
|
||||
|
||||
glBindVertexArray(m_quadVAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_quadVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
|
||||
glGenVertexArrays(1, &m_quadVAO);
|
||||
glGenBuffers(1, &m_quadVBO);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,4*sizeof(float),(void*)0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,4*sizeof(float),(void*)(2*sizeof(float)));
|
||||
glBindVertexArray(m_quadVAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_quadVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2,GL_FLOAT,GL_FALSE, 4 * sizeof(float), (void *) 0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2,GL_FLOAT,GL_FALSE, 4 * sizeof(float), (void *) (2 * sizeof(float)));
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
} // namespace OX
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "glm/glm.hpp"
|
||||
#include "systems/Shader.h"
|
||||
#include <gl/glew.h>
|
||||
|
||||
#include "types/vec2.h"
|
||||
namespace OX {
|
||||
|
||||
struct Sprite {
|
||||
@ -54,6 +54,7 @@ namespace OX {
|
||||
|
||||
private:
|
||||
// offscreen
|
||||
Vec2i size;
|
||||
GLuint m_fbo = 0;
|
||||
GLuint m_colorTex = 0;
|
||||
GLuint m_depthRBO = 0;
|
||||
|
@ -24,7 +24,7 @@ namespace OX
|
||||
|
||||
void Use() const;
|
||||
|
||||
void CheckHotReload(); // 🔥
|
||||
void CheckHotReload();
|
||||
|
||||
GLuint GetID() const { return m_programID; }
|
||||
|
||||
|
@ -146,7 +146,7 @@ namespace OX
|
||||
|
||||
// --- Render ImGui onto FBO 0 ---
|
||||
{
|
||||
OX_PROFILE_LABEL("VSYNC Wait");
|
||||
|
||||
|
||||
ImGui::EndFrame();
|
||||
ImGui::Render();
|
||||
|
@ -1,6 +1,7 @@
|
||||
// File: src/FileBrowser.cpp
|
||||
#include "FileBrowser.h"
|
||||
#include <filesystem>
|
||||
#include "systems/Profiler.h"
|
||||
|
||||
namespace OX
|
||||
{
|
||||
@ -13,6 +14,7 @@ namespace OX
|
||||
|
||||
void FileBrowser::Draw(const char *title)
|
||||
{
|
||||
OX_PROFILE_FUNCTION();
|
||||
ImGui::Begin(title);
|
||||
|
||||
// --- toolbar now contains back button, inline path, filter & view toggle all on one row ---
|
||||
@ -86,6 +88,7 @@ namespace OX
|
||||
// ——— Polished grid view ———
|
||||
void FileBrowser::DrawGridView(const std::shared_ptr<ResourceTreeNode> &node)
|
||||
{
|
||||
OX_PROFILE_FUNCTION();
|
||||
const float cellW = _cfg.thumbnailSize + _cfg.padding * 2;
|
||||
ImVec2 avail = ImGui::GetContentRegionAvail();
|
||||
int cols = std::max(1, int(avail.x / cellW));
|
||||
@ -93,13 +96,11 @@ namespace OX
|
||||
ImGui::BeginChild("GridRegion", ImVec2(0, 0), false, ImGuiWindowFlags_AlwaysUseWindowPadding);
|
||||
ImGui::Columns(cols, nullptr, false);
|
||||
|
||||
std::vector<std::shared_ptr<ResourceTreeNode> > children;
|
||||
|
||||
{
|
||||
std::vector<std::shared_ptr<ResourceTreeNode> > children; {
|
||||
std::lock_guard<std::mutex> lock(AssetManager::s_TreeMutex); // assume you add this mutex
|
||||
children = node->children;
|
||||
}
|
||||
for (auto& c : children) {
|
||||
for (auto &c: children) {
|
||||
if (!c) return;
|
||||
|
||||
if (!_filter.empty() && !PassesFilter(c->name)) continue;
|
||||
|
Loading…
Reference in New Issue
Block a user