💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
5.5 KiB

/*
* Copyright (C) 2023 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ANTKEEPER_RENDER_MATERIAL_PASS_HPP
#define ANTKEEPER_RENDER_MATERIAL_PASS_HPP
#include <engine/render/pass.hpp>
#include <engine/render/material.hpp>
#include <engine/render/material-blend-mode.hpp>
#include <engine/math/vector.hpp>
#include <engine/gl/shader-program.hpp>
#include <engine/gl/shader-variable.hpp>
#include <engine/gl/texture-2d.hpp>
#include <functional>
#include <unordered_map>
#include <span>
class resource_manager;
namespace render {
/**
* Renders scene objects using their material-specified shaders and properties.
*/
class material_pass: public pass
{
public:
material_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffer, resource_manager* resource_manager);
void render(render::context& ctx) override;
/// Sets the material to be used when a render operation is missing a material. If no fallback material is specified, render operations without materials will not be processed.
void set_fallback_material(std::shared_ptr<render::material> fallback);
inline void set_mouse_position(const math::fvec2& position)
{
mouse_position = position;
}
private:
struct shader_cache_entry
{
std::unique_ptr<gl::shader_program> shader_program;
/// Command buffer which enables the shader and updates render state-related shader variables.
std::vector<std::function<void()>> shader_command_buffer;
/// Command buffer which updates geometry-related shader variables.
std::vector<std::function<void()>> geometry_command_buffer;
/// Map of materials to command buffers which update corresponding material shader variables.
std::unordered_map<const material*, std::vector<std::function<void()>>> material_command_buffers;
};
/// Map of state hashes to shader cache entries.
std::unordered_map<std::size_t, shader_cache_entry> shader_cache;
/**
* Evaluates the active camera and stores camera information in local variables to be passed to shaders.
*/
void evaluate_camera(const render::context& ctx);
/**
* Evaluates scene lights and stores lighting information in local variables to be passed to shaders.
*/
void evaluate_lighting(const render::context& ctx, std::uint32_t layer_mask);
void evaluate_misc(const render::context& ctx);
[[nodiscard]] std::unique_ptr<gl::shader_program> generate_shader_program(const gl::shader_template& shader_template, material_blend_mode blend_mode) const;
void build_shader_command_buffer(std::vector<std::function<void()>>& command_buffer, const gl::shader_program& shader_program) const;
void build_geometry_command_buffer(std::vector<std::function<void()>>& command_buffer, const gl::shader_program& shader_program) const;
void build_material_command_buffer(std::vector<std::function<void()>>& command_buffer, const gl::shader_program& shader_program, const material& material) const;
// Camera
const math::fmat4* view;
const math::fmat4* projection;
const math::fmat4* view_projection;
const math::fvec3* camera_position;
float camera_exposure;
math::fvec2 clip_depth;
float log_depth_coef;
// Light probes
const gl::texture_cube* light_probe_luminance_texture{};
const gl::texture_1d* light_probe_illuminance_texture{};
std::size_t light_probe_count;
// Point lights
std::vector<math::fvec3> point_light_colors;
std::vector<math::fvec3> point_light_positions;
std::size_t point_light_count;
// Directional lights
std::vector<math::fvec3> directional_light_colors;
std::vector<math::fvec3> directional_light_directions;
std::size_t directional_light_count;
// Directional shadows
std::vector<const gl::texture_2d*> directional_shadow_maps;
std::vector<math::fvec4> directional_shadow_splits;
std::vector<float> directional_shadow_fade_ranges;
std::vector<std::span<const math::fmat4>> directional_shadow_matrices;
std::size_t directional_shadow_count;
// Spot lights
std::vector<math::fvec3> spot_light_colors;
std::vector<math::fvec3> spot_light_positions;
std::vector<math::fvec3> spot_light_directions;
std::vector<math::fvec2> spot_light_cutoffs;
std::size_t spot_light_count;
// Rectangle lights
std::vector<math::fvec3> rectangle_light_colors;
std::vector<math::fvec3> rectangle_light_corners;
std::size_t rectangle_light_count;
// LTC
std::shared_ptr<gl::texture_2d> ltc_lut_1;
std::shared_ptr<gl::texture_2d> ltc_lut_2;
// IBL
std::shared_ptr<gl::texture_2d> brdf_lut;
// Misc
float time;
float timestep;
unsigned int frame{0};
float subframe;
math::fvec2 resolution;
math::fvec2 mouse_position;
// Geometry
const math::fmat4* model;
std::span<const math::fmat4> matrix_palette;
/// Hash of the lighting state.
std::size_t lighting_state_hash;
std::shared_ptr<render::material> fallback_material;
};
} // namespace render
#endif // ANTKEEPER_RENDER_MATERIAL_PASS_HPP