mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-18 00:49:19 +02:00
renderer changes, time and environment window
This commit is contained in:
@@ -127,6 +127,7 @@ set(SOURCES
|
|||||||
"widgets/map.cpp"
|
"widgets/map.cpp"
|
||||||
"widgets/map_objects.cpp"
|
"widgets/map_objects.cpp"
|
||||||
"widgets/popup.cpp"
|
"widgets/popup.cpp"
|
||||||
|
"widgets/time.cpp"
|
||||||
|
|
||||||
"ref/glad/src/glad.c"
|
"ref/glad/src/glad.c"
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ struct global_settings {
|
|||||||
std::mt19937 random_engine;
|
std::mt19937 random_engine;
|
||||||
std::mt19937 local_random_engine;
|
std::mt19937 local_random_engine;
|
||||||
bool ready_to_load { false };
|
bool ready_to_load { false };
|
||||||
|
std::time_t starting_timestamp = 0; // starting time, in local timezone
|
||||||
uint32_t random_seed = 0;
|
uint32_t random_seed = 0;
|
||||||
TCamera pCamera; // parametry kamery
|
TCamera pCamera; // parametry kamery
|
||||||
TCamera pDebugCamera;
|
TCamera pDebugCamera;
|
||||||
@@ -73,8 +74,7 @@ struct global_settings {
|
|||||||
float FrictionWeatherFactor { 1.f };
|
float FrictionWeatherFactor { 1.f };
|
||||||
bool bLiveTraction{ true };
|
bool bLiveTraction{ true };
|
||||||
float Overcast{ 0.1f }; // NOTE: all this weather stuff should be moved elsewhere
|
float Overcast{ 0.1f }; // NOTE: all this weather stuff should be moved elsewhere
|
||||||
glm::vec3 FogColor = { 0.6f, 0.7f, 0.8f };
|
glm::vec3 FogColor = { 0.6f, 0.7f, 0.8f };
|
||||||
double fFogStart{ 1700 };
|
|
||||||
double fFogEnd{ 2000 };
|
double fFogEnd{ 2000 };
|
||||||
std::string Season{}; // season of the year, based on simulation date
|
std::string Season{}; // season of the year, based on simulation date
|
||||||
std::string Weather{ "cloudy:" }; // current weather
|
std::string Weather{ "cloudy:" }; // current weather
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ void UpdateTimers(bool pause)
|
|||||||
QueryPerformanceCounter((LARGE_INTEGER *)&count);
|
QueryPerformanceCounter((LARGE_INTEGER *)&count);
|
||||||
#elif __linux__
|
#elif __linux__
|
||||||
timespec ts;
|
timespec ts;
|
||||||
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
count = (uint64_t)ts.tv_sec * 1000000000 + (uint64_t)ts.tv_nsec;
|
count = (uint64_t)ts.tv_sec * 1000000000 + (uint64_t)ts.tv_nsec;
|
||||||
fr = 1000000000;
|
fr = 1000000000;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -767,6 +767,12 @@ bool eu07_application::init_network() {
|
|||||||
if (!Global.random_seed)
|
if (!Global.random_seed)
|
||||||
Global.random_seed = std::random_device{}();
|
Global.random_seed = std::random_device{}();
|
||||||
Global.random_engine.seed(Global.random_seed);
|
Global.random_engine.seed(Global.random_seed);
|
||||||
|
|
||||||
|
// TODO: sort out this timezone mess
|
||||||
|
std::time_t utc_now = std::time(nullptr);
|
||||||
|
std::time_t local_now = utc_now + (std::mktime(std::localtime(&utc_now)) - std::mktime(std::gmtime(&utc_now)));
|
||||||
|
|
||||||
|
Global.starting_timestamp = local_now;
|
||||||
Global.ready_to_load = true;
|
Global.ready_to_load = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -227,6 +227,9 @@ commanddescription_sequence Commands_descriptions = {
|
|||||||
{ "timejump", command_target::simulation, command_mode::oneoff },
|
{ "timejump", command_target::simulation, command_mode::oneoff },
|
||||||
{ "timejumplarge", command_target::simulation, command_mode::oneoff },
|
{ "timejumplarge", command_target::simulation, command_mode::oneoff },
|
||||||
{ "timejumpsmall", command_target::simulation, command_mode::oneoff },
|
{ "timejumpsmall", command_target::simulation, command_mode::oneoff },
|
||||||
|
{ "setdatetime", command_target::simulation, command_mode::oneoff },
|
||||||
|
{ "setweather", command_target::simulation, command_mode::oneoff },
|
||||||
|
{ "settemperature", command_target::simulation, command_mode::oneoff },
|
||||||
{ "vehiclemove", command_target::vehicle, command_mode::oneoff },
|
{ "vehiclemove", command_target::vehicle, command_mode::oneoff },
|
||||||
{ "vehiclemoveforwards", command_target::vehicle, command_mode::oneoff },
|
{ "vehiclemoveforwards", command_target::vehicle, command_mode::oneoff },
|
||||||
{ "vehiclemovebackwards", command_target::vehicle, command_mode::oneoff },
|
{ "vehiclemovebackwards", command_target::vehicle, command_mode::oneoff },
|
||||||
|
|||||||
@@ -221,6 +221,9 @@ enum class user_command {
|
|||||||
timejump,
|
timejump,
|
||||||
timejumplarge,
|
timejumplarge,
|
||||||
timejumpsmall,
|
timejumpsmall,
|
||||||
|
setdatetime,
|
||||||
|
setweather,
|
||||||
|
settemperature,
|
||||||
vehiclemove,
|
vehiclemove,
|
||||||
vehiclemoveforwards,
|
vehiclemoveforwards,
|
||||||
vehiclemovebackwards,
|
vehiclemovebackwards,
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ driver_ui::driver_ui() {
|
|||||||
push_back( &m_transcriptspanel );
|
push_back( &m_transcriptspanel );
|
||||||
|
|
||||||
//push_back( &m_vehiclelist );
|
//push_back( &m_vehiclelist );
|
||||||
|
push_back( &m_timepanel );
|
||||||
push_back( &m_mappanel );
|
push_back( &m_mappanel );
|
||||||
push_back( &m_logpanel );
|
push_back( &m_logpanel );
|
||||||
m_logpanel.is_open = false;
|
m_logpanel.is_open = false;
|
||||||
@@ -52,6 +53,10 @@ void driver_ui::render_menu_contents() {
|
|||||||
ImGui::MenuItem(m_timetablepanel.title.c_str(), "F2", &m_timetablepanel.is_open);
|
ImGui::MenuItem(m_timetablepanel.title.c_str(), "F2", &m_timetablepanel.is_open);
|
||||||
ImGui::MenuItem(m_debugpanel.get_name().c_str(), "F12", &m_debugpanel.is_open);
|
ImGui::MenuItem(m_debugpanel.get_name().c_str(), "F12", &m_debugpanel.is_open);
|
||||||
ImGui::MenuItem(m_mappanel.get_name().c_str(), "Tab", &m_mappanel.is_open);
|
ImGui::MenuItem(m_mappanel.get_name().c_str(), "Tab", &m_mappanel.is_open);
|
||||||
|
|
||||||
|
if (ImGui::MenuItem(m_timepanel.get_name().c_str()))
|
||||||
|
m_timepanel.open();
|
||||||
|
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#include "widgets/vehiclelist.h"
|
#include "widgets/vehiclelist.h"
|
||||||
#include "widgets/map.h"
|
#include "widgets/map.h"
|
||||||
|
#include "widgets/time.h"
|
||||||
|
|
||||||
class driver_ui : public ui_layer {
|
class driver_ui : public ui_layer {
|
||||||
|
|
||||||
@@ -58,4 +59,5 @@ private:
|
|||||||
command_relay m_relay;
|
command_relay m_relay;
|
||||||
ui::vehiclelist_panel m_vehiclelist;
|
ui::vehiclelist_panel m_vehiclelist;
|
||||||
ui::map_panel m_mappanel;
|
ui::map_panel m_mappanel;
|
||||||
|
ui::time_panel m_timepanel;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,11 +16,13 @@ void network::client_hello::deserialize(std::istream &stream)
|
|||||||
void network::server_hello::serialize(std::ostream &stream) const
|
void network::server_hello::serialize(std::ostream &stream) const
|
||||||
{
|
{
|
||||||
sn_utils::ls_uint32(stream, seed);
|
sn_utils::ls_uint32(stream, seed);
|
||||||
|
sn_utils::ls_int64(stream, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void network::server_hello::deserialize(std::istream &stream)
|
void network::server_hello::deserialize(std::istream &stream)
|
||||||
{
|
{
|
||||||
seed = sn_utils::ld_uint32(stream);
|
seed = sn_utils::ld_uint32(stream);
|
||||||
|
timestamp = sn_utils::ld_int64(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ::network::request_command::serialize(std::ostream &stream) const
|
void ::network::request_command::serialize(std::ostream &stream) const
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ struct server_hello : public message
|
|||||||
server_hello() : message(SERVER_HELLO) {}
|
server_hello() : message(SERVER_HELLO) {}
|
||||||
|
|
||||||
uint32_t seed;
|
uint32_t seed;
|
||||||
|
int64_t timestamp;
|
||||||
|
|
||||||
virtual void serialize(std::ostream &stream) const override;
|
virtual void serialize(std::ostream &stream) const override;
|
||||||
virtual void deserialize(std::istream &stream) override;
|
virtual void deserialize(std::istream &stream) override;
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ void network::server::handle_message(std::shared_ptr<connection> conn, const mes
|
|||||||
|
|
||||||
server_hello reply;
|
server_hello reply;
|
||||||
reply.seed = Global.random_seed;
|
reply.seed = Global.random_seed;
|
||||||
|
reply.timestamp = Global.starting_timestamp;
|
||||||
conn->state = connection::CATCHING_UP;
|
conn->state = connection::CATCHING_UP;
|
||||||
conn->backbuffer = backbuffer;
|
conn->backbuffer = backbuffer;
|
||||||
conn->backbuffer_pos = 0;
|
conn->backbuffer_pos = 0;
|
||||||
@@ -229,6 +230,7 @@ void network::client::handle_message(std::shared_ptr<connection> conn, const mes
|
|||||||
if (!Global.ready_to_load) {
|
if (!Global.ready_to_load) {
|
||||||
Global.random_seed = cmd.seed;
|
Global.random_seed = cmd.seed;
|
||||||
Global.random_engine.seed(Global.random_seed);
|
Global.random_engine.seed(Global.random_seed);
|
||||||
|
Global.starting_timestamp = cmd.timestamp;
|
||||||
Global.ready_to_load = true;
|
Global.ready_to_load = true;
|
||||||
} else if (Global.random_seed != cmd.seed) {
|
} else if (Global.random_seed != cmd.seed) {
|
||||||
ErrorLog("net: seed mismatch", logtype::net);
|
ErrorLog("net: seed mismatch", logtype::net);
|
||||||
|
|||||||
@@ -90,24 +90,28 @@ basic_precipitation::init() {
|
|||||||
|
|
||||||
create( 18 );
|
create( 18 );
|
||||||
|
|
||||||
// TODO: select texture based on current overcast level
|
|
||||||
// TODO: when the overcast level dynamic change is in check the current level during render and pick the appropriate texture on the fly
|
|
||||||
std::string const densitysuffix { (
|
|
||||||
Global.Overcast < 1.35 ?
|
|
||||||
"_light" :
|
|
||||||
"_medium" ) };
|
|
||||||
if( Global.Weather == "rain:" ) {
|
|
||||||
m_moverateweathertypefactor = 2.f;
|
|
||||||
m_texture = GfxRenderer.Fetch_Texture( "fx/rain" + densitysuffix );
|
|
||||||
}
|
|
||||||
else if( Global.Weather == "snow:" ) {
|
|
||||||
m_moverateweathertypefactor = 1.25f;
|
|
||||||
m_texture = GfxRenderer.Fetch_Texture( "fx/snow" + densitysuffix );
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
basic_precipitation::update_weather() {
|
||||||
|
|
||||||
|
// TODO: select texture based on current overcast level
|
||||||
|
// TODO: when the overcast level dynamic change is in check the current level during render and pick the appropriate texture on the fly
|
||||||
|
std::string const densitysuffix { (
|
||||||
|
Global.Overcast < 1.35 ?
|
||||||
|
"_light" :
|
||||||
|
"_medium" ) };
|
||||||
|
if( Global.Weather == "rain:" ) {
|
||||||
|
m_moverateweathertypefactor = 2.f;
|
||||||
|
m_texture = GfxRenderer.Fetch_Texture( "fx/rain" + densitysuffix );
|
||||||
|
}
|
||||||
|
else if( Global.Weather == "snow:" ) {
|
||||||
|
m_moverateweathertypefactor = 1.25f;
|
||||||
|
m_texture = GfxRenderer.Fetch_Texture( "fx/snow" + densitysuffix );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
basic_precipitation::update() {
|
basic_precipitation::update() {
|
||||||
|
|
||||||
|
|||||||
@@ -26,11 +26,14 @@ public:
|
|||||||
// methods
|
// methods
|
||||||
bool
|
bool
|
||||||
init();
|
init();
|
||||||
|
void
|
||||||
|
update_weather();
|
||||||
void
|
void
|
||||||
update();
|
update();
|
||||||
void
|
void
|
||||||
render();
|
render();
|
||||||
float get_textureoffset();
|
float
|
||||||
|
get_textureoffset();
|
||||||
|
|
||||||
glm::dvec3 m_cameramove{ 0.0 };
|
glm::dvec3 m_cameramove{ 0.0 };
|
||||||
|
|
||||||
|
|||||||
75
renderer.cpp
75
renderer.cpp
@@ -195,9 +195,26 @@ bool opengl_renderer::Init(GLFWwindow *Window)
|
|||||||
m_empty_cubemap = std::make_unique<gl::cubemap>();
|
m_empty_cubemap = std::make_unique<gl::cubemap>();
|
||||||
m_empty_cubemap->alloc(Global.gfx_format_color, 16, 16, GL_RGB, GL_FLOAT);
|
m_empty_cubemap->alloc(Global.gfx_format_color, 16, 16, GL_RGB, GL_FLOAT);
|
||||||
|
|
||||||
m_current_viewport = &default_viewport;
|
m_viewports.push_back(std::make_unique<viewport_config>());
|
||||||
if (!init_viewport(default_viewport))
|
viewport_config &default_viewport = *m_viewports.front().get();
|
||||||
return false;
|
default_viewport.width = Global.gfx_framebuffer_width;
|
||||||
|
default_viewport.height = Global.gfx_framebuffer_height;
|
||||||
|
|
||||||
|
/*
|
||||||
|
default_viewport.camera_transform = glm::rotate(glm::mat4(), 0.5f, glm::vec3(1.0f, 0.0f, 0.f));
|
||||||
|
|
||||||
|
m_viewports.push_back(std::make_unique<viewport_config>());
|
||||||
|
viewport_config &vp2 = *m_viewports.back().get();
|
||||||
|
vp2.width = Global.gfx_framebuffer_width;
|
||||||
|
vp2.height = Global.gfx_framebuffer_height;
|
||||||
|
|
||||||
|
vp2.camera_transform = glm::rotate(glm::mat4(), -0.5f, glm::vec3(1.0f, 0.0f, 0.f));
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (auto &viewport : m_viewports) {
|
||||||
|
if (!init_viewport(*viewport.get()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
m_pick_tex = std::make_unique<opengl_texture>();
|
m_pick_tex = std::make_unique<opengl_texture>();
|
||||||
m_pick_tex->alloc_rendertarget(GL_RGB8, GL_RGB, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE);
|
m_pick_tex->alloc_rendertarget(GL_RGB8, GL_RGB, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE);
|
||||||
@@ -271,17 +288,17 @@ bool opengl_renderer::Init(GLFWwindow *Window)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool opengl_renderer::init_viewport(viewport_data &vp)
|
bool opengl_renderer::init_viewport(viewport_config &vp)
|
||||||
{
|
{
|
||||||
int samples = 1 << Global.iMultisampling;
|
int samples = 1 << Global.iMultisampling;
|
||||||
|
|
||||||
if (!Global.gfx_skippipeline)
|
if (!Global.gfx_skippipeline)
|
||||||
{
|
{
|
||||||
vp.msaa_rbc = std::make_unique<gl::renderbuffer>();
|
vp.msaa_rbc = std::make_unique<gl::renderbuffer>();
|
||||||
vp.msaa_rbc->alloc(Global.gfx_format_color, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, samples);
|
vp.msaa_rbc->alloc(Global.gfx_format_color, vp.width, vp.height, samples);
|
||||||
|
|
||||||
vp.msaa_rbd = std::make_unique<gl::renderbuffer>();
|
vp.msaa_rbd = std::make_unique<gl::renderbuffer>();
|
||||||
vp.msaa_rbd->alloc(Global.gfx_format_depth, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, samples);
|
vp.msaa_rbd->alloc(Global.gfx_format_depth, vp.width, vp.height, samples);
|
||||||
|
|
||||||
vp.msaa_fb = std::make_unique<gl::framebuffer>();
|
vp.msaa_fb = std::make_unique<gl::framebuffer>();
|
||||||
vp.msaa_fb->attach(*vp.msaa_rbc, GL_COLOR_ATTACHMENT0);
|
vp.msaa_fb->attach(*vp.msaa_rbc, GL_COLOR_ATTACHMENT0);
|
||||||
@@ -290,17 +307,17 @@ bool opengl_renderer::init_viewport(viewport_data &vp)
|
|||||||
if (Global.gfx_postfx_motionblur_enabled)
|
if (Global.gfx_postfx_motionblur_enabled)
|
||||||
{
|
{
|
||||||
vp.msaa_rbv = std::make_unique<gl::renderbuffer>();
|
vp.msaa_rbv = std::make_unique<gl::renderbuffer>();
|
||||||
vp.msaa_rbv->alloc(Global.gfx_postfx_motionblur_format, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, samples);
|
vp.msaa_rbv->alloc(Global.gfx_postfx_motionblur_format, vp.width, vp.height, samples);
|
||||||
vp.msaa_fb->attach(*vp.msaa_rbv, GL_COLOR_ATTACHMENT1);
|
vp.msaa_fb->attach(*vp.msaa_rbv, GL_COLOR_ATTACHMENT1);
|
||||||
|
|
||||||
vp.main_tex = std::make_unique<opengl_texture>();
|
vp.main_tex = std::make_unique<opengl_texture>();
|
||||||
vp.main_tex->alloc_rendertarget(Global.gfx_format_color, GL_RGB, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, 1, GL_CLAMP_TO_EDGE);
|
vp.main_tex->alloc_rendertarget(Global.gfx_format_color, GL_RGB, vp.width, vp.height, 1, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
vp.main_fb = std::make_unique<gl::framebuffer>();
|
vp.main_fb = std::make_unique<gl::framebuffer>();
|
||||||
vp.main_fb->attach(*vp.main_tex, GL_COLOR_ATTACHMENT0);
|
vp.main_fb->attach(*vp.main_tex, GL_COLOR_ATTACHMENT0);
|
||||||
|
|
||||||
vp.main_texv = std::make_unique<opengl_texture>();
|
vp.main_texv = std::make_unique<opengl_texture>();
|
||||||
vp.main_texv->alloc_rendertarget(Global.gfx_postfx_motionblur_format, GL_RG, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height);
|
vp.main_texv->alloc_rendertarget(Global.gfx_postfx_motionblur_format, GL_RG, vp.width, vp.height);
|
||||||
vp.main_fb->attach(*vp.main_texv, GL_COLOR_ATTACHMENT1);
|
vp.main_fb->attach(*vp.main_texv, GL_COLOR_ATTACHMENT1);
|
||||||
vp.main_fb->setup_drawing(2);
|
vp.main_fb->setup_drawing(2);
|
||||||
|
|
||||||
@@ -314,7 +331,7 @@ bool opengl_renderer::init_viewport(viewport_data &vp)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
vp.main2_tex = std::make_unique<opengl_texture>();
|
vp.main2_tex = std::make_unique<opengl_texture>();
|
||||||
vp.main2_tex->alloc_rendertarget(Global.gfx_format_color, GL_RGB, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height);
|
vp.main2_tex->alloc_rendertarget(Global.gfx_format_color, GL_RGB, vp.width, vp.height);
|
||||||
|
|
||||||
vp.main2_fb = std::make_unique<gl::framebuffer>();
|
vp.main2_fb = std::make_unique<gl::framebuffer>();
|
||||||
vp.main2_fb->attach(*vp.main2_tex, GL_COLOR_ATTACHMENT0);
|
vp.main2_fb->attach(*vp.main2_tex, GL_COLOR_ATTACHMENT0);
|
||||||
@@ -412,7 +429,10 @@ bool opengl_renderer::Render()
|
|||||||
m_renderpass.draw_mode = rendermode::none; // force setup anew
|
m_renderpass.draw_mode = rendermode::none; // force setup anew
|
||||||
m_debugstats = debug_stats();
|
m_debugstats = debug_stats();
|
||||||
|
|
||||||
Render_pass(default_viewport, rendermode::color);
|
for (auto &viewport : m_viewports) {
|
||||||
|
Render_pass(*viewport.get(), rendermode::color);
|
||||||
|
}
|
||||||
|
//Render_pass(*m_viewports.front().get(), rendermode::color);
|
||||||
|
|
||||||
m_drawcount = m_cellqueue.size();
|
m_drawcount = m_cellqueue.size();
|
||||||
m_debugtimestext.clear();
|
m_debugtimestext.clear();
|
||||||
@@ -475,9 +495,9 @@ void opengl_renderer::draw_debug_ui()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// runs jobs needed to generate graphics for specified render pass
|
// runs jobs needed to generate graphics for specified render pass
|
||||||
void opengl_renderer::Render_pass(viewport_data &vp, rendermode const Mode)
|
void opengl_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||||
{
|
{
|
||||||
setup_pass(m_renderpass, Mode);
|
setup_pass(vp, m_renderpass, Mode);
|
||||||
switch (m_renderpass.draw_mode)
|
switch (m_renderpass.draw_mode)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -520,7 +540,7 @@ void opengl_renderer::Render_pass(viewport_data &vp, rendermode const Mode)
|
|||||||
Render_pass(vp, rendermode::shadows);
|
Render_pass(vp, rendermode::shadows);
|
||||||
if (!FreeFlyModeFlag)
|
if (!FreeFlyModeFlag)
|
||||||
Render_pass(vp, rendermode::cabshadows);
|
Render_pass(vp, rendermode::cabshadows);
|
||||||
setup_pass(m_renderpass, Mode); // restore draw mode. TBD, TODO: render mode stack
|
setup_pass(vp, m_renderpass, Mode); // restore draw mode. TBD, TODO: render mode stack
|
||||||
|
|
||||||
Timer::subsystem.gfx_shadows.stop();
|
Timer::subsystem.gfx_shadows.stop();
|
||||||
glDebug("render shadowmap end");
|
glDebug("render shadowmap end");
|
||||||
@@ -530,7 +550,7 @@ void opengl_renderer::Render_pass(viewport_data &vp, rendermode const Mode)
|
|||||||
{
|
{
|
||||||
// potentially update environmental cube map
|
// potentially update environmental cube map
|
||||||
if (Render_reflections(vp))
|
if (Render_reflections(vp))
|
||||||
setup_pass(m_renderpass, Mode); // restore color pass settings
|
setup_pass(vp, m_renderpass, Mode); // restore color pass settings
|
||||||
setup_env_map(vp.env_tex.get());
|
setup_env_map(vp.env_tex.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -851,7 +871,7 @@ void opengl_renderer::Render_pass(viewport_data &vp, rendermode const Mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// creates dynamic environment cubemap
|
// creates dynamic environment cubemap
|
||||||
bool opengl_renderer::Render_reflections(viewport_data &vp)
|
bool opengl_renderer::Render_reflections(viewport_config &vp)
|
||||||
{
|
{
|
||||||
if (Global.ReflectionUpdatesPerSecond == 0)
|
if (Global.ReflectionUpdatesPerSecond == 0)
|
||||||
return false;
|
return false;
|
||||||
@@ -943,7 +963,8 @@ glm::mat4 opengl_renderer::ortho_frustumtest_projection(float l, float r, float
|
|||||||
return glm::ortho(l, r, b, t, znear, zfar);
|
return glm::ortho(l, r, b, t, znear, zfar);
|
||||||
}
|
}
|
||||||
|
|
||||||
void opengl_renderer::setup_pass(renderpass_config &Config, rendermode const Mode, float const Znear, float const Zfar, bool const Ignoredebug)
|
void opengl_renderer::setup_pass(viewport_config &Viewport, renderpass_config &Config, rendermode const Mode,
|
||||||
|
float const Znear, float const Zfar, bool const Ignoredebug)
|
||||||
{
|
{
|
||||||
|
|
||||||
Config.draw_mode = Mode;
|
Config.draw_mode = Mode;
|
||||||
@@ -1001,10 +1022,14 @@ void opengl_renderer::setup_pass(renderpass_config &Config, rendermode const Mod
|
|||||||
float const fovy = glm::radians(Global.FieldOfView / Global.ZoomFactor);
|
float const fovy = glm::radians(Global.FieldOfView / Global.ZoomFactor);
|
||||||
float const aspect = std::max(1.f, (float)Global.iWindowWidth) / std::max(1.f, (float)Global.iWindowHeight);
|
float const aspect = std::max(1.f, (float)Global.iWindowWidth) / std::max(1.f, (float)Global.iWindowHeight);
|
||||||
|
|
||||||
|
Config.viewport_camera.position() = Global.pCamera.Pos;
|
||||||
|
|
||||||
switch (Mode)
|
switch (Mode)
|
||||||
{
|
{
|
||||||
case rendermode::color:
|
case rendermode::color:
|
||||||
{
|
{
|
||||||
|
viewmatrix = glm::dmat4(Viewport.camera_transform);
|
||||||
|
|
||||||
// modelview
|
// modelview
|
||||||
if ((false == DebugCameraFlag) || (true == Ignoredebug))
|
if ((false == DebugCameraFlag) || (true == Ignoredebug))
|
||||||
{
|
{
|
||||||
@@ -1016,6 +1041,7 @@ void opengl_renderer::setup_pass(renderpass_config &Config, rendermode const Mod
|
|||||||
camera.position() = Global.pDebugCamera.Pos;
|
camera.position() = Global.pDebugCamera.Pos;
|
||||||
Global.pDebugCamera.SetMatrix(viewmatrix);
|
Global.pDebugCamera.SetMatrix(viewmatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// projection
|
// projection
|
||||||
auto const zfar = Config.draw_range * Global.fDistanceFactor * Zfar;
|
auto const zfar = Config.draw_range * Global.fDistanceFactor * Zfar;
|
||||||
auto const znear = (Znear > 0.f ? Znear * zfar : 0.1f * Global.ZoomFactor);
|
auto const znear = (Znear > 0.f ? Znear * zfar : 0.1f * Global.ZoomFactor);
|
||||||
@@ -1030,7 +1056,7 @@ void opengl_renderer::setup_pass(renderpass_config &Config, rendermode const Mod
|
|||||||
// ...setup chunk of frustum we're interested in...
|
// ...setup chunk of frustum we're interested in...
|
||||||
auto const zfar = std::min(1.f, Global.shadowtune.depth / (Global.BaseDrawRange * Global.fDistanceFactor) * std::max(1.f, Global.ZoomFactor * 0.5f));
|
auto const zfar = std::min(1.f, Global.shadowtune.depth / (Global.BaseDrawRange * Global.fDistanceFactor) * std::max(1.f, Global.ZoomFactor * 0.5f));
|
||||||
renderpass_config worldview;
|
renderpass_config worldview;
|
||||||
setup_pass(worldview, rendermode::color, 0.f, zfar, true);
|
setup_pass(Viewport, worldview, rendermode::color, 0.f, zfar, true);
|
||||||
auto &frustumchunkshapepoints = worldview.pass_camera.frustum_points();
|
auto &frustumchunkshapepoints = worldview.pass_camera.frustum_points();
|
||||||
// ...modelview matrix: determine the centre of frustum chunk in world space...
|
// ...modelview matrix: determine the centre of frustum chunk in world space...
|
||||||
glm::vec3 frustumchunkmin, frustumchunkmax;
|
glm::vec3 frustumchunkmin, frustumchunkmax;
|
||||||
@@ -1110,9 +1136,12 @@ void opengl_renderer::setup_pass(renderpass_config &Config, rendermode const Mod
|
|||||||
case rendermode::pickcontrols:
|
case rendermode::pickcontrols:
|
||||||
case rendermode::pickscenery:
|
case rendermode::pickscenery:
|
||||||
{
|
{
|
||||||
|
viewmatrix = glm::dmat4(Viewport.camera_transform);
|
||||||
|
|
||||||
// modelview
|
// modelview
|
||||||
camera.position() = Global.pCamera.Pos;
|
camera.position() = Global.pCamera.Pos;
|
||||||
Global.pCamera.SetMatrix(viewmatrix);
|
Global.pCamera.SetMatrix(viewmatrix);
|
||||||
|
|
||||||
// projection
|
// projection
|
||||||
float znear = 0.1f * Global.ZoomFactor;
|
float znear = 0.1f * Global.ZoomFactor;
|
||||||
float zfar = Config.draw_range * Global.fDistanceFactor;
|
float zfar = Config.draw_range * Global.fDistanceFactor;
|
||||||
@@ -1998,7 +2027,7 @@ void opengl_renderer::Render(scene::shape_node const &Shape, bool const Ignorera
|
|||||||
case rendermode::shadows:
|
case rendermode::shadows:
|
||||||
{
|
{
|
||||||
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
||||||
distancesquared = Math3D::SquareMagnitude((data.area.center - Global.pCamera.Pos) / Global.ZoomFactor) / Global.fDistanceFactor;
|
distancesquared = Math3D::SquareMagnitude((data.area.center - m_renderpass.viewport_camera.position()) / (double)Global.ZoomFactor) / Global.fDistanceFactor;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -2052,7 +2081,7 @@ void opengl_renderer::Render(TAnimModel *Instance)
|
|||||||
case rendermode::shadows:
|
case rendermode::shadows:
|
||||||
{
|
{
|
||||||
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
||||||
distancesquared = Math3D::SquareMagnitude((Instance->location() - Global.pCamera.Pos) / Global.ZoomFactor) / Global.fDistanceFactor;
|
distancesquared = Math3D::SquareMagnitude((Instance->location() - m_renderpass.viewport_camera.position()) / (double)Global.ZoomFactor) / Global.fDistanceFactor;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -2110,7 +2139,7 @@ bool opengl_renderer::Render(TDynamicObject *Dynamic)
|
|||||||
{
|
{
|
||||||
case rendermode::shadows:
|
case rendermode::shadows:
|
||||||
{
|
{
|
||||||
squaredistance = glm::length2(glm::vec3{glm::dvec3{Dynamic->vPosition - Global.pCamera.Pos}} / Global.ZoomFactor) / Global.fDistanceFactor;
|
squaredistance = glm::length2(glm::vec3{glm::dvec3{Dynamic->vPosition - m_renderpass.viewport_camera.position()}} / Global.ZoomFactor) / Global.fDistanceFactor;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -3430,7 +3459,7 @@ void opengl_renderer::Update_Pick_Control()
|
|||||||
pickbufferpos = glm::ivec2{mousepos.x * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowWidth), mousepos.y * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowHeight)};
|
pickbufferpos = glm::ivec2{mousepos.x * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowWidth), mousepos.y * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowHeight)};
|
||||||
pickbufferpos = glm::clamp(pickbufferpos, glm::ivec2(0, 0), glm::ivec2(EU07_PICKBUFFERSIZE - 1, EU07_PICKBUFFERSIZE - 1));
|
pickbufferpos = glm::clamp(pickbufferpos, glm::ivec2(0, 0), glm::ivec2(EU07_PICKBUFFERSIZE - 1, EU07_PICKBUFFERSIZE - 1));
|
||||||
|
|
||||||
Render_pass(default_viewport, rendermode::pickcontrols);
|
Render_pass(*m_viewports.front().get(), rendermode::pickcontrols);
|
||||||
m_pick_fb->bind();
|
m_pick_fb->bind();
|
||||||
m_picking_pbo->request_read(pickbufferpos.x, pickbufferpos.y, 1, 1);
|
m_picking_pbo->request_read(pickbufferpos.x, pickbufferpos.y, 1, 1);
|
||||||
m_pick_fb->unbind();
|
m_pick_fb->unbind();
|
||||||
@@ -3469,7 +3498,7 @@ void opengl_renderer::Update_Pick_Node()
|
|||||||
pickbufferpos = glm::ivec2{mousepos.x * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowWidth), mousepos.y * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowHeight)};
|
pickbufferpos = glm::ivec2{mousepos.x * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowWidth), mousepos.y * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowHeight)};
|
||||||
pickbufferpos = glm::clamp(pickbufferpos, glm::ivec2(0, 0), glm::ivec2(EU07_PICKBUFFERSIZE - 1, EU07_PICKBUFFERSIZE - 1));
|
pickbufferpos = glm::clamp(pickbufferpos, glm::ivec2(0, 0), glm::ivec2(EU07_PICKBUFFERSIZE - 1, EU07_PICKBUFFERSIZE - 1));
|
||||||
|
|
||||||
Render_pass(default_viewport, rendermode::pickscenery);
|
Render_pass(*m_viewports.front().get(), rendermode::pickscenery);
|
||||||
m_pick_fb->bind();
|
m_pick_fb->bind();
|
||||||
m_picking_node_pbo->request_read(pickbufferpos.x, pickbufferpos.y, 1, 1);
|
m_picking_node_pbo->request_read(pickbufferpos.x, pickbufferpos.y, 1, 1);
|
||||||
m_pick_fb->unbind();
|
m_pick_fb->unbind();
|
||||||
|
|||||||
19
renderer.h
19
renderer.h
@@ -235,7 +235,12 @@ class opengl_renderer
|
|||||||
float draw_range{0.0f};
|
float draw_range{0.0f};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct viewport_data {
|
struct viewport_config {
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
|
||||||
|
glm::mat4 camera_transform;
|
||||||
|
|
||||||
std::unique_ptr<gl::framebuffer> msaa_fb;
|
std::unique_ptr<gl::framebuffer> msaa_fb;
|
||||||
std::unique_ptr<gl::renderbuffer> msaa_rbc;
|
std::unique_ptr<gl::renderbuffer> msaa_rbc;
|
||||||
std::unique_ptr<gl::renderbuffer> msaa_rbv;
|
std::unique_ptr<gl::renderbuffer> msaa_rbv;
|
||||||
@@ -264,16 +269,16 @@ class opengl_renderer
|
|||||||
// methods
|
// methods
|
||||||
std::unique_ptr<gl::program> make_shader(std::string v, std::string f);
|
std::unique_ptr<gl::program> make_shader(std::string v, std::string f);
|
||||||
bool Init_caps();
|
bool Init_caps();
|
||||||
void setup_pass(renderpass_config &Config, rendermode const Mode, float const Znear = 0.f, float const Zfar = 1.f, bool const Ignoredebug = false);
|
void setup_pass(viewport_config &Viewport, renderpass_config &Config, rendermode const Mode, float const Znear = 0.f, float const Zfar = 1.f, bool const Ignoredebug = false);
|
||||||
void setup_matrices();
|
void setup_matrices();
|
||||||
void setup_drawing(bool const Alpha = false);
|
void setup_drawing(bool const Alpha = false);
|
||||||
void setup_shadow_map(opengl_texture *tex, renderpass_config conf);
|
void setup_shadow_map(opengl_texture *tex, renderpass_config conf);
|
||||||
void setup_env_map(gl::cubemap *tex);
|
void setup_env_map(gl::cubemap *tex);
|
||||||
void setup_environment_light(TEnvironmentType const Environment = e_flat);
|
void setup_environment_light(TEnvironmentType const Environment = e_flat);
|
||||||
// runs jobs needed to generate graphics for specified render pass
|
// runs jobs needed to generate graphics for specified render pass
|
||||||
void Render_pass(viewport_data &vp, rendermode const Mode);
|
void Render_pass(viewport_config &vp, rendermode const Mode);
|
||||||
// creates dynamic environment cubemap
|
// creates dynamic environment cubemap
|
||||||
bool Render_reflections(viewport_data &vp);
|
bool Render_reflections(viewport_config &vp);
|
||||||
bool Render(world_environment *Environment);
|
bool Render(world_environment *Environment);
|
||||||
void Render(scene::basic_region *Region);
|
void Render(scene::basic_region *Region);
|
||||||
void Render(section_sequence::iterator First, section_sequence::iterator Last);
|
void Render(section_sequence::iterator First, section_sequence::iterator Last);
|
||||||
@@ -302,7 +307,7 @@ class opengl_renderer
|
|||||||
glm::vec3 pick_color(std::size_t const Index);
|
glm::vec3 pick_color(std::size_t const Index);
|
||||||
std::size_t pick_index(glm::ivec3 const &Color);
|
std::size_t pick_index(glm::ivec3 const &Color);
|
||||||
|
|
||||||
bool init_viewport(viewport_data &vp);
|
bool init_viewport(viewport_config &vp);
|
||||||
|
|
||||||
void draw(const gfx::geometry_handle &handle);
|
void draw(const gfx::geometry_handle &handle);
|
||||||
void draw(std::vector<gfx::geometrybank_handle>::iterator begin, std::vector<gfx::geometrybank_handle>::iterator end);
|
void draw(std::vector<gfx::geometrybank_handle>::iterator begin, std::vector<gfx::geometrybank_handle>::iterator end);
|
||||||
@@ -350,7 +355,7 @@ class opengl_renderer
|
|||||||
float m_fogrange = 2000.0f;
|
float m_fogrange = 2000.0f;
|
||||||
|
|
||||||
renderpass_config m_renderpass; // parameters for current render pass
|
renderpass_config m_renderpass; // parameters for current render pass
|
||||||
viewport_data *m_current_viewport; // active viewport
|
viewport_config *m_current_viewport; // active viewport
|
||||||
section_sequence m_sectionqueue; // list of sections in current render pass
|
section_sequence m_sectionqueue; // list of sections in current render pass
|
||||||
cell_sequence m_cellqueue;
|
cell_sequence m_cellqueue;
|
||||||
renderpass_config m_colorpass; // parametrs of most recent color pass
|
renderpass_config m_colorpass; // parametrs of most recent color pass
|
||||||
@@ -395,7 +400,7 @@ class opengl_renderer
|
|||||||
|
|
||||||
std::unique_ptr<gl::vao> m_empty_vao;
|
std::unique_ptr<gl::vao> m_empty_vao;
|
||||||
|
|
||||||
viewport_data default_viewport;
|
std::vector<std::unique_ptr<viewport_config>> m_viewports;
|
||||||
|
|
||||||
std::unique_ptr<gl::postfx> m_pfx_motionblur;
|
std::unique_ptr<gl::postfx> m_pfx_motionblur;
|
||||||
std::unique_ptr<gl::postfx> m_pfx_tonemapping;
|
std::unique_ptr<gl::postfx> m_pfx_tonemapping;
|
||||||
|
|||||||
@@ -91,6 +91,6 @@ scenarioloader_mode::enter() {
|
|||||||
void
|
void
|
||||||
scenarioloader_mode::exit() {
|
scenarioloader_mode::exit() {
|
||||||
|
|
||||||
simulation::Time.init();
|
simulation::Time.init(Global.starting_timestamp);
|
||||||
simulation::Environment.init();
|
simulation::Environment.init();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ void state_manager::process_commands() {
|
|||||||
|
|
||||||
if (commanddata.command == user_command::queueevent) {
|
if (commanddata.command == user_command::queueevent) {
|
||||||
uint32_t id = std::round(commanddata.param1);
|
uint32_t id = std::round(commanddata.param1);
|
||||||
basic_event *ev = Events.FindEventById(id);
|
basic_event *ev = Events.FindEventById(id); // TODO: depends on vector position
|
||||||
Events.AddToQuery(ev, nullptr);
|
Events.AddToQuery(ev, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +139,26 @@ void state_manager::process_commands() {
|
|||||||
int light = std::round(commanddata.param1);
|
int light = std::round(commanddata.param1);
|
||||||
float state = commanddata.param2;
|
float state = commanddata.param2;
|
||||||
if (id < simulation::Instances.sequence().size())
|
if (id < simulation::Instances.sequence().size())
|
||||||
simulation::Instances.sequence()[id]->LightSet(light, state);
|
simulation::Instances.sequence()[id]->LightSet(light, state); // TODO: depends on vector position
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commanddata.command == user_command::setdatetime) {
|
||||||
|
int yearday = std::round(commanddata.param1);
|
||||||
|
int minute = std::round(commanddata.param2 * 60.0);
|
||||||
|
simulation::Time.set_time(yearday, minute);
|
||||||
|
|
||||||
|
simulation::Environment.compute_season(yearday);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commanddata.command == user_command::setweather) {
|
||||||
|
Global.fFogEnd = commanddata.param1;
|
||||||
|
Global.Overcast = commanddata.param2;
|
||||||
|
|
||||||
|
simulation::Environment.compute_weather();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commanddata.command == user_command::settemperature) {
|
||||||
|
Global.AirTemperature = commanddata.param1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DebugModeFlag) {
|
if (DebugModeFlag) {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ world_environment::toggle_daylight() {
|
|||||||
|
|
||||||
// calculates current season of the year based on set simulation date
|
// calculates current season of the year based on set simulation date
|
||||||
void
|
void
|
||||||
world_environment::compute_season( int const Yearday ) const {
|
world_environment::compute_season( int const Yearday ) {
|
||||||
|
|
||||||
using dayseasonpair = std::pair<int, std::string>;
|
using dayseasonpair = std::pair<int, std::string>;
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ world_environment::compute_season( int const Yearday ) const {
|
|||||||
|
|
||||||
// calculates current weather
|
// calculates current weather
|
||||||
void
|
void
|
||||||
world_environment::compute_weather() const {
|
world_environment::compute_weather() {
|
||||||
|
|
||||||
Global.Weather = (
|
Global.Weather = (
|
||||||
Global.Overcast <= 0.25 ? "clear:" :
|
Global.Overcast <= 0.25 ? "clear:" :
|
||||||
@@ -67,6 +67,8 @@ world_environment::compute_weather() const {
|
|||||||
( Global.Season != "winter:" ?
|
( Global.Season != "winter:" ?
|
||||||
"rain:" :
|
"rain:" :
|
||||||
"snow:" ) );
|
"snow:" ) );
|
||||||
|
|
||||||
|
m_precipitation.update_weather();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -161,7 +163,11 @@ world_environment::update() {
|
|||||||
else if( Global.Weather == "snow:" ) {
|
else if( Global.Weather == "snow:" ) {
|
||||||
// reduce friction due to snow
|
// reduce friction due to snow
|
||||||
Global.FrictionWeatherFactor = 0.75f;
|
Global.FrictionWeatherFactor = 0.75f;
|
||||||
|
m_precipitationsound.stop();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
m_precipitationsound.stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ public:
|
|||||||
// switches between static and dynamic daylight calculation
|
// switches between static and dynamic daylight calculation
|
||||||
void toggle_daylight();
|
void toggle_daylight();
|
||||||
// calculates current season of the year based on set simulation date
|
// calculates current season of the year based on set simulation date
|
||||||
void compute_season( int const Yearday ) const;
|
void compute_season( int const Yearday );
|
||||||
// calculates current weather
|
// calculates current weather
|
||||||
void compute_weather() const;
|
void compute_weather();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// members
|
// members
|
||||||
|
|||||||
@@ -150,10 +150,9 @@ state_serializer::deserialize_atmo( cParser &Input, scene::scratch_data &Scratch
|
|||||||
// atmosphere color; legacy parameter, no longer used
|
// atmosphere color; legacy parameter, no longer used
|
||||||
Input.getTokens( 3 );
|
Input.getTokens( 3 );
|
||||||
// fog range
|
// fog range
|
||||||
Input.getTokens( 2 );
|
Input.getTokens( 1 ); // fog start ignored
|
||||||
Input
|
Input.getTokens( 1 );
|
||||||
>> Global.fFogStart
|
Input >> Global.fFogEnd;
|
||||||
>> Global.fFogEnd;
|
|
||||||
|
|
||||||
if( Global.fFogEnd > 0.0 ) {
|
if( Global.fFogEnd > 0.0 ) {
|
||||||
// fog colour; optional legacy parameter, no longer used
|
// fog colour; optional legacy parameter, no longer used
|
||||||
@@ -297,9 +296,24 @@ state_serializer::deserialize_firstinit( cParser &Input, scene::scratch_data &Sc
|
|||||||
simulation::Events.InitLaunchers();
|
simulation::Events.InitLaunchers();
|
||||||
simulation::Memory.InitCells();
|
simulation::Memory.InitCells();
|
||||||
|
|
||||||
|
init_time();
|
||||||
|
|
||||||
Scratchpad.initialized = true;
|
Scratchpad.initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void state_serializer::init_time() {
|
||||||
|
auto &time = simulation::Time.data();
|
||||||
|
if( true == Global.ScenarioTimeCurrent ) {
|
||||||
|
// calculate time shift required to match scenario time with local clock
|
||||||
|
auto const *localtime = std::gmtime( &Global.starting_timestamp );
|
||||||
|
Global.ScenarioTimeOffset = ( ( localtime->tm_hour * 60 + localtime->tm_min ) - ( time.wHour * 60 + time.wMinute ) ) / 60.f;
|
||||||
|
}
|
||||||
|
else if( false == std::isnan( Global.ScenarioTimeOverride ) ) {
|
||||||
|
// scenario time override takes precedence over scenario time offset
|
||||||
|
Global.ScenarioTimeOffset = ( ( Global.ScenarioTimeOverride * 60 ) - ( time.wHour * 60 + time.wMinute ) ) / 60.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_serializer::deserialize_group( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_group( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
@@ -583,17 +597,6 @@ state_serializer::deserialize_time( cParser &Input, scene::scratch_data &Scratch
|
|||||||
>> time.wHour
|
>> time.wHour
|
||||||
>> time.wMinute;
|
>> time.wMinute;
|
||||||
|
|
||||||
if( true == Global.ScenarioTimeCurrent ) {
|
|
||||||
// calculate time shift required to match scenario time with local clock
|
|
||||||
auto timenow = std::time( 0 );
|
|
||||||
auto const *localtime = std::localtime( &timenow );
|
|
||||||
Global.ScenarioTimeOffset = ( ( localtime->tm_hour * 60 + localtime->tm_min ) - ( time.wHour * 60 + time.wMinute ) ) / 60.f;
|
|
||||||
}
|
|
||||||
else if( false == std::isnan( Global.ScenarioTimeOverride ) ) {
|
|
||||||
// scenario time override takes precedence over scenario time offset
|
|
||||||
Global.ScenarioTimeOffset = ( ( Global.ScenarioTimeOverride * 60 ) - ( time.wHour * 60 + time.wMinute ) ) / 60.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remaining sunrise and sunset parameters are no longer used, as they're now calculated dynamically
|
// remaining sunrise and sunset parameters are no longer used, as they're now calculated dynamically
|
||||||
// anything else left in the section has no defined meaning
|
// anything else left in the section has no defined meaning
|
||||||
skip_until( Input, "endtime" );
|
skip_until( Input, "endtime" );
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ private:
|
|||||||
TAnimModel * deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
TAnimModel * deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
TDynamicObject * deserialize_dynamic( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
TDynamicObject * deserialize_dynamic( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
sound_source * deserialize_sound( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
sound_source * deserialize_sound( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
|
void init_time();
|
||||||
// skips content of stream until specified token
|
// skips content of stream until specified token
|
||||||
void skip_until( cParser &Input, std::string const &Token );
|
void skip_until( cParser &Input, std::string const &Token );
|
||||||
// transforms provided location by specifed rotation and offset
|
// transforms provided location by specifed rotation and offset
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ scenario_time Time;
|
|||||||
} // simulation
|
} // simulation
|
||||||
|
|
||||||
void
|
void
|
||||||
scenario_time::init() {
|
scenario_time::init(std::time_t timestamp) {
|
||||||
char monthdaycounts[ 2 ][ 13 ] = {
|
char monthdaycounts[ 2 ][ 13 ] = {
|
||||||
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
|
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
|
||||||
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
|
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
|
||||||
@@ -32,10 +32,7 @@ scenario_time::init() {
|
|||||||
auto const requestedminute { requestedtime % 60 };
|
auto const requestedminute { requestedtime % 60 };
|
||||||
// cache requested elements, if any
|
// cache requested elements, if any
|
||||||
|
|
||||||
#ifdef __linux__
|
std::tm *tms = std::gmtime(×tamp);
|
||||||
timespec ts;
|
|
||||||
clock_gettime(CLOCK_REALTIME, &ts);
|
|
||||||
tm *tms = localtime(&ts.tv_sec);
|
|
||||||
m_time.wYear = tms->tm_year;
|
m_time.wYear = tms->tm_year;
|
||||||
m_time.wMonth = tms->tm_mon;
|
m_time.wMonth = tms->tm_mon;
|
||||||
m_time.wDayOfWeek = tms->tm_wday;
|
m_time.wDayOfWeek = tms->tm_wday;
|
||||||
@@ -43,16 +40,7 @@ scenario_time::init() {
|
|||||||
m_time.wHour = tms->tm_hour;
|
m_time.wHour = tms->tm_hour;
|
||||||
m_time.wMinute = tms->tm_min;
|
m_time.wMinute = tms->tm_min;
|
||||||
m_time.wSecond = tms->tm_sec;
|
m_time.wSecond = tms->tm_sec;
|
||||||
m_time.wMilliseconds = ts.tv_nsec / 1000000;
|
m_time.wMilliseconds = 0;
|
||||||
|
|
||||||
/*
|
|
||||||
time_t local = mktime(localtime(&ts.tv_sec));
|
|
||||||
time_t utc = mktime(gmtime(&ts.tv_sec));
|
|
||||||
m_timezonebias = (double)(local - utc) / 3600.0f;
|
|
||||||
*/
|
|
||||||
#elif _WIN32
|
|
||||||
::GetLocalTime( &m_time );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if( Global.fMoveLight > 0.0 ) {
|
if( Global.fMoveLight > 0.0 ) {
|
||||||
// day and month of the year can be overriden by scenario setup
|
// day and month of the year can be overriden by scenario setup
|
||||||
@@ -94,7 +82,7 @@ scenario_time::init() {
|
|||||||
zonebias += timezoneinfo.StandardBias;
|
zonebias += timezoneinfo.StandardBias;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_timezonebias = ( zonebias / 60.0 );
|
m_timezonebias = ( zonebias / 60.0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -197,6 +185,12 @@ scenario_time::julian_day() const {
|
|||||||
return JD;
|
return JD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scenario_time::set_time(int yearday, int minute) {
|
||||||
|
daymonth(m_time.wDay, m_time.wMonth, m_time.wYear, yearday);
|
||||||
|
m_time.wHour = minute / 60;
|
||||||
|
m_time.wMinute = minute % 60;
|
||||||
|
}
|
||||||
|
|
||||||
// calculates day of week for provided date
|
// calculates day of week for provided date
|
||||||
int
|
int
|
||||||
scenario_time::day_of_week( int const Day, int const Month, int const Year ) const {
|
scenario_time::day_of_week( int const Day, int const Month, int const Year ) const {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public:
|
|||||||
scenario_time() {
|
scenario_time() {
|
||||||
m_time.wHour = 10; m_time.wMinute = 30; }
|
m_time.wHour = 10; m_time.wMinute = 30; }
|
||||||
void
|
void
|
||||||
init();
|
init(time_t timestamp);
|
||||||
void
|
void
|
||||||
update( double const Deltatime );
|
update( double const Deltatime );
|
||||||
inline
|
inline
|
||||||
@@ -45,6 +45,8 @@ public:
|
|||||||
double
|
double
|
||||||
zone_bias() const {
|
zone_bias() const {
|
||||||
return m_timezonebias; }
|
return m_timezonebias; }
|
||||||
|
void
|
||||||
|
set_time(int yearday, int minute);
|
||||||
|
|
||||||
/** Returns std::string in format: `"mm:ss"`. */
|
/** Returns std::string in format: `"mm:ss"`. */
|
||||||
operator std::string();
|
operator std::string();
|
||||||
|
|||||||
26
sn_utils.cpp
26
sn_utils.cpp
@@ -38,6 +38,18 @@ int32_t sn_utils::ld_int32(std::istream &s)
|
|||||||
return reinterpret_cast<int32_t&>(v);
|
return reinterpret_cast<int32_t&>(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deserialize little endian int64
|
||||||
|
int64_t sn_utils::ld_int64(std::istream &s)
|
||||||
|
{
|
||||||
|
uint8_t buf[8];
|
||||||
|
s.read((char*)buf, 8);
|
||||||
|
uint64_t v = ((uint64_t)buf[7] << 56) | ((uint64_t)buf[6] << 48) |
|
||||||
|
((uint64_t)buf[5] << 40) | ((uint64_t)buf[4] << 32) |
|
||||||
|
((uint64_t)buf[3] << 24) | ((uint64_t)buf[2] << 16) |
|
||||||
|
((uint64_t)buf[1] << 8) | (uint64_t)buf[0];
|
||||||
|
return reinterpret_cast<int64_t&>(v);
|
||||||
|
}
|
||||||
|
|
||||||
// deserialize little endian ieee754 float32
|
// deserialize little endian ieee754 float32
|
||||||
float sn_utils::ld_float32(std::istream &s)
|
float sn_utils::ld_float32(std::istream &s)
|
||||||
{
|
{
|
||||||
@@ -133,6 +145,20 @@ void sn_utils::ls_int32(std::ostream &s, int32_t v)
|
|||||||
s.write((char*)buf, 4);
|
s.write((char*)buf, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sn_utils::ls_int64(std::ostream &s, int64_t v)
|
||||||
|
{
|
||||||
|
uint8_t buf[8];
|
||||||
|
buf[0] = v;
|
||||||
|
buf[1] = v >> 8;
|
||||||
|
buf[2] = v >> 16;
|
||||||
|
buf[3] = v >> 24;
|
||||||
|
buf[4] = v >> 32;
|
||||||
|
buf[5] = v >> 40;
|
||||||
|
buf[6] = v >> 48;
|
||||||
|
buf[7] = v >> 56;
|
||||||
|
s.write((char*)buf, 8);
|
||||||
|
}
|
||||||
|
|
||||||
void sn_utils::ls_float32(std::ostream &s, float t)
|
void sn_utils::ls_float32(std::ostream &s, float t)
|
||||||
{
|
{
|
||||||
uint32_t v = reinterpret_cast<uint32_t&>(t);
|
uint32_t v = reinterpret_cast<uint32_t&>(t);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ public:
|
|||||||
static uint16_t ld_uint16(std::istream&);
|
static uint16_t ld_uint16(std::istream&);
|
||||||
static uint32_t ld_uint32(std::istream&);
|
static uint32_t ld_uint32(std::istream&);
|
||||||
static int32_t ld_int32(std::istream&);
|
static int32_t ld_int32(std::istream&);
|
||||||
|
static int64_t ld_int64(std::istream&);
|
||||||
static float ld_float32(std::istream&);
|
static float ld_float32(std::istream&);
|
||||||
static double ld_float64(std::istream&);
|
static double ld_float64(std::istream&);
|
||||||
static std::string d_str(std::istream&);
|
static std::string d_str(std::istream&);
|
||||||
@@ -21,6 +22,7 @@ public:
|
|||||||
static void ls_uint16(std::ostream&, uint16_t);
|
static void ls_uint16(std::ostream&, uint16_t);
|
||||||
static void ls_uint32(std::ostream&, uint32_t);
|
static void ls_uint32(std::ostream&, uint32_t);
|
||||||
static void ls_int32(std::ostream&, int32_t);
|
static void ls_int32(std::ostream&, int32_t);
|
||||||
|
static void ls_int64(std::ostream&, int64_t);
|
||||||
static void ls_float32(std::ostream&, float);
|
static void ls_float32(std::ostream&, float);
|
||||||
static void ls_float64(std::ostream&, double);
|
static void ls_float64(std::ostream&, double);
|
||||||
static void s_str(std::ostream&, std::string);
|
static void s_str(std::ostream&, std::string);
|
||||||
|
|||||||
@@ -79,6 +79,14 @@ init() {
|
|||||||
"Map",
|
"Map",
|
||||||
"Mode windows",
|
"Mode windows",
|
||||||
|
|
||||||
|
"Time and environment",
|
||||||
|
"Time",
|
||||||
|
"Day in year",
|
||||||
|
"Visibility",
|
||||||
|
"Overcast and precipitation",
|
||||||
|
"Temperature",
|
||||||
|
"Apply",
|
||||||
|
|
||||||
"Straight |",
|
"Straight |",
|
||||||
"Divert /",
|
"Divert /",
|
||||||
|
|
||||||
@@ -242,6 +250,14 @@ init() {
|
|||||||
u8"Mapa",
|
u8"Mapa",
|
||||||
u8"Okna trybu",
|
u8"Okna trybu",
|
||||||
|
|
||||||
|
u8"Czas i środowisko",
|
||||||
|
u8"Czas",
|
||||||
|
u8"Dzień w roku",
|
||||||
|
u8"Widoczność",
|
||||||
|
u8"Zachmurzenie i opady",
|
||||||
|
u8"Temperatura",
|
||||||
|
u8"Zastosuj",
|
||||||
|
|
||||||
u8"Prosto |",
|
u8"Prosto |",
|
||||||
u8"W bok /",
|
u8"W bok /",
|
||||||
|
|
||||||
|
|||||||
@@ -68,6 +68,14 @@ enum string {
|
|||||||
ui_map,
|
ui_map,
|
||||||
ui_mode_windows,
|
ui_mode_windows,
|
||||||
|
|
||||||
|
time_window,
|
||||||
|
time_time,
|
||||||
|
time_yearday,
|
||||||
|
time_visibility,
|
||||||
|
time_weather,
|
||||||
|
time_temperature,
|
||||||
|
time_apply,
|
||||||
|
|
||||||
map_straight,
|
map_straight,
|
||||||
map_divert,
|
map_divert,
|
||||||
|
|
||||||
|
|||||||
@@ -133,8 +133,10 @@ void ui::map_panel::render_labels(glm::mat4 transform, ImVec2 origin, glm::vec2
|
|||||||
for (TDynamicObject *vehicle : simulation::Vehicles.sequence()) {
|
for (TDynamicObject *vehicle : simulation::Vehicles.sequence()) {
|
||||||
if (vehicle->Prev() || !vehicle->Mechanik)
|
if (vehicle->Prev() || !vehicle->Mechanik)
|
||||||
continue;
|
continue;
|
||||||
if (vehicle->Mechanik->TrainName().empty())
|
|
||||||
continue;
|
std::string label = vehicle->Mechanik->TrainName();
|
||||||
|
if (label.empty() || label == "none")
|
||||||
|
label = ToUpper(vehicle->name());
|
||||||
|
|
||||||
glm::vec4 ndc_pos = transform * glm::vec4(glm::vec3(vehicle->GetPosition()), 1.0f);
|
glm::vec4 ndc_pos = transform * glm::vec4(glm::vec3(vehicle->GetPosition()), 1.0f);
|
||||||
if (glm::abs(ndc_pos.x) > 1.0f || glm::abs(ndc_pos.z) > 1.0f)
|
if (glm::abs(ndc_pos.x) > 1.0f || glm::abs(ndc_pos.z) > 1.0f)
|
||||||
@@ -144,11 +146,10 @@ void ui::map_panel::render_labels(glm::mat4 transform, ImVec2 origin, glm::vec2
|
|||||||
|
|
||||||
TDynamicObject *veh = vehicle;
|
TDynamicObject *veh = vehicle;
|
||||||
|
|
||||||
const char *desc = vehicle->Mechanik->TrainName().c_str();
|
ImVec2 textsize = ImGui::CalcTextSize(label.c_str());
|
||||||
ImVec2 textsize = ImGui::CalcTextSize(desc);
|
|
||||||
ImGui::SetCursorPos(ImVec2(origin.x + gui_pos.x - textsize.x / 2.0f,
|
ImGui::SetCursorPos(ImVec2(origin.x + gui_pos.x - textsize.x / 2.0f,
|
||||||
origin.y + gui_pos.y - textsize.y / 2.0f));
|
origin.y + gui_pos.y - textsize.y / 2.0f));
|
||||||
ImGui::TextUnformatted(desc);
|
ImGui::TextUnformatted(label.c_str());
|
||||||
}
|
}
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
|
|||||||
41
widgets/time.cpp
Normal file
41
widgets/time.cpp
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "widgets/time.h"
|
||||||
|
#include "simulationtime.h"
|
||||||
|
#include "Globals.h"
|
||||||
|
|
||||||
|
ui::time_panel::time_panel()
|
||||||
|
: ui_panel(LOC_STR(time_window), false)
|
||||||
|
{
|
||||||
|
size.x = 450;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::time_panel::render_contents()
|
||||||
|
{
|
||||||
|
ImGui::SliderFloat(LOC_STR(time_time), &time, 0.0f, 24.0f, "%.1f");
|
||||||
|
ImGui::SliderInt(LOC_STR(time_yearday), &yearday, 1, 365);
|
||||||
|
ImGui::SliderFloat(LOC_STR(time_visibility), &fog, 50.0f, 3000.0f, "%.0f");
|
||||||
|
ImGui::SliderFloat(LOC_STR(time_weather), &overcast, 0.0f, 2.0f, "%.1f");
|
||||||
|
ImGui::SliderFloat(LOC_STR(time_temperature), &temperature, -20.0f, 40.0f, "%.0f");
|
||||||
|
|
||||||
|
if (ImGui::Button(LOC_STR(time_apply))) {
|
||||||
|
m_relay.post(user_command::setdatetime, (double)yearday, time, 1, 0);
|
||||||
|
m_relay.post(user_command::setweather, fog, overcast, 1, 0);
|
||||||
|
m_relay.post(user_command::settemperature, temperature, 0.0, 1, 0);
|
||||||
|
|
||||||
|
is_open = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::time_panel::open()
|
||||||
|
{
|
||||||
|
auto &data = simulation::Time.data();
|
||||||
|
time = (float)data.wHour + (float)data.wMinute / 60.0f;
|
||||||
|
|
||||||
|
yearday = simulation::Time.year_day();
|
||||||
|
fog = Global.fFogEnd;
|
||||||
|
|
||||||
|
overcast = Global.Overcast;
|
||||||
|
temperature = Global.AirTemperature;
|
||||||
|
|
||||||
|
is_open = true;
|
||||||
|
}
|
||||||
21
widgets/time.h
Normal file
21
widgets/time.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#include "uilayer.h"
|
||||||
|
#include "translation.h"
|
||||||
|
#include "command.h"
|
||||||
|
|
||||||
|
namespace ui {
|
||||||
|
class time_panel : public ui_panel {
|
||||||
|
command_relay m_relay;
|
||||||
|
|
||||||
|
float time;
|
||||||
|
int yearday;
|
||||||
|
float fog;
|
||||||
|
float overcast;
|
||||||
|
float temperature;
|
||||||
|
|
||||||
|
public:
|
||||||
|
time_panel();
|
||||||
|
|
||||||
|
void render_contents() override;
|
||||||
|
void open();
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user