diff --git a/DynObj.h b/DynObj.h index ad41c53e..09889f64 100644 --- a/DynObj.h +++ b/DynObj.h @@ -458,8 +458,8 @@ private: sound_source sHorn3 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; std::vector 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 diff --git a/Globals.cpp b/Globals.cpp index fc4d0694..22952aaa 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -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() ) }; - 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) { } } */ -} +} \ No newline at end of file diff --git a/Globals.h b/Globals.h index e3b92986..d7863085 100644 --- a/Globals.h +++ b/Globals.h @@ -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 ); diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 91964e5a..a6bc43a9 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -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 diff --git a/McZapkie/hamulce.h b/McZapkie/hamulce.h index 8ad460d3..b74924e0 100644 --- a/McZapkie/hamulce.h +++ b/McZapkie/hamulce.h @@ -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 { diff --git a/PyInt.cpp b/PyInt.cpp index 52f3e1a3..41af5783 100644 --- a/PyInt.cpp +++ b/PyInt.cpp @@ -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( 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 ); } diff --git a/Train.cpp b/Train.cpp index b807d13f..38ec2749 100644 --- a/Train.cpp +++ b/Train.cpp @@ -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( 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( mvOccupied->Compressor ), @@ -647,7 +647,10 @@ TTrain::get_state() const { static_cast( mvOccupied->BrakePress ), fHVoltage, { fHCurrent[ ( mvControlled->TrainType & dt_EZT ) ? 0 : 1 ], fHCurrent[ 2 ], fHCurrent[ 3 ] }, - ggLVoltage.GetValue() + ggLVoltage.GetValue(), + mvOccupied->DistCounter, + RadioChannel(), + btLampkaSpringBrakeActive.GetValue() }; } diff --git a/Train.h b/Train.h index c6511b8b..2372b4a7 100644 --- a/Train.h +++ b/Train.h @@ -101,6 +101,9 @@ class TTrain { float hv_voltage; std::array hv_current; float lv_voltage; + double distance; + int radio_channel; + bool springbrake_active; }; // constructors diff --git a/application.cpp b/application.cpp index ed3b553d..c5f29813 100644 --- a/application.cpp +++ b/application.cpp @@ -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; diff --git a/drivermode.cpp b/drivermode.cpp index a5359afd..fb0b6807 100644 --- a/drivermode.cpp +++ b/drivermode.cpp @@ -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->init(); } +#endif #ifdef _WIN32 Console::On(); // włączenie konsoli #endif diff --git a/gl/postfx.cpp b/gl/postfx.cpp index 6587475a..1a4ea18e 100644 --- a/gl/postfx.cpp +++ b/gl/postfx.cpp @@ -30,6 +30,7 @@ void gl::postfx::apply(std::vector src, framebuffer *dst) { if (dst) { + gl::program::unbind(); dst->clear(GL_COLOR_BUFFER_BIT); dst->bind(); } diff --git a/opengl33renderer.cpp b/opengl33renderer.cpp index 8b1edf9e..62396c49 100644 --- a/opengl33renderer.cpp +++ b/opengl33renderer.cpp @@ -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) diff --git a/openglmatrixstack.h b/openglmatrixstack.h index 8444b96f..3dab28b1 100644 --- a/openglmatrixstack.h +++ b/openglmatrixstack.h @@ -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 void load_matrix( Type_ const *Matrix ) { load_matrix( glm::make_mat4( Matrix ) ); } @@ -135,7 +138,8 @@ public: glm::vec3( static_cast( X ), static_cast( Y ), - static_cast( Z ) ) ); } + static_cast( Z ) ), + m_upload ); } template void translate( Type_ const X, Type_ const Y, Type_ const Z ) { @@ -143,7 +147,8 @@ public: glm::vec3( static_cast( X ), static_cast( Y ), - static_cast( Z ) ) ); } + static_cast( Z ) ), + m_upload ); } template void scale( Type_ const X, Type_ const Y, Type_ const Z ) { @@ -151,12 +156,14 @@ public: glm::vec3( static_cast( X ), static_cast( Y ), - static_cast( Z ) ) ); } + static_cast( Z ) ), + m_upload ); } template void multiply( Type_ const *Matrix ) { m_stacks[ m_mode ].multiply( - glm::make_mat4( Matrix ) ); } + glm::make_mat4( Matrix ), + m_upload ); } template 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( Bottom ), static_cast( Top ), static_cast( Znear ), - static_cast( Zfar ) ); } + static_cast( Zfar ), + m_upload ); } template void perspective( Type_ const Fovy, Type_ const Aspect, Type_ const Znear, Type_ const Zfar ) { @@ -174,7 +182,8 @@ public: static_cast( glm::radians( Fovy ) ), static_cast( Aspect ), static_cast( Znear ), - static_cast( Zfar ) ); } + static_cast( Zfar ), + m_upload ); } template 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( Upx ), static_cast( Upy ), - static_cast( Upz ) ) ); } + static_cast( 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; diff --git a/openglrenderer.cpp b/openglrenderer.cpp index a9a91bfb..6bef883d 100644 --- a/openglrenderer.cpp +++ b/openglrenderer.cpp @@ -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(); diff --git a/simulationstateserializer.cpp b/simulationstateserializer.cpp index fbf441a9..cc4506ec 100644 --- a/simulationstateserializer.cpp +++ b/simulationstateserializer.cpp @@ -118,7 +118,7 @@ state_serializer::deserialize( cParser &Input, scene::scratch_data &Scratchpad ) } timenow = std::chrono::steady_clock::now(); - if( std::chrono::duration_cast( timenow - timelast ).count() >= 50 ) { + if( std::chrono::duration_cast( timenow - timelast ).count() >= 75 ) { timelast = timenow; glfwPollEvents(); Application.set_progress( Input.getProgress(), Input.getFullProgress() ); diff --git a/uart.cpp b/uart.cpp index 35dd0c0e..7343c4bc 100644 --- a/uart.cpp +++ b/uart.cpp @@ -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 buffer = { 0 }; + std::array 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(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 buffer { - //byte 0 - tacho, - //byte 1 - 0, + std::array 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; } -} +} \ No newline at end of file diff --git a/uart.h b/uart.h index a1887353..73a65300 100644 --- a/uart.h +++ b/uart.h @@ -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; diff --git a/uilayer.cpp b/uilayer.cpp index 723f1e5f..bb47e4a8 100644 --- a/uilayer.cpp +++ b/uilayer.cpp @@ -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( 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(tex.id), size, ImVec2(0, 1), ImVec2(1, 0)); + ImGui::Image(reinterpret_cast(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( 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(); -} diff --git a/uilayer.h b/uilayer.h index ee524d0a..075936f3 100644 --- a/uilayer.h +++ b/uilayer.h @@ -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