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 };
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 rscurve { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; // youBy
sound_source rsDerailment { sound_placement::external, 250.f }; // McZapkie-051202
sound_source rscurve { sound_placement::external, 2 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; // youBy
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_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 "Console.h"
#include "PyInt.h"
#include "Timer.h"
global_settings Global;
@@ -74,13 +75,21 @@ global_settings::ConfigParse(cParser &Parser) {
}
else if (token == "heightbase")
{
Parser.getTokens(1, false);
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")
{
Parser.getTokens();
Parser >> bFullScreen;
}
@@ -245,8 +254,10 @@ global_settings::ConfigParse(cParser &Parser) {
Parser.getTokens( 1, false );
Parser >> AnisotropicFiltering;
if (AnisotropicFiltering < 1.0f)
AnisotropicFiltering = 1.0f;
}
else if( token == "usevbo" )
else if( token == "usevbo" )
{
Parser.getTokens();
@@ -310,7 +321,17 @@ global_settings::ConfigParse(cParser &Parser) {
else if( token == "scenario.time.override" ) {
// shift (in hours) applied to train timetables
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 );
}
else if( token == "scenario.time.offset" ) {
@@ -346,21 +367,21 @@ global_settings::ConfigParse(cParser &Parser) {
// shadow render toggle
Parser.getTokens();
Parser >> RenderShadows;
}
else if( token == "shadowtune" ) {
}
else if( token == "shadowtune" ) {
Parser.getTokens( 4, false );
Parser
>> shadowtune.map_size
>> shadowtune.width
>> shadowtune.depth
>> shadowtune.distance;
}
else if( token == "gfx.shadows.cab.range" ) {
}
else if( token == "gfx.shadows.cab.range" ) {
// shadow render toggle
Parser.getTokens();
Parser >> RenderCabShadowsRange;
}
else if( token == "gfx.smoke" ) {
else if( token == "gfx.smoke" ) {
// smoke visualization toggle
Parser.getTokens();
Parser >> Smoke;
@@ -372,8 +393,7 @@ global_settings::ConfigParse(cParser &Parser) {
Parser >> smokefidelity;
SmokeFidelity = clamp( smokefidelity, 1.f, 4.f );
}
else if (token == "smoothtraction")
{
else if( token == "smoothtraction" ) {
// podwójna jasność ambient
Parser.getTokens();
Parser >> bSmoothTraction;
@@ -385,6 +405,10 @@ global_settings::ConfigParse(cParser &Parser) {
Parser >> splinefidelity;
SplineFidelity = clamp( splinefidelity, 1.f, 4.f );
}
else if (token == "rendercab") {
Parser.getTokens();
Parser >> render_cab;
}
else if( token == "createswitchtrackbeds" ) {
// podwójna jasność ambient
Parser.getTokens();
@@ -403,16 +427,12 @@ global_settings::ConfigParse(cParser &Parser) {
else if( token == "gfx.reflections.framerate" ) {
auto const updatespersecond { std::abs( Parser.getToken<double>() ) };
ReflectionUpdateInterval = (
updatespersecond > 0 ?
1.0 / std::min( 30.0, updatespersecond ) :
0 );
ReflectionUpdateInterval = 1.0 / updatespersecond;
}
else if (token == "timespeed")
{
// przyspieszenie czasu, zmienna do testów
Parser.getTokens(1, false);
Parser >> fTimeSpeed;
else if( token == "timespeed" ) {
// przyspieszenie czasu, zmienna do testów
Parser.getTokens( 1, false );
Parser >> fTimeSpeed;
}
else if (token == "multisampling")
{
@@ -420,12 +440,6 @@ global_settings::ConfigParse(cParser &Parser) {
Parser.getTokens(1, false);
Parser >> iMultisampling;
}
else if (token == "glutfont")
{
// tekst generowany przez GLUT
Parser.getTokens();
Parser >> bGlutFont;
}
else if (token == "latitude")
{
// szerokość geograficzna
@@ -577,7 +591,6 @@ global_settings::ConfigParse(cParser &Parser) {
}
else if (token == "brakestep")
{
// krok zmiany hamulca dla klawiszy [Num3] i [Num9]
Parser.getTokens(1, false);
Parser >> fBrakeStep;
}
@@ -617,6 +630,11 @@ global_settings::ConfigParse(cParser &Parser) {
priority == "lowest" ? 1000 :
200 );
}
else if( token == "python.updatetime" )
{
Parser.getTokens();
Parser >> PythonScreenUpdateRate;
}
else if( token == "uitextcolor" ) {
// color of the ui text. NOTE: will be obsolete once the real ui is in place
Parser.getTokens( 3, false );
@@ -638,7 +656,8 @@ global_settings::ConfigParse(cParser &Parser) {
// czy grupować eventy o tych samych nazwach
Parser.getTokens();
Parser >> InputGamepad;
}
}
#ifdef WITH_UART
else if( token == "uart" ) {
uart_conf.enable = true;
Parser.getTokens( 3, false );
@@ -667,6 +686,10 @@ global_settings::ConfigParse(cParser &Parser) {
>> uart_conf.lvmax
>> uart_conf.lvuart;
}
else if ( token == "uarttachoscale" ) {
Parser.getTokens( 1 );
Parser >> uart_conf.tachoscale;
}
else if( token == "uartfeature" ) {
Parser.getTokens( 4 );
Parser
@@ -679,10 +702,126 @@ global_settings::ConfigParse(cParser &Parser) {
Parser.getTokens( 1 );
Parser >> uart_conf.debug;
}
else if( token == "compresstex" ) {
#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") {
Parser.getTokens( 1 );
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)
// na koniec trochę zależności
if (!bLoadTraction) // wczytywanie drutów i słupów
@@ -713,7 +852,7 @@ global_settings::ConfigParse(cParser &Parser) {
if (qp)
{ // to poniżej wykonywane tylko raz, jedynie po wczytaniu eu07.ini*/
#ifdef _WIN32
Console::ModeSet(iFeedbackMode, iFeedbackPort); // tryb pracy konsoli sterowniczej
Console::ModeSet(iFeedbackMode, iFeedbackPort); // tryb pracy konsoli sterowniczej
#endif
/*iFpsRadiusMax = 0.000025 * fFpsRadiusMax *
fFpsRadiusMax; // maksymalny promień renderowania 3000.0 -> 225
@@ -730,4 +869,4 @@ global_settings::ConfigParse(cParser &Parser) {
}
}
*/
}
}

View File

@@ -9,12 +9,16 @@ http://mozilla.org/MPL/2.0/.
#pragma once
#define WITH_UART
#include "Classes.h"
#include "Camera.h"
#include "dumb3d.h"
#include "Float3d.h"
#include "light.h"
#ifdef WITH_UART
#include "uart.h"
#endif
#include "utilities.h"
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 compress_tex{ true }; // all textures are compressed on gpu side
std::string asSky{ "1" };
bool bGlutFont{ false }; // czy tekst generowany przez GLUT32.DLL
double fFpsAverage{ 20.0 }; // oczekiwana wartosć FPS
double fFpsDeviation{ 5.0 }; // odchylenie standardowe FPS
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 };
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
#ifdef WITH_UART
uart_input::conf_t uart_conf;
#endif
// multiplayer
int iMultiplayer{ 0 }; // blokada działania niektórych eventów na rzecz kominikacji
// other
@@ -193,6 +198,7 @@ struct global_settings {
bool gfx_extraeffects = true;
bool gfx_shadergamma = false;
bool gfx_usegles = false;
bool python_mipmaps = true;
// methods
void LoadIniFile( std::string asFileName );

View File

@@ -630,6 +630,10 @@ struct TSecuritySystem
int VelocityAllowed;
int NextVelocityAllowed; /*predkosc pokazywana przez sygnalizacje kabinowa*/
bool RadioStop; // czy jest RadioStop
inline bool is_beeping() const {
return TestFlag( Status, s_SHPalarm );
}
};
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
// 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));
static int const i_bcpno = 5;
// static double const pi = 3.141592653589793; //definicja w mctools
enum TUniversalBrake // możliwe działania uniwersalnego przycisku hamulca
@@ -533,6 +532,7 @@ class TDriverHandle {
bool ManualOvrld = false; //czy jest asymilacja reczna przyciskiem
bool ManualOvrldActive = false; //czy jest wcisniety przycisk asymilacji
int UniversalFlag = 0; //flaga wcisnietych przyciskow uniwersalnych
int i_bcpno = 6;
public:
bool Time = false;
bool TimeEP = false;
@@ -591,7 +591,7 @@ class TFV4aM : public TDriverHandle {
double GetCP();
inline TFV4aM() :
TDriverHandle()
{}
{}
};
class TMHZ_EN57 : public TDriverHandle {
@@ -722,7 +722,8 @@ class TM394 : public TDriverHandle {
inline TM394(void) :
TDriverHandle()
{}
{
i_bcpno = 5; }
};
class TH14K1 : public TDriverHandle {
@@ -744,7 +745,8 @@ class TH14K1 : public TDriverHandle {
inline TH14K1(void) :
TDriverHandle()
{}
{
i_bcpno = 4; }
};
class TSt113 : public TH14K1 {

View File

@@ -36,20 +36,25 @@ void render_task::run() {
&& ( outputheight != nullptr ) ) {
::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
::glTexImage2D(
GL_TEXTURE_2D, 0,
( Global.GfxFramebufferSRGB ? GL_SRGB8 : GL_RGBA8 ),
PyInt_AsLong( outputwidth ), PyInt_AsLong( outputheight ), 0,
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();
}
if( outputheight != nullptr ) { Py_DECREF( outputheight ); }

View File

@@ -622,8 +622,8 @@ TTrain::state_t
TTrain::get_state() const {
return {
btLampkaSHP.GetValue(),
btLampkaCzuwaka.GetValue(),
btLampkaSHP.GetValue(),
btLampkaCzuwaka.GetValue(),
btLampkaRadioStop.GetValue(),
btLampkaOpory.GetValue(),
btLampkaWylSzybki.GetValue(),
@@ -639,7 +639,7 @@ TTrain::get_state() const {
static_cast<std::uint8_t>( iCabn ),
btHaslerBrakes.GetValue(),
btHaslerCurrent.GetValue(),
( TestFlag( mvOccupied->SecuritySystem.Status, s_CAalarm ) || TestFlag( mvOccupied->SecuritySystem.Status, s_SHPalarm ) ),
mvOccupied->SecuritySystem.is_beeping(),
btLampkaHVoltageB.GetValue(),
fTachoVelocity,
static_cast<float>( mvOccupied->Compressor ),
@@ -647,7 +647,10 @@ TTrain::get_state() const {
static_cast<float>( mvOccupied->BrakePress ),
fHVoltage,
{ 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;
std::array<float, 3> hv_current;
float lv_voltage;
double distance;
int radio_channel;
bool springbrake_active;
};
// constructors

View File

@@ -475,6 +475,27 @@ eu07_application::init_glfw() {
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 ) {
// match screen dimensions with selected monitor, for 'borderless window' in fullscreen mode
Global.iWindowWidth = vmode->width;

View File

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

View File

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

View File

@@ -33,6 +33,8 @@ bool opengl33_renderer::Init(GLFWwindow *Window)
WriteLog("preparing renderer..");
OpenGLMatrices.upload() = false; // set matrix stack in virtual mode
m_window = Window;
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)
{
gl::program::unbind();
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);
@@ -866,18 +869,15 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
// creates dynamic environment cubemap
bool opengl33_renderer::Render_reflections(viewport_config &vp)
{
if (Global.ReflectionUpdateInterval == 0.0)
return false;
if( Global.ReflectionUpdateInterval == 0 ) { return false; }
auto const timestamp = Timer::GetTime();
if ((timestamp - m_environmentupdatetime < Global.ReflectionUpdateInterval)
&& (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
return false;
}
m_environmentupdatetime = timestamp;
auto const timestamp{ Timer::GetTime() };
if( ( timestamp - m_environmentupdatetime < Global.ReflectionUpdateInterval )
&& ( 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
return false;
}
m_environmentupdatetime = timestamp;
m_environmentupdatelocation = m_renderpass.pass_camera.position();
glViewport(0, 0, gl::ENVMAP_SIZE, gl::ENVMAP_SIZE);
@@ -1142,11 +1142,11 @@ void opengl33_renderer::setup_pass(viewport_config &Viewport, renderpass_config
void opengl33_renderer::setup_matrices()
{
::glMatrixMode(GL_PROJECTION);
OpenGLMatrices.mode(GL_PROJECTION);
OpenGLMatrices.load_matrix(m_renderpass.pass_camera.projection());
// 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())));
}
@@ -1317,12 +1317,9 @@ bool opengl33_renderer::Render(world_environment *Environment)
// skydome uses a custom vbo which could potentially confuse the main geometry system. hardly elegant but, eh
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 );
// stars
// stars
if (Environment->m_stars.m_stars != nullptr)
{
// setup
@@ -1435,7 +1432,8 @@ bool opengl33_renderer::Render(world_environment *Environment)
model_ubo->update(model_ubs);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
::glPopAttrib();
::glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
// clouds
if (Environment->m_clouds.mdCloud)
@@ -2492,7 +2490,7 @@ void opengl33_renderer::Render(TSubModel *Submodel)
Bind_Material(Submodel->m_material, Submodel);
// main draw call
model_ubs.param[1].x = 2.0f;
model_ubs.param[1].x = 2.0f * 2.0f;
draw(Submodel->m_geometry);
}
@@ -3372,7 +3370,7 @@ void opengl33_renderer::Render_Alpha(TSubModel *Submodel)
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));
if (!Submodel->occlusion_query)

View File

@@ -33,46 +33,46 @@ public:
push_matrix() {
m_stack.emplace( m_stack.top() ); }
void
pop_matrix() {
pop_matrix( bool const Upload = true ) {
if( m_stack.size() > 1 ) {
m_stack.pop();
upload(); } }
if( Upload ) { upload(); } } }
void
load_identity() {
load_identity( bool const Upload = true ) {
m_stack.top() = glm::mat4( 1.f );
upload(); }
if( Upload ) { upload(); } }
void
load_matrix( glm::mat4 const &Matrix ) {
load_matrix( glm::mat4 const &Matrix, bool const Upload = true ) {
m_stack.top() = Matrix;
upload(); }
if( Upload ) { upload(); } }
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 );
upload(); }
if( Upload ) { upload(); } }
void
translate( glm::vec3 const &Translation ) {
translate( glm::vec3 const &Translation, bool const Upload = true ) {
m_stack.top() = glm::translate( m_stack.top(), Translation );
upload(); }
if( Upload ) { upload(); } }
void
scale( glm::vec3 const &Scale ) {
scale( glm::vec3 const &Scale, bool const Upload = true ) {
m_stack.top() = glm::scale( m_stack.top(), Scale );
upload(); }
if( Upload ) { upload(); } }
void
multiply( glm::mat4 const &Matrix ) {
multiply( glm::mat4 const &Matrix, bool const Upload = true ) {
m_stack.top() *= Matrix;
upload(); }
if( Upload ) { upload(); } }
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 );
upload(); }
if( Upload ) { upload(); } }
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 );
upload(); }
if( Upload ) { upload(); } }
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 );
upload(); }
if( Upload ) { upload(); } }
private:
// types:
@@ -98,6 +98,9 @@ public:
}
// methods:
bool &
upload() {
return m_upload; }
void
mode( GLuint const Mode ) {
switch( Mode ) {
@@ -105,7 +108,7 @@ public:
case GL_PROJECTION: { m_mode = stack_mode::gl_projection; break; }
case GL_TEXTURE: { m_mode = stack_mode::gl_texture; break; }
default: { break; } }
::glMatrixMode( Mode ); }
if( m_upload ) {::glMatrixMode( Mode ); } }
glm::mat4 const &
data( GLuint const Mode = -1 ) const {
switch( Mode ) {
@@ -119,11 +122,11 @@ public:
void
push_matrix() { m_stacks[ m_mode ].push_matrix(); }
void
pop_matrix() { m_stacks[ m_mode ].pop_matrix(); }
pop_matrix() { m_stacks[ m_mode ].pop_matrix( m_upload ); }
void
load_identity() { m_stacks[ m_mode ].load_identity(); }
load_identity() { m_stacks[ m_mode ].load_identity( m_upload ); }
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_>
void
load_matrix( Type_ const *Matrix ) { load_matrix( glm::make_mat4( Matrix ) ); }
@@ -135,7 +138,8 @@ public:
glm::vec3(
static_cast<float>( X ),
static_cast<float>( Y ),
static_cast<float>( Z ) ) ); }
static_cast<float>( Z ) ),
m_upload ); }
template <typename Type_>
void
translate( Type_ const X, Type_ const Y, Type_ const Z ) {
@@ -143,7 +147,8 @@ public:
glm::vec3(
static_cast<float>( X ),
static_cast<float>( Y ),
static_cast<float>( Z ) ) ); }
static_cast<float>( Z ) ),
m_upload ); }
template <typename Type_>
void
scale( Type_ const X, Type_ const Y, Type_ const Z ) {
@@ -151,12 +156,14 @@ public:
glm::vec3(
static_cast<float>( X ),
static_cast<float>( Y ),
static_cast<float>( Z ) ) ); }
static_cast<float>( Z ) ),
m_upload ); }
template <typename Type_>
void
multiply( Type_ const *Matrix ) {
m_stacks[ m_mode ].multiply(
glm::make_mat4( Matrix ) ); }
glm::make_mat4( Matrix ),
m_upload ); }
template <typename Type_>
void
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>( Top ),
static_cast<float>( Znear ),
static_cast<float>( Zfar ) ); }
static_cast<float>( Zfar ),
m_upload ); }
template <typename Type_>
void
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>( Aspect ),
static_cast<float>( Znear ),
static_cast<float>( Zfar ) ); }
static_cast<float>( Zfar ),
m_upload ); }
template <typename Type_>
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 ) {
@@ -190,13 +199,14 @@ public:
glm::vec3(
static_cast<float>( Upx ),
static_cast<float>( Upy ),
static_cast<float>( Upz ) ) ); }
static_cast<float>( Upz ) ),
m_upload ); }
private:
// members:
stack_mode m_mode{ stack_mode::gl_projection };
openglstack_array m_stacks;
bool m_upload { true };
};
extern opengl_matrices OpenGLMatrices;

