mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
submodel opacity parameter, additional light blinking modes, scenario event queue filtering
This commit is contained in:
110
AnimModel.cpp
110
AnimModel.cpp
@@ -444,8 +444,9 @@ bool TAnimModel::Init(std::string const &asName, std::string const &asReplacable
|
||||
// tekstura nieprzezroczysta - nie renderować w cyklu przezroczystych
|
||||
m_materialdata.textures_alpha = 0x30300030;
|
||||
}
|
||||
|
||||
fBlinkTimer = double( Random( 1000 * fOffTime ) ) / ( 1000 * fOffTime );
|
||||
|
||||
// TODO: redo the random timer initialization
|
||||
// fBlinkTimer = Random() * ( fOnTime + fOffTime );
|
||||
|
||||
pModel = TModelsManager::GetModel( asName );
|
||||
return ( pModel != nullptr );
|
||||
@@ -547,9 +548,73 @@ void TAnimModel::RaAnimate( unsigned int const Framestamp ) {
|
||||
|
||||
if( Framestamp == m_framestamp ) { return; }
|
||||
|
||||
fBlinkTimer -= Timer::GetDeltaTime();
|
||||
if( fBlinkTimer <= 0 )
|
||||
fBlinkTimer += fOffTime;
|
||||
auto const timedelta { Timer::GetDeltaTime() };
|
||||
|
||||
// interpretacja ułamka zależnie od typu
|
||||
// case ls_Off: ustalenie czasu migotania, t<1s (f>1Hz), np. 0.1 => t=0.1 (f=10Hz)
|
||||
// case ls_On: ustalenie wypełnienia ułamkiem, np. 1.25 => zapalony przez 1/4 okresu
|
||||
// case ls_Blink: ustalenie częstotliwości migotania, f<1Hz (t>1s), np. 2.2 => f=0.2Hz (t=5s)
|
||||
float modeintegral, modefractional;
|
||||
for( int idx = 0; idx < iNumLights; ++idx ) {
|
||||
|
||||
modefractional = std::modf( std::abs( lsLights[ idx ] ), &modeintegral );
|
||||
|
||||
if( modeintegral >= ls_Dark ) {
|
||||
// light threshold modes don't use timers
|
||||
continue;
|
||||
}
|
||||
auto const mode { static_cast<int>( modeintegral ) };
|
||||
|
||||
auto &opacity { m_lightopacities[ idx ] };
|
||||
auto &timer { m_lighttimers[ idx ] };
|
||||
if( ( modeintegral < ls_Blink ) && ( modefractional < 0.01f ) ) {
|
||||
// simple flip modes
|
||||
switch( mode ) {
|
||||
case ls_Off: {
|
||||
// reduce to zero
|
||||
timer = std::max<float>( 0.f, timer - timedelta );
|
||||
break;
|
||||
}
|
||||
case ls_On: {
|
||||
// increase to max value
|
||||
timer = std::min<float>( fTransitionTime, timer + timedelta );
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
opacity = timer / fTransitionTime;
|
||||
}
|
||||
else {
|
||||
// blink modes
|
||||
auto const ontime { (
|
||||
( mode == ls_Blink ) ? ( ( modefractional < 0.01f ) ? fOnTime : ( 1.f / modefractional ) * 0.5f ) :
|
||||
( mode == ls_Off ) ? modefractional * 0.5f :
|
||||
( mode == ls_On ) ? modefractional * ( fOnTime + fOffTime ) :
|
||||
fOnTime ) }; // fallback
|
||||
auto const offtime { (
|
||||
( mode == ls_Blink ) ? ( ( modefractional < 0.01f ) ? fOffTime : ontime ) :
|
||||
( mode == ls_Off ) ? ontime :
|
||||
( mode == ls_On ) ? ( fOnTime + fOffTime ) - ontime :
|
||||
fOffTime ) }; // fallback
|
||||
auto const transitiontime {
|
||||
std::min(
|
||||
1.f,
|
||||
std::min( ontime, offtime ) * 0.9f ) };
|
||||
|
||||
timer = clamp_circular<float>( timer + timedelta * ( lsLights[ idx ] > 0.f ? 1.f : -1.f ), ontime + offtime );
|
||||
// set opacity depending on blink stage
|
||||
if( timer < ontime ) {
|
||||
// blink on
|
||||
opacity = clamp( timer / transitiontime, 0.f, 1.f );
|
||||
}
|
||||
else {
|
||||
// blink off
|
||||
opacity = 1.f - clamp( ( timer - ontime ) / transitiontime, 0.f, 1.f );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ra 2F1I: to by można pomijać dla modeli bez animacji, których jest większość
|
||||
TAnimContainer *pCurrent;
|
||||
@@ -568,17 +633,19 @@ void TAnimModel::RaPrepare()
|
||||
bool state; // stan światła
|
||||
for (int i = 0; i < iNumLights; ++i)
|
||||
{
|
||||
auto const lightmode { static_cast<int>( lsLights[ i ] ) };
|
||||
auto const lightmode { static_cast<int>( std::abs( lsLights[ i ] ) ) };
|
||||
switch( lightmode ) {
|
||||
case ls_On:
|
||||
case ls_Off: {
|
||||
// zapalony albo zgaszony
|
||||
state = ( lightmode == ls_On );
|
||||
break;
|
||||
}
|
||||
case ls_Off:
|
||||
case ls_Blink: {
|
||||
// migotanie
|
||||
state = ( fBlinkTimer < fOnTime );
|
||||
if (LightsOn[i]) {
|
||||
LightsOn[i]->iVisible = ( m_lightopacities[i] > 0.f );
|
||||
LightsOn[i]->SetVisibilityLevel( m_lightopacities[i], true, false );
|
||||
}
|
||||
if (LightsOff[i]) {
|
||||
LightsOff[i]->iVisible = ( m_lightopacities[i] < 1.f );
|
||||
LightsOff[i]->SetVisibilityLevel( 1.f, true, false );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ls_Dark: {
|
||||
@@ -606,10 +673,16 @@ void TAnimModel::RaPrepare()
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (LightsOn[i])
|
||||
LightsOn[i]->iVisible = state;
|
||||
if (LightsOff[i])
|
||||
LightsOff[i]->iVisible = !state;
|
||||
if( lightmode >= ls_Dark ) {
|
||||
// crude as hell but for test will do :x
|
||||
if (LightsOn[i]) {
|
||||
LightsOn[i]->iVisible = state;
|
||||
// TODO: set visibility for the entire submodel's children as well
|
||||
LightsOn[i]->fVisible = m_lightopacities[i];
|
||||
}
|
||||
if (LightsOff[i])
|
||||
LightsOff[i]->iVisible = !state;
|
||||
}
|
||||
}
|
||||
TSubModel::iInstance = reinterpret_cast<std::uintptr_t>( this ); //żeby nie robić cudzych animacji
|
||||
TSubModel::pasText = &asText; // przekazanie tekstu do wyświetlacza (!!!! do przemyślenia)
|
||||
@@ -774,8 +847,9 @@ void TAnimModel::AnimationVND(void *pData, double a, double b, double c, double
|
||||
//---------------------------------------------------------------------------
|
||||
void TAnimModel::LightSet(int const n, float const v)
|
||||
{ // ustawienie światła (n) na wartość (v)
|
||||
if (n >= iMaxNumLights)
|
||||
if( n >= iMaxNumLights ) {
|
||||
return; // przekroczony zakres
|
||||
}
|
||||
lsLights[ n ] = v;
|
||||
};
|
||||
|
||||
|
||||
11
AnimModel.h
11
AnimModel.h
@@ -179,7 +179,7 @@ private:
|
||||
// members
|
||||
TAnimContainer *pRoot { nullptr }; // pojemniki sterujące, tylko dla aniomowanych submodeli
|
||||
TModel3d *pModel { nullptr };
|
||||
double fBlinkTimer { 0.0 };
|
||||
// double fBlinkTimer { 0.0 };
|
||||
int iNumLights { 0 };
|
||||
TSubModel *LightsOn[ iMaxNumLights ]; // Ra: te wskaźniki powinny być w ramach TModel3d
|
||||
TSubModel *LightsOff[ iMaxNumLights ];
|
||||
@@ -188,10 +188,13 @@ private:
|
||||
|
||||
std::string asText; // tekst dla wyświetlacza znakowego
|
||||
TAnimAdvanced *pAdvanced { nullptr };
|
||||
// TODO: wrap into a light state struct
|
||||
float lsLights[ iMaxNumLights ];
|
||||
// float fDark { DefaultDarkThresholdLevel }; // poziom zapalanie światła (powinno być chyba powiązane z danym światłem?)
|
||||
float fOnTime { 0.66f };
|
||||
float fOffTime { 0.66f + 0.66f }; // były stałymi, teraz mogą być zmienne dla każdego egzemplarza
|
||||
std::array<float, iMaxNumLights> m_lighttimers { 0.f };
|
||||
std::array<float, iMaxNumLights> m_lightopacities { 1.f };
|
||||
float fOnTime { 1.f / 2 };// { 60.f / 45.f / 2 };
|
||||
float fOffTime { 1.f / 2 };// { 60.f / 45.f / 2 }; // były stałymi, teraz mogą być zmienne dla każdego egzemplarza
|
||||
float fTransitionTime { fOnTime * 0.9f }; // time
|
||||
unsigned int m_framestamp { 0 }; // id of last rendered gfx frame
|
||||
};
|
||||
|
||||
|
||||
@@ -342,8 +342,8 @@ std::string TSpeedPos::TableText() const
|
||||
{ // pozycja tabelki pr?dko?ci
|
||||
if (iFlags & spEnabled)
|
||||
{ // o ile pozycja istotna
|
||||
return "Flags:" + to_hex_str(iFlags, 8) + ", Dist:" + to_string(fDist, 1, 6) +
|
||||
", Vel:" + (fVelNext == -1.0 ? " - " : to_string(static_cast<int>(fVelNext), 0, 3)) + ", Name:" + GetName();
|
||||
return to_hex_str(iFlags, 8) + " " + to_string(fDist, 1, 6) +
|
||||
" " + (fVelNext == -1.0 ? " -" : to_string(static_cast<int>(fVelNext), 0, 3)) + " " + GetName();
|
||||
}
|
||||
return "Empty";
|
||||
}
|
||||
|
||||
23
Model3d.cpp
23
Model3d.cpp
@@ -71,6 +71,23 @@ void TSubModel::Name(std::string const &Name)
|
||||
pName = Name;
|
||||
};
|
||||
|
||||
// sets visibility level (alpha component) to specified value
|
||||
void
|
||||
TSubModel::SetVisibilityLevel( float const Level, bool const Includechildren, bool const Includesiblings ) {
|
||||
|
||||
fVisible = Level;
|
||||
if( true == Includesiblings ) {
|
||||
auto sibling { this };
|
||||
while( ( sibling = sibling->Next ) != nullptr ) {
|
||||
sibling->SetVisibilityLevel( Level, Includechildren, false ); // no need for all siblings to duplicate the work
|
||||
}
|
||||
}
|
||||
if( ( true == Includechildren )
|
||||
&& ( Child != nullptr ) ) {
|
||||
Child->SetVisibilityLevel( Level, Includechildren, true ); // node's children include child's siblings and children
|
||||
}
|
||||
}
|
||||
|
||||
// sets light level (alpha component of illumination color) to specified value
|
||||
void
|
||||
TSubModel::SetLightLevel( float const Level, bool const Includechildren, bool const Includesiblings ) {
|
||||
@@ -1313,7 +1330,8 @@ void TSubModel::serialize(std::ostream &s,
|
||||
else
|
||||
sn_utils::ls_int32(s, (int32_t)get_container_pos(textures, m_materialname));
|
||||
|
||||
sn_utils::ls_float32(s, fVisible);
|
||||
// sn_utils::ls_float32(s, fVisible);
|
||||
sn_utils::ls_float32(s, 1.f);
|
||||
sn_utils::ls_float32(s, fLight);
|
||||
|
||||
sn_utils::s_vec4(s, f4Ambient);
|
||||
@@ -1433,7 +1451,8 @@ void TSubModel::deserialize(std::istream &s)
|
||||
tVboPtr = sn_utils::ld_int32(s);
|
||||
iTexture = sn_utils::ld_int32(s);
|
||||
|
||||
fVisible = sn_utils::ld_float32(s);
|
||||
// fVisible = sn_utils::ld_float32(s);
|
||||
auto discard = sn_utils::ld_float32(s);
|
||||
fLight = sn_utils::ld_float32(s);
|
||||
|
||||
f4Ambient = sn_utils::d_vec4(s);
|
||||
|
||||
@@ -98,7 +98,6 @@ private:
|
||||
int iNumVerts { -1 }; // ilość wierzchołków (1 dla FreeSpotLight)
|
||||
int tVboPtr; // początek na liście wierzchołków albo indeksów
|
||||
int iTexture { 0 }; // numer nazwy tekstury, -1 wymienna, 0 brak
|
||||
float fVisible { 0.0f }; // próg jasności światła do załączenia submodelu
|
||||
float fLight { -1.0f }; // próg jasności światła do zadziałania selfillum
|
||||
glm::vec4
|
||||
f4Ambient { 1.0f,1.0f,1.0f,1.0f },
|
||||
@@ -140,7 +139,8 @@ public: // chwilowo
|
||||
float4x4 *mAnimMatrix{ nullptr }; // macierz do animacji kwaternionowych (należy do AnimContainer)
|
||||
TSubModel **smLetter{ nullptr }; // wskaźnik na tablicę submdeli do generoania tekstu (docelowo zapisać do E3D)
|
||||
TSubModel *Parent{ nullptr }; // nadrzędny, np. do wymnażania macierzy
|
||||
int iVisible{ 1 }; // roboczy stan widoczności
|
||||
int iVisible { 1 }; // roboczy stan widoczności
|
||||
float fVisible { 1.f }; // visibility level
|
||||
std::string m_materialname; // robocza nazwa tekstury do zapisania w pliku binarnym
|
||||
std::string pName; // robocza nazwa
|
||||
private:
|
||||
@@ -192,6 +192,8 @@ public:
|
||||
int Flags() const { return iFlags; };
|
||||
void UnFlagNext() { iFlags &= 0x00FFFFFF; };
|
||||
void ColorsSet( glm::vec3 const &Ambient, glm::vec3 const &Diffuse, glm::vec3 const &Specular );
|
||||
// sets visibility level (alpha component) to specified value
|
||||
void SetVisibilityLevel( float const Level, bool const Includechildren = false, bool const Includesiblings = false );
|
||||
// sets light level (alpha component of illumination color) to specified value
|
||||
void SetLightLevel( float const Level, bool const Includechildren = false, bool const Includesiblings = false );
|
||||
inline float3 Translation1Get() {
|
||||
|
||||
@@ -565,7 +565,7 @@ TTraction::wire_color() const {
|
||||
color.r *= Global.DayLight.ambient[ 0 ];
|
||||
color.g *= Global.DayLight.ambient[ 1 ];
|
||||
color.b *= Global.DayLight.ambient[ 2 ];
|
||||
color *= 0.5f;
|
||||
color *= 0.35f;
|
||||
}
|
||||
else {
|
||||
// tymczasowo pokazanie zasilanych odcinków
|
||||
|
||||
@@ -356,7 +356,10 @@ debug_panel::render() {
|
||||
render_section( "Vehicle AI", m_ailines );
|
||||
render_section( "Vehicle Scan Table", m_scantablelines );
|
||||
render_section( "Scenario", m_scenariolines );
|
||||
render_section( "Scenario Event Queue", m_eventqueuelines );
|
||||
if( true == render_section( "Scenario Event Queue", m_eventqueuelines ) ) {
|
||||
// event queue filter
|
||||
ImGui::Checkbox( "By This Vehicle Only", &m_eventqueueactivevehicleonly );
|
||||
}
|
||||
render_section( "Camera", m_cameralines );
|
||||
render_section( "Gfx Renderer", m_rendererlines );
|
||||
// toggles
|
||||
@@ -764,6 +767,8 @@ debug_panel::update_section_scantable( std::vector<text_line> &Output ) {
|
||||
|
||||
if( m_input.mechanik == nullptr ) { return; }
|
||||
|
||||
Output.emplace_back( "Flags: Dist: Vel: Name:", Global.UITextColor );
|
||||
|
||||
auto const &mechanik{ *m_input.mechanik };
|
||||
|
||||
std::size_t i = 0; std::size_t const speedtablesize = clamp( static_cast<int>( mechanik.TableSize() ) - 1, 0, 30 );
|
||||
@@ -773,8 +778,8 @@ debug_panel::update_section_scantable( std::vector<text_line> &Output ) {
|
||||
Output.emplace_back( Bezogonkow( scanline ), Global.UITextColor );
|
||||
++i;
|
||||
} while( i < speedtablesize );
|
||||
if( Output.empty() ) {
|
||||
Output.emplace_back( "(no points of interest)", Global.UITextColor );
|
||||
if( Output.size() == 1 ) {
|
||||
Output.front().data = "(no points of interest)";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -787,7 +792,8 @@ debug_panel::update_section_scenario( std::vector<text_line> &Output ) {
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
// current luminance level
|
||||
textline = "Light level: " + to_string( Global.fLuminance, 3 );
|
||||
textline = "Cloud cover: " + to_string( Global.Overcast, 3 );
|
||||
textline += "\nLight level: " + to_string( Global.fLuminance, 3 );
|
||||
if( Global.FakeLight ) { textline += "(*)"; }
|
||||
textline += "\nAir temperature: " + to_string( Global.AirTemperature, 1 ) + " deg C";
|
||||
|
||||
@@ -799,32 +805,33 @@ debug_panel::update_section_eventqueue( std::vector<text_line> &Output ) {
|
||||
|
||||
std::string textline;
|
||||
|
||||
// current event queue
|
||||
auto const time { Timer::GetTime() };
|
||||
auto const *event { simulation::Events.begin() };
|
||||
auto eventtableindex{ 0 };
|
||||
while( ( event != nullptr )
|
||||
&& ( eventtableindex < 30 ) ) {
|
||||
// current event queue
|
||||
auto const time { Timer::GetTime() };
|
||||
auto const *event { simulation::Events.begin() };
|
||||
|
||||
if( ( false == event->m_ignored )
|
||||
&& ( false == event->m_passive ) ) {
|
||||
Output.emplace_back( "Delay: Event:", Global.UITextColor );
|
||||
|
||||
auto const delay { " " + to_string( std::max( 0.0, event->m_launchtime - time ), 1 ) };
|
||||
textline =
|
||||
"Delay: " + delay.substr( delay.length() - 6 )
|
||||
+ ", Event: " + event->m_name
|
||||
+ ( event->m_activator ? " (by: " + event->m_activator->asName + ")" : "" )
|
||||
+ ( event->m_sibling ? " (joint event)" : "" );
|
||||
while( ( event != nullptr )
|
||||
&& ( Output.size() < 30 ) ) {
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
++eventtableindex;
|
||||
}
|
||||
event = event->m_next;
|
||||
}
|
||||
if( Output.empty() ) {
|
||||
textline = "(no queued events)";
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
}
|
||||
if( ( false == event->m_ignored )
|
||||
&& ( false == event->m_passive )
|
||||
&& ( ( false == m_eventqueueactivevehicleonly )
|
||||
|| ( event->m_activator == m_input.vehicle ) ) ) {
|
||||
|
||||
auto const delay { " " + to_string( std::max( 0.0, event->m_launchtime - time ), 1 ) };
|
||||
textline = delay.substr( delay.length() - 6 )
|
||||
+ " " + event->m_name
|
||||
+ ( event->m_activator ? " (by: " + event->m_activator->asName + ")" : "" )
|
||||
+ ( event->m_sibling ? " (joint event)" : "" );
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
}
|
||||
event = event->m_next;
|
||||
}
|
||||
if( Output.size() == 1 ) {
|
||||
Output.front().data = "(no queued events)";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -888,15 +895,16 @@ debug_panel::update_section_renderer( std::vector<text_line> &Output ) {
|
||||
Output.emplace_back( GfxRenderer.info_stats(), Global.UITextColor );
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
debug_panel::render_section( std::string const &Header, std::vector<text_line> const &Lines ) {
|
||||
|
||||
if( Lines.empty() ) { return; }
|
||||
if( false == ImGui::CollapsingHeader( Header.c_str() ) ) { return; }
|
||||
if( true == Lines.empty() ) { return false; }
|
||||
if( false == ImGui::CollapsingHeader( Header.c_str() ) ) { return false; }
|
||||
|
||||
for( auto const &line : Lines ) {
|
||||
ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -76,7 +76,7 @@ private:
|
||||
std::string update_vehicle_coupler( int const Side );
|
||||
std::string update_vehicle_brake() const;
|
||||
// renders provided lines, under specified collapsing header
|
||||
void render_section( std::string const &Header, std::vector<text_line> const &Lines );
|
||||
bool render_section( std::string const &Header, std::vector<text_line> const &Lines );
|
||||
// members
|
||||
std::array<char, 1024> m_buffer;
|
||||
input_data m_input;
|
||||
@@ -92,6 +92,7 @@ private:
|
||||
int tprev { 0 }; // poprzedni czas
|
||||
double VelPrev { 0.0 }; // poprzednia prędkość
|
||||
double Acc { 0.0 }; // przyspieszenie styczne
|
||||
bool m_eventqueueactivevehicleonly { false };
|
||||
};
|
||||
|
||||
class transcripts_panel : public ui_panel {
|
||||
|
||||
36
renderer.cpp
36
renderer.cpp
@@ -2409,7 +2409,20 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
Bind_Material( Submodel->m_material );
|
||||
}
|
||||
// ...colors...
|
||||
::glColor3fv( glm::value_ptr( Submodel->f4Diffuse ) ); // McZapkie-240702: zamiast ub
|
||||
if( Submodel->fVisible < 1.f ) {
|
||||
// setup
|
||||
::glAlphaFunc( GL_GREATER, 0.f );
|
||||
::glEnable( GL_BLEND );
|
||||
::glColor4f(
|
||||
Submodel->f4Diffuse.r,
|
||||
Submodel->f4Diffuse.g,
|
||||
Submodel->f4Diffuse.b,
|
||||
Submodel->fVisible );
|
||||
}
|
||||
else {
|
||||
::glColor3fv( glm::value_ptr( Submodel->f4Diffuse ) ); // McZapkie-240702: zamiast ub
|
||||
}
|
||||
// ...specular...
|
||||
if( ( true == m_renderspecular ) && ( m_sunlight.specular.a > 0.01f ) ) {
|
||||
// specular strength in legacy models is set uniformly to 150, 150, 150 so we scale it down for opaque elements
|
||||
::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( Submodel->f4Specular * m_sunlight.specular.a * m_specularopaquescalefactor ) );
|
||||
@@ -2441,6 +2454,10 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
}
|
||||
*/
|
||||
// post-draw reset
|
||||
if( Submodel->fVisible < 1.f ) {
|
||||
::glAlphaFunc( GL_GREATER, 0.5f );
|
||||
::glDisable( GL_BLEND );
|
||||
}
|
||||
if( ( true == m_renderspecular ) && ( m_sunlight.specular.a > 0.01f ) ) {
|
||||
::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( colors::none ) );
|
||||
}
|
||||
@@ -2535,7 +2552,7 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
// distance attenuation. NOTE: since it's fixed pipeline with built-in gamma correction we're using linear 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 ) };
|
||||
float const precipitationfactor { std::max( 1.f, 0.5f * ( Global.Overcast - 1.f ) ) };
|
||||
|
||||
if( lightlevel > 0.f ) {
|
||||
// material configuration:
|
||||
@@ -2543,9 +2560,11 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
|
||||
Bind_Material( null_handle );
|
||||
::glPointSize( std::max( 3.f, 5.f * distancefactor * anglefactor ) );
|
||||
::glColor4f( Submodel->f4Diffuse[ 0 ], Submodel->f4Diffuse[ 1 ], Submodel->f4Diffuse[ 2 ], std::min( 1.f, lightlevel * anglefactor * precipitationfactor ) );
|
||||
::glColor4f( Submodel->f4Diffuse[ 0 ], Submodel->f4Diffuse[ 1 ], Submodel->f4Diffuse[ 2 ], Submodel->fVisible * std::min( 1.f, lightlevel * anglefactor * precipitationfactor ) );
|
||||
::glDisable( GL_LIGHTING );
|
||||
::glDisable( GL_FOG );
|
||||
::glEnable( GL_BLEND );
|
||||
::glAlphaFunc( GL_GREATER, 0.f );
|
||||
|
||||
::glPushMatrix();
|
||||
::glLoadIdentity();
|
||||
@@ -3439,10 +3458,10 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
||||
float glarelevel = 0.6f; // luminosity at night is at level of ~0.1, so the overall resulting transparency in clear conditions is ~0.5 at full 'brightness'
|
||||
if( Submodel->fCosViewAngle > Submodel->fCosFalloffAngle ) {
|
||||
// only bother if the viewer is inside the visibility cone
|
||||
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
|
||||
auto glarelevel { clamp(
|
||||
std::max<float>(
|
||||
0.6f - Global.fLuminance, // reduce the glare in bright daylight
|
||||
Global.Overcast - 1.f ), // ensure some 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 );
|
||||
@@ -3452,8 +3471,9 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
||||
::glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT );
|
||||
|
||||
Bind_Texture( m_glaretexture );
|
||||
::glColor4f( Submodel->f4Diffuse[ 0 ], Submodel->f4Diffuse[ 1 ], Submodel->f4Diffuse[ 2 ], glarelevel );
|
||||
::glColor4f( Submodel->f4Diffuse[ 0 ], Submodel->f4Diffuse[ 1 ], Submodel->f4Diffuse[ 2 ], Submodel->fVisible * glarelevel );
|
||||
::glDisable( GL_LIGHTING );
|
||||
::glDisable( GL_FOG );
|
||||
::glDepthMask( GL_FALSE );
|
||||
::glBlendFunc( GL_SRC_ALPHA, GL_ONE );
|
||||
|
||||
|
||||
Reference in New Issue
Block a user