180 lines
4.8 KiB
C++
180 lines
4.8 KiB
C++
#pragma once
|
|
#include <glad.h>
|
|
#include <GLFW/glfw3.h>
|
|
#include <glm/glm.hpp>
|
|
#include <glm/gtc/matrix_transform.hpp>
|
|
#include <vector>
|
|
#include <memory>
|
|
#include <functional>
|
|
#include "ThreadPool.h"
|
|
|
|
|
|
// Forward declarations
|
|
class Primitive;
|
|
class GameObject;
|
|
|
|
|
|
class Engine {
|
|
public:
|
|
Engine(int window_width = 1280, int window_height = 720, const char* title = "C++ Engine");
|
|
virtual ~Engine();
|
|
|
|
|
|
virtual bool OnInitialize();
|
|
virtual void OnShutdown();
|
|
virtual void OnUpdate(float delta_time);
|
|
virtual void OnRender();
|
|
|
|
|
|
void Run();
|
|
|
|
|
|
// Primitive factory methods
|
|
std::shared_ptr<Primitive> CreateCube(const glm::vec3& color = glm::vec3(1.0f));
|
|
std::shared_ptr<Primitive> CreateSphere(int segments = 32, const glm::vec3& color = glm::vec3(1.0f));
|
|
std::shared_ptr<Primitive> CreatePlane(float width = 2.0f, float height = 2.0f, const glm::vec3& color = glm::vec3(1.0f));
|
|
std::shared_ptr<Primitive> CreateGrid(int size = 20, float spacing = 1.0f, const glm::vec3& color = glm::vec3(0.6f));
|
|
std::shared_ptr<Primitive> CreateOBJModel(const std::string& objPath, const std::string& texturePath = "");
|
|
|
|
|
|
// GameObject management
|
|
std::shared_ptr<GameObject> CreateGameObject(std::shared_ptr<Primitive> primitive, const glm::vec3& position = glm::vec3(0.0f));
|
|
void AddGameObject(std::shared_ptr<GameObject> obj);
|
|
void RemoveGameObject(std::shared_ptr<GameObject> obj);
|
|
|
|
|
|
// Camera control
|
|
void SetCameraPosition(const glm::vec3& position);
|
|
void SetCameraTarget(const glm::vec3& target);
|
|
void SetCameraOrbit(float distance, float angle, float height = 5.0f);
|
|
|
|
GLuint text_vao = 0, text_vbo = 0;
|
|
|
|
|
|
GLFWwindow* GetWindow() const { return window_; }
|
|
float GetTime() const { return (float)glfwGetTime(); }
|
|
|
|
|
|
|
|
private:
|
|
ThreadPool threadPool_;
|
|
|
|
// Culling result structure
|
|
struct CullingBatch {
|
|
Primitive* primitive;
|
|
std::vector<glm::mat4> modelMatrices;
|
|
};
|
|
|
|
using CullingResult = std::vector<CullingBatch>;
|
|
|
|
// Helper methods
|
|
CullingResult CullObjectsSubset(
|
|
const std::vector<GameObject*>& objects,
|
|
size_t startIdx,
|
|
size_t endIdx,
|
|
const glm::mat4& viewProjection
|
|
);
|
|
|
|
void MergeCullingResults(
|
|
const std::vector<CullingResult>& results,
|
|
std::unordered_map<Primitive*, std::vector<glm::mat4>>& outBatches
|
|
);
|
|
|
|
|
|
|
|
|
|
protected:
|
|
void InitializeShader();
|
|
void RenderScene();
|
|
void RenderSceneInstanced();
|
|
void RenderOverlay();
|
|
void RenderOverlayTestPoint();
|
|
void InitOverlay();
|
|
|
|
static void FramebufferSizeCallback(GLFWwindow* window, int width, int height);
|
|
|
|
int width_, height_;
|
|
GLFWwindow* window_;
|
|
float last_time_ = 0.0f;
|
|
|
|
// Camera
|
|
glm::vec3 camera_position_ = glm::vec3(0, 5, 10);
|
|
glm::vec3 camera_target_ = glm::vec3(0, 0, 0);
|
|
glm::vec3 camera_up_ = glm::vec3(0, 1, 0);
|
|
|
|
// Rendering
|
|
|
|
|
|
GLuint shader_program_ = 0;
|
|
std::vector<std::shared_ptr<GameObject>> game_objects_;
|
|
|
|
// Overlay VAO/VBO
|
|
GLuint overlay_vao = 0;
|
|
GLuint overlay_vbo = 0;
|
|
GLuint overlay_program = 0;
|
|
|
|
// Performance stats
|
|
static constexpr int PERF_HISTORY = 300;
|
|
float perf_times[PERF_HISTORY] = {0};
|
|
int perf_pos = 0;
|
|
int perf_count = 0;
|
|
|
|
// Projection matrix for overlay
|
|
glm::mat4 ortho2D;
|
|
|
|
// Font buffer for stb_easy_font
|
|
static const int FONT_BUFFER_SIZE = 9999;
|
|
char font_buffer[FONT_BUFFER_SIZE];
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
// Primitive base class
|
|
class Primitive {
|
|
public:
|
|
virtual ~Primitive() = default;
|
|
virtual void Render() = 0;
|
|
virtual void Bind() = 0;
|
|
virtual void Cleanup() = 0;
|
|
|
|
virtual GLenum GetDrawMode() const { return GL_TRIANGLES; }
|
|
virtual GLsizei GetIndexCount() const { return index_count_; }
|
|
virtual GLsizei GetVertexCount() const { return vertex_count_; }
|
|
virtual void Bind() const { glBindVertexArray(vao_); }
|
|
|
|
|
|
protected:
|
|
GLuint vao_ = 0;
|
|
GLuint vbo_ = 0;
|
|
GLuint ebo_ = 0;
|
|
GLsizei index_count_ = 0;
|
|
GLsizei vertex_count_ = 0;
|
|
GLenum draw_mode_ = GL_TRIANGLES;
|
|
glm::vec3 color_;
|
|
};
|
|
|
|
// GameObject class
|
|
class GameObject {
|
|
public:
|
|
GameObject(std::shared_ptr<Primitive> prim, const glm::vec3& pos);
|
|
// Add:
|
|
Primitive* GetPrimitive() const { return primitive_.get(); }
|
|
float GetBoundingRadius() const;
|
|
|
|
glm::vec3 GetPosition() const { return position_; }
|
|
glm::mat4 GetModelMatrix() const;
|
|
void Render();
|
|
void Cleanup();
|
|
|
|
void SetPosition(const glm::vec3& p) { position_ = p; }
|
|
void SetRotation(const glm::vec3& r) { rotation_ = r; }
|
|
void SetScale(const glm::vec3& s) { scale_ = s; }
|
|
|
|
private:
|
|
std::shared_ptr<Primitive> primitive_;
|
|
glm::vec3 position_;
|
|
glm::vec3 rotation_;
|
|
glm::vec3 scale_{1.0f};
|
|
}; |