View File

@@ -338,8 +338,11 @@ opengl_renderer::Render() {
Timer::subsystem.gfx_color.stop();
// add user interface
setup_units( true, false, false );
::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
::glClientActiveTexture( m_diffusetextureunit );
::glBindBuffer( GL_ARRAY_BUFFER, 0 );
Application.render_ui();
::glPopClientAttrib();
if( Global.bUseVBO ) {
// swapbuffers() will unbind current buffers so we prepare for it on our end
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();
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;
glfwPollEvents();
Application.set_progress( Input.getProgress(), Input.getFullProgress() );

View File

@@ -6,6 +6,7 @@
#include "Train.h"
#include "parser.h"
#include "Logs.h"
#include "simulationtime.h"
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)
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");
sp_port_config *config;
@@ -39,7 +40,7 @@ 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_drain(port);
@@ -121,7 +122,7 @@ uart_input::recall_bindings() {
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()
{
@@ -168,19 +169,19 @@ void uart_input::poll()
auto const action { (
type != input_type_t::impulse ?
GLFW_PRESS :
( true == state ?
( state ?
GLFW_PRESS :
GLFW_RELEASE ) ) };
auto const command { (
type != input_type_t::toggle ?
std::get<2>( entry ) :
( true == state ?
( state ?
std::get<2>( entry ) :
std::get<3>( entry ) ) ) };
// TODO: pass correct entity id once the missing systems are in place
relay.post( command, 0, 0, action, 0 );
relay.post( command, 0, 0, action, 0 );
}
if( true == conf.mainenable ) {
@@ -191,17 +192,17 @@ void uart_input::poll()
0,
GLFW_PRESS,
// TODO: pass correct entity id once the missing systems are in place
0 );
0 );
}
if( true == conf.scndenable ) {
// second controller
relay.post(
user_command::secondcontrollerset,
buffer[ 7 ],
static_cast<int8_t>(buffer[ 7 ]),
0,
GLFW_PRESS,
// TODO: pass correct entity id once the missing systems are in place
0 );
0 );
}
if( true == conf.trainenable ) {
// train brake
@@ -212,7 +213,7 @@ void uart_input::poll()
0,
GLFW_PRESS,
// TODO: pass correct entity id once the missing systems are in place
0 );
0 );
}
if( true == conf.localenable ) {
// independent brake
@@ -223,7 +224,7 @@ void uart_input::poll()
0,
GLFW_PRESS,
// TODO: pass correct entity id once the missing systems are in place
0 );
0 );
}
old_packet = buffer;
@@ -234,7 +235,8 @@ void uart_input::poll()
// TODO: ugly! move it into structure like input_bits
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 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);
@@ -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 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);
uint32_t odometer = trainstate.distance * 10000.0;
uint16_t lv_voltage = (uint16_t)std::min( conf.lvuart, trainstate.lv_voltage / conf.lvmax * conf.lvuart );
if( trainstate.cab > 0 ) {
// NOTE: moving from a cab to engine room doesn't change cab indicator
m_trainstatecab = trainstate.cab - 1;
}
std::array<uint8_t, 31> buffer {
//byte 0
tacho,
//byte 1
0,
std::array<uint8_t, 48> buffer {
//byte 0-1
SPLIT_INT16(tacho),
//byte 2
(uint8_t)(
trainstate.ventilator_overload << 1
@@ -280,7 +280,8 @@ void uart_input::poll()
m_trainstatecab << 2
| trainstate.recorder_braking << 3
| trainstate.recorder_power << 4
| trainstate.radio_stop <<5
| trainstate.radio_stop << 5
| trainstate.springbrake_active << 6
| trainstate.alerter_sound << 7),
//byte 7-8
SPLIT_INT16(brake_press),
@@ -296,10 +297,20 @@ void uart_input::poll()
SPLIT_INT16(current2),
//byte 19-20
SPLIT_INT16(current3),
//byte 21-22
SPLIT_INT16(lv_voltage),
//byte 23-30
0, 0, 0, 0, 0, 0, 0, 0
//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),
//byte 33
(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)
@@ -317,4 +328,4 @@ void uart_input::poll()
data_pending = true;
}
}
}

