Add GL error handling, resource fallbacks and GPU timing; speed up lighting

Bug fixes:
- Release static GL objects (UBOs, logo texture) before the context is
  destroyed via new Renderer::shutdown()
- Fix max point/spot light warnings never firing
- Show frame time in ms instead of seconds
- Size the viewport framebuffer in physical pixels on HiDPI displays
- Stop double-flipping OBJ UVs; add flip_uvs option to load_obj for
  models with a top-left UV origin (backpack)

Build:
- Track header dependencies (-MMD -MP) so header edits trigger rebuilds
- Create build/ automatically

Error handling:
- Add gldebug module: KHR_debug output routed to the logger in debug
  builds, object labels, and error/status string helpers
- Validate inputs and check GL errors when creating textures, meshes,
  framebuffers, uniform buffers and shaders; FrameBuffer::resize() and
  Renderer::init() now report failure

Resources:
- Add ResourceCache: shares textures and shaders by path and substitutes
  fallbacks (magenta checkerboard texture, unlit shader, cube mesh) for
  assets that fail to load; specular maps are optional
- load_obj never fails, a broken model becomes a fallback cube
- Renderer draws submeshes with broken materials using the fallback
  material instead of skipping them
- Add Texture::create_from_pixels, Shader::create_from_source and
  Mesh::create_cube
- Cache uniform locations in Shader, looked up with string_view so
  hits don't allocate; missing uniforms warn once

Performance:
- Add CpuTimer and GpuTimer (GL_TIME_ELAPSED, non-blocking readback)
  and a Performance section in the UI with averaged overlay numbers
- Sample material textures once per fragment and apply material colors
  after accumulating lights
- Pass camera position through CameraBlock instead of inverting the
  view matrix per fragment
- Compute the normal matrix on the CPU instead of per vertex
- Skip spot light work for fragments outside the outer cone
This commit is contained in:
2026-10-28 21:23:41 +01:00
parent 642d29634a
commit d081108ea5
39 changed files with 1275 additions and 274 deletions

View File

@@ -11,15 +11,24 @@ namespace Fan
class Renderer
{
public:
static void init();
// init() needs a current GL context and also initializes the ResourceCache.
// shutdown() must run before the window (and its context) is destroyed
static bool init();
static void shutdown();
static void set_viewport(int x, int y, int width, int height);
static void set_clear_color(const glm::vec4& color);
static void set_wireframe(bool enabled);
static void set_wireframe(bool enabled); // Global, stays on until disabled
static void clear();
// Draws into the currently bound framebuffer without clearing it.
// screen_width and screen_height only set the camera aspect ratio
static void draw_scene(const Scene& scene, const Camera& camera,
int screen_width, int screen_height);
// debug_shader needs u_model, u_view_projection and u_color. default_mesh is
// drawn for entities without a mesh and for lights. Disables wireframe when done
static void draw_debug_wireframes(const Scene& scene, const Camera& camera,
int screen_width, int screen_height,
const Rc<Shader>& debug_shader,
@@ -35,6 +44,7 @@ private:
struct CameraData {
glm::mat4 view;
glm::mat4 projection;
glm::vec4 position; // w unused, std140 pads vec3 to 16 bytes anyway
};
// Maps to Fan::DirectionalLight
@@ -75,7 +85,6 @@ private:
PointLightData point_lights[MAX_POINT_LIGHTS];
SpotLightData spot_lights[MAX_SPOT_LIGHTS];
};
};
} // namespace Fan