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

opengl 3.3 renderer switch to core profile, additional train state data exposed to uart interface, minor bug fixes

This commit is contained in:
tmj-fstate
2019-11-01 17:31:46 +01:00
parent ae3cecfa42
commit 1dc81abae9
19 changed files with 407 additions and 199 deletions

View File

@@ -458,8 +458,8 @@ private:
sound_source sHorn3 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; sound_source sHorn3 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
std::vector<sound_source> m_bogiesounds; // TBD, TODO: wrapper for all bogie-related sounds (noise, brakes, squeal etc) std::vector<sound_source> m_bogiesounds; // TBD, TODO: wrapper for all bogie-related sounds (noise, brakes, squeal etc)
sound_source m_wheelflat { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; sound_source m_wheelflat { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
sound_source rscurve { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; // youBy sound_source rscurve { sound_placement::external, 2 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; // youBy
sound_source rsDerailment { sound_placement::external, 250.f }; // McZapkie-051202 sound_source rsDerailment { sound_placement::external, 2 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; // McZapkie-051202
exchange_data m_exchange; // state of active load exchange procedure, if any exchange_data m_exchange; // state of active load exchange procedure, if any
exchange_sounds m_exchangesounds; // sounds associated with the load exchange exchange_sounds m_exchangesounds; // sounds associated with the load exchange

View File

@@ -20,6 +20,7 @@ http://mozilla.org/MPL/2.0/.
#include "Logs.h" #include "Logs.h"
#include "Console.h" #include "Console.h"
#include "PyInt.h" #include "PyInt.h"
#include "Timer.h"
global_settings Global; global_settings Global;
@@ -74,13 +75,21 @@ global_settings::ConfigParse(cParser &Parser) {
} }
else if (token == "heightbase") else if (token == "heightbase")
{ {
Parser.getTokens(1, false); Parser.getTokens(1, false);
Parser >> fDistanceFactor; Parser >> fDistanceFactor;
} }
else if (token == "targetfps")
{
Parser.getTokens(1, false);
Parser >> targetfps;
}
else if (token == "basedrawrange")
{
Parser.getTokens(1);
Parser >> BaseDrawRange;
}
else if (token == "fullscreen") else if (token == "fullscreen")
{ {
Parser.getTokens(); Parser.getTokens();
Parser >> bFullScreen; Parser >> bFullScreen;
} }
@@ -245,6 +254,8 @@ global_settings::ConfigParse(cParser &Parser) {
Parser.getTokens( 1, false ); Parser.getTokens( 1, false );
Parser >> AnisotropicFiltering; Parser >> AnisotropicFiltering;
if (AnisotropicFiltering < 1.0f)
AnisotropicFiltering = 1.0f;
} }
else if( token == "usevbo" ) else if( token == "usevbo" )
{ {
@@ -310,7 +321,17 @@ global_settings::ConfigParse(cParser &Parser) {
else if( token == "scenario.time.override" ) { else if( token == "scenario.time.override" ) {
// shift (in hours) applied to train timetables // shift (in hours) applied to train timetables
Parser.getTokens( 1, false ); Parser.getTokens( 1, false );
Parser >> ScenarioTimeOverride; std::string token;
Parser >> token;
std::istringstream stream(token);
if (token.find(':') != -1) {
float a, b;
char s;
stream >> a >> s >> b;
ScenarioTimeOverride = a + b / 60.0;
}
else
stream >> ScenarioTimeOverride;
ScenarioTimeOverride = clamp( ScenarioTimeOverride, 0.f, 24 * 1439 / 1440.f ); ScenarioTimeOverride = clamp( ScenarioTimeOverride, 0.f, 24 * 1439 / 1440.f );
} }
else if( token == "scenario.time.offset" ) { else if( token == "scenario.time.offset" ) {
@@ -372,8 +393,7 @@ global_settings::ConfigParse(cParser &Parser) {
Parser >> smokefidelity; Parser >> smokefidelity;
SmokeFidelity = clamp( smokefidelity, 1.f, 4.f ); SmokeFidelity = clamp( smokefidelity, 1.f, 4.f );
} }
else if (token == "smoothtraction") else if( token == "smoothtraction" ) {
{
// podwójna jasność ambient // podwójna jasność ambient
Parser.getTokens(); Parser.getTokens();
Parser >> bSmoothTraction; Parser >> bSmoothTraction;
@@ -385,6 +405,10 @@ global_settings::ConfigParse(cParser &Parser) {
Parser >> splinefidelity; Parser >> splinefidelity;
SplineFidelity = clamp( splinefidelity, 1.f, 4.f ); SplineFidelity = clamp( splinefidelity, 1.f, 4.f );
} }
else if (token == "rendercab") {
Parser.getTokens();
Parser >> render_cab;
}
else if( token == "createswitchtrackbeds" ) { else if( token == "createswitchtrackbeds" ) {
// podwójna jasność ambient // podwójna jasność ambient
Parser.getTokens(); Parser.getTokens();
@@ -403,13 +427,9 @@ global_settings::ConfigParse(cParser &Parser) {
else if( token == "gfx.reflections.framerate" ) { else if( token == "gfx.reflections.framerate" ) {
auto const updatespersecond { std::abs( Parser.getToken<double>() ) }; auto const updatespersecond { std::abs( Parser.getToken<double>() ) };
ReflectionUpdateInterval = ( ReflectionUpdateInterval = 1.0 / updatespersecond;
updatespersecond > 0 ?
1.0 / std::min( 30.0, updatespersecond ) :
0 );
} }
else if (token == "timespeed") else if( token == "timespeed" ) {
{
// przyspieszenie czasu, zmienna do testów // przyspieszenie czasu, zmienna do testów
Parser.getTokens( 1, false ); Parser.getTokens( 1, false );
Parser >> fTimeSpeed; Parser >> fTimeSpeed;
@@ -420,12 +440,6 @@ global_settings::ConfigParse(cParser &Parser) {
Parser.getTokens(1, false); Parser.getTokens(1, false);
Parser >> iMultisampling; Parser >> iMultisampling;
} }
else if (token == "glutfont")
{
// tekst generowany przez GLUT
Parser.getTokens();
Parser >> bGlutFont;
}
else if (token == "latitude") else if (token == "latitude")
{ {
// szerokość geograficzna // szerokość geograficzna
@@ -577,7 +591,6 @@ global_settings::ConfigParse(cParser &Parser) {
} }
else if (token == "brakestep") else if (token == "brakestep")
{ {
// krok zmiany hamulca dla klawiszy [Num3] i [Num9]
Parser.getTokens(1, false); Parser.getTokens(1, false);
Parser >> fBrakeStep; Parser >> fBrakeStep;
} }
@@ -617,6 +630,11 @@ global_settings::ConfigParse(cParser &Parser) {
priority == "lowest" ? 1000 : priority == "lowest" ? 1000 :
200 ); 200 );
} }
else if( token == "python.updatetime" )
{
Parser.getTokens();
Parser >> PythonScreenUpdateRate;
}
else if( token == "uitextcolor" ) { else if( token == "uitextcolor" ) {
// color of the ui text. NOTE: will be obsolete once the real ui is in place // color of the ui text. NOTE: will be obsolete once the real ui is in place
Parser.getTokens( 3, false ); Parser.getTokens( 3, false );
@@ -639,6 +657,7 @@ global_settings::ConfigParse(cParser &Parser) {
Parser.getTokens(); Parser.getTokens();
Parser >> InputGamepad; Parser >> InputGamepad;
} }
#ifdef WITH_UART
else if( token == "uart" ) { else if( token == "uart" ) {
uart_conf.enable = true; uart_conf.enable = true;
Parser.getTokens( 3, false ); Parser.getTokens( 3, false );
@@ -667,6 +686,10 @@ global_settings::ConfigParse(cParser &Parser) {
>> uart_conf.lvmax >> uart_conf.lvmax
>> uart_conf.lvuart; >> uart_conf.lvuart;
} }
else if ( token == "uarttachoscale" ) {
Parser.getTokens( 1 );
Parser >> uart_conf.tachoscale;
}
else if( token == "uartfeature" ) { else if( token == "uartfeature" ) {
Parser.getTokens( 4 ); Parser.getTokens( 4 );
Parser Parser
@@ -679,10 +702,126 @@ global_settings::ConfigParse(cParser &Parser) {
Parser.getTokens( 1 ); Parser.getTokens( 1 );
Parser >> uart_conf.debug; Parser >> uart_conf.debug;
} }
#endif
#ifdef USE_EXTCAM_CAMERA
else if( token == "extcam.cmd" ) {
Parser.getTokens( 1 );
Parser >> extcam_cmd;
}
else if( token == "extcam.rec" ) {
Parser.getTokens( 1 );
Parser >> extcam_rec;
}
else if( token == "extcam.res" ) {
Parser.getTokens( 2 );
Parser >> extcam_res.x >> extcam_res.y;
}
#endif
else if (token == "compresstex") { else if (token == "compresstex") {
Parser.getTokens( 1 ); Parser.getTokens( 1 );
Parser >> compress_tex; Parser >> compress_tex;
} }
else if (token == "gfx.framebuffer.width")
{
Parser.getTokens(1, false);
Parser >> gfx_framebuffer_width;
}
else if (token == "gfx.framebuffer.height")
{
Parser.getTokens(1, false);
Parser >> gfx_framebuffer_height;
}
else if (token == "gfx.shadowmap.enabled")
{
Parser.getTokens(1);
Parser >> gfx_shadowmap_enabled;
}
else if (token == "gfx.envmap.enabled")
{
Parser.getTokens(1);
Parser >> gfx_envmap_enabled;
}
else if (token == "gfx.postfx.motionblur.enabled")
{
Parser.getTokens(1);
Parser >> gfx_postfx_motionblur_enabled;
}
else if (token == "gfx.postfx.motionblur.shutter")
{
Parser.getTokens(1);
Parser >> gfx_postfx_motionblur_shutter;
}
else if (token == "gfx.postfx.motionblur.format")
{
Parser.getTokens(1);
std::string token;
Parser >> token;
if (token == "rg16f")
gfx_postfx_motionblur_format = GL_RG16F;
else if (token == "rg32f")
gfx_postfx_motionblur_format = GL_RG32F;
}
else if (token == "gfx.format.color")
{
Parser.getTokens(1);
std::string token;
Parser >> token;
if (token == "rgb8")
gfx_format_color = GL_RGB8;
else if (token == "rgb16f")
gfx_format_color = GL_RGB16F;
else if (token == "rgb32f")
gfx_format_color = GL_RGB32F;
else if (token == "r11f_g11f_b10f")
gfx_format_color = GL_R11F_G11F_B10F;
}
else if (token == "gfx.format.depth")
{
Parser.getTokens(1);
std::string token;
Parser >> token;
if (token == "z16")
gfx_format_depth = GL_DEPTH_COMPONENT16;
else if (token == "z24")
gfx_format_depth = GL_DEPTH_COMPONENT24;
else if (token == "z32")
gfx_format_depth = GL_DEPTH_COMPONENT32;
else if (token == "z32f")
gfx_format_depth = GL_DEPTH_COMPONENT32F;
}
else if (token == "gfx.skippipeline")
{
Parser.getTokens(1);
Parser >> gfx_skippipeline;
}
else if (token == "gfx.extraeffects")
{
Parser.getTokens(1);
Parser >> gfx_extraeffects;
}
/*
else if (token == "gfx.usegles")
{
Parser.getTokens(1);
Parser >> gfx_usegles;
}
*/
else if (token == "gfx.shadergamma")
{
Parser.getTokens(1);
Parser >> gfx_shadergamma;
}
else if (token == "python.mipmaps")
{
Parser.getTokens(1);
Parser >> python_mipmaps;
}
/*
else if (token == "crashdamage") {
Parser.getTokens(1);
Parser >> crash_damage;
}
*/
} while ((token != "") && (token != "endconfig")); //(!Parser->EndOfFile) } while ((token != "") && (token != "endconfig")); //(!Parser->EndOfFile)
// na koniec trochę zależności // na koniec trochę zależności
if (!bLoadTraction) // wczytywanie drutów i słupów if (!bLoadTraction) // wczytywanie drutów i słupów

View File

@@ -9,12 +9,16 @@ http://mozilla.org/MPL/2.0/.
#pragma once #pragma once
#define WITH_UART
#include "Classes.h" #include "Classes.h"
#include "Camera.h" #include "Camera.h"
#include "dumb3d.h" #include "dumb3d.h"
#include "Float3d.h" #include "Float3d.h"
#include "light.h" #include "light.h"
#ifdef WITH_UART
#include "uart.h" #include "uart.h"
#endif
#include "utilities.h" #include "utilities.h"
struct global_settings { struct global_settings {
@@ -132,7 +136,6 @@ struct global_settings {
bool ResourceMove{ false }; // gfx resources are moved between cpu and gpu side instead of sending a copy bool ResourceMove{ false }; // gfx resources are moved between cpu and gpu side instead of sending a copy
bool compress_tex{ true }; // all textures are compressed on gpu side bool compress_tex{ true }; // all textures are compressed on gpu side
std::string asSky{ "1" }; std::string asSky{ "1" };
bool bGlutFont{ false }; // czy tekst generowany przez GLUT32.DLL
double fFpsAverage{ 20.0 }; // oczekiwana wartosć FPS double fFpsAverage{ 20.0 }; // oczekiwana wartosć FPS
double fFpsDeviation{ 5.0 }; // odchylenie standardowe FPS double fFpsDeviation{ 5.0 }; // odchylenie standardowe FPS
double fFpsMin{ 30.0 }; // dolna granica FPS, przy której promień scenerii będzie zmniejszany double fFpsMin{ 30.0 }; // dolna granica FPS, przy której promień scenerii będzie zmniejszany
@@ -172,7 +175,9 @@ struct global_settings {
0, 0, 0, 0, 0, 0, 0 }; 0, 0, 0, 0, 0, 0, 0 };
int iCalibrateOutDebugInfo { -1 }; // numer wyjścia kalibrowanego dla którego wyświetlać informacje podczas kalibracji int iCalibrateOutDebugInfo { -1 }; // numer wyjścia kalibrowanego dla którego wyświetlać informacje podczas kalibracji
int iPoKeysPWM[ 7 ] = { 0, 1, 2, 3, 4, 5, 6 }; // numery wejść dla PWM int iPoKeysPWM[ 7 ] = { 0, 1, 2, 3, 4, 5, 6 }; // numery wejść dla PWM
#ifdef WITH_UART
uart_input::conf_t uart_conf; uart_input::conf_t uart_conf;
#endif
// multiplayer // multiplayer
int iMultiplayer{ 0 }; // blokada działania niektórych eventów na rzecz kominikacji int iMultiplayer{ 0 }; // blokada działania niektórych eventów na rzecz kominikacji
// other // other
@@ -193,6 +198,7 @@ struct global_settings {
bool gfx_extraeffects = true; bool gfx_extraeffects = true;
bool gfx_shadergamma = false; bool gfx_shadergamma = false;
bool gfx_usegles = false; bool gfx_usegles = false;
bool python_mipmaps = true;
// methods // methods
void LoadIniFile( std::string asFileName ); void LoadIniFile( std::string asFileName );

View File

@@ -630,6 +630,10 @@ struct TSecuritySystem
int VelocityAllowed; int VelocityAllowed;
int NextVelocityAllowed; /*predkosc pokazywana przez sygnalizacje kabinowa*/ int NextVelocityAllowed; /*predkosc pokazywana przez sygnalizacje kabinowa*/
bool RadioStop; // czy jest RadioStop bool RadioStop; // czy jest RadioStop
inline bool is_beeping() const {
return TestFlag( Status, s_SHPalarm );
}
}; };
struct TTransmision struct TTransmision

View File

@@ -130,7 +130,6 @@ static double const BPT_394[7][2] = { {13 , 10.0} , {5 , 5.0} , {0 , -1} , {5 ,
//double *BPT_394 = zero_based_BPT_394[1]; //tablica pozycji hamulca dla zakresu -1..5 //double *BPT_394 = zero_based_BPT_394[1]; //tablica pozycji hamulca dla zakresu -1..5
// BPT: array[-2..6] of array [0..1] of real= ((0, 5.0), (12, 5.4), (9, 5.0), (9, 4.6), (9, 4.2), (9, 3.8), (9, 3.4), (9, 2.8), (34, 2.8)); // BPT: array[-2..6] of array [0..1] of real= ((0, 5.0), (12, 5.4), (9, 5.0), (9, 4.6), (9, 4.2), (9, 3.8), (9, 3.4), (9, 2.8), (34, 2.8));
// BPT: array[-2..6] of array [0..1] of real= ((0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0)); // BPT: array[-2..6] of array [0..1] of real= ((0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0));
static int const i_bcpno = 5;
// static double const pi = 3.141592653589793; //definicja w mctools // static double const pi = 3.141592653589793; //definicja w mctools
enum TUniversalBrake // możliwe działania uniwersalnego przycisku hamulca enum TUniversalBrake // możliwe działania uniwersalnego przycisku hamulca
@@ -533,6 +532,7 @@ class TDriverHandle {
bool ManualOvrld = false; //czy jest asymilacja reczna przyciskiem bool ManualOvrld = false; //czy jest asymilacja reczna przyciskiem
bool ManualOvrldActive = false; //czy jest wcisniety przycisk asymilacji bool ManualOvrldActive = false; //czy jest wcisniety przycisk asymilacji
int UniversalFlag = 0; //flaga wcisnietych przyciskow uniwersalnych int UniversalFlag = 0; //flaga wcisnietych przyciskow uniwersalnych
int i_bcpno = 6;
public: public:
bool Time = false; bool Time = false;
bool TimeEP = false; bool TimeEP = false;
@@ -722,7 +722,8 @@ class TM394 : public TDriverHandle {
inline TM394(void) : inline TM394(void) :
TDriverHandle() TDriverHandle()
{} {
i_bcpno = 5; }
}; };
class TH14K1 : public TDriverHandle { class TH14K1 : public TDriverHandle {
@@ -744,7 +745,8 @@ class TH14K1 : public TDriverHandle {
inline TH14K1(void) : inline TH14K1(void) :
TDriverHandle() TDriverHandle()
{} {
i_bcpno = 4; }
}; };
class TSt113 : public TH14K1 { class TSt113 : public TH14K1 {

View File

@@ -36,20 +36,25 @@ void render_task::run() {
&& ( outputheight != nullptr ) ) { && ( outputheight != nullptr ) ) {
::glBindTexture( GL_TEXTURE_2D, m_target ); ::glBindTexture( GL_TEXTURE_2D, m_target );
// setup texture parameters
::glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE );
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
if( GL_EXT_texture_filter_anisotropic ) {
// anisotropic filtering
::glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, Global.AnisotropicFiltering );
}
// build texture // build texture
::glTexImage2D( ::glTexImage2D(
GL_TEXTURE_2D, 0, GL_TEXTURE_2D, 0,
( Global.GfxFramebufferSRGB ? GL_SRGB8 : GL_RGBA8 ), ( Global.GfxFramebufferSRGB ? GL_SRGB8 : GL_RGBA8 ),
PyInt_AsLong( outputwidth ), PyInt_AsLong( outputheight ), 0, PyInt_AsLong( outputwidth ), PyInt_AsLong( outputheight ), 0,
GL_RGB, GL_UNSIGNED_BYTE, reinterpret_cast<GLubyte const *>( PyString_AsString( output ) ) ); GL_RGB, GL_UNSIGNED_BYTE, reinterpret_cast<GLubyte const *>( PyString_AsString( output ) ) );
// setup texture parameters
if( GL_EXT_texture_filter_anisotropic ) {
// anisotropic filtering
::glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, Global.AnisotropicFiltering );
}
if( Global.python_mipmaps ) {
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
::glGenerateMipmap( GL_TEXTURE_2D );
}
else {
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
}
// all done
::glFlush(); ::glFlush();
} }
if( outputheight != nullptr ) { Py_DECREF( outputheight ); } if( outputheight != nullptr ) { Py_DECREF( outputheight ); }

View File

@@ -639,7 +639,7 @@ TTrain::get_state() const {
static_cast<std::uint8_t>( iCabn ), static_cast<std::uint8_t>( iCabn ),
btHaslerBrakes.GetValue(), btHaslerBrakes.GetValue(),
btHaslerCurrent.GetValue(), btHaslerCurrent.GetValue(),
( TestFlag( mvOccupied->SecuritySystem.Status, s_CAalarm ) || TestFlag( mvOccupied->SecuritySystem.Status, s_SHPalarm ) ), mvOccupied->SecuritySystem.is_beeping(),
btLampkaHVoltageB.GetValue(), btLampkaHVoltageB.GetValue(),
fTachoVelocity, fTachoVelocity,
static_cast<float>( mvOccupied->Compressor ), static_cast<float>( mvOccupied->Compressor ),
@@ -647,7 +647,10 @@ TTrain::get_state() const {
static_cast<float>( mvOccupied->BrakePress ), static_cast<float>( mvOccupied->BrakePress ),
fHVoltage, fHVoltage,
{ fHCurrent[ ( mvControlled->TrainType & dt_EZT ) ? 0 : 1 ], fHCurrent[ 2 ], fHCurrent[ 3 ] }, { fHCurrent[ ( mvControlled->TrainType & dt_EZT ) ? 0 : 1 ], fHCurrent[ 2 ], fHCurrent[ 3 ] },
ggLVoltage.GetValue() ggLVoltage.GetValue(),
mvOccupied->DistCounter,
RadioChannel(),
btLampkaSpringBrakeActive.GetValue()
}; };
} }

View File

@@ -101,6 +101,9 @@ class TTrain {
float hv_voltage; float hv_voltage;
std::array<float, 3> hv_current; std::array<float, 3> hv_current;
float lv_voltage; float lv_voltage;
double distance;
int radio_channel;
bool springbrake_active;
}; };
// constructors // constructors

View File

@@ -475,6 +475,27 @@ eu07_application::init_glfw() {
glfwWindowHint( GLFW_SAMPLES, 1 << Global.iMultisampling ); glfwWindowHint( GLFW_SAMPLES, 1 << Global.iMultisampling );
} }
glfwWindowHint(GLFW_SRGB_CAPABLE, !Global.gfx_shadergamma);
if( Global.GfxRenderer == "default" ) {
// activate core profile for opengl 3.3 renderer
if( !Global.gfx_usegles ) {
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
}
else {
#ifdef GLFW_CONTEXT_CREATION_API
glfwWindowHint( GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API );
#endif
glfwWindowHint( GLFW_CLIENT_API, GLFW_OPENGL_ES_API );
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 0 );
}
}
glfwWindowHint( GLFW_AUTO_ICONIFY, GLFW_FALSE );
if( Global.bFullScreen ) { if( Global.bFullScreen ) {
// match screen dimensions with selected monitor, for 'borderless window' in fullscreen mode // match screen dimensions with selected monitor, for 'borderless window' in fullscreen mode
Global.iWindowWidth = vmode->width; Global.iWindowWidth = vmode->width;

View File

@@ -67,10 +67,12 @@ driver_mode::drivermode_input::init() {
if( true == Global.InputGamepad ) { if( true == Global.InputGamepad ) {
gamepad.init(); gamepad.init();
} }
#ifdef WITH_UART
if( true == Global.uart_conf.enable ) { if( true == Global.uart_conf.enable ) {
uart = std::make_unique<uart_input>(); uart = std::make_unique<uart_input>();
uart->init(); uart->init();
} }
#endif
#ifdef _WIN32 #ifdef _WIN32
Console::On(); // włączenie konsoli Console::On(); // włączenie konsoli
#endif #endif

View File

@@ -30,6 +30,7 @@ void gl::postfx::apply(std::vector<opengl_texture *> src, framebuffer *dst)
{ {
if (dst) if (dst)
{ {
gl::program::unbind();
dst->clear(GL_COLOR_BUFFER_BIT); dst->clear(GL_COLOR_BUFFER_BIT);
dst->bind(); dst->bind();
} }

View File

@@ -33,6 +33,8 @@ bool opengl33_renderer::Init(GLFWwindow *Window)
WriteLog("preparing renderer.."); WriteLog("preparing renderer..");
OpenGLMatrices.upload() = false; // set matrix stack in virtual mode
m_window = Window; m_window = Window;
gl::glsl_common_setup(); gl::glsl_common_setup();
@@ -668,6 +670,7 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
{ {
if (Global.gfx_postfx_motionblur_enabled) 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_ATTACHMENT0);
vp.msaa_fb->blit_to(vp.main_fb.get(), vp.width, vp.height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT1); vp.msaa_fb->blit_to(vp.main_fb.get(), vp.width, vp.height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT1);
@@ -866,14 +869,11 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
// creates dynamic environment cubemap // creates dynamic environment cubemap
bool opengl33_renderer::Render_reflections(viewport_config &vp) bool opengl33_renderer::Render_reflections(viewport_config &vp)
{ {
if (Global.ReflectionUpdateInterval == 0.0) if( Global.ReflectionUpdateInterval == 0 ) { return false; }
return false;
auto const timestamp = Timer::GetTime();
auto const timestamp{ Timer::GetTime() };
if( ( timestamp - m_environmentupdatetime < Global.ReflectionUpdateInterval ) if( ( timestamp - m_environmentupdatetime < Global.ReflectionUpdateInterval )
&& (glm::length(m_renderpass.pass_camera.position() - m_environmentupdatelocation) < 1000.0)) && ( glm::length( m_renderpass.pass_camera.position() - m_environmentupdatelocation ) < 1000.0 ) ) {
{
// run update every 5+ mins of simulation time, or at least 1km from the last location // run update every 5+ mins of simulation time, or at least 1km from the last location
return false; return false;
} }
@@ -1142,11 +1142,11 @@ void opengl33_renderer::setup_pass(viewport_config &Viewport, renderpass_config
void opengl33_renderer::setup_matrices() void opengl33_renderer::setup_matrices()
{ {
::glMatrixMode(GL_PROJECTION); OpenGLMatrices.mode(GL_PROJECTION);
OpenGLMatrices.load_matrix(m_renderpass.pass_camera.projection()); OpenGLMatrices.load_matrix(m_renderpass.pass_camera.projection());
// trim modelview matrix just to rotation, since rendering is done in camera-centric world space // trim modelview matrix just to rotation, since rendering is done in camera-centric world space
::glMatrixMode(GL_MODELVIEW); 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())));
} }
@@ -1317,9 +1317,6 @@ bool opengl33_renderer::Render(world_environment *Environment)
// skydome uses a custom vbo which could potentially confuse the main geometry system. hardly elegant but, eh // skydome uses a custom vbo which could potentially confuse the main geometry system. hardly elegant but, eh
gfx::opengl_vbogeometrybank::reset(); gfx::opengl_vbogeometrybank::reset();
::glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT );
::glDisable( GL_ALPHA_TEST );
::glEnable( GL_BLEND );
::glBlendFunc( GL_SRC_ALPHA, GL_ONE ); ::glBlendFunc( GL_SRC_ALPHA, GL_ONE );
// stars // stars
@@ -1435,7 +1432,8 @@ bool opengl33_renderer::Render(world_environment *Environment)
model_ubo->update(model_ubs); model_ubo->update(model_ubs);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
} }
::glPopAttrib();
::glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
// clouds // clouds
if (Environment->m_clouds.mdCloud) if (Environment->m_clouds.mdCloud)
@@ -2492,7 +2490,7 @@ void opengl33_renderer::Render(TSubModel *Submodel)
Bind_Material(Submodel->m_material, Submodel); Bind_Material(Submodel->m_material, Submodel);
// main draw call // main draw call
model_ubs.param[1].x = 2.0f; model_ubs.param[1].x = 2.0f * 2.0f;
draw(Submodel->m_geometry); draw(Submodel->m_geometry);
} }
@@ -3372,7 +3370,7 @@ void opengl33_renderer::Render_Alpha(TSubModel *Submodel)
draw(Submodel->m_geometry); draw(Submodel->m_geometry);
} }
model_ubs.param[1].x = pointsize * resolutionratio; model_ubs.param[1].x = pointsize * resolutionratio * 2.0f;
model_ubs.param[0] = glm::vec4(glm::vec3(lightcolor), Submodel->fVisible * std::min(1.f, lightlevel)); model_ubs.param[0] = glm::vec4(glm::vec3(lightcolor), Submodel->fVisible * std::min(1.f, lightlevel));
if (!Submodel->occlusion_query) if (!Submodel->occlusion_query)

View File

@@ -33,46 +33,46 @@ public:
push_matrix() { push_matrix() {
m_stack.emplace( m_stack.top() ); } m_stack.emplace( m_stack.top() ); }
void void
pop_matrix() { pop_matrix( bool const Upload = true ) {
if( m_stack.size() > 1 ) { if( m_stack.size() > 1 ) {
m_stack.pop(); m_stack.pop();
upload(); } } if( Upload ) { upload(); } } }
void void
load_identity() { load_identity( bool const Upload = true ) {
m_stack.top() = glm::mat4( 1.f ); m_stack.top() = glm::mat4( 1.f );
upload(); } if( Upload ) { upload(); } }
void void
load_matrix( glm::mat4 const &Matrix ) { load_matrix( glm::mat4 const &Matrix, bool const Upload = true ) {
m_stack.top() = Matrix; m_stack.top() = Matrix;
upload(); } if( Upload ) { upload(); } }
void void
rotate( float const Angle, glm::vec3 const &Axis ) { rotate( float const Angle, glm::vec3 const &Axis, bool const Upload = true ) {
m_stack.top() = glm::rotate( m_stack.top(), Angle, Axis ); m_stack.top() = glm::rotate( m_stack.top(), Angle, Axis );
upload(); } if( Upload ) { upload(); } }
void void
translate( glm::vec3 const &Translation ) { translate( glm::vec3 const &Translation, bool const Upload = true ) {
m_stack.top() = glm::translate( m_stack.top(), Translation ); m_stack.top() = glm::translate( m_stack.top(), Translation );
upload(); } if( Upload ) { upload(); } }
void void
scale( glm::vec3 const &Scale ) { scale( glm::vec3 const &Scale, bool const Upload = true ) {
m_stack.top() = glm::scale( m_stack.top(), Scale ); m_stack.top() = glm::scale( m_stack.top(), Scale );
upload(); } if( Upload ) { upload(); } }
void void
multiply( glm::mat4 const &Matrix ) { multiply( glm::mat4 const &Matrix, bool const Upload = true ) {
m_stack.top() *= Matrix; m_stack.top() *= Matrix;
upload(); } if( Upload ) { upload(); } }
void void
ortho( float const Left, float const Right, float const Bottom, float const Top, float const Znear, float const Zfar ) { ortho( float const Left, float const Right, float const Bottom, float const Top, float const Znear, float const Zfar, bool const Upload = true ) {
m_stack.top() *= glm::ortho( Left, Right, Bottom, Top, Znear, Zfar ); m_stack.top() *= glm::ortho( Left, Right, Bottom, Top, Znear, Zfar );
upload(); } if( Upload ) { upload(); } }
void void
perspective( float const Fovy, float const Aspect, float const Znear, float const Zfar ) { perspective( float const Fovy, float const Aspect, float const Znear, float const Zfar, bool const Upload = true ) {
m_stack.top() *= glm::perspective( Fovy, Aspect, Znear, Zfar ); m_stack.top() *= glm::perspective( Fovy, Aspect, Znear, Zfar );
upload(); } if( Upload ) { upload(); } }
void void
look_at( glm::vec3 const &Eye, glm::vec3 const &Center, glm::vec3 const &Up ) { look_at( glm::vec3 const &Eye, glm::vec3 const &Center, glm::vec3 const &Up, bool const Upload = true ) {
m_stack.top() *= glm::lookAt( Eye, Center, Up ); m_stack.top() *= glm::lookAt( Eye, Center, Up );
upload(); } if( Upload ) { upload(); } }
private: private:
// types: // types:
@@ -98,6 +98,9 @@ public:
} }
// methods: // methods:
bool &
upload() {
return m_upload; }
void void
mode( GLuint const Mode ) { mode( GLuint const Mode ) {
switch( Mode ) { switch( Mode ) {
@@ -105,7 +108,7 @@ public:
case GL_PROJECTION: { m_mode = stack_mode::gl_projection; break; } case GL_PROJECTION: { m_mode = stack_mode::gl_projection; break; }
case GL_TEXTURE: { m_mode = stack_mode::gl_texture; break; } case GL_TEXTURE: { m_mode = stack_mode::gl_texture; break; }
default: { break; } } default: { break; } }
::glMatrixMode( Mode ); } if( m_upload ) {::glMatrixMode( Mode ); } }
glm::mat4 const & glm::mat4 const &
data( GLuint const Mode = -1 ) const { data( GLuint const Mode = -1 ) const {
switch( Mode ) { switch( Mode ) {
@@ -119,11 +122,11 @@ public:
void void
push_matrix() { m_stacks[ m_mode ].push_matrix(); } push_matrix() { m_stacks[ m_mode ].push_matrix(); }
void void
pop_matrix() { m_stacks[ m_mode ].pop_matrix(); } pop_matrix() { m_stacks[ m_mode ].pop_matrix( m_upload ); }
void void
load_identity() { m_stacks[ m_mode ].load_identity(); } load_identity() { m_stacks[ m_mode ].load_identity( m_upload ); }
void void
load_matrix( glm::mat4 const &Matrix ) { m_stacks[ m_mode ].load_matrix( Matrix ); } load_matrix( glm::mat4 const &Matrix ) { m_stacks[ m_mode ].load_matrix( Matrix, m_upload ); }
template <typename Type_> template <typename Type_>
void void
load_matrix( Type_ const *Matrix ) { load_matrix( glm::make_mat4( Matrix ) ); } load_matrix( Type_ const *Matrix ) { load_matrix( glm::make_mat4( Matrix ) ); }
@@ -135,7 +138,8 @@ public:
glm::vec3( glm::vec3(
static_cast<float>( X ), static_cast<float>( X ),
static_cast<float>( Y ), static_cast<float>( Y ),
static_cast<float>( Z ) ) ); } static_cast<float>( Z ) ),
m_upload ); }
template <typename Type_> template <typename Type_>
void void
translate( Type_ const X, Type_ const Y, Type_ const Z ) { translate( Type_ const X, Type_ const Y, Type_ const Z ) {
@@ -143,7 +147,8 @@ public:
glm::vec3( glm::vec3(
static_cast<float>( X ), static_cast<float>( X ),
static_cast<float>( Y ), static_cast<float>( Y ),
static_cast<float>( Z ) ) ); } static_cast<float>( Z ) ),
m_upload ); }
template <typename Type_> template <typename Type_>
void void
scale( Type_ const X, Type_ const Y, Type_ const Z ) { scale( Type_ const X, Type_ const Y, Type_ const Z ) {
@@ -151,12 +156,14 @@ public:
glm::vec3( glm::vec3(
static_cast<float>( X ), static_cast<float>( X ),
static_cast<float>( Y ), static_cast<float>( Y ),
static_cast<float>( Z ) ) ); } static_cast<float>( Z ) ),
m_upload ); }
template <typename Type_> template <typename Type_>
void void
multiply( Type_ const *Matrix ) { multiply( Type_ const *Matrix ) {
m_stacks[ m_mode ].multiply( m_stacks[ m_mode ].multiply(
glm::make_mat4( Matrix ) ); } glm::make_mat4( Matrix ),
m_upload ); }
template <typename Type_> template <typename Type_>
void void
ortho( Type_ const Left, Type_ const Right, Type_ const Bottom, Type_ const Top, Type_ const Znear, Type_ const Zfar ) { ortho( Type_ const Left, Type_ const Right, Type_ const Bottom, Type_ const Top, Type_ const Znear, Type_ const Zfar ) {
@@ -166,7 +173,8 @@ public:
static_cast<float>( Bottom ), static_cast<float>( Bottom ),
static_cast<float>( Top ), static_cast<float>( Top ),
static_cast<float>( Znear ), static_cast<float>( Znear ),
static_cast<float>( Zfar ) ); } static_cast<float>( Zfar ),
m_upload ); }
template <typename Type_> template <typename Type_>
void void
perspective( Type_ const Fovy, Type_ const Aspect, Type_ const Znear, Type_ const Zfar ) { perspective( Type_ const Fovy, Type_ const Aspect, Type_ const Znear, Type_ const Zfar ) {
@@ -174,7 +182,8 @@ public:
static_cast<float>( glm::radians( Fovy ) ), static_cast<float>( glm::radians( Fovy ) ),
static_cast<float>( Aspect ), static_cast<float>( Aspect ),
static_cast<float>( Znear ), static_cast<float>( Znear ),
static_cast<float>( Zfar ) ); } static_cast<float>( Zfar ),
m_upload ); }
template <typename Type_> template <typename Type_>
void void
look_at( Type_ const Eyex, Type_ const Eyey, Type_ const Eyez, Type_ const Centerx, Type_ const Centery, Type_ const Centerz, Type_ const Upx, Type_ const Upy, Type_ const Upz ) { look_at( Type_ const Eyex, Type_ const Eyey, Type_ const Eyez, Type_ const Centerx, Type_ const Centery, Type_ const Centerz, Type_ const Upx, Type_ const Upy, Type_ const Upz ) {
@@ -190,13 +199,14 @@ public:
glm::vec3( glm::vec3(
static_cast<float>( Upx ), static_cast<float>( Upx ),
static_cast<float>( Upy ), static_cast<float>( Upy ),
static_cast<float>( Upz ) ) ); } static_cast<float>( Upz ) ),
m_upload ); }
private: private:
// members: // members:
stack_mode m_mode{ stack_mode::gl_projection }; stack_mode m_mode{ stack_mode::gl_projection };
openglstack_array m_stacks; openglstack_array m_stacks;
bool m_upload { true };
}; };
extern opengl_matrices OpenGLMatrices; extern opengl_matrices OpenGLMatrices;

