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
93 lines
2.9 KiB
C++
93 lines
2.9 KiB
C++
#ifndef FAN_RENDERER_HPP_
|
|
#define FAN_RENDERER_HPP_
|
|
|
|
#include "scene.hpp"
|
|
#include "camera.hpp"
|
|
#include "uniformbuffer.hpp"
|
|
|
|
namespace Fan
|
|
{
|
|
|
|
class Renderer
|
|
{
|
|
public:
|
|
// 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); // 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,
|
|
const Rc<Mesh>& default_mesh);
|
|
|
|
private:
|
|
static Rc<UniformBuffer> s_camera_ubo;
|
|
static Rc<UniformBuffer> s_light_ubo;
|
|
|
|
static void update_global_data(const Scene& scene, const Camera& camera,
|
|
int screen_width, int screen_height);
|
|
|
|
struct CameraData {
|
|
glm::mat4 view;
|
|
glm::mat4 projection;
|
|
glm::vec4 position; // w unused, std140 pads vec3 to 16 bytes anyway
|
|
};
|
|
|
|
// Maps to Fan::DirectionalLight
|
|
struct DirectionalLightData {
|
|
glm::vec4 direction;
|
|
glm::vec4 ambient;
|
|
glm::vec4 diffuse;
|
|
glm::vec4 specular;
|
|
};
|
|
|
|
// Maps to Fan::PointLight
|
|
struct PointLightData {
|
|
glm::vec4 position;
|
|
glm::vec4 ambient;
|
|
glm::vec4 diffuse;
|
|
glm::vec4 specular;
|
|
glm::vec4 attenuation; // x = constant, y = linear, z = quadratic
|
|
};
|
|
|
|
// Maps to Fan::SpotLight
|
|
struct SpotLightData {
|
|
glm::vec4 position;
|
|
glm::vec4 direction;
|
|
glm::vec4 ambient;
|
|
glm::vec4 diffuse;
|
|
glm::vec4 specular;
|
|
glm::vec4 attenuation; // x = constant, y = linear, z = quadratic
|
|
glm::vec4 cut_offs; // x = cut_off (cos), y = outer_cut_off (cos)
|
|
};
|
|
|
|
struct LightEnvironmentData {
|
|
DirectionalLightData dir_light;
|
|
|
|
int active_point_lights;
|
|
int active_spot_lights;
|
|
int _padding[2]; // Pad the 8 bytes of integers to a 16-byte boundary
|
|
|
|
PointLightData point_lights[MAX_POINT_LIGHTS];
|
|
SpotLightData spot_lights[MAX_SPOT_LIGHTS];
|
|
};
|
|
};
|
|
|
|
} // namespace Fan
|
|
|
|
#endif // FAN_RENDERER_HPP_
|