added more debug stats, and updated renderer and created asset manager v1
This commit is contained in:
parent
d81fa19bc4
commit
ceb1f81f1b
1
Makefile
1
Makefile
@ -12,6 +12,7 @@ BUILD_DIR := build
|
||||
# Include Directories
|
||||
GLFW_INCLUDE := C:/libraries/glfw/include
|
||||
INCLUDE_DIRS := $(SRC_DIR) $(VENDOR_DIRS) $(GLFW_INCLUDE) vendor/stb/include
|
||||
INCLUDE_DIRS := $(SRC_DIR) $(VENDOR_DIRS) $(GLFW_INCLUDE) vendor/gcml
|
||||
INCLUDES := $(addprefix -I, $(INCLUDE_DIRS))
|
||||
|
||||
# Update compiler flags with include paths
|
||||
|
@ -1,5 +1,11 @@
|
||||
// src/Engine.cpp
|
||||
|
||||
|
||||
|
||||
// Settings
|
||||
|
||||
#define VSync 0
|
||||
|
||||
#include "Engine.h"
|
||||
#include <cstdio>
|
||||
#include <chrono>
|
||||
@ -15,8 +21,15 @@
|
||||
#include "Windows/PerformanceWindow.h"
|
||||
#include "Windows/LoggerWindow.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AssetManager g_AssetManager;
|
||||
|
||||
bool MyEngine::Init(int width, int height, const std::string& title)
|
||||
{
|
||||
DEBUG_PRINT("[START] Engine Init");
|
||||
// ------------------------------------------
|
||||
// 1) Initialize GLFW
|
||||
// ------------------------------------------
|
||||
@ -40,7 +53,7 @@ bool MyEngine::Init(int width, int height, const std::string& title)
|
||||
return false;
|
||||
}
|
||||
glfwMakeContextCurrent(m_Window);
|
||||
glfwSwapInterval(1); // vsync
|
||||
glfwSwapInterval(VSync); // vsync
|
||||
|
||||
// ------------------------------------------
|
||||
// 2) Initialize GLEW
|
||||
@ -81,11 +94,15 @@ bool MyEngine::Init(int width, int height, const std::string& title)
|
||||
|
||||
m_Running = true;
|
||||
m_LastTime = glfwGetTime();
|
||||
DEBUG_PRINT("[OK] Engine Init ");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MyEngine::Run()
|
||||
{
|
||||
DEBUG_PRINT("[START] Engine Run ");
|
||||
|
||||
while (!glfwWindowShouldClose(m_Window) && m_Running)
|
||||
{
|
||||
// Poll
|
||||
@ -112,15 +129,23 @@ void MyEngine::Run()
|
||||
// Show our windows
|
||||
m_RenderWindow->Show(); // The spinning triangle as ImGui::Image
|
||||
m_PerformanceWindow->Show(m_Fps, m_Ms); // FPS & ms
|
||||
m_LoggerWindow->Show(); // Logs
|
||||
m_LoggerWindow->Show(); // Logs
|
||||
|
||||
// After rendering
|
||||
m_PerformanceWindow->UpdatePerformanceStats(-1, -1);
|
||||
|
||||
|
||||
// End frame
|
||||
EndFrame();
|
||||
}
|
||||
DEBUG_PRINT("[OK] Engine Run ");
|
||||
|
||||
}
|
||||
|
||||
void MyEngine::Cleanup()
|
||||
{
|
||||
DEBUG_PRINT("[START] Engine Cleanup ");
|
||||
|
||||
// ImGui cleanup
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
@ -135,6 +160,8 @@ void MyEngine::Cleanup()
|
||||
glfwTerminate();
|
||||
|
||||
m_Running = false;
|
||||
DEBUG_PRINT("[OK] Engine Cleanup ");
|
||||
|
||||
}
|
||||
|
||||
void MyEngine::BeginFrame()
|
||||
|
@ -6,6 +6,10 @@
|
||||
#include "Windows/RenderWindow.h"
|
||||
#include "Windows/PerformanceWindow.h"
|
||||
#include "Windows/LoggerWindow.h"
|
||||
#include "Engine/AssetManager.h"
|
||||
|
||||
//#define DEBUG
|
||||
#include "gcml.h"
|
||||
|
||||
// Forward declaration to avoid including GLFW in the header if you prefer
|
||||
struct GLFWwindow;
|
||||
@ -14,6 +18,8 @@ struct GLFWwindow;
|
||||
class MyEngine
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
bool Init(int width, int height, const std::string& title);
|
||||
void Run();
|
||||
void Cleanup();
|
||||
@ -25,6 +31,8 @@ private:
|
||||
void ShowDockSpace();
|
||||
|
||||
private:
|
||||
|
||||
|
||||
GLFWwindow* m_Window = nullptr;
|
||||
bool m_Running = false;
|
||||
|
||||
|
119
src/Engine/AssetManager.cpp
Normal file
119
src/Engine/AssetManager.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
#include "AssetManager.h"
|
||||
#include <iostream>
|
||||
#include <GL/glew.h> // or <GL/glew.h>, whichever you use
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb/stb_image.h"
|
||||
|
||||
void* AssetManager::loadAsset(AssetType type, const std::string& path)
|
||||
{
|
||||
// 1) Generate a unique key for this type+path
|
||||
std::string key = generateKey(type, path);
|
||||
|
||||
// 2) Check if this asset is already loaded/cached
|
||||
auto it = m_AssetMap.find(key);
|
||||
if (it != m_AssetMap.end())
|
||||
{
|
||||
// Already loaded, return existing data
|
||||
return it->second.data;
|
||||
}
|
||||
|
||||
// 3) Not loaded yet, so load from disk
|
||||
void* assetData = loadAssetFromDisk(type, path);
|
||||
if (!assetData)
|
||||
{
|
||||
std::cerr << "[AssetManager] Failed to load asset: " << path << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 4) Cache the result in m_AssetMap
|
||||
GenericAsset newAsset;
|
||||
newAsset.data = assetData;
|
||||
m_AssetMap[key] = newAsset;
|
||||
|
||||
// 5) Return the new asset pointer
|
||||
return assetData;
|
||||
}
|
||||
|
||||
std::string AssetManager::generateKey(AssetType type, const std::string& path)
|
||||
{
|
||||
// Combine the numeric type and path into a single string key
|
||||
return std::to_string(static_cast<int>(type)) + ":" + path;
|
||||
}
|
||||
|
||||
void* AssetManager::loadAssetFromDisk(AssetType type, const std::string& path)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case AssetType::TEXTURE:
|
||||
{
|
||||
// ----------------------------------------------------------
|
||||
// REAL CODE: load an image file (PNG, JPG, etc.) with stb_image
|
||||
// and upload it as an OpenGL texture.
|
||||
// ----------------------------------------------------------
|
||||
std::cout << "[AssetManager] Loading TEXTURE from " << path << std::endl;
|
||||
|
||||
// 1) Load pixels using stb_image
|
||||
int width, height, channels;
|
||||
unsigned char* data = stbi_load(path.c_str(), &width, &height, &channels, 0);
|
||||
if (!data)
|
||||
{
|
||||
std::cerr << "[AssetManager] stb_image failed to load: " << path << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 2) Determine the pixel format
|
||||
GLenum format = GL_RGBA; // default
|
||||
if (channels == 1)
|
||||
format = GL_RED;
|
||||
else if (channels == 3)
|
||||
format = GL_RGB;
|
||||
// if channels == 4, already RGBA
|
||||
|
||||
// 3) Generate and bind a texture
|
||||
GLuint textureID = 0;
|
||||
glGenTextures(1, &textureID);
|
||||
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||
|
||||
// 4) Upload the data to OpenGL
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format,
|
||||
GL_UNSIGNED_BYTE, data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
// 5) Set texture parameters (filtering, wrapping, etc.)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
// 6) Unbind and free the stb_image data
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
stbi_image_free(data);
|
||||
|
||||
// Return the texture ID, but cast it to `void*`
|
||||
// so it fits our `GenericAsset.data` usage.
|
||||
return reinterpret_cast<void*>(static_cast<uintptr_t>(textureID));
|
||||
}
|
||||
|
||||
case AssetType::SHADER:
|
||||
{
|
||||
std::cout << "[AssetManager] Loading SHADER from " << path << std::endl;
|
||||
// Stub: in real code, read/compile .vert/.frag, return program ID
|
||||
return (void*)0x87654321;
|
||||
}
|
||||
|
||||
case AssetType::SOUND:
|
||||
{
|
||||
std::cout << "[AssetManager] Loading SOUND from " << path << std::endl;
|
||||
// Stub: load .wav or .ogg file, return pointer to sound data
|
||||
return (void*)0xAAAA8888;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
std::cerr << "[AssetManager] Unknown asset type!\n";
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
54
src/Engine/AssetManager.h
Normal file
54
src/Engine/AssetManager.h
Normal file
@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// 1. Define an enum for various asset types
|
||||
// --------------------------------------------------------------------------
|
||||
enum class AssetType
|
||||
{
|
||||
TEXTURE,
|
||||
SHADER,
|
||||
SOUND,
|
||||
// Add more as needed
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// 2. A placeholder "GenericAsset" struct
|
||||
//
|
||||
// In a real system, you might have a base class (e.g., class Asset)
|
||||
// with derived classes, or store typed data in union/variant.
|
||||
// --------------------------------------------------------------------------
|
||||
struct GenericAsset
|
||||
{
|
||||
void* data = nullptr; // Points to the actual loaded asset data
|
||||
// In a real engine, you'd store more metadata here.
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// 3. The AssetManager class
|
||||
// --------------------------------------------------------------------------
|
||||
class AssetManager
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
AssetManager() = default;
|
||||
~AssetManager() = default;
|
||||
|
||||
// loadAsset() returns a pointer to the loaded asset data.
|
||||
// In a real engine, you might return a typed pointer or a handle.
|
||||
void* loadAsset(AssetType type, const std::string& path);
|
||||
|
||||
private:
|
||||
// Map from "type+path" -> GenericAsset
|
||||
std::unordered_map<std::string, GenericAsset> m_AssetMap;
|
||||
|
||||
// Generate a unique key for each asset based on type + path
|
||||
std::string generateKey(AssetType type, const std::string& path);
|
||||
|
||||
// Actually load asset data from disk, specialized by AssetType
|
||||
void* loadAssetFromDisk(AssetType type, const std::string& path);
|
||||
};
|
@ -1,14 +1,82 @@
|
||||
// src/Windows/PerformanceWindow.cpp
|
||||
|
||||
#include "PerformanceWindow.h"
|
||||
#include "imgui.h"
|
||||
#include <algorithm> // for std::move, etc.
|
||||
|
||||
// Initialize static members
|
||||
int PerformanceWindow::m_OpenGLCallCount = 0;
|
||||
int PerformanceWindow::m_TriangleCount = 0;
|
||||
|
||||
// We'll store up to 60 data points for each stat.
|
||||
static float s_FpsHistory[60] = {0.0f};
|
||||
static float s_MsHistory[60] = {0.0f};
|
||||
static float s_CallsHistory[60] = {0.0f};
|
||||
static float s_TriangleHistory[60] = {0.0f};
|
||||
|
||||
// This function shifts the old values left and appends a new value at the end.
|
||||
static void PushValueToHistory(float* historyArray, int historySize, float newValue)
|
||||
{
|
||||
for (int i = 0; i < historySize - 1; i++)
|
||||
historyArray[i] = historyArray[i + 1];
|
||||
historyArray[historySize - 1] = newValue;
|
||||
}
|
||||
|
||||
// We'll track when we last pushed data to our history.
|
||||
static double s_LastPushTime = 0.0;
|
||||
|
||||
// Update counters from the outside
|
||||
void PerformanceWindow::UpdatePerformanceStats(int newCallCount, int newTriangleCount)
|
||||
{
|
||||
m_OpenGLCallCount = newCallCount;
|
||||
m_TriangleCount = newTriangleCount;
|
||||
}
|
||||
|
||||
void PerformanceWindow::Show(float fps, float ms)
|
||||
{
|
||||
// Get current time from ImGui's internal clock
|
||||
double currentTime = ImGui::GetTime();
|
||||
// If at least 1ms (0.001s) has passed, push new data
|
||||
if ((currentTime - s_LastPushTime) >= 0.05)
|
||||
{
|
||||
s_LastPushTime = currentTime;
|
||||
|
||||
// Push new values into our history arrays
|
||||
PushValueToHistory(s_FpsHistory, 60, fps);
|
||||
PushValueToHistory(s_MsHistory, 60, ms);
|
||||
PushValueToHistory(s_CallsHistory, 60, (float)m_OpenGLCallCount);
|
||||
PushValueToHistory(s_TriangleHistory, 60, (float)m_TriangleCount);
|
||||
}
|
||||
|
||||
// Optional style adjustments
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
|
||||
ImGui::Begin("Performance");
|
||||
ImGui::Text("FPS: %.1f", fps);
|
||||
ImGui::Text("ms/frame: %.3f ms", ms);
|
||||
|
||||
// Colored header
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.2f, 1.0f), "Performance Stats");
|
||||
ImGui::Separator();
|
||||
|
||||
// Show current FPS/ms
|
||||
ImGui::TextColored(ImVec4(0.4f, 1.0f, 0.4f, 1.0f), "FPS: %.1f", fps);
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(ImVec4(0.4f, 1.0f, 0.8f, 1.0f), "| ms: %.3f", ms);
|
||||
|
||||
// Graphs for FPS + MS
|
||||
ImGui::PlotLines("FPS (60 frames)", s_FpsHistory, IM_ARRAYSIZE(s_FpsHistory),
|
||||
0, nullptr, 0.0f, 1000.0f, ImVec2(0, 60));
|
||||
ImGui::PlotHistogram("ms/frame", s_MsHistory, IM_ARRAYSIZE(s_MsHistory),
|
||||
0, nullptr, 0.0f, 25.0f, ImVec2(0, 60));
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
// Show OpenGL calls + Triangles
|
||||
ImGui::Text("OpenGL Calls: %d", m_OpenGLCallCount);
|
||||
ImGui::PlotLines("GL Calls (60 frames)", s_CallsHistory, IM_ARRAYSIZE(s_CallsHistory),
|
||||
0, nullptr, 0.0f, 300.0f, ImVec2(0, 50));
|
||||
|
||||
ImGui::Text("Triangles: %d", m_TriangleCount);
|
||||
ImGui::PlotHistogram("Triangles (60 frames)", s_TriangleHistory, IM_ARRAYSIZE(s_TriangleHistory),
|
||||
0, nullptr, 0.0f, 5000.0f, ImVec2(0, 50));
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Text("You can display more stats here (CPU/GPU usage, etc.)");
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
@ -5,5 +5,16 @@
|
||||
class PerformanceWindow
|
||||
{
|
||||
public:
|
||||
// Displays the performance window in ImGui.
|
||||
// fps = frames per second
|
||||
// ms = milliseconds per frame
|
||||
void Show(float fps, float ms);
|
||||
|
||||
// Updates the counters for OpenGL calls and triangle count.
|
||||
void UpdatePerformanceStats(int newCallCount, int newTriangleCount);
|
||||
|
||||
private:
|
||||
// These are static so they're shared across all instances
|
||||
static int m_OpenGLCallCount;
|
||||
static int m_TriangleCount;
|
||||
};
|
||||
|
@ -1,61 +1,85 @@
|
||||
#include "RenderWindow.h"
|
||||
#include <GL/glew.h>
|
||||
#include <glm/gtc/matrix_transform.hpp> // for perspective, translate, rotate
|
||||
#include <glm/gtc/type_ptr.hpp> // for value_ptr
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include "imgui.h"
|
||||
|
||||
// A simple data structure for a colored cube
|
||||
// position (x,y,z), color(r,g,b)
|
||||
static float g_CubeVertices[] = {
|
||||
// x, y, z, r, g, b
|
||||
// Front face
|
||||
-1.f, -1.f, 1.f, 1.f, 0.f, 0.f, // bottom-left
|
||||
1.f, -1.f, 1.f, 1.f, 0.f, 0.f, // bottom-right
|
||||
1.f, 1.f, 1.f, 1.f, 0.f, 0.f, // top-right
|
||||
-1.f, 1.f, 1.f, 1.f, 0.f, 0.f, // top-left
|
||||
// Include your AssetManager header
|
||||
|
||||
// Back face
|
||||
-1.f, -1.f, -1.f, 0.f, 1.f, 0.f,
|
||||
1.f, -1.f, -1.f, 0.f, 1.f, 0.f,
|
||||
1.f, 1.f, -1.f, 0.f, 1.f, 0.f,
|
||||
-1.f, 1.f, -1.f, 0.f, 1.f, 0.f,
|
||||
// Assume we have an extern or global asset manager declared somewhere
|
||||
// e.g. in "Engine.cpp": AssetManager g_AssetManager;
|
||||
// and in "AssetManager.h": extern AssetManager g_AssetManager;
|
||||
extern AssetManager g_AssetManager;
|
||||
|
||||
// --------------------------------------------------
|
||||
// Cube vertex data and indices (unchanged)
|
||||
// --------------------------------------------------
|
||||
static float g_CubeVertices[] =
|
||||
{
|
||||
// FRONT (z=+1)
|
||||
-1.f, -1.f, 1.f, 0.f, 0.f,
|
||||
1.f, -1.f, 1.f, 1.f, 0.f,
|
||||
1.f, 1.f, 1.f, 1.f, 1.f,
|
||||
-1.f, 1.f, 1.f, 0.f, 1.f,
|
||||
|
||||
// BACK (z=-1)
|
||||
-1.f, -1.f, -1.f, 1.f, 0.f,
|
||||
1.f, -1.f, -1.f, 0.f, 0.f,
|
||||
1.f, 1.f, -1.f, 0.f, 1.f,
|
||||
-1.f, 1.f, -1.f, 1.f, 1.f,
|
||||
|
||||
// LEFT (x=-1)
|
||||
-1.f, -1.f, -1.f, 0.f, 0.f,
|
||||
-1.f, -1.f, 1.f, 1.f, 0.f,
|
||||
-1.f, 1.f, 1.f, 1.f, 1.f,
|
||||
-1.f, 1.f, -1.f, 0.f, 1.f,
|
||||
|
||||
// RIGHT (x=+1)
|
||||
1.f, -1.f, -1.f, 1.f, 0.f,
|
||||
1.f, -1.f, 1.f, 0.f, 0.f,
|
||||
1.f, 1.f, 1.f, 0.f, 1.f,
|
||||
1.f, 1.f, -1.f, 1.f, 1.f,
|
||||
|
||||
// TOP (y=+1)
|
||||
-1.f, 1.f, -1.f, 0.f, 0.f,
|
||||
1.f, 1.f, -1.f, 1.f, 0.f,
|
||||
1.f, 1.f, 1.f, 1.f, 1.f,
|
||||
-1.f, 1.f, 1.f, 0.f, 1.f,
|
||||
|
||||
// BOTTOM (y=-1)
|
||||
-1.f, -1.f, -1.f, 1.f, 0.f,
|
||||
1.f, -1.f, -1.f, 0.f, 0.f,
|
||||
1.f, -1.f, 1.f, 0.f, 1.f,
|
||||
-1.f, -1.f, 1.f, 1.f, 1.f,
|
||||
};
|
||||
|
||||
static unsigned int g_CubeIndices[] = {
|
||||
// Front face
|
||||
0, 1, 2,
|
||||
2, 3, 0,
|
||||
|
||||
// Back face
|
||||
5, 4, 7,
|
||||
7, 6, 5,
|
||||
|
||||
// Left face
|
||||
4, 0, 3,
|
||||
3, 7, 4,
|
||||
|
||||
// Right face
|
||||
1, 5, 6,
|
||||
6, 2, 1,
|
||||
|
||||
// Top face
|
||||
3, 2, 6,
|
||||
6, 7, 3,
|
||||
|
||||
// Bottom face
|
||||
4, 5, 1,
|
||||
1, 0, 4
|
||||
static unsigned int g_CubeIndices[] =
|
||||
{
|
||||
// Front
|
||||
0,1,2, 2,3,0,
|
||||
// Back
|
||||
4,5,6, 6,7,4,
|
||||
// Left
|
||||
8,9,10, 10,11,8,
|
||||
// Right
|
||||
12,13,14, 14,15,12,
|
||||
// Top
|
||||
16,17,18, 18,19,16,
|
||||
// Bottom
|
||||
20,21,22, 22,23,20
|
||||
};
|
||||
|
||||
// --------------------------------------------------
|
||||
// Show() - ImGui window to display the FBO
|
||||
// --------------------------------------------------
|
||||
void RenderWindow::Show()
|
||||
{
|
||||
ImGui::Begin("OpenGL Output");
|
||||
|
||||
ImVec2 size = ImGui::GetContentRegionAvail();
|
||||
int w = (int)size.x;
|
||||
int h = (int)size.y;
|
||||
int w = static_cast<int>(size.x);
|
||||
int h = static_cast<int>(size.y);
|
||||
|
||||
// Lazy init, so we only do it once
|
||||
if (!m_Initialized)
|
||||
{
|
||||
InitGLResources();
|
||||
@ -64,7 +88,6 @@ void RenderWindow::Show()
|
||||
|
||||
if (w > 0 && h > 0)
|
||||
{
|
||||
// Re-create FBO if size changed
|
||||
if (w != m_LastWidth || h != m_LastHeight)
|
||||
{
|
||||
m_FBO.Create(w, h);
|
||||
@ -72,10 +95,7 @@ void RenderWindow::Show()
|
||||
m_LastHeight = h;
|
||||
}
|
||||
|
||||
// Render our scene to the FBO
|
||||
RenderSceneToFBO();
|
||||
|
||||
// Display the FBO texture in ImGui
|
||||
ImGui::Image(m_FBO.GetTextureID(), size, ImVec2(0,0), ImVec2(1,1));
|
||||
}
|
||||
else
|
||||
@ -86,88 +106,104 @@ void RenderWindow::Show()
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// InitGLResources() - Setup VAO/VBO/EBO and load texture
|
||||
// --------------------------------------------------
|
||||
void RenderWindow::InitGLResources()
|
||||
{
|
||||
// 1) Load and compile our unlit shader
|
||||
// Adjust paths if needed. Ex: "shaders/UnlitMaterial.vert"
|
||||
// 1) Load & compile our unlit texture shader (with UV support)
|
||||
if (!m_Shader.Load("shaders/UnlitMaterial.vert", "shaders/UnlitMaterial.frag"))
|
||||
{
|
||||
// Fail gracefully or throw
|
||||
fprintf(stderr, "[RenderWindow] Failed to load UnlitMaterial shader.\n");
|
||||
fprintf(stderr, "[RenderWindow] Failed to load unlit material shader.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// 2) Create VAO
|
||||
// 2) Create a VAO for the cube
|
||||
glGenVertexArrays(1, &m_VAO);
|
||||
glBindVertexArray(m_VAO);
|
||||
|
||||
// 3) Create VBO
|
||||
// 3) Create a VBO
|
||||
glGenBuffers(1, &m_VBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(g_CubeVertices), g_CubeVertices, GL_STATIC_DRAW);
|
||||
|
||||
// 4) Create EBO
|
||||
// 4) Create an EBO
|
||||
glGenBuffers(1, &m_EBO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(g_CubeIndices), g_CubeIndices, GL_STATIC_DRAW);
|
||||
|
||||
// 5) Setup vertex attribs:
|
||||
// layout(location = 0) => aPos (3 floats)
|
||||
// layout(location = 1) => aColor (3 floats)
|
||||
// Stride: 6 floats total
|
||||
// Positions start at offset 0
|
||||
// Color starts at offset 3 * sizeof(float)
|
||||
|
||||
// Position
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
|
||||
// 5) Setup vertex attribs
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// Color
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float),
|
||||
(void*)(3 * sizeof(float)));
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,
|
||||
5 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
// Unbind VAO (optional, but good practice)
|
||||
glBindVertexArray(0);
|
||||
|
||||
// 6) Load the texture via AssetManager
|
||||
// This call returns a void*, which we cast to a GLuint
|
||||
{
|
||||
void* assetPtr = g_AssetManager.loadAsset(AssetType::TEXTURE, "assets/textures/default.png");
|
||||
if (!assetPtr)
|
||||
{
|
||||
fprintf(stderr, "[RenderWindow] Failed to load texture via AssetManager.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert void* to GLuint
|
||||
m_TextureID = static_cast<GLuint>(reinterpret_cast<uintptr_t>(assetPtr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// RenderSceneToFBO() - Offscreen render of the spinning cube
|
||||
// --------------------------------------------------
|
||||
void RenderWindow::RenderSceneToFBO()
|
||||
{
|
||||
// Spin
|
||||
m_RotationAngle += 0.5f;
|
||||
m_RotationAngle += 0.5f; // degrees per frame
|
||||
|
||||
m_FBO.Bind();
|
||||
glViewport(0, 0, m_LastWidth, m_LastHeight);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glClearColor(0.1f, 0.15f, 0.2f, 1.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Use our unlit shader
|
||||
// Use our unlit texture shader
|
||||
m_Shader.Use();
|
||||
|
||||
// Build a MVP matrix with GLM (model * view * proj)
|
||||
// 1) Model: rotate around Y or diagonal axis
|
||||
glm::mat4 model = glm::mat4(1.0f);
|
||||
model = glm::rotate(model, glm::radians(m_RotationAngle), glm::vec3(1.0f, 1.0f, 0.0f));
|
||||
// Build MVP
|
||||
glm::mat4 model = glm::rotate(glm::mat4(1.0f),
|
||||
glm::radians(m_RotationAngle),
|
||||
glm::vec3(1.f, 1.f, 0.f));
|
||||
|
||||
// 2) View: move camera back by 5 on Z
|
||||
glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(0.f, 0.f, -5.f));
|
||||
glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(0.f, 0.f, -5.f));
|
||||
float aspect = (m_LastHeight != 0) ? (float)m_LastWidth / (float)m_LastHeight : 1.0f;
|
||||
glm::mat4 proj = glm::perspective(glm::radians(45.f), aspect, 0.1f, 100.f);
|
||||
glm::mat4 mvp = proj * view * model;
|
||||
|
||||
// 3) Projection: perspective
|
||||
float aspect = (float)m_LastWidth / (float)m_LastHeight;
|
||||
glm::mat4 projection = glm::perspective(glm::radians(45.f), aspect, 0.1f, 100.f);
|
||||
|
||||
glm::mat4 mvp = projection * view * model;
|
||||
|
||||
// Upload MVP to the shader
|
||||
// Pass MVP
|
||||
GLint mvpLoc = glGetUniformLocation(m_Shader.GetProgramID(), "uMVP");
|
||||
glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, &mvp[0][0]);
|
||||
glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, glm::value_ptr(mvp));
|
||||
|
||||
// Draw the cube with our VAO
|
||||
// Texture uniform -> unit 0
|
||||
GLint texLoc = glGetUniformLocation(m_Shader.GetProgramID(), "uTexture");
|
||||
glUniform1i(texLoc, 0);
|
||||
|
||||
// Bind the texture from asset manager
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_TextureID);
|
||||
|
||||
// Draw
|
||||
glBindVertexArray(m_VAO);
|
||||
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
|
||||
|
||||
// Cleanup
|
||||
glBindVertexArray(0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
FBO::Unbind();
|
||||
}
|
||||
|
@ -1,28 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include "../Rendering/FBO.h"
|
||||
#include "../Rendering/Shader.h"
|
||||
#include <glm/glm.hpp>
|
||||
#include "../Engine/AssetManager.h"
|
||||
|
||||
|
||||
// Forward-declare a texture loading function if you have it in a separate file.
|
||||
// extern unsigned int LoadTexture(const char* filePath);
|
||||
|
||||
class RenderWindow
|
||||
{
|
||||
public:
|
||||
void Show(); // Called per-frame
|
||||
void Show(); // Called each frame to draw the ImGui window with the rendered texture
|
||||
|
||||
private:
|
||||
void InitGLResources(); // Create VAO/VBO/EBO + load shader
|
||||
void RenderSceneToFBO(); // Renders the spinning cube with our unlit shader
|
||||
// Initialize VAO/VBO/EBO, load shaders/textures, etc.
|
||||
void InitGLResources();
|
||||
|
||||
FBO m_FBO;
|
||||
float m_RotationAngle = 0.f;
|
||||
int m_LastWidth = 0;
|
||||
int m_LastHeight = 0;
|
||||
// Actually render the spinning cube into the FBO each frame
|
||||
void RenderSceneToFBO();
|
||||
|
||||
// VAO/VBO/EBO IDs
|
||||
// Offscreen render target
|
||||
FBO m_FBO;
|
||||
|
||||
// Our unlit shader
|
||||
Shader m_Shader;
|
||||
|
||||
// Keep track if we've initialized (so we only do so once)
|
||||
bool m_Initialized = false;
|
||||
|
||||
// GL objects for the cube
|
||||
unsigned int m_VAO = 0;
|
||||
unsigned int m_VBO = 0;
|
||||
unsigned int m_EBO = 0;
|
||||
|
||||
// Our unlit shader
|
||||
Shader m_Shader;
|
||||
bool m_Initialized = false;
|
||||
// Spin
|
||||
float m_RotationAngle = 0.0f;
|
||||
|
||||
// Track last known size (to recreate FBO if user resizes ImGui window)
|
||||
int m_LastWidth = 0;
|
||||
int m_LastHeight = 0;
|
||||
|
||||
// The loaded texture handle
|
||||
unsigned int m_TextureID = 0;
|
||||
};
|
||||
|
@ -3,9 +3,15 @@
|
||||
#include <cstdio>
|
||||
#include "Engine.h"
|
||||
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
DEBUG_PRINT("[START] Creating Global Engine ");
|
||||
|
||||
MyEngine engine;
|
||||
DEBUG_PRINT("[OK] Creating Global Engine ");
|
||||
|
||||
// Initialize the engine (creates GLFW window, sets up ImGui, etc.)
|
||||
if (!engine.Init(1280, 720, "Tesseract Engine"))
|
||||
{
|
||||
|
2
vendor/gcml/gcml.h
vendored
2
vendor/gcml/gcml.h
vendored
@ -48,7 +48,7 @@
|
||||
* @brief Prints debug messages with file name, line number, and function name.
|
||||
*/
|
||||
#define DEBUG_PRINT(fmt, ...) \
|
||||
fprintf(stderr, "DEBUG: %s:%d:%s(): " fmt "\n", \
|
||||
fprintf(stderr, "%s:%d:%s(): " fmt "\n", \
|
||||
__FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_PRINT(fmt, ...) // No operation in release builds
|
||||
|
Loading…
Reference in New Issue
Block a user