reverted terrain rendering, range adjustment moved to renderer, now based on frame drawing time instead of entire scene refresh rate.

This commit is contained in:
tmj-fstate
2017-03-12 16:46:20 +01:00
parent 54a9642221
commit 0cd3109587
7 changed files with 95 additions and 71 deletions

View File

@@ -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<LPARAM>( icon ) );
#endif
GfxRenderer.Init();

View File

@@ -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

View File

@@ -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);
/*

View File

@@ -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) )

View File

@@ -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)

View File

@@ -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::milliseconds>( ( 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

View File

@@ -153,6 +153,8 @@ private:
};
typedef std::vector<opengl_light> 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;