|
|
@ -33,18 +33,23 @@ |
|
|
|
#include "renderer/vertex-attributes.hpp"
|
|
|
|
#include "renderer/render-context.hpp"
|
|
|
|
#include "renderer/model.hpp"
|
|
|
|
#include "renderer/material.hpp"
|
|
|
|
#include "scene/camera.hpp"
|
|
|
|
#include "scene/scene.hpp"
|
|
|
|
#include "scene/scene.hpp"
|
|
|
|
#include "utility/fundamental-types.hpp"
|
|
|
|
#include <cmath>
|
|
|
|
#include <glad/glad.h>
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
sky_pass::sky_pass(::rasterizer* rasterizer, const ::framebuffer* framebuffer, resource_manager* resource_manager): |
|
|
|
render_pass(rasterizer, framebuffer), |
|
|
|
mouse_position({0.0f, 0.0f}), |
|
|
|
sky_model(nullptr), |
|
|
|
sky_model_vao(nullptr), |
|
|
|
moon_model(nullptr), |
|
|
|
moon_model_vao(nullptr), |
|
|
|
moon_shader_program(nullptr), |
|
|
|
blue_noise_map(nullptr), |
|
|
|
observer_coordinates{0.0f, 0.0f} |
|
|
|
{ |
|
|
@ -63,24 +68,6 @@ sky_pass::sky_pass(::rasterizer* rasterizer, const ::framebuffer* framebuffer, r |
|
|
|
moon_az_el_input = shader_program->get_input("moon_az_el"); |
|
|
|
julian_day_input = shader_program->get_input("julian_day"); |
|
|
|
|
|
|
|
const float vertex_data[] = |
|
|
|
{ |
|
|
|
-1.0f, 1.0f, 0.0f, |
|
|
|
-1.0f, -1.0f, 0.0f, |
|
|
|
1.0f, 1.0f, 0.0f, |
|
|
|
1.0f, 1.0f, 0.0f, |
|
|
|
-1.0f, -1.0f, 0.0f, |
|
|
|
1.0f, -1.0f, 0.0f |
|
|
|
}; |
|
|
|
|
|
|
|
std::size_t vertex_size = 3; |
|
|
|
std::size_t vertex_stride = sizeof(float) * vertex_size; |
|
|
|
std::size_t vertex_count = 6; |
|
|
|
|
|
|
|
quad_vbo = new vertex_buffer(sizeof(float) * vertex_size * vertex_count, vertex_data); |
|
|
|
quad_vao = new vertex_array(); |
|
|
|
quad_vao->bind_attribute(VERTEX_POSITION_LOCATION, *quad_vbo, 3, vertex_attribute_type::float_32, vertex_stride, 0); |
|
|
|
|
|
|
|
sky_gradient[0] = {1.0, 0.0f, 0.0f, 0.0f}; |
|
|
|
sky_gradient[1] = {0.0, 1.0f, 0.0f, 0.333f}; |
|
|
|
sky_gradient[2] = {0.0, 0.0f, 1.0f, 0.667f}; |
|
|
@ -88,10 +75,7 @@ sky_pass::sky_pass(::rasterizer* rasterizer, const ::framebuffer* framebuffer, r |
|
|
|
} |
|
|
|
|
|
|
|
sky_pass::~sky_pass() |
|
|
|
{ |
|
|
|
delete quad_vao; |
|
|
|
delete quad_vbo; |
|
|
|
} |
|
|
|
{} |
|
|
|
|
|
|
|
void sky_pass::render(render_context* context) const |
|
|
|
{ |
|
|
@ -117,7 +101,8 @@ void sky_pass::render(render_context* context) const |
|
|
|
float clip_far = camera.get_clip_far_tween().interpolate(context->alpha); |
|
|
|
float3 model_scale = float3{1.0f, 1.0f, 1.0f} * (clip_near + clip_far) * 0.5f; |
|
|
|
float4x4 model = math::scale(math::identity4x4<float>, model_scale); |
|
|
|
float4x4 model_view = math::resize<4, 4>(math::resize<3, 3>(camera.get_view_tween().interpolate(context->alpha))) * model; |
|
|
|
float4x4 view = math::resize<4, 4>(math::resize<3, 3>(camera.get_view_tween().interpolate(context->alpha))); |
|
|
|
float4x4 model_view = view * model; |
|
|
|
float4x4 projection = camera.get_projection_tween().interpolate(context->alpha); |
|
|
|
float4x4 model_view_projection = projection * model_view; |
|
|
|
|
|
|
@ -129,40 +114,68 @@ void sky_pass::render(render_context* context) const |
|
|
|
float3 moon_position = moon_position_tween.interpolate(context->alpha); |
|
|
|
float2 moon_az_el = moon_az_el_tween.interpolate(context->alpha); |
|
|
|
|
|
|
|
// Change shader program
|
|
|
|
rasterizer->use_program(*shader_program); |
|
|
|
|
|
|
|
// Upload shader parameters
|
|
|
|
if (model_view_projection_input) |
|
|
|
model_view_projection_input->upload(model_view_projection); |
|
|
|
if (sky_gradient_input) |
|
|
|
sky_gradient_input->upload(0, &sky_gradient[0], 4); |
|
|
|
if (mouse_input) |
|
|
|
mouse_input->upload(mouse_position); |
|
|
|
if (resolution_input) |
|
|
|
resolution_input->upload(resolution); |
|
|
|
if (time_input) |
|
|
|
time_input->upload(time); |
|
|
|
if (time_of_day_input) |
|
|
|
time_of_day_input->upload(time_of_day); |
|
|
|
if (blue_noise_map_input) |
|
|
|
blue_noise_map_input->upload(blue_noise_map); |
|
|
|
if (observer_coordinates_input) |
|
|
|
observer_coordinates_input->upload(observer_coordinates); |
|
|
|
|
|
|
|
if (sun_position_input) |
|
|
|
sun_position_input->upload(sun_position); |
|
|
|
if (sun_az_el_input) |
|
|
|
sun_az_el_input->upload(sun_az_el); |
|
|
|
if (moon_position_input) |
|
|
|
moon_position_input->upload(moon_position); |
|
|
|
if (moon_az_el_input) |
|
|
|
moon_az_el_input->upload(moon_az_el); |
|
|
|
if (julian_day_input) |
|
|
|
julian_day_input->upload(julian_day); |
|
|
|
|
|
|
|
// Draw sky model
|
|
|
|
rasterizer->draw_arrays(*sky_model_vao, sky_model_drawing_mode, sky_model_start_index, sky_model_index_count); |
|
|
|
{ |
|
|
|
rasterizer->use_program(*shader_program); |
|
|
|
|
|
|
|
// Upload shader parameters
|
|
|
|
if (model_view_projection_input) |
|
|
|
model_view_projection_input->upload(model_view_projection); |
|
|
|
if (sky_gradient_input) |
|
|
|
sky_gradient_input->upload(0, &sky_gradient[0], 4); |
|
|
|
if (mouse_input) |
|
|
|
mouse_input->upload(mouse_position); |
|
|
|
if (resolution_input) |
|
|
|
resolution_input->upload(resolution); |
|
|
|
if (time_input) |
|
|
|
time_input->upload(time); |
|
|
|
if (time_of_day_input) |
|
|
|
time_of_day_input->upload(time_of_day); |
|
|
|
if (blue_noise_map_input) |
|
|
|
blue_noise_map_input->upload(blue_noise_map); |
|
|
|
if (observer_coordinates_input) |
|
|
|
observer_coordinates_input->upload(observer_coordinates); |
|
|
|
|
|
|
|
if (sun_position_input) |
|
|
|
sun_position_input->upload(sun_position); |
|
|
|
if (sun_az_el_input) |
|
|
|
sun_az_el_input->upload(sun_az_el); |
|
|
|
if (moon_position_input) |
|
|
|
moon_position_input->upload(moon_position); |
|
|
|
if (moon_az_el_input) |
|
|
|
moon_az_el_input->upload(moon_az_el); |
|
|
|
if (julian_day_input) |
|
|
|
julian_day_input->upload(julian_day); |
|
|
|
|
|
|
|
rasterizer->draw_arrays(*sky_model_vao, sky_model_drawing_mode, sky_model_start_index, sky_model_index_count); |
|
|
|
} |
|
|
|
|
|
|
|
// Draw moon model
|
|
|
|
{ |
|
|
|
glEnable(GL_BLEND); |
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE); |
|
|
|
|
|
|
|
float moon_angular_radius = math::radians(1.0f); |
|
|
|
float moon_distance = (clip_near + clip_far) * 0.5f; |
|
|
|
float moon_radius = moon_angular_radius * moon_distance; |
|
|
|
|
|
|
|
model = math::scale(math::translate(math::identity4x4<float>, moon_position * -moon_distance), float3{moon_radius, moon_radius, moon_radius}); |
|
|
|
model_view = view * model; |
|
|
|
model_view_projection = projection * model_view; |
|
|
|
float3x3 normal_model = math::transpose(math::inverse(math::resize<3, 3>(model))); |
|
|
|
|
|
|
|
rasterizer->use_program(*moon_shader_program); |
|
|
|
if (moon_model_view_projection_input) |
|
|
|
moon_model_view_projection_input->upload(model_view_projection); |
|
|
|
if (moon_normal_model_input) |
|
|
|
moon_normal_model_input->upload(normal_model); |
|
|
|
if (moon_moon_position_input) |
|
|
|
moon_moon_position_input->upload(moon_position); |
|
|
|
if (moon_sun_position_input) |
|
|
|
moon_sun_position_input->upload(sun_position); |
|
|
|
moon_material->upload(context->alpha); |
|
|
|
rasterizer->draw_arrays(*moon_model_vao, moon_model_drawing_mode, moon_model_start_index, moon_model_index_count); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void sky_pass::set_sky_model(const model* model) |
|
|
@ -187,6 +200,42 @@ void sky_pass::set_sky_model(const model* model) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void sky_pass::set_moon_model(const model* model) |
|
|
|
{ |
|
|
|
moon_model = model; |
|
|
|
|
|
|
|
if (moon_model) |
|
|
|
{ |
|
|
|
moon_model_vao = model->get_vertex_array(); |
|
|
|
|
|
|
|
const std::vector<model_group*>& groups = *model->get_groups(); |
|
|
|
for (model_group* group: groups) |
|
|
|
{ |
|
|
|
moon_material = group->get_material(); |
|
|
|
moon_model_drawing_mode = group->get_drawing_mode(); |
|
|
|
moon_model_start_index = group->get_start_index(); |
|
|
|
moon_model_index_count = group->get_index_count(); |
|
|
|
} |
|
|
|
|
|
|
|
if (moon_material) |
|
|
|
{ |
|
|
|
moon_shader_program = moon_material->get_shader_program(); |
|
|
|
|
|
|
|
if (moon_shader_program) |
|
|
|
{ |
|
|
|
moon_model_view_projection_input = moon_shader_program->get_input("model_view_projection"); |
|
|
|
moon_normal_model_input = moon_shader_program->get_input("normal_model"); |
|
|
|
moon_moon_position_input = moon_shader_program->get_input("moon_position"); |
|
|
|
moon_sun_position_input = moon_shader_program->get_input("sun_position"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
moon_model = nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void sky_pass::update_tweens() |
|
|
|
{ |
|
|
|
julian_day_tween.update(); |
|
|
|