diff --git a/src/game/states/play-state.cpp b/src/game/states/play-state.cpp index d9a24c8..a480774 100644 --- a/src/game/states/play-state.cpp +++ b/src/game/states/play-state.cpp @@ -89,6 +89,7 @@ void play_state_enter(game_context* ctx) sky_pass* sky_pass = ctx->overworld_sky_pass; sky_pass->set_enabled(true); sky_pass->set_sky_model(ctx->resource_manager->load("sky-dome.mdl")); + sky_pass->set_moon_model(ctx->resource_manager->load("moon.mdl")); ctx->weather_system->set_coordinates(ctx->biome->coordinates); ctx->weather_system->set_time(2020, 6, 1, 5, 0, 0, -7.0); diff --git a/src/game/systems/vegetation-system.cpp b/src/game/systems/vegetation-system.cpp index 6c65da3..8727761 100644 --- a/src/game/systems/vegetation-system.cpp +++ b/src/game/systems/vegetation-system.cpp @@ -90,7 +90,6 @@ void vegetation_system::on_terrain_construct(entt::registry& registry, entt::ent for (int row = 0; row < vegetation_patch_rows; ++row) { // Calculate center of vegetation patch - /* // Create vegetation patch entity diff --git a/src/renderer/passes/sky-pass.cpp b/src/renderer/passes/sky-pass.cpp index af79b9d..b2594ed 100644 --- a/src/renderer/passes/sky-pass.cpp +++ b/src/renderer/passes/sky-pass.cpp @@ -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 #include +#include 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, 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, 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& 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(); diff --git a/src/renderer/passes/sky-pass.hpp b/src/renderer/passes/sky-pass.hpp index 01785c2..b8c494a 100644 --- a/src/renderer/passes/sky-pass.hpp +++ b/src/renderer/passes/sky-pass.hpp @@ -33,6 +33,7 @@ class vertex_array; class texture_2d; class resource_manager; class model; +class material; enum class drawing_mode; /** @@ -53,6 +54,7 @@ public: void set_time_of_day(float time); void set_blue_noise_map(const texture_2d* texture); void set_time_tween(const tween* time); + void set_moon_model(const model* model); void set_julian_day(float jd); void set_observer_coordinates(const float2& coordinates); @@ -76,16 +78,25 @@ private: const shader_input* moon_az_el_input; const shader_input* blue_noise_map_input; const shader_input* julian_day_input; - - vertex_buffer* quad_vbo; - vertex_array* quad_vao; + ::shader_program* moon_shader_program; + const shader_input* moon_model_view_projection_input; + const shader_input* moon_normal_model_input; + const shader_input* moon_moon_position_input; + const shader_input* moon_sun_position_input; const model* sky_model; const vertex_array* sky_model_vao; drawing_mode sky_model_drawing_mode; std::size_t sky_model_start_index; std::size_t sky_model_index_count; + + const model* moon_model; + const material* moon_material; + const vertex_array* moon_model_vao; + drawing_mode moon_model_drawing_mode; + std::size_t moon_model_start_index; + std::size_t moon_model_index_count; const texture_2d* blue_noise_map; float2 mouse_position;