16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-19 03:09:18 +02:00

Merge branch 'milek-dev' into gfx-work

This commit is contained in:
milek7
2018-10-10 19:33:08 +02:00
49 changed files with 1697 additions and 1026 deletions

View File

@@ -342,15 +342,9 @@ bool opengl_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 );
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);
if (DebugModeFlag)
m_debugtimestext += m_textures.info();
@@ -364,7 +358,7 @@ void opengl_renderer::SwapBuffers()
{
Timer::subsystem.gfx_swap.start();
glfwSwapBuffers(m_window);
// swapbuffers() will unbind current buffers so we prepare for it on our end
// swapbuffers() could unbind current buffers so we prepare for it on our end
gfx::opengl_vbogeometrybank::reset();
Timer::subsystem.gfx_swap.stop();
}
@@ -402,7 +396,6 @@ void opengl_renderer::Render_pass(rendermode const Mode)
else
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
setup_shadow_map(nullptr, m_renderpass);
setup_env_map(nullptr);
@@ -465,7 +458,9 @@ void opengl_renderer::Render_pass(rendermode const Mode)
// opaque parts...
setup_drawing(false);
if (false == FreeFlyModeFlag)
// without rain/snow we can render the cab early to limit the overdraw
// precipitation happens when overcast is in 1-2 range
if (!FreeFlyModeFlag && Global.Overcast <= 1.0f)
{
glDebug("render cab opaque");
if (Global.gfx_shadowmap_enabled)
@@ -488,15 +483,26 @@ void opengl_renderer::Render_pass(rendermode const Mode)
glDebug("render translucent region");
setup_drawing(true);
Render_Alpha(simulation::Region);
// precipitation; done at end, only before cab render
Render_precipitation();
// cab render
if (false == FreeFlyModeFlag)
{
glDebug("render translucent cab");
model_ubs.future = glm::mat4();
// cab render is performed without shadows, due to low resolution and number of models without windows :|
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 (Global.Overcast > 1.0f)
{
// with active precipitation draw the opaque cab parts here to mask rain/snow placed 'inside' the cab
setup_drawing(false);
Render_cab(vehicle, false);
setup_drawing(true);
}
Render_cab(vehicle, true);
}
@@ -1152,13 +1158,16 @@ bool opengl_renderer::Render(world_environment *Environment)
model_ubo->update(model_ubs);
// skydome
// drawn with 500m radius to blend in if the fog range is low
glPushMatrix();
glScalef(500.0f, 500.0f, 500.0f);
Environment->m_skydome.Render();
glPopMatrix();
// skydome uses a custom vbo which could potentially confuse the main geometry system. hardly elegant but, eh
gfx::opengl_vbogeometrybank::reset();
// celestial bodies
float const duskfactor = 1.0f - clamp(std::abs(Environment->m_sun.getAngle()), 0.0f, 12.0f) / 12.0f;
glm::vec3 suncolor = interpolate(glm::vec3(255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f), glm::vec3(235.0f / 255.0f, 140.0f / 255.0f, 36.0f / 255.0f), duskfactor);
opengl_texture::reset_unit_cache();
@@ -1182,6 +1191,10 @@ bool opengl_renderer::Render(world_environment *Environment)
m_sunlight.apply_angle();
m_sunlight.apply_intensity();
auto const fogfactor{clamp<float>(Global.fFogEnd / 2000.f, 0.f, 1.f)}; // stronger fog reduces opacity of the celestial bodies
float const duskfactor = 1.0f - clamp(std::abs(Environment->m_sun.getAngle()), 0.0f, 12.0f) / 12.0f;
glm::vec3 suncolor = interpolate(glm::vec3(255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f), glm::vec3(235.0f / 255.0f, 140.0f / 255.0f, 36.0f / 255.0f), duskfactor);
// clouds
if (Environment->m_clouds.mdCloud)
{
@@ -1832,7 +1845,7 @@ bool opengl_renderer::Render(TDynamicObject *Dynamic)
++m_debugstats.dynamics;
// setup
TSubModel::iInstance = reinterpret_cast<std::uintptr_t>( Dynamic ); //żeby nie robić cudzych animacji
TSubModel::iInstance = reinterpret_cast<std::uintptr_t>(Dynamic); //żeby nie robić cudzych animacji
glm::dvec3 const originoffset = Dynamic->vPosition - m_renderpass.camera.position();
// lod visibility ranges are defined for base (x 1.0) viewing distance. for render we adjust them for actual range multiplier and zoom
float squaredistance;
@@ -1902,7 +1915,7 @@ bool opengl_renderer::Render(TDynamicObject *Dynamic)
Render(Dynamic->mdModel, Dynamic->Material(), squaredistance);
if (Dynamic->mdLoad) // renderowanie nieprzezroczystego ładunku
Render_Alpha( Dynamic->mdLoad, Dynamic->Material(), squaredistance, { 0.f, Dynamic->LoadOffset, 0.f }, {} );
Render_Alpha(Dynamic->mdLoad, Dynamic->Material(), squaredistance, {0.f, Dynamic->LoadOffset, 0.f}, {});
// post-render cleanup
// calc_motion = false;
@@ -2251,9 +2264,10 @@ void opengl_renderer::Render(TSubModel *Submodel)
float lightlevel = 1.f; // TODO, TBD: parameter to control light strength
// view angle attenuation
float const anglefactor = clamp((Submodel->fCosViewAngle - Submodel->fCosFalloffAngle) / (Submodel->fCosHotspotAngle - Submodel->fCosFalloffAngle), 0.f, 1.f);
// distance attenuation. NOTE: since it's fixed pipeline with built-in gamma correction we're using linear attenuation
// distance attenuation
// we're capping how much effect the distance attenuation can have, otherwise the lights get too tiny at regular distances
float const distancefactor = std::max(0.5f, (Submodel->fSquareMaxDist - TSubModel::fSquareDist) / Submodel->fSquareMaxDist);
float const precipitationfactor = std::max(1.f, Global.Overcast - 1.f);
if (lightlevel > 0.f)
{
@@ -2271,7 +2285,7 @@ void opengl_renderer::Render(TSubModel *Submodel)
// main draw call
model_ubs.param[0] = glm::vec4(glm::vec3(Submodel->f4Diffuse), 0.0f);
model_ubs.emission = lightlevel * anglefactor;
model_ubs.emission = std::min(1.f, lightlevel * anglefactor * precipitationfactor);
m_freespot_shader->bind();
draw(Submodel->m_geometry);
@@ -2569,6 +2583,55 @@ void opengl_renderer::Render(TMemCell *Memcell)
::glPopMatrix();
}
void opengl_renderer::Render_precipitation()
{
if (Global.Overcast <= 1.f)
{
return;
}
::glPushMatrix();
// tilt the precipitation cone against the velocity vector for crude motion blur
auto const velocity{simulation::Environment.m_precipitation.m_cameramove * -1.0};
if (glm::length2(velocity) > 0.0)
{
auto const forward{glm::normalize(velocity)};
auto left{glm::cross(forward, {0.0, 1.0, 0.0})};
auto const rotationangle{std::min(45.0, (FreeFlyModeFlag ? 5 * glm::length(velocity) : simulation::Train->Dynamic()->GetVelocity() * 0.2))};
::glRotated(rotationangle, left.x, 0.0, left.z);
}
if (false == FreeFlyModeFlag)
{
// counter potential vehicle roll
auto const roll{0.5 * glm::degrees(simulation::Train->Dynamic()->Roll())};
if (roll != 0.0)
{
auto const forward{simulation::Train->Dynamic()->VectorFront()};
auto const vehicledirection = simulation::Train->Dynamic()->DirectionGet();
::glRotated(roll, forward.x, 0.0, forward.z);
}
}
if (Global.Weather == "rain:")
{
// oddly enough random streaks produce more natural looking rain than ones the eye can follow
::glRotated(Random() * 360, 0.0, 1.0, 0.0);
}
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
model_ubs.param[0] = interpolate(0.5f * (Global.DayLight.diffuse + Global.DayLight.ambient), colors::white, 0.5f * clamp<float>(Global.fLuminance, 0.f, 1.f));
model_ubs.param[1].x = simulation::Environment.m_precipitation.get_textureoffset();
model_ubo->update(model_ubs);
// momentarily disable depth write, to allow vehicle cab drawn afterwards to mask it instead of leaving it 'inside'
::glDepthMask(GL_FALSE);
simulation::Environment.m_precipitation.render();
::glDepthMask(GL_TRUE);
::glPopMatrix();
}
void opengl_renderer::Render_Alpha(scene::basic_region *Region)
{
@@ -3040,8 +3103,7 @@ void opengl_renderer::Render_Alpha(TSubModel *Submodel)
}
else if (Submodel->eType == TP_FREESPOTLIGHT)
{
if (Global.fLuminance < Submodel->fLight)
if (Global.fLuminance < Submodel->fLight || Global.Overcast > 1.0f)
{
// NOTE: we're forced here to redo view angle calculations etc, because this data isn't instanced but stored along with the single mesh
// TODO: separate instance data from reusable geometry
@@ -3054,15 +3116,12 @@ void opengl_renderer::Render_Alpha(TSubModel *Submodel)
if (Submodel->fCosViewAngle > Submodel->fCosFalloffAngle)
{
// only bother if the viewer is inside the visibility cone
if (Global.Overcast > 1.0)
{
// increase the glare in rainy/foggy conditions
glarelevel += std::max(0.f, 0.5f * (Global.Overcast - 1.f));
}
auto glarelevel{clamp<float>(0.6f - Global.fLuminance // reduce the glare in bright daylight
+ std::max(0.f, Global.Overcast - 1.f), // increase the glare in rainy/foggy conditions
0.f, 1.f)};
// scale it down based on view angle
glarelevel *= (Submodel->fCosViewAngle - Submodel->fCosFalloffAngle) / (1.0f - Submodel->fCosFalloffAngle);
// reduce the glare in bright daylight
glarelevel = clamp(glarelevel - static_cast<float>(Global.fLuminance), 0.f, 1.f);
if (glarelevel > 0.0f)
{
@@ -3403,7 +3462,10 @@ void opengl_renderer::Update_Lights(light_array &Lights)
light_ubs.fog_color = Global.FogColor;
if (Global.fFogEnd > 0)
light_ubs.fog_density = 1.0f / Global.fFogEnd;
{
auto const adjustedfogrange{Global.fFogEnd / std::max(1.f, Global.Overcast * 2.f)};
light_ubs.fog_density = 1.0f / adjustedfogrange;
}
else
light_ubs.fog_density = 0.0f;