added files

This commit is contained in:
ben de roo
2026-09-06 21:15:01 +02:00
parent 64d277d9d1
commit 3a2a671325
55 changed files with 5597 additions and 0 deletions
+62
View File
@@ -0,0 +1,62 @@
#pragma once
#include <glm/glm.hpp>
namespace planetarium {
// -----------------------------------------------------------------------
// Camera
//
// A custom orbital ("arcball") camera. It orbits a focus point at a
// controllable yaw/pitch/distance, with all parameters critically-damped
// toward their target values every frame so camera moves - including
// "focus on selected planet" - feel like smooth, cinematic transitions
// rather than instant snaps.
// -----------------------------------------------------------------------
class Camera {
public:
Camera();
// Input handlers - called directly from Engine's GLFW callbacks.
void onMouseDrag(float deltaX, float deltaY);
void onMousePan(float deltaX, float deltaY);
void onScroll(float deltaY);
void reset();
// Smoothly re-targets the orbit focus to a world-space point (e.g. a
// selected planet's position) and optionally suggests a nice viewing
// distance for that object's scale.
void focusOn(const glm::vec3& worldPoint, float suggestedDistance);
// Advances the smoothing/interpolation. Must be called once per frame
// with the frame's delta time in seconds.
void update(float deltaTime);
glm::mat4 viewMatrix() const;
glm::vec3 position() const { return currentPosition_; }
glm::vec3 focusPoint() const { return currentFocus_; }
float distance() const { return currentDistance_; }
private:
// Target (goal) state, set instantly by input; current state chases
// it every update() call using exponential smoothing.
float targetYaw_ = -0.6f;
float targetPitch_ = 0.45f;
float targetDistance_ = 18.0f;
glm::vec3 targetFocus_{0.0f};
float currentYaw_ = -0.6f;
float currentPitch_ = 0.45f;
float currentDistance_ = 18.0f;
glm::vec3 currentFocus_{0.0f};
glm::vec3 currentPosition_{0.0f};
static constexpr float kMinPitch = -1.45f;
static constexpr float kMaxPitch = 1.45f;
static constexpr float kMinDistance = 2.0f;
static constexpr float kMaxDistance = 400.0f;
static constexpr float kSmoothingSpeed = 6.0f;
};
} // namespace planetarium
+77
View File
@@ -0,0 +1,77 @@
#pragma once
#include "Camera.hpp"
#include <functional>
struct GLFWwindow;
namespace planetarium {
// -----------------------------------------------------------------------
// Engine
//
// Top-level owner of the GLFW window/context, the frame loop, and input
// routing between raw GLFW callbacks and the Camera. This is the only
// class that knows about GLFW directly.
//
// This is the reusable "engine" half of the original Planetarium project
// with every game-specific piece (SolarSystem, Planet, UI, picking)
// removed. Hook your own logic in via setUpdateCallback/setRenderCallback:
//
// Engine engine;
// engine.initialize(1600, 900, "My App");
// engine.setUpdateCallback([](float dt) { ... });
// engine.setRenderCallback([&](int fbWidth, int fbHeight) { ... });
// engine.run();
//
// Left-drag orbits the camera, middle-drag pans it, scroll zooms, and R
// resets it - wire up more input in your own update/render callbacks via
// window() if you need it.
// -----------------------------------------------------------------------
class Engine {
public:
using UpdateCallback = std::function<void(float deltaTime)>;
using RenderCallback = std::function<void(int framebufferWidth, int framebufferHeight)>;
~Engine();
bool initialize(int width, int height, const char* title);
void run();
void setUpdateCallback(UpdateCallback cb) { updateCallback_ = std::move(cb); }
void setRenderCallback(RenderCallback cb) { renderCallback_ = std::move(cb); }
Camera& camera() { return camera_; }
const Camera& camera() const { return camera_; }
GLFWwindow* window() const { return window_; }
private:
void update(float deltaTime);
void render();
// GLFW callback trampolines (static -> instance via glfwGetWindowUserPointer).
static void cursorPosCallback(GLFWwindow* window, double x, double y);
static void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods);
static void scrollCallback(GLFWwindow* window, double xOffset, double yOffset);
static void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
static void framebufferSizeCallback(GLFWwindow* window, int width, int height);
GLFWwindow* window_ = nullptr;
Camera camera_;
UpdateCallback updateCallback_;
RenderCallback renderCallback_;
int framebufferWidth_ = 1600;
int framebufferHeight_ = 900;
double lastMouseX_ = 0.0;
double lastMouseY_ = 0.0;
bool rotating_ = false;
bool panning_ = false;
double lastFrameTime_ = 0.0;
};
} // namespace planetarium
+146
View File
@@ -0,0 +1,146 @@
#pragma once
// -----------------------------------------------------------------------
// GLFunctions
//
// Linux distributions only ship GL/gl.h with legacy (<=1.1/1.2) function
// declarations; everything from OpenGL 1.5 onward (VAOs/VBOs, GLSL
// shaders, etc.) must be resolved at runtime as function pointers. This
// is a small, self-contained loader for exactly the subset of OpenGL 3.3
// core functions this project's renderer uses. It is intentionally
// separate from Dear ImGui's own bundled loader (imgui_impl_opengl3_loader.h)
// to avoid the multiple-definition problems that occur when two GL
// loaders are mixed in the same program - see the comment at the top of
// that file for details.
//
// Usage: call planetarium::gl::loadGLFunctions() exactly once, right
// after the GLFW OpenGL context has been made current and before any
// other GL call in the project's own rendering code.
// -----------------------------------------------------------------------
#include <GL/gl.h>
#include <cstddef>
#ifndef GL_ARRAY_BUFFER
#define GL_ARRAY_BUFFER 0x8892
#endif
#ifndef GL_ELEMENT_ARRAY_BUFFER
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
#endif
#ifndef GL_STATIC_DRAW
#define GL_STATIC_DRAW 0x88E4
#endif
#ifndef GL_DYNAMIC_DRAW
#define GL_DYNAMIC_DRAW 0x88E8
#endif
#ifndef GL_FRAGMENT_SHADER
#define GL_FRAGMENT_SHADER 0x8B30
#endif
#ifndef GL_VERTEX_SHADER
#define GL_VERTEX_SHADER 0x8B31
#endif
#ifndef GL_COMPILE_STATUS
#define GL_COMPILE_STATUS 0x8B81
#endif
#ifndef GL_LINK_STATUS
#define GL_LINK_STATUS 0x8B82
#endif
#ifndef GL_TEXTURE0
#define GL_TEXTURE0 0x84C0
#endif
#ifndef GL_PROGRAM_POINT_SIZE
#define GL_PROGRAM_POINT_SIZE 0x8642
#endif
#ifndef GL_CLAMP_TO_EDGE
#define GL_CLAMP_TO_EDGE 0x812F
#endif
#ifndef GL_MULTISAMPLE
#define GL_MULTISAMPLE 0x809D
#endif
#ifndef GL_MAJOR_VERSION
#define GL_MAJOR_VERSION 0x821B
#endif
#ifndef GL_MINOR_VERSION
#define GL_MINOR_VERSION 0x821C
#endif
typedef char GLchar;
typedef ptrdiff_t GLsizeiptr;
typedef ptrdiff_t GLintptr;
namespace planetarium::gl {
using PFNGLGENVERTEXARRAYS = void (*)(GLsizei, GLuint*);
using PFNGLBINDVERTEXARRAY = void (*)(GLuint);
using PFNGLDELETEVERTEXARRAYS = void (*)(GLsizei, const GLuint*);
using PFNGLGENBUFFERS = void (*)(GLsizei, GLuint*);
using PFNGLBINDBUFFER = void (*)(GLenum, GLuint);
using PFNGLBUFFERDATA = void (*)(GLenum, GLsizeiptr, const void*, GLenum);
using PFNGLDELETEBUFFERS = void (*)(GLsizei, const GLuint*);
using PFNGLVERTEXATTRIBPOINTER = void (*)(GLuint, GLint, GLenum, GLboolean, GLsizei, const void*);
using PFNGLENABLEVERTEXATTRIBARRAY = void (*)(GLuint);
using PFNGLDISABLEVERTEXATTRIBARRAY = void (*)(GLuint);
using PFNGLCREATESHADER = GLuint (*)(GLenum);
using PFNGLSHADERSOURCE = void (*)(GLuint, GLsizei, const GLchar* const*, const GLint*);
using PFNGLCOMPILESHADER = void (*)(GLuint);
using PFNGLGETSHADERIV = void (*)(GLuint, GLenum, GLint*);
using PFNGLGETSHADERINFOLOG = void (*)(GLuint, GLsizei, GLsizei*, GLchar*);
using PFNGLDELETESHADER = void (*)(GLuint);
using PFNGLCREATEPROGRAM = GLuint (*)();
using PFNGLATTACHSHADER = void (*)(GLuint, GLuint);
using PFNGLLINKPROGRAM = void (*)(GLuint);
using PFNGLGETPROGRAMIV = void (*)(GLuint, GLenum, GLint*);
using PFNGLGETPROGRAMINFOLOG = void (*)(GLuint, GLsizei, GLsizei*, GLchar*);
using PFNGLUSEPROGRAM = void (*)(GLuint);
using PFNGLDELETEPROGRAM = void (*)(GLuint);
using PFNGLGETUNIFORMLOCATION = GLint (*)(GLuint, const GLchar*);
using PFNGLUNIFORMMATRIX4FV = void (*)(GLint, GLsizei, GLboolean, const GLfloat*);
using PFNGLUNIFORM3FV = void (*)(GLint, GLsizei, const GLfloat*);
using PFNGLUNIFORM4FV = void (*)(GLint, GLsizei, const GLfloat*);
using PFNGLUNIFORM1F = void (*)(GLint, GLfloat);
using PFNGLUNIFORM1I = void (*)(GLint, GLint);
using PFNGLACTIVETEXTURE = void (*)(GLenum);
using PFNGLGENERATEMIPMAP = void (*)(GLenum);
extern PFNGLGENVERTEXARRAYS glGenVertexArrays;
extern PFNGLBINDVERTEXARRAY glBindVertexArray;
extern PFNGLDELETEVERTEXARRAYS glDeleteVertexArrays;
extern PFNGLGENBUFFERS glGenBuffers;
extern PFNGLBINDBUFFER glBindBuffer;
extern PFNGLBUFFERDATA glBufferData;
extern PFNGLDELETEBUFFERS glDeleteBuffers;
extern PFNGLVERTEXATTRIBPOINTER glVertexAttribPointer;
extern PFNGLENABLEVERTEXATTRIBARRAY glEnableVertexAttribArray;
extern PFNGLDISABLEVERTEXATTRIBARRAY glDisableVertexAttribArray;
extern PFNGLCREATESHADER glCreateShader;
extern PFNGLSHADERSOURCE glShaderSource;
extern PFNGLCOMPILESHADER glCompileShader;
extern PFNGLGETSHADERIV glGetShaderiv;
extern PFNGLGETSHADERINFOLOG glGetShaderInfoLog;
extern PFNGLDELETESHADER glDeleteShader;
extern PFNGLCREATEPROGRAM glCreateProgram;
extern PFNGLATTACHSHADER glAttachShader;
extern PFNGLLINKPROGRAM glLinkProgram;
extern PFNGLGETPROGRAMIV glGetProgramiv;
extern PFNGLGETPROGRAMINFOLOG glGetProgramInfoLog;
extern PFNGLUSEPROGRAM glUseProgram;
extern PFNGLDELETEPROGRAM glDeleteProgram;
extern PFNGLGETUNIFORMLOCATION glGetUniformLocation;
extern PFNGLUNIFORMMATRIX4FV glUniformMatrix4fv;
extern PFNGLUNIFORM3FV glUniform3fv;
extern PFNGLUNIFORM4FV glUniform4fv;
extern PFNGLUNIFORM1F glUniform1f;
extern PFNGLUNIFORM1I glUniform1i;
extern PFNGLACTIVETEXTURE glActiveTexture;
extern PFNGLGENERATEMIPMAP glGenerateMipmap;
// Resolves every function pointer above via glfwGetProcAddress. Must be
// called once, after glfwMakeContextCurrent(). Returns false if any
// required entry point could not be resolved.
bool loadGLFunctions();
} // namespace planetarium::gl
+54
View File
@@ -0,0 +1,54 @@
#pragma once
#include "GLFunctions.hpp"
#include <glm/glm.hpp>
#include <vector>
namespace planetarium {
// -----------------------------------------------------------------------
// Mesh
//
// Owns a VAO/VBO/(optional)EBO describing an interleaved
// position+normal+uv vertex stream, plus static factory methods that
// procedurally build a few common primitive shapes (spheres, rings,
// circles) so a project has no dependency on external model files.
// -----------------------------------------------------------------------
struct Vertex {
glm::vec3 position;
glm::vec3 normal;
glm::vec2 uv;
};
class Mesh {
public:
Mesh() = default;
~Mesh();
Mesh(const Mesh&) = delete;
Mesh& operator=(const Mesh&) = delete;
Mesh(Mesh&& other) noexcept;
Mesh& operator=(Mesh&& other) noexcept;
void upload(const std::vector<Vertex>& vertices, const std::vector<unsigned int>& indices);
void uploadLineStrip(const std::vector<glm::vec3>& points);
void draw() const;
void drawLineStrip() const;
static Mesh createUVSphere(int stacks, int slices);
static Mesh createRing(float innerRadius, float outerRadius, int segments);
static Mesh createOrbitCircle(int segments); // unit circle in XZ
private:
void release();
GLuint vao_ = 0;
GLuint vbo_ = 0;
GLuint ebo_ = 0;
GLsizei indexCount_ = 0;
GLsizei vertexCount_ = 0;
bool isLineStrip_ = false;
};
} // namespace planetarium
+45
View File
@@ -0,0 +1,45 @@
#pragma once
#include "GLFunctions.hpp"
#include <glm/glm.hpp>
#include <string>
namespace planetarium {
// -----------------------------------------------------------------------
// Shader
//
// Thin RAII wrapper around a linked OpenGL program object, compiled from
// a vertex + fragment shader pair loaded from disk.
// -----------------------------------------------------------------------
class Shader {
public:
Shader() = default;
~Shader();
Shader(const Shader&) = delete;
Shader& operator=(const Shader&) = delete;
Shader(Shader&& other) noexcept;
Shader& operator=(Shader&& other) noexcept;
// Compiles and links the program. Returns false (and logs to stderr)
// on failure; the shader remains unusable but the caller can continue
// running with a null program.
bool loadFromFiles(const std::string& vertexPath, const std::string& fragmentPath);
void use() const;
GLuint id() const { return program_; }
void setMat4(const std::string& name, const glm::mat4& m) const;
void setVec3(const std::string& name, const glm::vec3& v) const;
void setVec4(const std::string& name, const glm::vec4& v) const;
void setFloat(const std::string& name, float f) const;
void setInt(const std::string& name, int i) const;
private:
GLuint program_ = 0;
GLint locationOf(const std::string& name) const;
};
} // namespace planetarium