View File

@@ -338,8 +338,11 @@ opengl_renderer::Render() {
Timer::subsystem.gfx_color.stop(); Timer::subsystem.gfx_color.stop();
// add user interface // add user interface
setup_units( true, false, false ); setup_units( true, false, false );
::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
::glClientActiveTexture( m_diffusetextureunit );
::glBindBuffer( GL_ARRAY_BUFFER, 0 );
Application.render_ui(); Application.render_ui();
::glPopClientAttrib();
if( Global.bUseVBO ) { if( Global.bUseVBO ) {
// swapbuffers() will unbind current buffers so we prepare for it on our end // swapbuffers() will unbind current buffers so we prepare for it on our end
gfx::opengl_vbogeometrybank::reset(); gfx::opengl_vbogeometrybank::reset();

View File

@@ -118,7 +118,7 @@ state_serializer::deserialize( cParser &Input, scene::scratch_data &Scratchpad )
} }
timenow = std::chrono::steady_clock::now(); timenow = std::chrono::steady_clock::now();
if( std::chrono::duration_cast<std::chrono::milliseconds>( timenow - timelast ).count() >= 50 ) { if( std::chrono::duration_cast<std::chrono::milliseconds>( timenow - timelast ).count() >= 75 ) {
timelast = timenow; timelast = timenow;
glfwPollEvents(); glfwPollEvents();
Application.set_progress( Input.getProgress(), Input.getFullProgress() ); Application.set_progress( Input.getProgress(), Input.getFullProgress() );

View File

@@ -6,6 +6,7 @@
#include "Train.h" #include "Train.h"
#include "parser.h" #include "parser.h"
#include "Logs.h" #include "Logs.h"
#include "simulationtime.h"
uart_input::uart_input() uart_input::uart_input()
{ {
@@ -14,7 +15,7 @@ uart_input::uart_input()
if (sp_get_port_by_name(conf.port.c_str(), &port) != SP_OK) if (sp_get_port_by_name(conf.port.c_str(), &port) != SP_OK)
throw std::runtime_error("uart: cannot find specified port"); throw std::runtime_error("uart: cannot find specified port");
if (sp_open(port, SP_MODE_READ_WRITE) != SP_OK) if (sp_open(port, (sp_mode)(SP_MODE_READ | SP_MODE_WRITE)) != SP_OK)
throw std::runtime_error("uart: cannot open port"); throw std::runtime_error("uart: cannot open port");
sp_port_config *config; sp_port_config *config;
@@ -39,7 +40,7 @@ uart_input::uart_input()
uart_input::~uart_input() uart_input::~uart_input()
{ {
std::array<std::uint8_t, 31> buffer = { 0 }; std::array<std::uint8_t, 48> buffer = { 0 };
sp_blocking_write(port, (void*)buffer.data(), buffer.size(), 0); sp_blocking_write(port, (void*)buffer.data(), buffer.size(), 0);
sp_drain(port); sp_drain(port);
@@ -121,7 +122,7 @@ uart_input::recall_bindings() {
return true; return true;
} }
#define SPLIT_INT16(x) (uint8_t)x, (uint8_t)(x >> 8) #define SPLIT_INT16(x) (uint8_t)(x), (uint8_t)((x) >> 8)
void uart_input::poll() void uart_input::poll()
{ {
@@ -168,14 +169,14 @@ void uart_input::poll()
auto const action { ( auto const action { (
type != input_type_t::impulse ? type != input_type_t::impulse ?
GLFW_PRESS : GLFW_PRESS :
( true == state ? ( state ?
GLFW_PRESS : GLFW_PRESS :
GLFW_RELEASE ) ) }; GLFW_RELEASE ) ) };
auto const command { ( auto const command { (
type != input_type_t::toggle ? type != input_type_t::toggle ?
std::get<2>( entry ) : std::get<2>( entry ) :
( true == state ? ( state ?
std::get<2>( entry ) : std::get<2>( entry ) :
std::get<3>( entry ) ) ) }; std::get<3>( entry ) ) ) };
@@ -197,7 +198,7 @@ void uart_input::poll()
// second controller // second controller
relay.post( relay.post(
user_command::secondcontrollerset, user_command::secondcontrollerset,
buffer[ 7 ], static_cast<int8_t>(buffer[ 7 ]),
0, 0,
GLFW_PRESS, GLFW_PRESS,
// TODO: pass correct entity id once the missing systems are in place // TODO: pass correct entity id once the missing systems are in place
@@ -234,7 +235,8 @@ void uart_input::poll()
// TODO: ugly! move it into structure like input_bits // TODO: ugly! move it into structure like input_bits
auto const trainstate = t->get_state(); auto const trainstate = t->get_state();
uint8_t tacho = Global.iPause ? 0 : trainstate.velocity; SYSTEMTIME time = simulation::Time.data();
uint16_t tacho = Global.iPause ? 0 : (trainstate.velocity * conf.tachoscale);
uint16_t tank_press = (uint16_t)std::min(conf.tankuart, trainstate.reservoir_pressure * 0.1f / conf.tankmax * conf.tankuart); uint16_t tank_press = (uint16_t)std::min(conf.tankuart, trainstate.reservoir_pressure * 0.1f / conf.tankmax * conf.tankuart);
uint16_t pipe_press = (uint16_t)std::min(conf.pipeuart, trainstate.pipe_pressure * 0.1f / conf.pipemax * conf.pipeuart); uint16_t pipe_press = (uint16_t)std::min(conf.pipeuart, trainstate.pipe_pressure * 0.1f / conf.pipemax * conf.pipeuart);
uint16_t brake_press = (uint16_t)std::min(conf.brakeuart, trainstate.brake_pressure * 0.1f / conf.brakemax * conf.brakeuart); uint16_t brake_press = (uint16_t)std::min(conf.brakeuart, trainstate.brake_pressure * 0.1f / conf.brakemax * conf.brakeuart);
@@ -242,18 +244,16 @@ void uart_input::poll()
uint16_t current1 = (uint16_t)std::min(conf.currentuart, trainstate.hv_current[0] / conf.currentmax * conf.currentuart); uint16_t current1 = (uint16_t)std::min(conf.currentuart, trainstate.hv_current[0] / conf.currentmax * conf.currentuart);
uint16_t current2 = (uint16_t)std::min(conf.currentuart, trainstate.hv_current[1] / conf.currentmax * conf.currentuart); uint16_t current2 = (uint16_t)std::min(conf.currentuart, trainstate.hv_current[1] / conf.currentmax * conf.currentuart);
uint16_t current3 = (uint16_t)std::min(conf.currentuart, trainstate.hv_current[2] / conf.currentmax * conf.currentuart); uint16_t current3 = (uint16_t)std::min(conf.currentuart, trainstate.hv_current[2] / conf.currentmax * conf.currentuart);
uint32_t odometer = trainstate.distance * 10000.0;
uint16_t lv_voltage = (uint16_t)std::min( conf.lvuart, trainstate.lv_voltage / conf.lvmax * conf.lvuart ); uint16_t lv_voltage = (uint16_t)std::min( conf.lvuart, trainstate.lv_voltage / conf.lvmax * conf.lvuart );
if( trainstate.cab > 0 ) { if( trainstate.cab > 0 ) {
// NOTE: moving from a cab to engine room doesn't change cab indicator // NOTE: moving from a cab to engine room doesn't change cab indicator
m_trainstatecab = trainstate.cab - 1; m_trainstatecab = trainstate.cab - 1;
} }
std::array<uint8_t, 31> buffer { std::array<uint8_t, 48> buffer {
//byte 0 //byte 0-1
tacho, SPLIT_INT16(tacho),
//byte 1
0,
//byte 2 //byte 2
(uint8_t)( (uint8_t)(
trainstate.ventilator_overload << 1 trainstate.ventilator_overload << 1
@@ -281,6 +281,7 @@ void uart_input::poll()
| trainstate.recorder_braking << 3 | trainstate.recorder_braking << 3
| trainstate.recorder_power << 4 | trainstate.recorder_power << 4
| trainstate.radio_stop << 5 | trainstate.radio_stop << 5
| trainstate.springbrake_active << 6
| trainstate.alerter_sound << 7), | trainstate.alerter_sound << 7),
//byte 7-8 //byte 7-8
SPLIT_INT16(brake_press), SPLIT_INT16(brake_press),
@@ -297,9 +298,19 @@ void uart_input::poll()
//byte 19-20 //byte 19-20
SPLIT_INT16(current3), SPLIT_INT16(current3),
//byte 21-22 //byte 21-22
SPLIT_INT16((time.wYear - 1) * 12 + time.wMonth - 1),
//byte 23-24
SPLIT_INT16((time.wDay - 1) * 1440 + time.wHour * 60 + time.wMinute),
//byte 25-26
SPLIT_INT16(time.wSecond * 1000 + time.wMilliseconds),
//byte 27-30
SPLIT_INT16((uint16_t)odometer), SPLIT_INT16((uint16_t)(odometer >> 16)),
//byte 31-32
SPLIT_INT16(lv_voltage), SPLIT_INT16(lv_voltage),
//byte 23-30 //byte 33
0, 0, 0, 0, 0, 0, 0, 0 (uint8_t)trainstate.radio_channel,
//byte 34-48
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}; };
if (conf.debug) if (conf.debug)

1
uart.h
View File

@@ -29,6 +29,7 @@ public:
float currentuart = 65535.0f; float currentuart = 65535.0f;
float lvmax = 150.0f; float lvmax = 150.0f;
float lvuart = 65535.0f; float lvuart = 65535.0f;
float tachoscale = 1.0f;
bool mainenable = true; bool mainenable = true;
bool scndenable = true; bool scndenable = true;

View File

@@ -89,7 +89,19 @@ ui_layer::init( GLFWwindow *Window ) {
ImGui_ImplOpenGL2_Init(); ImGui_ImplOpenGL2_Init();
#else #else
// ImGui_ImplOpenGL3_Init( "#version 140" ); // ImGui_ImplOpenGL3_Init( "#version 140" );
if( Global.GfxRenderer == "default" ) {
// opengl 3.3 render path
if( Global.gfx_usegles ) {
ImGui_ImplOpenGL3_Init( "#version 300 es\nprecision highp float;" );
}
else {
ImGui_ImplOpenGL3_Init( "#version 330 core" );
}
}
else {
// legacy render path
ImGui_ImplOpenGL3_Init(); ImGui_ImplOpenGL3_Init();
}
#endif #endif
init_colors(); init_colors();
@@ -187,35 +199,7 @@ ui_layer::update() {
void void
ui_layer::render() { ui_layer::render() {
// legacy ui code
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho( 0, std::max( 1, Global.iWindowWidth ), std::max( 1, Global.iWindowHeight ), 0, -1, 1 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/*
glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT ); // blendfunc included since 3rd party gui doesn't play nice
glDisable( GL_LIGHTING );
glDisable( GL_DEPTH_TEST );
glDisable( GL_ALPHA_TEST );
glEnable( GL_TEXTURE_2D );
glEnable( GL_BLEND );
::glColor4fv( glm::value_ptr( colors::white ) );
// render code here
render_texture();
glPopAttrib();
*/
// imgui ui code // imgui ui code
::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
::glClientActiveTexture( m_textureunit );
::glBindBuffer( GL_ARRAY_BUFFER, 0 );
#ifdef EU07_USEIMGUIIMPLOPENGL2 #ifdef EU07_USEIMGUIIMPLOPENGL2
ImGui_ImplOpenGL2_NewFrame(); ImGui_ImplOpenGL2_NewFrame();
#else #else
@@ -237,8 +221,6 @@ ui_layer::render() {
#else #else
ImGui_ImplOpenGL3_RenderDrawData( ImGui::GetDrawData() ); ImGui_ImplOpenGL3_RenderDrawData( ImGui::GetDrawData() );
#endif #endif
::glPopClientAttrib();
} }
void void
@@ -274,14 +256,58 @@ ui_layer::set_background( std::string const &Filename ) {
} }
} }
glm::vec4
background_placement( texture_handle const Background ) {
if( Background == null_handle ) {
return glm::vec4( 0.f, 0.f, Global.iWindowWidth, Global.iWindowHeight );
}
auto const background { GfxRenderer->Texture( Background ) };
// determine background placement, taking into account screen ratio may be different from background image ratio
auto const height { 768.0f };
auto const width = (
background.width() == background.height() ?
1024.0f : // legacy mode, square texture displayed as 4:3 image
background.width() / ( background.height() / 768.0f ) );
// background coordinates on virtual 1024x768 screen
auto const coordinates {
glm::vec4(
( 1024.0f * 0.5f ) - ( width * 0.5f ),
( 768.0f * 0.5f ) - ( height * 0.5f ),
( 1024.0f * 0.5f ) - ( width * 0.5f ) + width,
( 768.0f * 0.5f ) - ( height * 0.5f ) + height ) };
// convert to current screen coordinates
auto const screenratio { static_cast<float>( Global.iWindowWidth ) / Global.iWindowHeight };
auto const screenwidth {
( screenratio >= ( 4.f / 3.f ) ?
( 4.f / 3.f ) * Global.iWindowHeight :
Global.iWindowWidth ) };
auto const heightratio {
( screenratio >= ( 4.f / 3.f ) ?
Global.iWindowHeight / 768.f :
Global.iWindowHeight / 768.f * screenratio / ( 4.f / 3.f ) ) };
auto const screenheight = 768.f * heightratio;
return
glm::vec4{
0.5f * ( Global.iWindowWidth - screenwidth ) + coordinates.x * heightratio,
0.5f * ( Global.iWindowHeight - screenheight ) + coordinates.y * heightratio,
0.5f * ( Global.iWindowWidth - screenwidth ) + coordinates.z * heightratio,
0.5f * ( Global.iWindowHeight - screenheight ) + coordinates.w * heightratio };
}
void void
ui_layer::render_progress() { ui_layer::render_progress() {
if ((m_progress == 0.0f) && (m_subtaskprogress == 0.0f)) if ((m_progress == 0.0f) && (m_subtaskprogress == 0.0f))
return; return;
ImGui::SetNextWindowPos(ImVec2(50, Global.iWindowHeight - 50)); auto const area{ glm::clamp( background_placement( m_background ), glm::vec4(0.f), glm::vec4(Global.iWindowWidth, Global.iWindowHeight, Global.iWindowWidth, Global.iWindowHeight) ) };
ImGui::SetNextWindowSize(ImVec2(0, 0)); auto const areasize{ ImVec2( area.z - area.x, area.w - area.y ) };
ImGui::SetNextWindowPos(ImVec2( area.x + 50, Global.iWindowHeight - 50));
ImGui::SetNextWindowSize(ImVec2(areasize.x - 100, 0));
ImGui::Begin( ImGui::Begin(
"Loading", nullptr, "Loading", nullptr,
ImGuiWindowFlags_NoTitleBar ImGuiWindowFlags_NoTitleBar
@@ -295,7 +321,7 @@ ui_layer::render_progress() {
ImGui::SetCursorPos( ImVec2( 40, 18 ) ); ImGui::SetCursorPos( ImVec2( 40, 18 ) );
*/ */
ImGui::SetCursorPos( ImVec2( 15, 15 ) ); ImGui::SetCursorPos( ImVec2( 15, 15 ) );
ImGui::BufferingBar( "##buffer_bar", m_progress, ImVec2( Global.iWindowWidth - 125, 4 ), bg, col ); ImGui::BufferingBar( "##buffer_bar", m_progress, ImVec2( areasize.x - 125, 4 ), bg, col );
ImGui::End(); ImGui::End();
} }
@@ -320,21 +346,23 @@ ui_layer::render_tooltip() {
void void
ui_layer::render_background() { ui_layer::render_background() {
if (m_background == 0) if( m_background == null_handle ) { return; }
return;
ImVec2 size = ImGui::GetIO().DisplaySize; opengl_texture &background = GfxRenderer->Texture(m_background);
opengl_texture &tex = GfxRenderer->Texture(m_background); background.create();
tex.create(); // determine background placement, taking into account screen ratio may be different from background image ratio
auto const placement{ background_placement( m_background ) };
ImGui::SetNextWindowPos(ImVec2(0, 0)); //ImVec2 size = ImGui::GetIO().DisplaySize;
auto const size{ ImVec2( placement.z - placement.x, placement.w - placement.y ) };
// ready, set, draw
ImGui::SetNextWindowPos(ImVec2(placement.x, placement.y));
ImGui::SetNextWindowSize(size); ImGui::SetNextWindowSize(size);
ImGui::Begin( ImGui::Begin(
"Logo", nullptr, "Logo", nullptr,
ImGuiWindowFlags_NoTitleBar ImGuiWindowFlags_NoTitleBar
| ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse
| ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus ); | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus );
ImGui::Image(reinterpret_cast<void *>(tex.id), size, ImVec2(0, 1), ImVec2(1, 0)); ImGui::Image(reinterpret_cast<void *>(background.id), size, ImVec2(0, 1), ImVec2(1, 0));
ImGui::End(); ImGui::End();
} }
@@ -362,29 +390,3 @@ ui_layer::render_texture() {
::glBindTexture( GL_TEXTURE_2D, 0 ); ::glBindTexture( GL_TEXTURE_2D, 0 );
} }
} }
void
ui_layer::quad( glm::vec4 const &Coordinates, glm::vec4 const &Color ) {
float const screenratio = static_cast<float>( Global.iWindowWidth ) / Global.iWindowHeight;
float const width =
( screenratio >= ( 4.f / 3.f ) ?
( 4.f / 3.f ) * Global.iWindowHeight :
Global.iWindowWidth );
float const heightratio =
( screenratio >= ( 4.f / 3.f ) ?
Global.iWindowHeight / 768.f :
Global.iWindowHeight / 768.f * screenratio / ( 4.f / 3.f ) );
float const height = 768.f * heightratio;
glColor4fv(glm::value_ptr(Color));
glBegin( GL_TRIANGLE_STRIP );
glMultiTexCoord2f( m_textureunit, 0.f, 1.f ); glVertex2f( 0.5f * ( Global.iWindowWidth - width ) + Coordinates.x * heightratio, 0.5f * ( Global.iWindowHeight - height ) + Coordinates.y * heightratio );
glMultiTexCoord2f( m_textureunit, 0.f, 0.f ); glVertex2f( 0.5f * ( Global.iWindowWidth - width ) + Coordinates.x * heightratio, 0.5f * ( Global.iWindowHeight - height ) + Coordinates.w * heightratio );
glMultiTexCoord2f( m_textureunit, 1.f, 1.f ); glVertex2f( 0.5f * ( Global.iWindowWidth - width ) + Coordinates.z * heightratio, 0.5f * ( Global.iWindowHeight - height ) + Coordinates.y * heightratio );
glMultiTexCoord2f( m_textureunit, 1.f, 0.f ); glVertex2f( 0.5f * ( Global.iWindowWidth - width ) + Coordinates.z * heightratio, 0.5f * ( Global.iWindowHeight - height ) + Coordinates.w * heightratio );
glEnd();
}

View File

@@ -132,9 +132,6 @@ private:
render_panels(); render_panels();
void void
render_tooltip(); render_tooltip();
// draws a quad between coordinates x,y and z,w with uv-coordinates spanning 0-1
void
quad( glm::vec4 const &Coordinates, glm::vec4 const &Color );
// input methods subclass details // input methods subclass details
virtual virtual
bool bool