diff --git a/EU07.cpp b/EU07.cpp index d97b4b27..ce879258 100644 --- a/EU07.cpp +++ b/EU07.cpp @@ -29,6 +29,7 @@ Stele, firleju, szociu, hunter, ZiomalCl, OLI_EU and others #include "Mover.h" #include "usefull.h" #include "timer.h" +#include "resource.h" #pragma comment( lib, "glfw3dll.lib" ) #pragma comment( lib, "glew32.lib" ) @@ -320,6 +321,16 @@ int main(int argc, char *argv[]) BaseWindowProc = (WNDPROC)::SetWindowLongPtr( Hwnd, GWLP_WNDPROC, (LONG_PTR)WndProc ); // switch off the topmost flag ::SetWindowPos( Hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE ); + + const HANDLE icon = ::LoadImage( + ::GetModuleHandle( 0 ), + MAKEINTRESOURCE( IDI_ICON1 ), + IMAGE_ICON, + ::GetSystemMetrics( SM_CXSMICON ), + ::GetSystemMetrics( SM_CYSMICON ), + 0 ); + if( icon ) + ::SendMessage( Hwnd, WM_SETICON, ICON_SMALL, reinterpret_cast( icon ) ); #endif GfxRenderer.Init(); diff --git a/Ground.cpp b/Ground.cpp index 59421974..2e581778 100644 --- a/Ground.cpp +++ b/Ground.cpp @@ -4933,31 +4933,26 @@ bool TGround::GetTraction(TDynamicObject *model) }; bool -TGround::Render_Hidden( Math3D::vector3 const &Camera ) { +TGround::Render( Math3D::vector3 const &Camera ) { GfxRenderer.Update_Lights( m_lights ); - - ++TGroundRect::iFrameNumber; // zwięszenie licznika ramek (do usuwniania nadanimacji) - - TGroundNode *node; - int n = 2 * iNumSubRects; //(2*==2km) promień wyświetlanej mapy w sektorach - int c = GetColFromX( Camera.x ); - int r = GetRowFromZ( Camera.z ); - TSubRect *tmp; - for( node = srGlobal.nRenderHidden; node; node = node->nNext3 ) - node->RenderHidden(); // rednerowanie globalnych (nie za często?) - int i, j, k; - // renderowanie czołgowe dla obiektów aktywnych a niewidocznych - for( j = r - n; j <= r + n; j++ ) - for( i = c - n; i <= c + n; i++ ) - if( ( tmp = FastGetSubRect( i, j ) ) != NULL ) { - tmp->LoadNodes(); // oznaczanie aktywnych sektorów - for( node = tmp->nRenderHidden; node; node = node->nNext3 ) - node->RenderHidden(); - tmp->RenderSounds(); // jeszcze dźwięki pojazdów by się przydały, również - // niewidocznych - } - + /* + if( Global::bUseVBO ) { // renderowanie przez VBO + if( !RenderVBO( Camera ) ) + return false; + if( !RenderAlphaVBO( Camera ) ) + return false; + } + else { + */ + // renderowanie przez Display List + if( !RenderDL( Camera ) ) + return false; + if( !RenderAlphaDL( Camera ) ) + return false; + /* + } + */ return true; } @@ -5010,10 +5005,8 @@ bool TGround::RenderDL(vector3 pPosition) continue; // pomijanie sektorów poza kątem patrzenia } // NOTE: terrain data is disabled, as it's moved to the renderer -/* Rects[(i + c) / iNumSubRects][(j + r) / iNumSubRects] .RenderDL(); // kwadrat kilometrowy nie zawsze, bo szkoda FPS -*/ if ((tmp = FastGetSubRect(i + c, j + r)) != NULL) if (tmp->iNodeCount) // o ile są jakieś obiekty, bo po co puste sektory przelatywać pRendered[iRendered++] = tmp; // tworzenie listy sektorów do renderowania diff --git a/Ground.h b/Ground.h index 1354aa06..dda67bfd 100644 --- a/Ground.h +++ b/Ground.h @@ -365,7 +365,7 @@ class TGround void Update_Lights(); // updates scene lights array bool AddToQuery(TEvent *Event, TDynamicObject *Node); bool GetTraction(TDynamicObject *model); - bool Render_Hidden( Math3D::vector3 const &Camera ); + bool Render( Math3D::vector3 const &Camera ); bool RenderDL(vector3 pPosition); bool RenderAlphaDL(vector3 pPosition); /* diff --git a/World.cpp b/World.cpp index e1be615d..a94c0ea3 100644 --- a/World.cpp +++ b/World.cpp @@ -55,7 +55,6 @@ TWorld::TWorld() OutText1 = ""; // teksty wyświetlane na ekranie OutText2 = ""; OutText3 = ""; - iCheckFPS = 0; // kiedy znów sprawdzić FPS, żeby wyłączać optymalizacji od razu do zera pDynamicNearest = NULL; fTimeBuffer = 0.0; // bufor czasu aktualizacji dla stałego kroku fizyki fMaxDt = 0.01; //[s] początkowy krok czasowy fizyki @@ -1000,43 +999,6 @@ bool TWorld::Update() WriteLog("Scenery moved"); }; #endif - if (iCheckFPS) - --iCheckFPS; - else - { // jak doszło do zera, to sprawdzamy wydajność - auto const framerate = Timer::GetFPS(); - // NOTE: until we have quadtree in place we have to rely on the legacy rendering - // once this is resolved we should be able to simply adjust draw range - if( framerate > 65.0 ) { - - Global::iSegmentsRendered = std::min( 400, Global::iSegmentsRendered + 5 ); - Global::fDistanceFactor = std::min( 3.0f, Global::fDistanceFactor + 0.025f ); - } - else if( framerate > 45.0 ) { - - Global::iSegmentsRendered = std::min( 225, Global::iSegmentsRendered + 5 ); - } - else if ( framerate < Global::fFpsMin) { - // 9=minimalny promień to 600m - Global::iSegmentsRendered = std::max( 9, Global::iSegmentsRendered - 3 ); - Global::fDistanceFactor = std::max( Global::ScreenHeight / 768.0f * 0.75f, Global::fDistanceFactor - 0.1f ); - } - if ((framerate < 15.0) && (Global::iSlowMotion < 7)) - { - Global::iSlowMotion = (Global::iSlowMotion << 1) + 1; // zapalenie kolejnego bitu - if (Global::iSlowMotionMask & 1) - if (Global::iMultisampling) // a multisampling jest włączony - glDisable(GL_MULTISAMPLE); // wyłączenie multisamplingu powinno poprawić FPS - } - else if ((framerate > 20.0) && Global::iSlowMotion) - { // FPS się zwiększył, można włączyć bajery - Global::iSlowMotion = (Global::iSlowMotion >> 1); // zgaszenie bitu - if (Global::iSlowMotion == 0) // jeśli jest pełna prędkość - if (Global::iMultisampling) // a multisampling jest włączony - glEnable(GL_MULTISAMPLE); - } - iCheckFPS = 0.25 * Timer::GetFPS(); // tak za 0.25 sekundy sprawdzić ponownie (jeszcze przycina?) - } Timer::UpdateTimers(Global::iPause != 0); if( (Global::iPause == false) || (m_init == false) ) diff --git a/World.h b/World.h index d9bbb954..ab05255c 100644 --- a/World.h +++ b/World.h @@ -82,7 +82,6 @@ class TWorld texture_manager::size_type light; // numer tekstury dla smugi TEvent *KeyEvents[10]; // eventy wyzwalane z klawiaury TMoverParameters *mvControlled; // wskaźnik na człon silnikowy, do wyświetlania jego parametrów - int iCheckFPS; // kiedy znów sprawdzić FPS, żeby wyłączać optymalizacji od razu do zera double fTime50Hz; // bufor czasu dla komunikacji z PoKeys double fTimeBuffer; // bufor czasu aktualizacji dla stałego kroku fizyki double fMaxDt; //[s] krok czasowy fizyki (0.01 dla normalnych warunków) diff --git a/renderer.cpp b/renderer.cpp index 23f25498..992c335b 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -58,6 +58,8 @@ opengl_renderer::Init() { bool opengl_renderer::Render() { + auto timestart = std::chrono::steady_clock::now(); + ::glColor3ub( 255, 255, 255 ); ::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); ::glDepthFunc( GL_LEQUAL ); @@ -81,14 +83,14 @@ opengl_renderer::Render() { World.Environment.render(); } - World.Ground.Render_Hidden( World.Camera.Pos ); - Render( &World.Ground ); - World.Ground.RenderDL( World.Camera.Pos ); - World.Ground.RenderAlphaDL( World.Camera.Pos ); + World.Ground.Render( World.Camera.Pos ); World.Render_Cab(); World.Render_UI(); + // accumulate last 20 frames worth of render time + m_drawtime = 0.95f * m_drawtime + std::chrono::duration_cast( ( std::chrono::steady_clock::now() - timestart ) ).count(); + return true; // for now always succeed } @@ -116,6 +118,7 @@ opengl_renderer::Render( TGround *Ground ) { } } } + return true; } @@ -335,9 +338,61 @@ opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, M } void -opengl_renderer::Update ( double const Deltatile ) { +opengl_renderer::Update ( double const Deltatime ) { - // TODO: add garbage collection and other works here + m_updateaccumulator += Deltatime; + + if( m_updateaccumulator < 1.0 ) { + // too early for any work + return; + } + + m_updateaccumulator = 0.0; + + // adjust draw ranges etc, based on recent performance + auto const framerate = 1000.0f / (m_drawtime * 0.05f); + + // NOTE: until we have quadtree in place we have to rely on the legacy rendering + // once this is resolved we should be able to simply adjust draw range + int targetsegments; + float targetfactor; + + if( framerate > 65.0 ) { targetsegments = 400; targetfactor = 3.0f; } + else if( framerate > 40.0 ) { targetsegments = 225; targetfactor = 1.5f; } + else if( framerate > 15.0 ) { targetsegments = 90; targetfactor = Global::ScreenHeight / 768.0f; } + else { targetsegments = 9; targetfactor = Global::ScreenHeight / 768.0f * 0.75f; } + + if( targetsegments > Global::iSegmentsRendered ) { + + Global::iSegmentsRendered = std::min( targetsegments, Global::iSegmentsRendered + 5 ); + } + else if( targetsegments < Global::iSegmentsRendered ) { + + Global::iSegmentsRendered = std::max( targetsegments, Global::iSegmentsRendered - 5 ); + } + if( targetfactor > Global::fDistanceFactor ) { + + Global::fDistanceFactor = std::min( targetfactor, Global::fDistanceFactor + 0.05f ); + } + else if( targetfactor < Global::fDistanceFactor ) { + + Global::fDistanceFactor = std::max( targetfactor, Global::fDistanceFactor - 0.05f ); + } + + if( ( framerate < 15.0 ) && ( Global::iSlowMotion < 7 ) ) { + Global::iSlowMotion = ( Global::iSlowMotion << 1 ) + 1; // zapalenie kolejnego bitu + if( Global::iSlowMotionMask & 1 ) + if( Global::iMultisampling ) // a multisampling jest włączony + ::glDisable( GL_MULTISAMPLE ); // wyłączenie multisamplingu powinno poprawić FPS + } + else if( ( framerate > 20.0 ) && Global::iSlowMotion ) { // FPS się zwiększył, można włączyć bajery + Global::iSlowMotion = ( Global::iSlowMotion >> 1 ); // zgaszenie bitu + if( Global::iSlowMotion == 0 ) // jeśli jest pełna prędkość + if( Global::iMultisampling ) // a multisampling jest włączony + ::glEnable( GL_MULTISAMPLE ); + } + + // TODO: add garbage collection and other less frequent works here }; void diff --git a/renderer.h b/renderer.h index 5d340855..22ab85a3 100644 --- a/renderer.h +++ b/renderer.h @@ -153,6 +153,8 @@ private: }; typedef std::vector opengllight_array; + +// methods // members rendermode renderpass{ rendermode::color }; @@ -160,6 +162,8 @@ private: texture_manager m_textures; opengl_camera m_camera; float m_drawrange{ 2500.0f }; // current drawing range + float m_drawtime{ 30.0f * 20.0f }; // start with presumed 'neutral' average of 30 fps + double m_updateaccumulator{ 0.0 }; }; extern opengl_renderer GfxRenderer;