1
uart.h
View File

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

View File

@@ -89,7 +89,19 @@ ui_layer::init( GLFWwindow *Window ) {
ImGui_ImplOpenGL2_Init();
#else
// ImGui_ImplOpenGL3_Init( "#version 140" );
ImGui_ImplOpenGL3_Init();
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();
}
#endif
init_colors();
@@ -187,35 +199,7 @@ ui_layer::update() {
void
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
::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
::glClientActiveTexture( m_textureunit );
::glBindBuffer( GL_ARRAY_BUFFER, 0 );
#ifdef EU07_USEIMGUIIMPLOPENGL2
ImGui_ImplOpenGL2_NewFrame();
#else
@@ -237,8 +221,6 @@ ui_layer::render() {
#else
ImGui_ImplOpenGL3_RenderDrawData( ImGui::GetDrawData() );
#endif
::glPopClientAttrib();
}
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
ui_layer::render_progress() {
if ((m_progress == 0.0f) && (m_subtaskprogress == 0.0f))
return;
ImGui::SetNextWindowPos(ImVec2(50, Global.iWindowHeight - 50));
ImGui::SetNextWindowSize(ImVec2(0, 0));
auto const area{ glm::clamp( background_placement( m_background ), glm::vec4(0.f), glm::vec4(Global.iWindowWidth, Global.iWindowHeight, Global.iWindowWidth, Global.iWindowHeight) ) };
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(
"Loading", nullptr,
ImGuiWindowFlags_NoTitleBar
@@ -295,7 +321,7 @@ ui_layer::render_progress() {
ImGui::SetCursorPos( ImVec2( 40, 18 ) );
*/
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();
}
@@ -320,21 +346,23 @@ ui_layer::render_tooltip() {
void
ui_layer::render_background() {
if (m_background == 0)
return;
if( m_background == null_handle ) { return; }
ImVec2 size = ImGui::GetIO().DisplaySize;
opengl_texture &tex = GfxRenderer->Texture(m_background);
tex.create();
ImGui::SetNextWindowPos(ImVec2(0, 0));
opengl_texture &background = GfxRenderer->Texture(m_background);
background.create();
// determine background placement, taking into account screen ratio may be different from background image ratio
auto const placement{ background_placement( m_background ) };
//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::Begin(
"Logo", nullptr,
ImGuiWindowFlags_NoTitleBar
| ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse
| 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();
}
@@ -362,29 +390,3 @@ ui_layer::render_texture() {
::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();
void
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
virtual
bool