driving aid panel enhancement, event queue text filter, minor bug fixes

This commit is contained in:
tmj-fstate
2021-03-11 03:27:22 +01:00
parent 98ef06e8fd
commit c216329bfa
10 changed files with 634 additions and 484 deletions

View File

@@ -876,6 +876,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
auto d { 0.0 }; // droga
auto d_to_next_sem { 10000.0 }; //ustaiwamy na pewno dalej niż widzi AI
auto go { TCommandType::cm_Unknown };
auto speedlimitiscontinuous { true }; // stays true if potential active speed limit is unbroken to the last (relevant) point in scan table
eSignNext = nullptr;
IsAtPassengerStop = false;
IsScheduledPassengerStopVisible = false;
@@ -903,11 +904,13 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
}
auto const railwaytrackend { ( true == TestFlag( point.iFlags, spEnd ) ) && ( is_train() ) };
if( ( v >= 0.0 )
if( ( v >= 0.0 ) // pozycje z prędkością -1 można spokojnie pomijać
|| ( railwaytrackend ) ) {
// pozycje z prędkością -1 można spokojnie pomijać
d = point.fDist;
if( v >= 0.0 ) {
// points located in front of us can potentially affect our acceleration and target speed
if( ( d > 0.0 )
&& ( false == TestFlag( point.iFlags, spElapsed ) ) ) {
// sygnał lub ograniczenie z przodu (+32=przejechane)
@@ -942,6 +945,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
}
}
}
// points located behind can affect our current speed, but little else
else if ( point.iFlags & spTrack) // jeśli tor
{ // tor ogranicza prędkość, dopóki cały skład nie przejedzie,
if( v >= 1.0 ) { // EU06 się zawieszało po dojechaniu na koniec toru postojowego
@@ -959,6 +963,9 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
if( v < VelLimitLastDist.first ) {
VelLimitLastDist.second = d + point.trTrack->Length() + fLength;
}
else if( VelLimitLastDist.second > 0 ) { // the speed limit can potentially start afterwards, so don't mark it as broken too soon
speedlimitiscontinuous = false;
}
if( false == railwaytrackend ) {
continue; // i tyle wystarczy
}
@@ -974,8 +981,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
}
// track can potentially end, which creates another virtual point of interest with speed limit of 0 at the end of it
// TBD, TODO: when tracing the route create a dedicated table entry for it, to simplify the code?
if( ( true == TestFlag( point.iFlags, spEnd ) )
&& ( is_train() ) ) {
if( railwaytrackend ) {
// if the railway track ends here set the velnext accordingly as well
// TODO: test this with turntables and such
auto const stopatendacceleration = ( -1.0 * mvOccupied->Vel * mvOccupied->Vel ) / ( 25.92 * ( d + point.trTrack->Length() ) );
@@ -990,27 +996,53 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
}
}
if ((a < fAcc) && (v == min_speed(v, fNext))) {
if( ( a <= fAcc )
&& ( ( v < fNext ) || ( fNext < 0 ) ) ) { // filter out consecutive, farther out blocks with the same speed limit; they'd make us accelerate slower due to their lower a value
// mniejsze przyspieszenie to mniejsza możliwość rozpędzenia się albo konieczność hamowania
// jeśli droga wolna, to może być a>1.0 i się tu nie załapuje
fAcc = a; // zalecane przyspieszenie (nie musi być uwzględniane przez AI)
fNext = v; // istotna jest prędkość na końcu tego odcinka
fDist = d; // dlugość odcinka
}
else if ((fAcc > 0) && (v >= 0) && (v <= fNext)) {
/*
else if ((fAcc > 0) && (v >= 0) && (v > fNext)) {
// jeśli nie ma wskazań do hamowania, można podać drogę i prędkość na jej końcu
fNext = v; // istotna jest prędkość na końcu tego odcinka
fDist = d; // dlugość odcinka (kolejne pozycje mogą wydłużać drogę, jeśli prędkość jest stała)
}
if( ( v < VelLimitLastDist.first ) /* && ( d < VelLimitLastDist.second ) */ ) {
// if we encounter another speed limit before we can clear current/last registered one,
// update our calculation where we'll be able to resume regular speed
*/
// we'll pick first scanned target speed as our goal
// farther scan table points can override it through previous clause, if they require lower acceleration or speed reduction
else if( ( a > 0 ) && ( a <= fAcc ) && ( v >= 0 ) && ( fNext < 0 ) ) {
fAcc = a;
fNext = v;
fDist = d;
}
// potentially update our current speed limit
if( ( v < VelLimitLastDist.first )
&& ( ( d < 0 ) // the point counts as part of last speed limit either if it's behind us
|| ( VelLimitLastDist.second > 0 ) ) ) { // or if we already have the last limit ongoing
VelLimitLastDist.second = d + fLength;
if( ( point.iFlags & spTrack ) != 0 ) {
VelLimitLastDist.second += point.trTrack->Length();
}
}
else {
// if we found a point which isn't part of the current speed limit mark the limit as broken
// NOTE: we exclude switches from this rule, as speed limits generally extend through these
if( ( point.iFlags & ( spSwitch | spPassengerStopPoint ) ) == 0 ) {
speedlimitiscontinuous = false;
}
}
} // if (v>=0.0)
// finding a point which doesn't impose speed limit means any potential active speed limit can't extend through entire scan table
// NOTE: we test actual speed value for the given point, as events may receive (v = -1) as a way to disable them in irrelevant modes
if( point.fVelNext < 0 ) {
// NOTE: we exclude switches from this rule, as speed limits generally extend through these
if( ( point.iFlags & ( spSwitch | spPassengerStopPoint ) ) == 0 ) {
speedlimitiscontinuous = false;
}
}
if (fNext >= 0.0)
{ // jeśli ograniczenie
if( ( point.iFlags & ( spEnabled | spEvent ) ) == ( spEnabled | spEvent ) ) { // tylko sygnał przypisujemy
@@ -1030,6 +1062,11 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
&& ( true == TestFlag( OrderCurrentGet(), Obey_train ) ) ) {
VelSignalLast = -1.0;
}
// if there's unbroken speed limit through our scan table take a note of it
if( ( VelLimitLastDist.second > 0 )
&& ( speedlimitiscontinuous ) ) {
VelLimitLastDist.second = EU07_AI_SPEEDLIMITEXTENDSBEYONDSCANRANGE;
}
// take into account the effect switches have on duration of signal-imposed speed limit, in calculation of speed limit end point
if( ( VelSignalLast >= 0.0 ) && ( SwitchClearDist >= 0.0 ) ) {
VelLimitLastDist.second = std::max( VelLimitLastDist.second, SwitchClearDist );
@@ -1054,7 +1091,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
bool
TController::TableUpdateStopPoint( TCommandType &Command, TSpeedPos &Point, double const Signaldistance ) {
// stop points are irrelevant when not in one of the basic modes
if( ( OrderCurrentGet() & ( Shunt | Loose_shunt | Obey_train | Bank ) ) == 0 ) { return true; }
if( ( OrderCurrentGet() & ( /*Shunt | Loose_shunt |*/ Obey_train | Bank ) ) == 0 ) { return true; }
// jeśli przystanek, trzeba obsłużyć wg rozkładu
iDrivigFlags |= moveStopPointFound;
// first 19 chars of the command is expected to be "PassengerStopPoint:" so we skip them
@@ -1498,12 +1535,17 @@ TController::TableUpdateEvent( double &Velocity, TCommandType &Command, TSpeedPo
// HACK: if so, make it a stop point, to prevent non-signals farther down affect us
auto const isforsomeoneelse { ( is_train() ) && ( Obstacle.distance < Point.fDist ) };
if( Point.fDist <= Signaldistance ) {
VelSignalNext = ( isforsomeoneelse ? 0.0 : Point.fVelNext );
}
if( isforsomeoneelse ) {
Velocity = 0.0;
// VelNext = 0.0;
// return true;
if( isforsomeoneelse ) {
VelSignalNext = 0.0;
Velocity = 0.0;
}
else {
VelSignalNext - Point.fVelNext;
if( Velocity < 0 ) {
Velocity = fVelMax;
VelSignal = fVelMax;
}
}
}
}
}
@@ -6877,29 +6919,33 @@ TController::pick_optimal_speed( double const Range ) {
// if( ( OrderCurrentGet() & ( Shunt | Loose_shunt | Obey_train | Bank | Connect | Disconnect | Change_direction ) ) == 0 ) { return; }
// set initial velocity and acceleration values
VelDesired = fVelMax; // wstępnie prędkość maksymalna dla pojazdu(-ów), będzie następnie ograniczana
VelNext = VelDesired; // maksymalna prędkość wynikająca z innych czynników niż trajektoria ruchu
SetDriverPsyche(); // ustawia AccPreferred (potrzebne tu?)
VelDesired = fVelMax; // wstępnie prędkość maksymalna dla pojazdu(-ów), będzie następnie ograniczana
AccDesired = AccPreferred; // AccPreferred wynika z osobowości mechanika
ActualProximityDist = Range; // funkcja Update() może pozostawić wartości bez zmian
VelLimitLastDist = { VelDesired, -1 };
SwitchClearDist = -1;
// if we're idling bail out early
if( false == is_active() ) {
VelDesired = 0.0;
VelNext = 0.0;
AccDesired = std::min( AccDesired, EU07_AI_NOACCELERATION );
return;
// nie przekraczać rozkladowej
if( ( ( OrderCurrentGet() & Obey_train ) != 0 )
&& ( TrainParams.TTVmax > 0.0 ) ) {
VelDesired =
min_speed(
VelDesired,
TrainParams.TTVmax );
}
// basic velocity and acceleration adjustments
// VelNext = VelDesired; // maksymalna prędkość wynikająca z innych czynników niż trajektoria ruchu
// HACK: -1 means we can pick up 0 speed limits in ( point.velnext > velnext ) tests aimed to find highest next speed,
// but also doubles as 'max speed' in min_speed tests, so it shouldn't interfere if we don't find any speed limits
VelNext = -1.0;
// basic velocity and acceleration adjustments
// jeśli manewry, to ograniczamy prędkość
if( ( OrderCurrentGet() & ( Obey_train | Bank ) ) == 0 ) { // spokojne manewry
SetVelocity( fShuntVelocity, fShuntVelocity );
VelDesired =
min_speed(
VelDesired,
fShuntVelocity );
}
// uncoupling mode changes velocity/acceleration between stages
if( ( OrderCurrentGet() & Disconnect ) != 0 ) {
if( iVehicleCount >= 0 ) {
@@ -6920,6 +6966,19 @@ TController::pick_optimal_speed( double const Range ) {
}
}
}
VelLimitLastDist = { VelDesired, -1 };
SwitchClearDist = -1;
ActualProximityDist = Range; // funkcja Update() może pozostawić wartości bez zmian
// if we're idling bail out early
if( false == is_active() ) {
VelDesired = 0.0;
VelNext = 0.0;
AccDesired = std::min( AccDesired, EU07_AI_NOACCELERATION );
return;
}
// Ra: odczyt (ActualProximityDist), (VelNext) i (AccPreferred) z tabelki prędkosci
check_route_ahead( Range );
@@ -7087,14 +7146,6 @@ TController::adjust_desired_speed_for_limits() {
VelDesired,
VelSignal );
}
if( ( ( OrderCurrentGet() & Obey_train ) != 0 )
&& ( TrainParams.TTVmax > 0.0 ) ) {
// jesli nie spozniony to nie przekraczać rozkladowej
VelDesired =
min_speed(
VelDesired,
TrainParams.TTVmax );
}
if( mvOccupied->RunningTrack.Velmax >= 0 ) {
// ograniczenie prędkości z trajektorii ruchu
VelDesired =

View File

@@ -18,6 +18,7 @@ http://mozilla.org/MPL/2.0/.
#include "translation.h"
auto const EU07_AI_NOACCELERATION = -0.05;
auto const EU07_AI_SPEEDLIMITEXTENDSBEYONDSCANRANGE = 10000.0;
enum TOrders
{ // rozkazy dla AI

File diff suppressed because it is too large Load Diff

View File

@@ -237,6 +237,7 @@ struct global_settings {
// methods
void LoadIniFile( std::string asFileName );
void ConfigParse( cParser &parser );
bool ConfigParse_gfx( cParser &parser, std::string_view const Token );
// sends basic content of the class in legacy (text) format to provided stream
void
export_as_text( std::ostream &Output ) const;

View File

@@ -3485,7 +3485,7 @@ void TMoverParameters::MainSwitch_( bool const State ) {
return;
}
bool const initialstate { Mains || dizel_startup };
bool const initialstate { Mains };
if( ( false == State )
|| ( true == MainSwitchCheck() ) ) {

View File

@@ -464,7 +464,9 @@ driver_mode::on_key( int const Key, int const Scancode, int const Action, int co
void
driver_mode::on_char( unsigned int const Char ) {
// TODO: implement
// give the ui first shot at the input processing...
if( true == m_userinterface->on_char( Char ) ) { return; }
}
void

View File

@@ -63,22 +63,54 @@ drivingaid_panel::update() {
gradetext = m_buffer.data();
}
// next speed limit
auto const speedlimit { static_cast<int>( std::floor( owner->VelDesired ) ) };
auto const speedlimit { static_cast<int>( owner->VelDesired ) };
auto nextspeedlimit { speedlimit };
auto nextspeedlimitdistance { 0.0 };
if( speedlimit != 0 ) {
// if we aren't allowed to move then any next speed limit is irrelevant
if( ( owner->VelLimitLastDist.first > 0.0 ) && ( owner->VelLimitLastDist.second > 0.0 ) ) {
// first take note of any speed change which should occur after passing potential current speed limit
nextspeedlimit = static_cast<int>( std::floor( owner->VelLimitLastDist.first ) );
auto nextspeedlimitdistance { std::numeric_limits<double>::max() };
if( speedlimit != 0 ) { // if we aren't allowed to move then any next speed limit is irrelevant
// nie przekraczać rozkladowej
auto const schedulespeedlimit { (
( ( owner->OrderCurrentGet() & ( Obey_train | Bank ) ) != 0 ) && ( owner->TrainParams.TTVmax > 0.0 ) ? static_cast<int>( owner->TrainParams.TTVmax ) :
( ( owner->OrderCurrentGet() & ( Obey_train | Bank ) ) == 0 ) ? static_cast<int>( owner->fShuntVelocity ) :
-1 ) };
// first take note of any speed change which should occur after passing potential current speed limit
if( owner->VelLimitLastDist.second > 0 ) {
nextspeedlimit = min_speed( schedulespeedlimit, static_cast<int>( owner->VelLimitLastDist.first ) );
nextspeedlimitdistance = owner->VelLimitLastDist.second;
}
auto const speedatproximitydistance{ static_cast<int>( std::floor( owner->VelNext ) ) };
if( ( speedatproximitydistance != speedlimit ) && ( speedatproximitydistance < nextspeedlimit ) ) {
// if there's speed reduction down the road then it's more important than any potential speedup
// then take into account speed change ahead, compare it with speed after potentially clearing last limit
// lower of these two takes priority; otherwise limit lasts at least until potential last limit is cleared
auto const noactivespeedlimit { owner->VelLimitLastDist.second < 0 };
auto const speedatproximitydistance { min_speed( schedulespeedlimit, static_cast<int>( owner->VelNext ) ) };
if( speedatproximitydistance == nextspeedlimit ) {
if( noactivespeedlimit ) {
nextspeedlimit = speedatproximitydistance;
nextspeedlimitdistance = owner->ActualProximityDist;
}
}
else if( speedatproximitydistance < nextspeedlimit ) {
// if the speed limit ahead is more strict than our current limit, it's important enough to report
if( speedatproximitydistance < owner->VelDesired ) {
nextspeedlimit = speedatproximitydistance;
nextspeedlimitdistance = owner->ActualProximityDist;
}
// otherwise report it only if it's located after our current (lower) limit ends
else if( owner->ActualProximityDist > nextspeedlimitdistance ) {
nextspeedlimit = speedatproximitydistance;
nextspeedlimitdistance = owner->ActualProximityDist;
}
}
else if( noactivespeedlimit ) { // implicit proximity > last, report only if last limit isn't present
nextspeedlimit = speedatproximitydistance;
nextspeedlimitdistance = owner->ActualProximityDist;
}
// HACK: if our current speed limit extends beyond our scan range don't display potentially misleading information about its length
if( nextspeedlimitdistance >= EU07_AI_SPEEDLIMITEXTENDSBEYONDSCANRANGE ) {
nextspeedlimit = speedlimit;
}
// HACK: hide next speed limit if the 'limit' is a vehicle in front of us
else if( owner->ActualProximityDist == std::abs( owner->TrackObstacle() ) ) {
nextspeedlimit = speedlimit;
}
}
std::string nextspeedlimittext;
if( nextspeedlimit != speedlimit ) {
@@ -590,10 +622,7 @@ debug_panel::render() {
render_section( "Vehicle AI", m_ailines );
render_section( "Vehicle Scan Table", m_scantablelines );
render_section_scenario();
if( true == render_section( "Scenario Event Queue", m_eventqueuelines ) ) {
// event queue filter
ImGui::Checkbox( "By This Vehicle Only", &m_eventqueueactivevehicleonly );
}
render_section_eventqueue();
if( true == render_section( "Power Grid", m_powergridlines ) ) {
// traction state debug
ImGui::Checkbox( "Debug Traction", &DebugTractionFlag );
@@ -693,6 +722,22 @@ debug_panel::render_section_scenario() {
return true;
}
bool
debug_panel::render_section_eventqueue() {
if( false == ImGui::CollapsingHeader( "Scenario Event Queue" ) ) { return false; }
// event queue name filter
ImGui::PushItemWidth( -1 );
ImGui::InputTextWithHint( "", "Search event queue", m_eventsearch.data(), m_eventsearch.size() );
ImGui::PopItemWidth();
// event queue
render_section( m_eventqueuelines );
// event queue activator filter
ImGui::Checkbox( "By This Vehicle Only", &m_eventqueueactivevehicleonly );
return true;
}
void
debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
@@ -1061,6 +1106,15 @@ debug_panel::update_section_ai( std::vector<text_line> &Output ) {
textline =
"Distances:\n proximity: " + to_string( mechanik.ActualProximityDist, 0 )
+ ", braking: " + to_string( mechanik.fBrakeDist, 0 );
if( mechanik.VelLimitLastDist.second > 0 ) {
textline += ", last limit: " + (
mechanik.VelLimitLastDist.second < EU07_AI_SPEEDLIMITEXTENDSBEYONDSCANRANGE ?
to_string( mechanik.VelLimitLastDist.second, 0 ) :
"???" );
}
if( mechanik.SwitchClearDist > 0 ) {
textline += ", switches: " + to_string( mechanik.SwitchClearDist, 0 );
}
if( mechanik.Obstacle.distance < 5000 ) {
textline +=
@@ -1116,7 +1170,7 @@ debug_panel::update_section_ai( std::vector<text_line> &Output ) {
textline =
"Brakes:\n highest pressure: " + to_string( mechanik.fReady, 2 ) + ( mechanik.Ready ? " (all brakes released)" : "" )
+ "\n activation threshold: " + to_string( mechanik.fAccThreshold, 2 )
+ "\n activation delays: " + to_string( mechanik.fBrake_a0[ 0 ], 2 ) + " + " + to_string( mechanik.fBrake_a1[ 0 ], 2 )
+ ", delays: " + to_string( mechanik.fBrake_a0[ 0 ], 2 ) + " + " + to_string( mechanik.fBrake_a1[ 0 ], 2 )
+ "\n virtual brake position: " + to_string( mechanik.BrakeCtrlPosition, 2 );
Output.emplace_back( textline, Global.UITextColor );
@@ -1188,6 +1242,7 @@ debug_panel::update_section_eventqueue( std::vector<text_line> &Output ) {
// current event queue
auto const time { Timer::GetTime() };
auto const *event { simulation::Events.begin() };
auto const searchfilter { std::string( m_eventsearch.data() ) };
Output.emplace_back( "Delay: Event:", Global.UITextColor );
@@ -1199,18 +1254,29 @@ debug_panel::update_section_eventqueue( std::vector<text_line> &Output ) {
&& ( ( false == m_eventqueueactivevehicleonly )
|| ( event->m_activator == m_input.vehicle ) ) ) {
if( ( false == searchfilter.empty() )
&& ( event->m_name.find( searchfilter ) == std::string::npos ) ) {
event = event->m_next;
continue;
}
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)" : "" );
auto const label { event->m_name + ( event->m_activator ? " (by: " + event->m_activator->asName + ")" : "" ) };
textline =
delay.substr( delay.length() - 6 )
+ " "
+ label + ( 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)";
// event queue can be empty either because no event got through active filters, or because it is genuinely empty
Output.front().data = (
simulation::Events.begin() == nullptr ?
"(no queued events)" :
"(no matching events)" );
}
}
@@ -1328,6 +1394,12 @@ debug_panel::render_section( std::string const &Header, std::vector<text_line> c
if( true == Lines.empty() ) { return false; }
if( false == ImGui::CollapsingHeader( Header.c_str() ) ) { return false; }
return render_section( Lines );
}
bool
debug_panel::render_section( std::vector<text_line> const &Lines ) {
for( auto const &line : Lines ) {
ImGui::PushStyleColor( ImGuiCol_Text, { line.color.r, line.color.g, line.color.b, line.color.a } );
ImGui::TextUnformatted( line.data.c_str() );

View File

@@ -95,10 +95,13 @@ private:
std::string update_vehicle_brake() const;
// renders provided lines, under specified collapsing header
bool render_section( std::string const &Header, std::vector<text_line> const &Lines );
bool render_section( std::vector<text_line> const &Lines );
bool render_section_scenario();
bool render_section_eventqueue();
bool render_section_settings();
// members
std::array<char, 1024> m_buffer;
std::array<char, 128> m_eventsearch;
input_data m_input;
std::vector<text_line>
m_vehiclelines,

View File

@@ -105,7 +105,7 @@ editor_mode::enter() {
m_statebackup = { Global.pCamera, FreeFlyModeFlag, Global.ControlPicking };
Global.pCamera = Camera;
Camera = Global.pCamera;
FreeFlyModeFlag = true;
Global.ControlPicking = true;
EditorModeFlag = true;

View File

@@ -386,31 +386,31 @@ bool opengl33_renderer::init_viewport(viewport_config &vp)
vp.msaa_fb->attach(*vp.msaa_rbc, GL_COLOR_ATTACHMENT0);
vp.msaa_fb->attach(*vp.msaa_rbd, GL_DEPTH_ATTACHMENT);
vp.main_tex = std::make_unique<opengl_texture>();
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);
if (Global.gfx_postfx_motionblur_enabled)
{
vp.msaa_rbv = std::make_unique<gl::renderbuffer>();
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.main_tex = std::make_unique<opengl_texture>();
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);
vp.main_texv = std::make_unique<opengl_texture>();
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->setup_drawing(2);
if( !vp.main_fb->is_complete() ) {
ErrorLog( "main framebuffer setup failed" );
return false;
}
WriteLog("motion blur enabled");
}
if( !vp.main_fb->is_complete() ) {
ErrorLog( "main framebuffer setup failed" );
return false;
}
if( !vp.msaa_fb->is_complete() ) {
ErrorLog( "msaa framebuffer setup failed" );
return false;
@@ -782,14 +782,16 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
if (Global.gfx_postfx_motionblur_enabled)
{
gl::program::unbind();
vp.main_fb->clear(GL_COLOR_BUFFER_BIT);
vp.main_fb->clear(GL_COLOR_BUFFER_BIT);
vp.msaa_fb->blit_to(vp.main_fb.get(), vp.width, vp.height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT0);
vp.msaa_fb->blit_to(vp.main_fb.get(), vp.width, vp.height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT1);
model_ubs.param[0].x = m_framerate / (1.0 / Global.gfx_postfx_motionblur_shutter);
model_ubo->update(model_ubs);
m_pfx_motionblur->apply({vp.main_tex.get(), vp.main_texv.get()}, vp.main2_fb.get());
}
vp.main_fb->setup_drawing(1); // restore draw buffers after blit operation
}
else
{
vp.main2_fb->clear(GL_COLOR_BUFFER_BIT);
@@ -802,6 +804,7 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
glViewport(0, 0, target_size.x, target_size.y);
if( Global.gfx_postfx_chromaticaberration_enabled ) {
// NOTE: for some unexplained reason need this setup_drawing() call here for the tonemapping effects to show up on the main_tex?
m_pfx_tonemapping->apply( *vp.main2_tex, vp.main_fb.get() );
m_pfx_chromaticaberration->apply( *vp.main_tex, nullptr );
}
@@ -3844,7 +3847,7 @@ void opengl33_renderer::Render_Alpha(TSubModel *Submodel)
auto lightcolor = glm::vec3(Submodel->DiffuseOverride.r < 0.f ? // -1 indicates no override
Submodel->f4Diffuse :
Submodel->DiffuseOverride);
lightcolor = glm::pow( lightcolor, gammacorrection );
// lightcolor = glm::pow( lightcolor, gammacorrection );
m_freespot_shader->bind();