mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
opengl 3.3 renderer cascaded shadow maps, minor gfx renderer optimizations
This commit is contained in:
@@ -166,8 +166,8 @@ bool opengl33_renderer::Init(GLFWwindow *Window)
|
||||
{
|
||||
m_shadow_fb = std::make_unique<gl::framebuffer>();
|
||||
m_shadow_tex = std::make_unique<opengl_texture>();
|
||||
m_shadow_tex->alloc_rendertarget(Global.gfx_format_depth, GL_DEPTH_COMPONENT, m_shadowbuffersize, m_shadowbuffersize);
|
||||
m_shadow_fb->attach(*m_shadow_tex, GL_DEPTH_ATTACHMENT);
|
||||
m_shadow_tex->alloc_rendertarget(Global.gfx_format_depth, GL_DEPTH_COMPONENT, m_shadowbuffersize, m_shadowbuffersize, m_shadowpass.size());
|
||||
m_shadow_fb->attach(*m_shadow_tex, GL_DEPTH_ATTACHMENT, 0);
|
||||
|
||||
if( !m_shadow_fb->is_complete() ) {
|
||||
ErrorLog( "shadow framebuffer setup failed" );
|
||||
@@ -175,18 +175,6 @@ bool opengl33_renderer::Init(GLFWwindow *Window)
|
||||
}
|
||||
|
||||
WriteLog("shadows enabled");
|
||||
|
||||
m_cabshadows_fb = std::make_unique<gl::framebuffer>();
|
||||
m_cabshadows_tex = std::make_unique<opengl_texture>();
|
||||
m_cabshadows_tex->alloc_rendertarget(Global.gfx_format_depth, GL_DEPTH_COMPONENT, m_shadowbuffersize, m_shadowbuffersize);
|
||||
m_cabshadows_fb->attach(*m_cabshadows_tex, GL_DEPTH_ATTACHMENT);
|
||||
|
||||
if( !m_cabshadows_fb->is_complete() ) {
|
||||
ErrorLog( "cabshadows framebuffer setup failed" );
|
||||
return false;
|
||||
}
|
||||
|
||||
WriteLog("cabshadows enabled");
|
||||
}
|
||||
|
||||
if (Global.gfx_envmap_enabled)
|
||||
@@ -378,7 +366,7 @@ bool opengl33_renderer::init_viewport(viewport_config &vp)
|
||||
vp.msaa_fb->attach(*vp.msaa_rbv, GL_COLOR_ATTACHMENT1);
|
||||
|
||||
vp.main_tex = std::make_unique<opengl_texture>();
|
||||
vp.main_tex->alloc_rendertarget(Global.gfx_format_color, GL_RGB, vp.width, vp.height, 1, GL_CLAMP_TO_EDGE);
|
||||
vp.main_tex->alloc_rendertarget(Global.gfx_format_color, GL_RGB, vp.width, vp.height, 1, 1, GL_CLAMP_TO_EDGE);
|
||||
|
||||
vp.main_fb = std::make_unique<gl::framebuffer>();
|
||||
vp.main_fb->attach(*vp.main_tex, GL_COLOR_ATTACHMENT0);
|
||||
@@ -448,7 +436,7 @@ bool opengl33_renderer::Render()
|
||||
opengl_texture::reset_unit_cache();
|
||||
|
||||
m_renderpass.draw_mode = rendermode::none; // force setup anew
|
||||
m_debugstats = debug_stats();
|
||||
m_renderpass.draw_stats = debug_stats();
|
||||
|
||||
for (auto &viewport : m_viewports) {
|
||||
Render_pass(*viewport, rendermode::color);
|
||||
@@ -471,10 +459,27 @@ bool opengl33_renderer::Render()
|
||||
if (m_gllasttime)
|
||||
m_debugtimestext += "gpu: " + to_string((double)(m_gllasttime / 1000ULL) / 1000.0, 3) + "ms";
|
||||
}
|
||||
|
||||
m_debugstatstext = "drawcalls: " + to_string(m_debugstats.drawcalls) + "\n" + " vehicles: " + to_string(m_debugstats.dynamics) + "\n" + " models: " + to_string(m_debugstats.models) + "\n" +
|
||||
" submodels: " + to_string(m_debugstats.submodels) + "\n" + " paths: " + to_string(m_debugstats.paths) + "\n" + " shapes: " + to_string(m_debugstats.shapes) + "\n" +
|
||||
" traction: " + to_string(m_debugstats.traction) + "\n" + " lines: " + to_string(m_debugstats.lines);
|
||||
|
||||
debug_stats shadowstats;
|
||||
for( auto const &shadowpass : m_shadowpass ) {
|
||||
shadowstats += shadowpass.draw_stats;
|
||||
}
|
||||
m_debugstatstext =
|
||||
"vehicles: " + to_string( m_colorpass.draw_stats.dynamics, 7 ) + " +" + to_string( shadowstats.dynamics, 7 )
|
||||
+ " =" + to_string( m_colorpass.draw_stats.dynamics + shadowstats.dynamics, 7 ) + "\n"
|
||||
+ "models: " + to_string( m_colorpass.draw_stats.models, 7 ) + " +" + to_string( shadowstats.models, 7 )
|
||||
+ " =" + to_string( m_colorpass.draw_stats.models + shadowstats.models, 7 ) + "\n"
|
||||
+ "drawcalls: " + to_string( m_colorpass.draw_stats.drawcalls, 7 ) + " +" + to_string( shadowstats.drawcalls, 7 )
|
||||
+ " =" + to_string( m_colorpass.draw_stats.drawcalls + shadowstats.drawcalls, 7 ) + "\n"
|
||||
+ " submodels:" + to_string( m_colorpass.draw_stats.submodels, 7 ) + " +" + to_string( shadowstats.submodels, 7 )
|
||||
+ " =" + to_string( m_colorpass.draw_stats.submodels + shadowstats.submodels, 7 ) + "\n"
|
||||
+ " paths: " + to_string( m_colorpass.draw_stats.paths, 7 ) + " +" + to_string( shadowstats.paths, 7 )
|
||||
+ " =" + to_string( m_colorpass.draw_stats.paths + shadowstats.paths, 7 ) + "\n"
|
||||
+ " shapes: " + to_string( m_colorpass.draw_stats.shapes, 7 ) + " +" + to_string( shadowstats.shapes, 7 )
|
||||
+ " =" + to_string( m_colorpass.draw_stats.shapes + shadowstats.shapes, 7 ) + "\n"
|
||||
+ " traction: " + to_string( m_colorpass.draw_stats.traction, 7 ) + "\n"
|
||||
+ " lines: " + to_string( m_colorpass.draw_stats.lines, 7 ) + "\n"
|
||||
+ "particles: " + to_string( m_colorpass.draw_stats.particles, 7 );
|
||||
|
||||
if (DebugModeFlag)
|
||||
m_debugtimestext += m_textures.info();
|
||||
@@ -528,7 +533,7 @@ void opengl33_renderer::draw_debug_ui()
|
||||
void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||
{
|
||||
setup_pass(vp, m_renderpass, Mode);
|
||||
switch (m_renderpass.draw_mode)
|
||||
switch (m_renderpass.draw_mode)
|
||||
{
|
||||
|
||||
case rendermode::color:
|
||||
@@ -553,14 +558,14 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||
break;
|
||||
}
|
||||
|
||||
m_colorpass = m_renderpass; // cache pass data
|
||||
|
||||
scene_ubs.time = Timer::GetTime();
|
||||
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
|
||||
scene_ubs.inv_view = glm::inverse( glm::mat4{ glm::mat3{ m_renderpass.pass_camera.modelview() } } );
|
||||
scene_ubo->update(scene_ubs);
|
||||
scene_ubo->bind_uniform();
|
||||
|
||||
m_colorpass = m_renderpass;
|
||||
|
||||
if (m_widelines_supported)
|
||||
glLineWidth(1.0f);
|
||||
|
||||
@@ -572,7 +577,7 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
|
||||
setup_shadow_map(nullptr, m_renderpass);
|
||||
setup_shadow_unbind_map();
|
||||
setup_env_map(nullptr);
|
||||
|
||||
if (Global.gfx_shadowmap_enabled && vp.main)
|
||||
@@ -580,10 +585,9 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||
glDebug("render shadowmap start");
|
||||
Timer::subsystem.gfx_shadows.start();
|
||||
|
||||
Render_pass(vp, rendermode::shadows);
|
||||
if (!FreeFlyModeFlag && Global.render_cab)
|
||||
Render_pass(vp, rendermode::cabshadows);
|
||||
setup_pass(vp, m_renderpass, Mode); // restore draw mode. TBD, TODO: render mode stack
|
||||
m_renderpass.draw_stats = {};
|
||||
Render_pass(vp, rendermode::shadows);
|
||||
m_renderpass = m_colorpass; // restore draw mode. TBD, TODO: render mode stack
|
||||
|
||||
Timer::subsystem.gfx_shadows.stop();
|
||||
glDebug("render shadowmap end");
|
||||
@@ -592,8 +596,9 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||
if (Global.gfx_envmap_enabled && vp.main)
|
||||
{
|
||||
// potentially update environmental cube map
|
||||
if (Render_reflections(vp))
|
||||
setup_pass(vp, m_renderpass, Mode); // restore color pass settings
|
||||
m_renderpass.draw_stats = {};
|
||||
if (Render_reflections(vp))
|
||||
m_renderpass = m_colorpass; // restore color pass settings
|
||||
setup_env_map(m_env_tex.get());
|
||||
}
|
||||
|
||||
@@ -632,6 +637,7 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||
Timer::subsystem.gfx_color.start();
|
||||
setup_matrices();
|
||||
setup_drawing(true);
|
||||
m_renderpass.draw_stats = {};
|
||||
|
||||
glm::mat4 future;
|
||||
if (Global.pCamera.m_owner != nullptr)
|
||||
@@ -649,6 +655,9 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||
scene_ubo->update(scene_ubs);
|
||||
Render(&simulation::Environment);
|
||||
|
||||
if( Global.gfx_shadowmap_enabled )
|
||||
setup_shadow_bind_map();
|
||||
|
||||
// opaque parts...
|
||||
setup_drawing(false);
|
||||
|
||||
@@ -657,9 +666,6 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||
if (!FreeFlyModeFlag && Global.Overcast <= 1.0f && Global.render_cab)
|
||||
{
|
||||
glDebug("render cab opaque");
|
||||
if( Global.gfx_shadowmap_enabled ) {
|
||||
setup_shadow_map( m_cabshadows_tex.get(), m_cabshadowpass );
|
||||
}
|
||||
// cache shadow colour in case we need to account for cab light
|
||||
auto const *vehicle{ simulation::Train->Dynamic() };
|
||||
if( vehicle->InteriorLightLevel > 0.f ) {
|
||||
@@ -675,9 +681,6 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||
|
||||
model_ubs.future = future;
|
||||
|
||||
if (Global.gfx_shadowmap_enabled)
|
||||
setup_shadow_map(m_shadow_tex.get(), m_shadowpass);
|
||||
|
||||
Render(simulation::Region);
|
||||
|
||||
// ...translucent parts
|
||||
@@ -696,9 +699,6 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||
{
|
||||
glDebug("render translucent cab");
|
||||
model_ubs.future = glm::mat4();
|
||||
if( Global.gfx_shadowmap_enabled ) {
|
||||
setup_shadow_map( m_cabshadows_tex.get(), m_cabshadowpass );
|
||||
}
|
||||
// cache shadow colour in case we need to account for cab light
|
||||
auto *vehicle { simulation::Train->Dynamic() };
|
||||
if( vehicle->InteriorLightLevel > 0.f ) {
|
||||
@@ -721,7 +721,10 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||
|
||||
Timer::subsystem.gfx_color.stop();
|
||||
|
||||
setup_shadow_map(nullptr, m_renderpass);
|
||||
// store draw stats
|
||||
m_colorpass.draw_stats = m_renderpass.draw_stats;
|
||||
|
||||
setup_shadow_unbind_map();
|
||||
setup_env_map(nullptr);
|
||||
|
||||
if (!Global.gfx_usegles)
|
||||
@@ -781,58 +784,46 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||
|
||||
glDebug("rendermode::shadows");
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
setup_drawing( false );
|
||||
|
||||
glViewport(0, 0, m_shadowbuffersize, m_shadowbuffersize);
|
||||
m_shadow_fb->bind();
|
||||
m_shadow_fb->clear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
setup_matrices();
|
||||
setup_drawing(false);
|
||||
|
||||
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
|
||||
scene_ubo->update(scene_ubs);
|
||||
|
||||
if( m_shadowcolor != colors::white ) {
|
||||
Render( simulation::Region );
|
||||
float csmstageboundaries[] = { 0.0f, 5.0f, 25.0f, 1.0f };
|
||||
if( Global.shadowtune.map_size > 2048 ) {
|
||||
// increase coverage if our shadow map is large enough to produce decent results
|
||||
csmstageboundaries[ 1 ] *= Global.shadowtune.map_size / 2048;
|
||||
csmstageboundaries[ 2 ] *= Global.shadowtune.map_size / 2048;
|
||||
}
|
||||
m_shadowpass = m_renderpass;
|
||||
|
||||
for( auto idx = 0; idx < m_shadowpass.size(); ++idx ) {
|
||||
|
||||
m_shadow_fb->attach( *m_shadow_tex, GL_DEPTH_ATTACHMENT, idx );
|
||||
m_shadow_fb->clear( GL_DEPTH_BUFFER_BIT );
|
||||
|
||||
setup_pass( vp, m_renderpass, rendermode::shadows, csmstageboundaries[ idx ], csmstageboundaries[ idx + 1 ] );
|
||||
m_shadowpass[ idx ] = m_renderpass; // store pass config for reference in other stages
|
||||
|
||||
setup_matrices();
|
||||
scene_ubs.projection = OpenGLMatrices.data( GL_PROJECTION );
|
||||
auto const csmstagezfar {
|
||||
( csmstageboundaries[ idx + 1 ] > 1.f ? csmstageboundaries[ idx + 1 ] : Global.shadowtune.range )
|
||||
+ ( m_shadowpass.size() - idx ) }; // we can fairly safely add some extra padding in the early stages
|
||||
scene_ubs.cascade_end[ idx ] = csmstagezfar * csmstagezfar; // store squared to allow semi-optimized length2 comparisons in the shader
|
||||
scene_ubo->update( scene_ubs );
|
||||
|
||||
if( m_shadowcolor != colors::white ) {
|
||||
Render( simulation::Region );
|
||||
if( idx > 0 ) { continue; } // render cab only in the closest csm stage
|
||||
if( !FreeFlyModeFlag && Global.render_cab ) {
|
||||
Render_cab( simulation::Train->Dynamic(), 0.0f, false );
|
||||
Render_cab( simulation::Train->Dynamic(), 0.0f, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
m_shadow_fb->unbind();
|
||||
|
||||
glDebug("rendermodeshadows ::end");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case rendermode::cabshadows:
|
||||
{
|
||||
glDebug("rendermode::cabshadows");
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glViewport(0, 0, m_shadowbuffersize, m_shadowbuffersize);
|
||||
m_cabshadows_fb->bind();
|
||||
m_cabshadows_fb->clear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
setup_matrices();
|
||||
setup_drawing(false);
|
||||
|
||||
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
|
||||
scene_ubo->update(scene_ubs);
|
||||
|
||||
if( m_shadowcolor != colors::white ) {
|
||||
if( Global.RenderCabShadowsRange > 0 ) {
|
||||
Render( simulation::Region );
|
||||
}
|
||||
Render_cab( simulation::Train->Dynamic(), 0.0f, false );
|
||||
Render_cab( simulation::Train->Dynamic(), 0.0f, true );
|
||||
}
|
||||
m_cabshadowpass = m_renderpass;
|
||||
|
||||
m_cabshadows_fb->unbind();
|
||||
|
||||
glDebug("rendermode::cabshadows end");
|
||||
glDebug("rendermode::shadows end");
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -853,19 +844,17 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||
setup_env_map(m_empty_cubemap.get());
|
||||
|
||||
setup_matrices();
|
||||
setup_shadow_map(nullptr, m_renderpass);
|
||||
|
||||
// render
|
||||
// environment...
|
||||
setup_drawing(true);
|
||||
|
||||
setup_shadow_unbind_map();
|
||||
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
|
||||
scene_ubo->update(scene_ubs);
|
||||
Render(&simulation::Environment);
|
||||
|
||||
// opaque parts...
|
||||
setup_drawing(false);
|
||||
setup_shadow_map(m_shadow_tex.get(), m_shadowpass);
|
||||
|
||||
setup_shadow_bind_map();
|
||||
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
|
||||
scene_ubo->update(scene_ubs);
|
||||
Render(simulation::Region);
|
||||
@@ -922,7 +911,7 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||
|
||||
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
|
||||
scene_ubo->update(scene_ubs);
|
||||
Render(simulation::Region);
|
||||
Render(simulation::Region);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1124,23 +1113,19 @@ glm::mat4 opengl33_renderer::ortho_frustumtest_projection(float l, float r, floa
|
||||
void opengl33_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;
|
||||
|
||||
if( false == simulation::is_ready ) { return; }
|
||||
// setup draw range
|
||||
switch( Mode ) {
|
||||
case rendermode::color: { Config.draw_range = Global.BaseDrawRange; break; }
|
||||
case rendermode::shadows: { Config.draw_range = Global.BaseDrawRange * 0.5f; break; }
|
||||
case rendermode::cabshadows: { Config.draw_range = ( Global.RenderCabShadowsRange > 0 ? clamp( Global.RenderCabShadowsRange, 5, 100 ) : simulation::Train->Occupied()->Dim.L ); break; }
|
||||
case rendermode::reflections: { Config.draw_range = Global.BaseDrawRange; break; }
|
||||
case rendermode::color: { Config.draw_range = Global.BaseDrawRange * Global.fDistanceFactor * Viewport.draw_range; break; }
|
||||
case rendermode::shadows: { Config.draw_range = Global.shadowtune.range; break; }
|
||||
case rendermode::reflections: { Config.draw_range = Global.BaseDrawRange * Viewport.draw_range; break; }
|
||||
case rendermode::pickcontrols: { Config.draw_range = 50.f; break; }
|
||||
case rendermode::pickscenery: { Config.draw_range = Global.BaseDrawRange * 0.5f; break; }
|
||||
case rendermode::pickscenery: { Config.draw_range = Global.BaseDrawRange * Viewport.draw_range * 0.5f; break; }
|
||||
default: { Config.draw_range = 0.f; break; }
|
||||
}
|
||||
|
||||
Config.draw_range *= Viewport.draw_range;
|
||||
|
||||
// setup camera
|
||||
auto &camera = Config.pass_camera;
|
||||
|
||||
@@ -1175,9 +1160,14 @@ void opengl33_renderer::setup_pass(viewport_config &Viewport, renderpass_config
|
||||
Global.pDebugCamera.SetMatrix(viewmatrix);
|
||||
}
|
||||
|
||||
// optimization: don't bother drawing things completely blended with the background
|
||||
// but ensure at least 2 km range to account for signals and lights
|
||||
Config.draw_range = std::min( Config.draw_range, m_fogrange * 2 );
|
||||
Config.draw_range = std::max( 2000.f, Config.draw_range );
|
||||
|
||||
// projection
|
||||
auto const zfar = Config.draw_range * Global.fDistanceFactor * Zfar;
|
||||
auto const znear = (Znear > 0.f ? Znear * zfar : 0.1f * Global.ZoomFactor);
|
||||
auto const zfar = ( Zfar > 1.f ? Zfar : Config.draw_range * Zfar );
|
||||
auto const znear = ( Znear > 1.f ? Znear : Znear > 0.f ? Znear * zfar : 0.1f * Global.ZoomFactor);
|
||||
|
||||
camera.projection() = perspective_projection(fovy, aspect, znear, zfar);
|
||||
frustumtest_proj = perpsective_frustumtest_projection(fovy, aspect, znear, zfar);
|
||||
@@ -1187,9 +1177,11 @@ void opengl33_renderer::setup_pass(viewport_config &Viewport, renderpass_config
|
||||
{
|
||||
// calculate lightview boundaries based on relevant area of the world camera frustum:
|
||||
// ...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.range / (Global.BaseDrawRange * Global.fDistanceFactor) * std::max(1.f, Global.ZoomFactor * 0.5f));
|
||||
// auto const zfar = ( Zfar > 1.f ? Zfar * std::max( 1.f, Global.ZoomFactor * 0.5f ) : Zfar );
|
||||
auto const zfar = ( Zfar > 1.f ? Zfar : Zfar * Global.shadowtune.range * std::max( Zfar, Global.ZoomFactor * 0.5f ) );
|
||||
renderpass_config worldview;
|
||||
setup_pass(Viewport, worldview, rendermode::color, 0.f, zfar, true);
|
||||
setup_pass(Viewport, worldview, rendermode::color, Znear, zfar, true);
|
||||
auto &frustumchunkshapepoints = worldview.pass_camera.frustum_points();
|
||||
// ...modelview matrix: determine the centre of frustum chunk in world space...
|
||||
glm::vec3 frustumchunkmin, frustumchunkmax;
|
||||
@@ -1208,29 +1200,14 @@ void opengl33_renderer::setup_pass(viewport_config &Viewport, renderpass_config
|
||||
}
|
||||
bounding_box(frustumchunkmin, frustumchunkmax, std::begin(frustumchunkshapepoints), std::end(frustumchunkshapepoints));
|
||||
// quantize the frustum points and add some padding, to reduce shadow shimmer on scale changes
|
||||
auto const quantizationstep{std::min(Global.shadowtune.depth, 50.f)};
|
||||
auto const frustumchunkdepth { zfar - ( Znear > 1.f ? Znear : 0.f ) };
|
||||
auto const quantizationstep{std::min(frustumchunkdepth, 50.f)};
|
||||
frustumchunkmin = quantizationstep * glm::floor(frustumchunkmin * (1.f / quantizationstep));
|
||||
frustumchunkmax = quantizationstep * glm::ceil(frustumchunkmax * (1.f / quantizationstep));
|
||||
// ...use the dimensions to set up light projection boundaries...
|
||||
// NOTE: since we only have one cascade map stage, we extend the chunk forward/back to catch areas normally covered by other stages
|
||||
camera.projection() = ortho_projection(frustumchunkmin.x, frustumchunkmax.x, frustumchunkmin.y, frustumchunkmax.y, frustumchunkmin.z - 500.f, frustumchunkmax.z + 500.f);
|
||||
frustumtest_proj = ortho_frustumtest_projection(frustumchunkmin.x, frustumchunkmax.x, frustumchunkmin.y, frustumchunkmax.y, frustumchunkmin.z - 500.f, frustumchunkmax.z + 500.f);
|
||||
/*
|
||||
// fixed ortho projection from old build, for quick quality comparisons
|
||||
camera.projection() *=
|
||||
ortho_projection(
|
||||
-Global.shadowtune.width, Global.shadowtune.width,
|
||||
-Global.shadowtune.width, Global.shadowtune.width,
|
||||
-Global.shadowtune.depth, Global.shadowtune.depth );
|
||||
camera.position() = Global.pCamera.Pos - glm::dvec3{ m_sunlight.direction };
|
||||
if( camera.position().y - Global.pCamera.Pos.y < 0.1 ) {
|
||||
camera.position().y = Global.pCamera.Pos.y + 0.1;
|
||||
}
|
||||
viewmatrix *= glm::lookAt(
|
||||
camera.position(),
|
||||
glm::dvec3{ Global.pCamera.Pos },
|
||||
glm::dvec3{ 0.f, 1.f, 0.f } );
|
||||
*/
|
||||
// ... and adjust the projection to sample complete shadow map texels:
|
||||
// get coordinates for a sample texel...
|
||||
auto shadowmaptexel = glm::vec2{camera.projection() * glm::mat4{viewmatrix} * glm::vec4{0.f, 0.f, 0.f, 1.f}};
|
||||
@@ -1244,28 +1221,6 @@ void opengl33_renderer::setup_pass(viewport_config &Viewport, renderpass_config
|
||||
|
||||
break;
|
||||
}
|
||||
case rendermode::cabshadows:
|
||||
{
|
||||
// fixed size cube large enough to enclose a vehicle compartment
|
||||
// modelview
|
||||
auto const lightvector = glm::normalize(glm::vec3{m_sunlight.direction.x, std::min(m_sunlight.direction.y, -0.2f), m_sunlight.direction.z});
|
||||
camera.position() = Global.pCamera.Pos - glm::dvec3{lightvector};
|
||||
viewmatrix *= glm::lookAt(camera.position(), glm::dvec3{Global.pCamera.Pos}, glm::dvec3{0.f, 1.f, 0.f});
|
||||
// projection
|
||||
auto const maphalfsize { std::min( 10.f, Config.draw_range * 0.5f ) };
|
||||
camera.projection() = ortho_projection(-maphalfsize, maphalfsize, -maphalfsize, maphalfsize, -Config.draw_range, Config.draw_range);
|
||||
frustumtest_proj = ortho_frustumtest_projection(-maphalfsize, maphalfsize, -maphalfsize, maphalfsize, -Config.draw_range, Config.draw_range);
|
||||
|
||||
/*
|
||||
// adjust the projection to sample complete shadow map texels
|
||||
auto shadowmaptexel = glm::vec2 { camera.projection() * glm::mat4{ viewmatrix } * glm::vec4{ 0.f, 0.f, 0.f, 1.f } };
|
||||
shadowmaptexel *= ( m_shadowbuffersize / 2 ) * 0.5f;
|
||||
auto shadowmapadjustment = glm::round( shadowmaptexel ) - shadowmaptexel;
|
||||
shadowmapadjustment /= ( m_shadowbuffersize / 2 ) * 0.5f;
|
||||
camera.projection() = glm::translate( glm::mat4{ 1.f }, glm::vec3{ shadowmapadjustment, 0.f } ) * camera.projection();
|
||||
*/
|
||||
break;
|
||||
}
|
||||
case rendermode::pickcontrols:
|
||||
case rendermode::pickscenery:
|
||||
{
|
||||
@@ -1312,7 +1267,7 @@ void opengl33_renderer::setup_matrices()
|
||||
OpenGLMatrices.load_matrix(m_renderpass.pass_camera.projection());
|
||||
// trim modelview matrix just to rotation, since rendering is done in camera-centric world space
|
||||
OpenGLMatrices.mode(GL_MODELVIEW);
|
||||
OpenGLMatrices.load_matrix(glm::mat4(glm::mat3(m_renderpass.pass_camera.modelview())));
|
||||
OpenGLMatrices.load_matrix(glm::mat4{glm::mat3{m_renderpass.pass_camera.modelview()}});
|
||||
}
|
||||
|
||||
void opengl33_renderer::setup_drawing(bool const Alpha)
|
||||
@@ -1339,7 +1294,6 @@ void opengl33_renderer::setup_drawing(bool const Alpha)
|
||||
break;
|
||||
}
|
||||
case rendermode::shadows:
|
||||
case rendermode::cabshadows:
|
||||
{
|
||||
glCullFace(GL_FRONT);
|
||||
break;
|
||||
@@ -1357,50 +1311,52 @@ void opengl33_renderer::setup_drawing(bool const Alpha)
|
||||
}
|
||||
}
|
||||
|
||||
// configures shadow texture unit for specified shadow map and conersion matrix
|
||||
void opengl33_renderer::setup_shadow_map(opengl_texture *tex, renderpass_config conf)
|
||||
void opengl33_renderer::setup_shadow_unbind_map()
|
||||
{
|
||||
if (tex)
|
||||
tex->bind(gl::MAX_TEXTURES + 0);
|
||||
opengl_texture::unbind( gl::MAX_TEXTURES + 0 );
|
||||
}
|
||||
|
||||
// binds shadow map and updates shadow map uniform data
|
||||
void opengl33_renderer::setup_shadow_bind_map()
|
||||
{
|
||||
m_shadow_tex->bind(gl::MAX_TEXTURES + 0);
|
||||
|
||||
glm::mat4 coordmove;
|
||||
|
||||
if (GLAD_GL_ARB_clip_control || GLAD_GL_EXT_clip_control)
|
||||
// transform 1..-1 NDC xy coordinates to 1..0
|
||||
coordmove = glm::mat4( //
|
||||
0.5, 0.0, 0.0, 0.0, //
|
||||
0.0, 0.5, 0.0, 0.0, //
|
||||
0.0, 0.0, 1.0, 0.0, //
|
||||
0.5, 0.5, 0.0, 1.0 //
|
||||
);
|
||||
else
|
||||
opengl_texture::unbind(gl::MAX_TEXTURES + 0);
|
||||
// without clip_control we also need to transform z
|
||||
coordmove = glm::mat4( //
|
||||
0.5, 0.0, 0.0, 0.0, //
|
||||
0.0, 0.5, 0.0, 0.0, //
|
||||
0.0, 0.0, 0.5, 0.0, //
|
||||
0.5, 0.5, 0.5, 1.0 //
|
||||
);
|
||||
|
||||
if (tex)
|
||||
{
|
||||
glm::mat4 coordmove;
|
||||
for( auto idx = 0; idx < m_shadowpass.size(); ++idx ) {
|
||||
|
||||
if (GLAD_GL_ARB_clip_control || GLAD_GL_EXT_clip_control)
|
||||
// transform 1..-1 NDC xy coordinates to 1..0
|
||||
coordmove = glm::mat4( //
|
||||
0.5, 0.0, 0.0, 0.0, //
|
||||
0.0, 0.5, 0.0, 0.0, //
|
||||
0.0, 0.0, 1.0, 0.0, //
|
||||
0.5, 0.5, 0.0, 1.0 //
|
||||
);
|
||||
else
|
||||
// without clip_control we also need to transform z
|
||||
coordmove = glm::mat4( //
|
||||
0.5, 0.0, 0.0, 0.0, //
|
||||
0.0, 0.5, 0.0, 0.0, //
|
||||
0.0, 0.0, 0.5, 0.0, //
|
||||
0.5, 0.5, 0.5, 1.0 //
|
||||
);
|
||||
glm::mat4 depthproj = conf.pass_camera.projection();
|
||||
glm::mat4 depthproj = m_shadowpass[ idx ].pass_camera.projection();
|
||||
// NOTE: we strip transformations from camera projections to remove jitter that occurs
|
||||
// with large (and unneded as we only need the offset) transformations back and forth
|
||||
auto const depthcam{ glm::mat3{ conf.pass_camera.modelview()} };
|
||||
auto const depthcam{ glm::mat3{ m_shadowpass[ idx ].pass_camera.modelview()} };
|
||||
auto const worldcam{ glm::mat3{ m_renderpass.pass_camera.modelview()} };
|
||||
|
||||
scene_ubs.lightview =
|
||||
scene_ubs.lightview[ idx ] =
|
||||
coordmove
|
||||
* depthproj
|
||||
* glm::translate(
|
||||
glm::mat4{ depthcam },
|
||||
glm::vec3{ m_renderpass.pass_camera.position() - conf.pass_camera.position() } )
|
||||
glm::vec3{ m_renderpass.pass_camera.position() - m_shadowpass[ idx ].pass_camera.position() } )
|
||||
* glm::mat4{ glm::inverse( worldcam ) };
|
||||
|
||||
scene_ubo->update(scene_ubs);
|
||||
}
|
||||
}
|
||||
scene_ubo->update(scene_ubs);
|
||||
}
|
||||
|
||||
void opengl33_renderer::setup_shadow_color( glm::vec4 const &Shadowcolor ) {
|
||||
@@ -1918,7 +1874,6 @@ void opengl33_renderer::Render(scene::basic_region *Region)
|
||||
break;
|
||||
}
|
||||
case rendermode::shadows:
|
||||
case rendermode::cabshadows:
|
||||
case rendermode::pickscenery:
|
||||
{
|
||||
// these render modes don't bother with lights
|
||||
@@ -1950,7 +1905,6 @@ void opengl33_renderer::Render(section_sequence::iterator First, section_sequenc
|
||||
{
|
||||
case rendermode::color:
|
||||
case rendermode::reflections:
|
||||
case rendermode::cabshadows:
|
||||
case rendermode::shadows:
|
||||
break;
|
||||
case rendermode::pickscenery:
|
||||
@@ -1975,7 +1929,6 @@ void opengl33_renderer::Render(section_sequence::iterator First, section_sequenc
|
||||
case rendermode::color:
|
||||
case rendermode::reflections:
|
||||
case rendermode::shadows:
|
||||
case rendermode::cabshadows:
|
||||
case rendermode::pickscenery:
|
||||
{
|
||||
if (false == section->m_shapes.empty())
|
||||
@@ -2006,7 +1959,6 @@ void opengl33_renderer::Render(section_sequence::iterator First, section_sequenc
|
||||
{
|
||||
case rendermode::color:
|
||||
case rendermode::shadows:
|
||||
case rendermode::cabshadows:
|
||||
case rendermode::pickscenery:
|
||||
{
|
||||
for (auto &cell : section->m_cells)
|
||||
@@ -2033,7 +1985,6 @@ void opengl33_renderer::Render(section_sequence::iterator First, section_sequenc
|
||||
switch (m_renderpass.draw_mode)
|
||||
{
|
||||
case rendermode::shadows:
|
||||
case rendermode::cabshadows:
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -2099,24 +2050,6 @@ void opengl33_renderer::Render(cell_sequence::iterator First, cell_sequence::ite
|
||||
|
||||
break;
|
||||
}
|
||||
case rendermode::cabshadows:
|
||||
{
|
||||
// since all shapes of the section share center point we can optimize out a few calls here
|
||||
::glPushMatrix();
|
||||
auto const originoffset{cell->m_area.center - m_renderpass.pass_camera.position()};
|
||||
::glTranslated(originoffset.x, originoffset.y, originoffset.z);
|
||||
|
||||
// render
|
||||
// opaque non-instanced shapes
|
||||
for (auto const &shape : cell->m_shapesopaque)
|
||||
Render(shape, false);
|
||||
// NOTE: tracks aren't likely to cast shadows into the cab, so we skip them in this pass
|
||||
|
||||
// post-render cleanup
|
||||
::glPopMatrix();
|
||||
|
||||
break;
|
||||
}
|
||||
case rendermode::pickscenery:
|
||||
{
|
||||
// same procedure like with regular render, but editor-enabled nodes receive custom colour used for picking
|
||||
@@ -2160,7 +2093,6 @@ void opengl33_renderer::Render(cell_sequence::iterator First, cell_sequence::ite
|
||||
{
|
||||
case rendermode::color:
|
||||
case rendermode::shadows:
|
||||
case rendermode::cabshadows:
|
||||
{
|
||||
// opaque parts of instanced models
|
||||
for (auto *instance : cell->m_instancesopaque)
|
||||
@@ -2237,7 +2169,6 @@ void opengl33_renderer::Render(scene::shape_node const &Shape, bool const Ignore
|
||||
switch (m_renderpass.draw_mode)
|
||||
{
|
||||
case rendermode::shadows:
|
||||
case rendermode::cabshadows:
|
||||
{
|
||||
// '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 - m_renderpass.viewport_camera.position()) / (double)Global.ZoomFactor) / Global.fDistanceFactor;
|
||||
@@ -2263,7 +2194,6 @@ void opengl33_renderer::Render(scene::shape_node const &Shape, bool const Ignore
|
||||
Bind_Material(data.material);
|
||||
break;
|
||||
case rendermode::shadows:
|
||||
case rendermode::cabshadows:
|
||||
Bind_Material_Shadow(data.material);
|
||||
break;
|
||||
case rendermode::pickscenery:
|
||||
@@ -2277,31 +2207,28 @@ void opengl33_renderer::Render(scene::shape_node const &Shape, bool const Ignore
|
||||
|
||||
draw(data.geometry);
|
||||
// debug data
|
||||
++m_debugstats.shapes;
|
||||
++m_debugstats.drawcalls;
|
||||
++m_renderpass.draw_stats.shapes;
|
||||
++m_renderpass.draw_stats.drawcalls;
|
||||
}
|
||||
|
||||
void opengl33_renderer::Render(TAnimModel *Instance)
|
||||
{
|
||||
|
||||
if (false == Instance->m_visible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (false == Instance->m_visible) { return; }
|
||||
if( false == m_renderpass.pass_camera.visible( Instance->m_area ) ) { return; }
|
||||
|
||||
double distancesquared;
|
||||
double distancesquared;
|
||||
switch (m_renderpass.draw_mode)
|
||||
{
|
||||
case rendermode::shadows:
|
||||
case rendermode::cabshadows:
|
||||
{
|
||||
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
||||
distancesquared = Math3D::SquareMagnitude((Instance->location() - m_renderpass.viewport_camera.position()) / (double)Global.ZoomFactor) / Global.fDistanceFactor;
|
||||
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
||||
distancesquared = glm::length2((Instance->location() - m_renderpass.viewport_camera.position()) / (double)Global.ZoomFactor) / Global.fDistanceFactor;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
distancesquared = Math3D::SquareMagnitude((Instance->location() - m_renderpass.pass_camera.position()) / (double)Global.ZoomFactor) / Global.fDistanceFactor;
|
||||
distancesquared = glm::length2((Instance->location() - m_renderpass.pass_camera.position()) / (double)Global.ZoomFactor) / Global.fDistanceFactor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2330,6 +2257,8 @@ void opengl33_renderer::Render(TAnimModel *Instance)
|
||||
{
|
||||
// renderowanie rekurencyjne submodeli
|
||||
Render(Instance->pModel, Instance->Material(), distancesquared, Instance->location() - m_renderpass.pass_camera.position(), Instance->vAngle);
|
||||
// debug data
|
||||
++m_renderpass.draw_stats.models;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2340,13 +2269,11 @@ bool opengl33_renderer::Render(TDynamicObject *Dynamic)
|
||||
if (!Global.render_cab && Global.pCamera.m_owner == Dynamic)
|
||||
return false;
|
||||
|
||||
Dynamic->renderme = m_renderpass.pass_camera.visible(Dynamic);
|
||||
if (false == Dynamic->renderme)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// debug data
|
||||
++m_debugstats.dynamics;
|
||||
Dynamic->renderme = (
|
||||
( Global.pCamera.m_owner == Dynamic && !FreeFlyModeFlag )
|
||||
|| ( m_renderpass.pass_camera.visible( Dynamic ) ) );
|
||||
|
||||
if (false == Dynamic->renderme) { return false; }
|
||||
|
||||
// setup
|
||||
TSubModel::iInstance = reinterpret_cast<std::uintptr_t>(Dynamic); //żeby nie robić cudzych animacji
|
||||
@@ -2364,18 +2291,23 @@ bool opengl33_renderer::Render(TDynamicObject *Dynamic)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case rendermode::cabshadows: {
|
||||
squaredistance = glm::length2( glm::vec3{ glm::dvec3{ Dynamic->vPosition - m_renderpass.viewport_camera.position() } } / Global.ZoomFactor ) / Global.fDistanceFactor;
|
||||
// filter out small details
|
||||
squaredistance = std::max( 100.f * 100.f, squaredistance );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
squaredistance = glm::length2(glm::vec3{originoffset} / Global.ZoomFactor) / Global.fDistanceFactor;
|
||||
// TODO: filter out small details based on fidelity setting
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// second stage visibility cull, reject vehicles too far away to be noticeable
|
||||
Dynamic->renderme = ( Dynamic->radius() * Global.ZoomFactor / std::sqrt( squaredistance ) > 0.003 );
|
||||
if( false == Dynamic->renderme ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// debug data
|
||||
++m_renderpass.draw_stats.dynamics;
|
||||
|
||||
Dynamic->ABuLittleUpdate(squaredistance); // ustawianie zmiennych submodeli dla wspólnego modelu
|
||||
|
||||
glm::mat4 future_stack = model_ubs.future;
|
||||
@@ -2428,7 +2360,6 @@ bool opengl33_renderer::Render(TDynamicObject *Dynamic)
|
||||
break;
|
||||
}
|
||||
case rendermode::shadows:
|
||||
case rendermode::cabshadows:
|
||||
{
|
||||
if( Dynamic->mdLowPolyInt ) {
|
||||
// low poly interior
|
||||
@@ -2543,7 +2474,8 @@ bool opengl33_renderer::Render_cab(TDynamicObject const *Dynamic, float const Li
|
||||
|
||||
break;
|
||||
}
|
||||
case rendermode::cabshadows: {
|
||||
case rendermode::shadows:
|
||||
{
|
||||
if( true == Alpha ) {
|
||||
// translucent parts
|
||||
Render_Alpha( Dynamic->mdKabina, Dynamic->Material(), 0.0 );
|
||||
@@ -2592,9 +2524,6 @@ bool opengl33_renderer::Render(TModel3d *Model, material_data const *Material, f
|
||||
// render
|
||||
Render(Model->Root);
|
||||
|
||||
// debug data
|
||||
++m_debugstats.models;
|
||||
|
||||
// post-render cleanup
|
||||
|
||||
return true;
|
||||
@@ -2627,8 +2556,8 @@ void opengl33_renderer::Render(TSubModel *Submodel)
|
||||
{
|
||||
|
||||
// debug data
|
||||
++m_debugstats.submodels;
|
||||
++m_debugstats.drawcalls;
|
||||
++m_renderpass.draw_stats.submodels;
|
||||
++m_renderpass.draw_stats.drawcalls;
|
||||
|
||||
glm::mat4 future_stack = model_ubs.future;
|
||||
|
||||
@@ -2689,7 +2618,6 @@ void opengl33_renderer::Render(TSubModel *Submodel)
|
||||
break;
|
||||
}
|
||||
case rendermode::shadows:
|
||||
case rendermode::cabshadows:
|
||||
{
|
||||
if (Submodel->m_material < 0)
|
||||
{ // zmienialne skóry
|
||||
@@ -2781,8 +2709,8 @@ void opengl33_renderer::Render(TTrack *Track)
|
||||
return;
|
||||
}
|
||||
|
||||
++m_debugstats.paths;
|
||||
++m_debugstats.drawcalls;
|
||||
++m_renderpass.draw_stats.paths;
|
||||
++m_renderpass.draw_stats.drawcalls;
|
||||
|
||||
switch (m_renderpass.draw_mode)
|
||||
{
|
||||
@@ -2813,7 +2741,6 @@ void opengl33_renderer::Render(scene::basic_cell::path_sequence::const_iterator
|
||||
switch (m_renderpass.draw_mode)
|
||||
{
|
||||
case rendermode::shadows:
|
||||
case rendermode::cabshadows:
|
||||
{
|
||||
// NOTE: roads-based platforms tend to miss parts of shadows if rendered with either back or front culling
|
||||
glDisable(GL_CULL_FACE);
|
||||
@@ -2841,8 +2768,8 @@ void opengl33_renderer::Render(scene::basic_cell::path_sequence::const_iterator
|
||||
continue;
|
||||
}
|
||||
|
||||
++m_debugstats.paths;
|
||||
++m_debugstats.drawcalls;
|
||||
++m_renderpass.draw_stats.paths;
|
||||
++m_renderpass.draw_stats.drawcalls;
|
||||
|
||||
switch (m_renderpass.draw_mode)
|
||||
{
|
||||
@@ -2863,7 +2790,6 @@ void opengl33_renderer::Render(scene::basic_cell::path_sequence::const_iterator
|
||||
break;
|
||||
}
|
||||
case rendermode::shadows:
|
||||
case rendermode::cabshadows:
|
||||
{
|
||||
if ((std::abs(track->fTexHeight1) < 0.35f) || (track->iCategoryFlag != 2))
|
||||
{
|
||||
@@ -2915,7 +2841,6 @@ void opengl33_renderer::Render(scene::basic_cell::path_sequence::const_iterator
|
||||
break;
|
||||
}
|
||||
case rendermode::shadows:
|
||||
case rendermode::cabshadows:
|
||||
{
|
||||
if ((std::abs(track->fTexHeight1) < 0.35f) || ((track->iCategoryFlag == 1) && (track->eType != tt_Normal)))
|
||||
{
|
||||
@@ -2973,7 +2898,6 @@ void opengl33_renderer::Render(scene::basic_cell::path_sequence::const_iterator
|
||||
break;
|
||||
}
|
||||
case rendermode::shadows:
|
||||
case rendermode::cabshadows:
|
||||
{
|
||||
if ((std::abs(track->fTexHeight1) < 0.35f) || ((track->iCategoryFlag == 1) && (track->eType != tt_Normal)))
|
||||
{
|
||||
@@ -2997,7 +2921,6 @@ void opengl33_renderer::Render(scene::basic_cell::path_sequence::const_iterator
|
||||
switch (m_renderpass.draw_mode)
|
||||
{
|
||||
case rendermode::shadows:
|
||||
case rendermode::cabshadows:
|
||||
{
|
||||
// restore standard face cull mode
|
||||
::glEnable(GL_CULL_FACE);
|
||||
@@ -3024,7 +2947,6 @@ void opengl33_renderer::Render(TMemCell *Memcell)
|
||||
break;
|
||||
}
|
||||
case rendermode::shadows:
|
||||
case rendermode::cabshadows:
|
||||
case rendermode::pickscenery:
|
||||
{
|
||||
break;
|
||||
@@ -3050,7 +2972,7 @@ void opengl33_renderer::Render_particles()
|
||||
|
||||
Bind_Texture(0, m_smoketexture);
|
||||
m_particlerenderer.update(m_renderpass.pass_camera);
|
||||
m_particlerenderer.render();
|
||||
m_renderpass.draw_stats.particles = m_particlerenderer.render();
|
||||
}
|
||||
|
||||
void opengl33_renderer::Render_precipitation()
|
||||
@@ -3210,15 +3132,18 @@ void opengl33_renderer::Render_Alpha(cell_sequence::reverse_iterator First, cell
|
||||
void opengl33_renderer::Render_Alpha(TAnimModel *Instance)
|
||||
{
|
||||
|
||||
if (false == Instance->m_visible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (false == Instance->m_visible) { return; }
|
||||
if( false == m_renderpass.pass_camera.visible( Instance->m_area ) ) { return; }
|
||||
|
||||
double distancesquared;
|
||||
double distancesquared;
|
||||
switch (m_renderpass.draw_mode)
|
||||
{
|
||||
case rendermode::shadows:
|
||||
{
|
||||
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
||||
distancesquared = glm::length2((Instance->location() - m_renderpass.viewport_camera.position()) / (double)Global.ZoomFactor) / Global.fDistanceFactor;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
distancesquared = glm::length2((Instance->location() - m_renderpass.pass_camera.position()) / (double)Global.ZoomFactor) / Global.fDistanceFactor;
|
||||
@@ -3277,8 +3202,8 @@ void opengl33_renderer::Render_Alpha(TTraction *Traction)
|
||||
draw(Traction->m_geometry);
|
||||
|
||||
// debug data
|
||||
++m_debugstats.traction;
|
||||
++m_debugstats.drawcalls;
|
||||
++m_renderpass.draw_stats.traction;
|
||||
++m_renderpass.draw_stats.drawcalls;
|
||||
|
||||
if (m_widelines_supported)
|
||||
glLineWidth(1.0f);
|
||||
@@ -3310,8 +3235,8 @@ void opengl33_renderer::Render_Alpha(scene::lines_node const &Lines)
|
||||
m_line_shader->bind();
|
||||
draw(data.geometry);
|
||||
|
||||
++m_debugstats.lines;
|
||||
++m_debugstats.drawcalls;
|
||||
++m_renderpass.draw_stats.lines;
|
||||
++m_renderpass.draw_stats.drawcalls;
|
||||
|
||||
if (m_widelines_supported)
|
||||
glLineWidth(1.0f);
|
||||
@@ -3446,8 +3371,8 @@ void opengl33_renderer::Render_Alpha(TSubModel *Submodel)
|
||||
{
|
||||
|
||||
// debug data
|
||||
++m_debugstats.submodels;
|
||||
++m_debugstats.drawcalls;
|
||||
++m_renderpass.draw_stats.submodels;
|
||||
++m_renderpass.draw_stats.drawcalls;
|
||||
|
||||
glm::mat4 future_stack = model_ubs.future;
|
||||
|
||||
@@ -3497,7 +3422,7 @@ void opengl33_renderer::Render_Alpha(TSubModel *Submodel)
|
||||
model_ubs.emission = 0.0f;
|
||||
break;
|
||||
}
|
||||
case rendermode::cabshadows:
|
||||
case rendermode::shadows:
|
||||
{
|
||||
if (Submodel->m_material < 0)
|
||||
{ // zmienialne skóry
|
||||
@@ -3610,7 +3535,7 @@ void opengl33_renderer::Render_Alpha(TSubModel *Submodel)
|
||||
|
||||
// material configuration:
|
||||
// limit impact of dense fog on the lights
|
||||
auto const lightrange { std::max<float>( 500, m_fogrange * 2 ) }; // arbitrary, visibility at least 750m
|
||||
auto const lightrange { std::max<float>( 500, m_fogrange * 2 ) }; // arbitrary, visibility at least 500m
|
||||
model_ubs.fog_density = 1.0 / lightrange;
|
||||
|
||||
// main draw call
|
||||
@@ -3901,12 +3826,12 @@ void opengl33_renderer::Update(double const Deltatime)
|
||||
// TODO: it doesn't make much sense with vsync
|
||||
if( Global.targetfps == 0.0f ) {
|
||||
// automatic adjustment
|
||||
auto const framerate = 1000.f / Timer::subsystem.gfx_color.average();
|
||||
auto const framerate = 0.5f * ( m_framerate + 1000.f / Timer::subsystem.gfx_color.average() );
|
||||
float targetfactor;
|
||||
if( framerate > 90.0 ) { targetfactor = 3.0f; }
|
||||
else if( framerate > 60.0 ) { targetfactor = 1.5f; }
|
||||
else if( framerate > 30.0 ) { targetfactor = 1.25; }
|
||||
else { targetfactor = 1.0f; }
|
||||
if( framerate > 120.0 ) { targetfactor = 3.00f; }
|
||||
else if( framerate > 90.0 ) { targetfactor = 1.50f; }
|
||||
else if( framerate > 60.0 ) { targetfactor = 1.25f; }
|
||||
else { targetfactor = 1.00f; }
|
||||
if( targetfactor > Global.fDistanceFactor ) {
|
||||
Global.fDistanceFactor = std::min( targetfactor, Global.fDistanceFactor + 0.05f );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user