diff --git a/AnimModel.cpp b/AnimModel.cpp index cf87fb43..ac8bc679 100644 --- a/AnimModel.cpp +++ b/AnimModel.cpp @@ -422,9 +422,8 @@ TAnimModel::~TAnimModel() bool TAnimModel::Init(TModel3d *pNewModel) { fBlinkTimer = double(Random(1000 * fOffTime)) / (1000 * fOffTime); - ; pModel = pNewModel; - return (pModel != NULL); + return (pModel != nullptr); } bool TAnimModel::Init(std::string const &asName, std::string const &asReplacableTexture) @@ -578,10 +577,10 @@ void TAnimModel::RaPrepare() switch (lightmode) { case ls_Blink: // migotanie - state = fBlinkTimer < fOnTime; + state = ( fBlinkTimer < fOnTime ); break; case ls_Dark: // zapalone, gdy ciemno - state = Global::fLuminance <= ( lsLights[i] - 3.0 ); + state = ( Global::fLuminance <= ( lsLights[i] - 3.0 ) ); break; default: // zapalony albo zgaszony state = (lightmode == ls_On); diff --git a/DynObj.cpp b/DynObj.cpp index 8ce3b99e..f4c1dc77 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -3697,6 +3697,7 @@ void TDynamicObject::RenderSounds() { } // szum w czasie jazdy if( ( GetVelocity() > 0.5 ) + && ( false == rsOuterNoise.empty() ) && ( // compound test whether the vehicle belongs to user-driven consist (as these don't emit outer noise in cab view) FreeFlyModeFlag ? true : // in external view all vehicles emit outer noise // Global::pWorld->train() == nullptr ? true : // (can skip this check, with no player train the external view is a given) @@ -3705,9 +3706,19 @@ void TDynamicObject::RenderSounds() { Global::CabWindowOpen ? true : // sticking head out we get to hear outer noise false ) ) { - volume = rsOuterNoise.m_amplitudefactor * MoverParameters->Vel + rsOuterNoise.m_amplitudeoffset; - frequency = rsOuterNoise.m_frequencyfactor * MoverParameters->Vel + rsOuterNoise.m_frequencyoffset; + // frequency calculation + auto const normalizer { ( + true == rsOuterNoise.is_combined() ? + MoverParameters->Vmax * 0.01f : + 1.f ) }; + frequency = + rsOuterNoise.m_frequencyoffset + + rsOuterNoise.m_frequencyfactor * MoverParameters->Vel * normalizer; + // volume calculation + volume = + rsOuterNoise.m_amplitudeoffset + + rsOuterNoise.m_amplitudefactor * MoverParameters->Vel; if( brakeforceratio > 0.0 ) { // hamulce wzmagaja halas volume *= 1 + 0.125 * brakeforceratio; @@ -3723,10 +3734,15 @@ void TDynamicObject::RenderSounds() { MoverParameters->Vel / 40.0, 0.0, 1.0 ) ); - rsOuterNoise - .pitch( frequency ) // arbitrary limits to prevent the pitch going out of whack - .gain( volume ) - .play( sound_flags::exclusive | sound_flags::looping ); + if( volume > 0.05 ) { + rsOuterNoise + .pitch( frequency ) // arbitrary limits to prevent the pitch going out of whack + .gain( volume ) + .play( sound_flags::exclusive | sound_flags::looping ); + } + else { + rsOuterNoise.stop(); + } } else { // don't play the optional ending sound if the listener switches views @@ -5524,12 +5540,13 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub || ( Vehicle.EngineType == Dumb ) ) { // frequency calculation - auto normalizer { 1.f }; - if( true == engine.is_combined() ) { - // for combined engine sound we calculate sound point in rpm, to make .mmd files setup easier - // NOTE: we supply 1/100th of actual value, as the sound module converts does the opposite, converting received (typically) 0-1 values to 0-100 range - normalizer = 60.f * 0.01f; - } + auto const normalizer { ( + true == engine.is_combined() ? + // for combined engine sound we calculate sound point in rpm, to make .mmd files setup easier + // NOTE: we supply 1/100th of actual value, as the sound module converts does the opposite, converting received (typically) 0-1 values to 0-100 range + 60.f * 0.01f : + // for legacy single-piece sounds the standard frequency calculation is left untouched + 1.f ) }; frequency = engine.m_frequencyoffset + engine.m_frequencyfactor * std::abs( Vehicle.enrot ) * normalizer; diff --git a/Globals.cpp b/Globals.cpp index ed7b8764..4dd3d0ff 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -116,6 +116,8 @@ std::string Global::LastGLError; GLint Global::iMaxTextureSize = 4096; // maksymalny rozmiar tekstury bool Global::bSmoothTraction { true }; // wygładzanie drutów starym sposobem float Global::SplineFidelity { 1.f }; // determines segment size during conversion of splines to geometry +bool Global::ResourceSweep { true }; // gfx resource garbage collection +bool Global::ResourceMove { false }; // gfx resources are moved between cpu and gpu side instead of sending a copy std::string Global::szDefaultExt = Global::szTexturesDDS; // domyślnie od DDS int Global::iMultisampling = 2; // tryb antyaliasingu: 0=brak,1=2px,2=4px,3=8px,4=16px bool Global::DLFont{ false }; // switch indicating presence of basic font @@ -512,6 +514,16 @@ void Global::ConfigParse(cParser &Parser) Parser >> splinefidelity; Global::SplineFidelity = clamp( splinefidelity, 1.f, 4.f ); } + else if( token == "gfx.resource.sweep" ) { + + Parser.getTokens(); + Parser >> Global::ResourceSweep; + } + else if( token == "gfx.resource.move" ) { + + Parser.getTokens(); + Parser >> Global::ResourceMove; + } else if (token == "timespeed") { // przyspieszenie czasu, zmienna do testów diff --git a/Globals.h b/Globals.h index 79f5e176..8213e37a 100644 --- a/Globals.h +++ b/Globals.h @@ -214,6 +214,8 @@ public: static bool bSmoothTraction; // wygładzanie drutów static float SplineFidelity; // determines segment size during conversion of splines to geometry static GLfloat FogColor[]; + static bool ResourceSweep; // gfx resource garbage collection + static bool ResourceMove; // gfx resources are moved between cpu and gpu side instead of sending a copy // sound renderer variables static bool bSoundEnabled; static float AudioVolume; diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 9869a246..12be0ceb 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -4429,29 +4429,36 @@ double TMoverParameters::TractionForce(double dt) } else // jazda ciapongowa { - auto power = Power; if( true == Heating ) { power -= HeatingPower; } if( power < 0.0 ) { power = 0.0; } - tmp = std::min( DElist[ MainCtrlPos ].GenPower, power );// Power - HeatingPower * double( Heating )); + // NOTE: very crude way to approximate power generated at current rpm instead of instant top output + auto const currentgenpower { ( + DElist[ MainCtrlPos ].RPM > 0 ? + DElist[ MainCtrlPos ].GenPower * ( 60.0 * enrot / DElist[ MainCtrlPos ].RPM ) : + 0.0 ) }; + + tmp = std::min( power, currentgenpower ); - PosRatio = DElist[MainCtrlPos].GenPower / DElist[MainCtrlPosNo].GenPower; + PosRatio = currentgenpower / DElist[MainCtrlPosNo].GenPower; // stosunek mocy teraz do mocy max - if ((MainCtrlPos > 0) && (ConverterFlag)) - if (tmpV < - (Vhyp * power / - DElist[MainCtrlPosNo].GenPower)) // czy na czesci prostej, czy na hiperboli - Ft = (Ftmax - - ((Ftmax - 1000.0 * DElist[MainCtrlPosNo].GenPower / (Vhyp + Vadd)) * - (tmpV / Vhyp) / PowerCorRatio)) * - PosRatio; // posratio - bo sila jakos tam sie rozklada + if( ( MainCtrlPos > 0 ) && ( ConverterFlag ) ) { - // Ft:=(Ftmax - (Ftmax - (1000.0 * DEList[MainCtrlPosNo].genpower / - //(Vhyp+Vadd) / PowerCorRatio)) * (tmpV/Vhyp)) * PosRatio //wersja z Megapacka - else // na hiperboli //1.107 - - // wspolczynnik sredniej nadwyzki Ft w symku nad charakterystyka - Ft = 1000.0 * tmp / (tmpV + Vadd) / - PowerCorRatio; // tu jest zawarty stosunek mocy + if( tmpV < ( Vhyp * power / DElist[ MainCtrlPosNo ].GenPower ) ) { + // czy na czesci prostej, czy na hiperboli + Ft = ( Ftmax + - ( ( Ftmax - 1000.0 * DElist[ MainCtrlPosNo ].GenPower / ( Vhyp + Vadd ) ) + * ( tmpV / Vhyp ) + / PowerCorRatio ) ) + * PosRatio; // posratio - bo sila jakos tam sie rozklada + } + else { + // na hiperboli + // 1.107 - wspolczynnik sredniej nadwyzki Ft w symku nad charakterystyka + Ft = 1000.0 * tmp / ( tmpV + Vadd ) / + PowerCorRatio; // tu jest zawarty stosunek mocy + } + } else Ft = 0; // jak nastawnik na zero, to sila tez zero diff --git a/Texture.cpp b/Texture.cpp index 0aedf1e3..bd4bce23 100644 --- a/Texture.cpp +++ b/Texture.cpp @@ -589,8 +589,12 @@ opengl_texture::create() { } } - data = std::vector(); - data_state = resource_state::none; + if( ( true == Global::ResourceMove ) + || ( false == Global::ResourceSweep ) ) { + // if garbage collection is disabled we don't expect having to upload the texture more than once + data = std::vector(); + data_state = resource_state::none; + } is_ready = true; } @@ -599,11 +603,14 @@ opengl_texture::create() { // releases resources allocated on the opengl end, storing local copy if requested void -opengl_texture::release( bool const Backup ) { +opengl_texture::release() { if( id == -1 ) { return; } - if( true == Backup ) { + if( true == Global::ResourceMove ) { + // if resource move is enabled we don't keep a cpu side copy after upload + // so need to re-acquire the data before release + // TBD, TODO: instead of vram-ram transfer fetch the data 'normally' from the disk using worker thread ::glBindTexture( GL_TEXTURE_2D, id ); GLint datasize {}; GLint iscompressed {}; diff --git a/Texture.h b/Texture.h index 1d5b2500..b6040169 100644 --- a/Texture.h +++ b/Texture.h @@ -30,7 +30,7 @@ struct opengl_texture { create(); // releases resources allocated on the opengl end, storing local copy if requested void - release( bool const Backup = true ); + release(); inline int width() const { diff --git a/Train.cpp b/Train.cpp index 3a164ca9..31a67212 100644 --- a/Train.cpp +++ b/Train.cpp @@ -4472,12 +4472,27 @@ TTrain::update_sounds( double const Deltatime ) { && ( false == Global::CabWindowOpen ) && ( DynamicObject->GetVelocity() > 0.5 ) ) { - volume = rsRunningNoise.m_amplitudeoffset + rsRunningNoise.m_amplitudefactor * mvOccupied->Vel; - auto frequency { rsRunningNoise.m_frequencyoffset + rsRunningNoise.m_frequencyfactor * mvOccupied->Vel }; + // frequency calculation + auto const normalizer { ( + true == rsRunningNoise.is_combined() ? + mvOccupied->Vmax * 0.01f : + 1.f ) }; + auto const frequency { + rsRunningNoise.m_frequencyoffset + + rsRunningNoise.m_frequencyfactor * mvOccupied->Vel * normalizer }; + // volume calculation + volume = + rsRunningNoise.m_amplitudeoffset + + rsRunningNoise.m_amplitudefactor * mvOccupied->Vel; if( std::abs( mvOccupied->nrot ) > 0.01 ) { // hamulce wzmagaja halas - volume *= 1 + 0.25 * ( mvOccupied->UnitBrakeForce / ( 1 + mvOccupied->MaxBrakeForce ) ); + auto const brakeforceratio { ( + clamp( + mvOccupied->UnitBrakeForce / std::max( 1.0, mvOccupied->BrakeForceR( 1.0, mvOccupied->Vel ) / ( mvOccupied->NAxles * std::max( 1, mvOccupied->NBpA ) ) ), + 0.0, 1.0 ) ) }; + + volume *= 1 + 0.125 * brakeforceratio; } // scale volume by track quality volume *= ( 20.0 + DynamicObject->MyTrack->iDamageFlag ) / 21; @@ -4489,10 +4504,16 @@ TTrain::update_sounds( double const Deltatime ) { clamp( mvOccupied->Vel / 40.0, 0.0, 1.0 ) ); - rsRunningNoise - .pitch( frequency ) - .gain( volume ) - .play( sound_flags::exclusive | sound_flags::looping ); + + if( volume > 0.05 ) { + rsRunningNoise + .pitch( frequency ) + .gain( volume ) + .play( sound_flags::exclusive | sound_flags::looping ); + } + else { + rsRunningNoise.stop(); + } } else { // don't play the optional ending sound if the listener switches views diff --git a/renderer.cpp b/renderer.cpp index 7a7303d2..7335c7b3 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -1325,6 +1325,10 @@ opengl_renderer::Render( world_environment *Environment ) { // turn on moon shadows after nautical twilight, if the moon is actually up m_shadowcolor = glm::vec4{ 0.5f, 0.5f, 0.5f, 1.f }; } + // soften shadows depending on sky overcast factor + m_shadowcolor = glm::min( + colors::white, + m_shadowcolor + glm::vec4{ glm::vec3{ 0.5f * Global::Overcast }, 1.f } ); if( Global::bWireFrame ) { // bez nieba w trybie rysowania linii @@ -3362,7 +3366,8 @@ opengl_renderer::Update( double const Deltatime ) { ::glEnable( GL_MULTISAMPLE ); } - if( true == World.InitPerformed() ) { + if( ( true == Global::ResourceSweep ) + && ( true == World.InitPerformed() ) ) { // garbage collection m_geometry.update(); m_textures.update(); diff --git a/version.h b/version.h index 36e55658..2ca029a2 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #pragma once #define VERSION_MAJOR 18 -#define VERSION_MINOR 115 +#define VERSION_MINOR 119 #define VERSION_REVISION 0