first commit

This commit is contained in:
David Ali
2026-01-09 13:50:52 +01:00
commit 9f87935db1
24 changed files with 7925 additions and 0 deletions

152
README.md Normal file
View File

@@ -0,0 +1,152 @@
# gren
A small modern OpenGL (4.5 core) playground written in C++20.
Focus: a simple, hackable renderer with hot-reloadable shaders, an orbit camera, and utilities for building meshes (quad/cube/ico and a pluggable terrain mesher).
https://git.alidavid.hu/gren
---
## Highlights
- **OpenGL 4.5 core** via GLFW context.
- **Z-up world** (`+Z` is up). Terrain height is written to `Z`.
- **Orbit camera** with aspect updates and input wiring.
- **Uniform buffers**:
- `PerFrame` (view/proj, lighting dir),
- `PerObject` (model matrix),
- `Material` (base color, etc.).
- **Shader hot reload**: shaders are polled each frame; edit files under `assets/shaders` and see changes immediately.
- **Mesh helpers**: unit quad, cube, icosahedron; GPU wrapper (`Graphics::MeshGL`) and pipeline abstraction.
- **Skybox pass**: inside-out cube with depth/state tweaks.
- **Procedural terrain API**: build a grid from a user-supplied height function.
---
## Repository layout
```
assets/
shaders/ GLSL vertex/fragment shaders
bin/ Built binaries
external/ Third-party code (if any)
obj/ Intermediate objects
src/ C++ sources (entry point: main.cpp)
Makefile (if present) convenience build
```
---
## Build
### Requirements
- C++20 compiler (g++ 12+/clang 15+)
- OpenGL 4.5 capable GPU/driver
- GLFW 3.x (window/context/input)
- GLM (math)
- A GL loader (provided in the project via `glfwx::load_gl_or_throw()`)
On Debian/Ubuntu:
```bash
sudo apt update
sudo apt install build-essential pkg-config libglfw3-dev libglm-dev
```
### Compile
If a `Makefile` is present:
```bash
make -j
```
Otherwise, a minimal one-liner build (adjust include/lib paths as needed):
```bash
g++ -std=gnu++20 -O2 -Wall -Wextra -Iexternal -Isrc \
src/*.cpp -lglfw -ldl -lpthread -o bin/main
```
Run from the repo root (so `assets/` is found):
```bash
./bin/main
```
---
## Coordinate system
- **World up:** `+Z`
- **Camera/view:** right-handed
- **Front faces:** counter-clockwise (CCW)
If lighting looks inverted, verify your mesh winding and the Z-up assumption.
---
## Shader hot reload
`Graphics::ShaderManager` polls shader files every frame:
- Edit anything under `assets/shaders/*.vert|*.frag`.
- The program re-links on the next poll; errors are printed to stdout/stderr.
---
## Procedural terrain (plug-in height function)
Build a terrain mesh by supplying a height function `(x, y) -> z`:
```cpp
#include <cmath>
#include "Asset.hpp"
// Example: gentle ridges
auto height = [](float x, float y) {
using std::sin; using std::cos;
return sin(x * 0.05f) * cos(y * 0.05f) * 5.0f;
};
// Generate a 256x256 grid (1 unit spacing), centered-ish
asset::Mesh terrain = asset::make_terrain(
/*W=*/256, /*H=*/256, /*dx=*/1.0f, /*dy=*/1.0f,
height,
/*genNormals=*/true, /*genUVs=*/true,
/*x0=*/-128.0f, /*y0=*/-128.0f);
Graphics::MeshGL gpuTerrain;
gpuTerrain.upload(terrain);
```
Notes:
- The grid lies in the **XY** plane; height is written to **Z**.
- Indices use CCW winding in XY so normals point `+Z`.
- Normals are computed as area-weighted sums of face normals and normalized per vertex.
---
## Camera
An orbit camera is provided. Controls are installed through the GLFW hook utilities.
See the implementation files for the exact bindings.
---
## Development tips
- Keep VAO attribute layouts consistent across meshes to avoid shader variant recompiles on some drivers.
- After the skybox pass, restore depth writes and CCW front faces before drawing regular geometry.
- For constant-screen-size debug gizmos, scale by distance in the vertex shader rather than world scale.
---
## Roadmap
- Entity/placement layer on top of the tile map (sprite atlas already integrated).
- Terrain polish: domain-warped noise presets, LOD chunks, and skirts.
- Shadowing pass (directional light; start with simple shadow mapping).
- Optional HTTP read-only clone and tarball snapshots via cgit configuration.