terrain drawing moved to renderer

This commit is contained in:
tmj-fstate
2017-03-12 01:04:41 +01:00
parent 5439fd86f3
commit 54a9642221
7 changed files with 220 additions and 74 deletions

View File

@@ -188,7 +188,7 @@ void focus_callback( GLFWwindow *window, int focus )
void scroll_callback( GLFWwindow* window, double xoffset, double yoffset ) {
if( DebugModeFlag && Global::ctrlState ) {
if( Global::ctrlState ) {
// ctrl + scroll wheel adjusts fov in debug mode
Global::FieldOfView = clamp( static_cast<float>(Global::FieldOfView - yoffset * 20.0 / Global::fFpsAverage), 15.0f, 75.0f );
}

View File

@@ -162,8 +162,8 @@ TAnimModel *Global::pTerrainCompact = NULL; // do zapisania terenu w pliku
std::string Global::asTerrainModel = ""; // nazwa obiektu terenu do zapisania w pliku
double Global::fFpsAverage = 20.0; // oczekiwana wartosć FPS
double Global::fFpsDeviation = 5.0; // odchylenie standardowe FPS
double Global::fFpsMin = 0.0; // dolna granica FPS, przy której promień scenerii będzie zmniejszany
double Global::fFpsMax = 0.0; // górna granica FPS, przy której promień scenerii będzie zwiększany
double Global::fFpsMin = 30.0; // dolna granica FPS, przy której promień scenerii będzie zmniejszany
double Global::fFpsMax = 65.0; // górna granica FPS, przy której promień scenerii będzie zwiększany
double Global::fFpsRadiusMax = 3000.0; // maksymalny promień renderowania
int Global::iFpsRadiusMax = 225; // maksymalny promień renderowania
double Global::fRadiusFactor = 1.1; // współczynnik jednorazowej zmiany promienia scenerii
@@ -941,10 +941,12 @@ void Global::ConfigParse(cParser &Parser)
// pauzowanie jest zablokowane dla (iMultiplayer&2)>0, więc iMultiplayer=1 da się zapauzować
// (tryb instruktora)
}
/*
fFpsMin = fFpsAverage -
fFpsDeviation; // dolna granica FPS, przy której promień scenerii będzie zmniejszany
fFpsMax = fFpsAverage +
fFpsDeviation; // górna granica FPS, przy której promień scenerii będzie zwiększany
*/
if (iPause)
iTextMode = GLFW_KEY_F1; // jak pauza, to pokazać zegar
/* this won't execute anymore with the old parser removed

View File

@@ -1168,6 +1168,45 @@ void TSubRect::RenderDL()
node->RenderDL(); // nieprzezroczyste z mieszanych modeli
for (int j = 0; j < iTracks; ++j)
tTracks[j]->RenderDyn(); // nieprzezroczyste fragmenty pojazdów na torach
/*
float width = 100.0f;
float height = 25.0f;
float3 vTopLeftFront( m_area.center.x - width, m_area.center.y + height, m_area.center.z + width );
float3 vTopLeftBack( m_area.center.x - width, m_area.center.y + height, m_area.center.z - width );
float3 vTopRightBack( m_area.center.x + width, m_area.center.y + height, m_area.center.z - width );
float3 vTopRightFront( m_area.center.x + width, m_area.center.y + height, m_area.center.z + width );
float3 vBottom_LeftFront( m_area.center.x - width, m_area.center.y - height, m_area.center.z + width );
float3 vBottom_LeftBack( m_area.center.x - width, m_area.center.y - height, m_area.center.z - width );
float3 vBottomRightBack( m_area.center.x + width, m_area.center.y - height, m_area.center.z - width );
float3 vBottomRightFront( m_area.center.x + width, m_area.center.y - height, m_area.center.z + width );
glDisable( GL_LIGHTING );
glDisable( GL_TEXTURE_2D );
glColor3ub( 255, 255, (iTracks ? 0 : 255) );
glBegin( GL_LINE_LOOP );
glVertex3fv( &vTopLeftFront.x );
glVertex3fv( &vTopLeftBack.x );
glVertex3fv( &vTopRightBack.x );
glVertex3fv( &vTopRightFront.x );
glEnd();
glBegin( GL_LINE_LOOP );
glVertex3fv( &vBottom_LeftFront.x );
glVertex3fv( &vBottom_LeftBack.x );
glVertex3fv( &vBottomRightBack.x );
glVertex3fv( &vBottomRightFront.x );
glEnd();
glBegin( GL_LINES );
glVertex3fv( &vTopLeftFront.x ); glVertex3fv( &vBottom_LeftFront.x );
glVertex3fv( &vTopLeftBack.x ); glVertex3fv( &vBottom_LeftBack.x );
glVertex3fv( &vTopRightBack.x ); glVertex3fv( &vBottomRightBack.x );
glVertex3fv( &vTopRightFront.x ); glVertex3fv( &vBottomRightFront.x );
glEnd();
glColor3ub( 255, 255, 255 );
glEnable( GL_TEXTURE_2D );
glEnable( GL_LIGHTING );
*/
};
void TSubRect::RenderAlphaDL()
@@ -1228,17 +1267,31 @@ void TSubRect::RenderSounds()
//---------------------------------------------------------------------------
int TGroundRect::iFrameNumber = 0; // licznik wyświetlanych klatek
TGroundRect::TGroundRect()
{
pSubRects = NULL;
nTerrain = NULL;
};
//TGroundRect::TGroundRect( float3 const &Position, float const Radius = 1000.0f * M_SQRT2 ) :
TGroundRect::~TGroundRect()
{
SafeDeleteArray(pSubRects);
};
void
TGroundRect::Init() {
pSubRects = new TSubRect[ iNumSubRects * iNumSubRects ];
float const subrectsize = 1000.0f / iNumSubRects;
for( int column = 0; column < iNumSubRects; ++column ) {
for( int row = 0; row < iNumSubRects; ++row ) {
auto &area = FastGetRect(column, row)->m_area;
area.center =
m_area.center
- float3( 500.0f, 0.0f, 500.0f ) // 'upper left' corner of rectangle
+ float3( subrectsize * 0.5f, 0.0f, subrectsize * 0.5f ) // center of sub-rectangle
+ float3( subrectsize * column, 0.0f, subrectsize * row );
area.radius = subrectsize * M_SQRT2;
}
}
};
void TGroundRect::RenderDL()
{ // renderowanie kwadratu kilometrowego (DL), jeśli jeszcze nie zrobione
if (iLastDisplay != iFrameNumber)
@@ -1263,6 +1316,44 @@ void TGroundRect::RenderDL()
nRootMesh->RenderDL();
iLastDisplay = iFrameNumber; // drugi raz nie potrzeba
}
/*
float width = 500.0f;
float height = 50.0f;
float3 vTopLeftFront( m_area.center.x - width, m_area.center.y + height, m_area.center.z + width );
float3 vTopLeftBack( m_area.center.x - width, m_area.center.y + height, m_area.center.z - width );
float3 vTopRightBack( m_area.center.x + width, m_area.center.y + height, m_area.center.z - width );
float3 vTopRightFront( m_area.center.x + width, m_area.center.y + height, m_area.center.z + width );
float3 vBottom_LeftFront( m_area.center.x - width, m_area.center.y - height, m_area.center.z + width );
float3 vBottom_LeftBack( m_area.center.x - width, m_area.center.y - height, m_area.center.z - width );
float3 vBottomRightBack( m_area.center.x + width, m_area.center.y - height, m_area.center.z - width );
float3 vBottomRightFront( m_area.center.x + width, m_area.center.y - height, m_area.center.z + width );
glDisable( GL_LIGHTING );
glDisable( GL_TEXTURE_2D );
glColor3ub( 0, 255, 255 );
glBegin( GL_LINE_LOOP );
glVertex3fv( &vTopLeftFront.x );
glVertex3fv( &vTopLeftBack.x );
glVertex3fv( &vTopRightBack.x );
glVertex3fv( &vTopRightFront.x );
glEnd();
glBegin( GL_LINE_LOOP );
glVertex3fv( &vBottom_LeftFront.x );
glVertex3fv( &vBottom_LeftBack.x );
glVertex3fv( &vBottomRightBack.x );
glVertex3fv( &vBottomRightFront.x );
glEnd();
glBegin( GL_LINES );
glVertex3fv( &vTopLeftFront.x ); glVertex3fv( &vBottom_LeftFront.x );
glVertex3fv( &vTopLeftBack.x ); glVertex3fv( &vBottom_LeftBack.x );
glVertex3fv( &vTopRightBack.x ); glVertex3fv( &vBottomRightBack.x );
glVertex3fv( &vTopRightFront.x ); glVertex3fv( &vBottomRightFront.x );
glEnd();
glColor3ub( 255, 255, 255 );
glEnable( GL_TEXTURE_2D );
glEnable( GL_LIGHTING );
*/
};
/*
void TGroundRect::RenderVBO()
@@ -1340,6 +1431,22 @@ TGround::TGround()
#endif
::SecureZeroMemory( TempConnectionType, sizeof( TempConnectionType ) );
::SecureZeroMemory( pRendered, sizeof( pRendered ) );
// set bounding area information for ground rectangles
float const rectsize = 1000.0f;
float3 const worldcenter( 0.0f, 0.0f, 0.0f );
for( int column = 0; column < iNumRects; ++column ) {
for( int row = 0; row < iNumRects; ++row ) {
auto &area = Rects[ column ][ row ].m_area;
// NOTE: in current implementation triangles can stick out to ~200m from the area, so we add extra padding
area.radius = 200.0f + rectsize * 0.5f * M_SQRT2;
area.center =
worldcenter
- float3( (iNumRects / 2) * rectsize, 0.0f, (iNumRects / 2) * rectsize ) // 'upper left' corner of the world
+ float3( rectsize * 0.5f, 0.0f, rectsize * 0.5f ) // center of the rectangle
+ float3( rectsize * column, 0.0f, rectsize * row );
}
}
}
TGround::~TGround()
@@ -4826,26 +4933,31 @@ bool TGround::GetTraction(TDynamicObject *model)
};
bool
TGround::Render( Math3D::vector3 const &Camera ) {
TGround::Render_Hidden( Math3D::vector3 const &Camera ) {
GfxRenderer.Update_Lights( m_lights );
/*
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;
/*
}
*/
++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
}
return true;
}
@@ -4897,8 +5009,11 @@ bool TGround::RenderDL(vector3 pPosition)
if (CameraDirection.x * direction.x + CameraDirection.z * direction.z < 0.55)
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

@@ -185,9 +185,16 @@ class TGroundNode : public Resource
*/
};
struct bounding_area {
float3 center; // mid point of the rectangle
float radius{ 0.0f }; // radius of the bounding sphere
};
class TSubRect : public Resource, public CMesh
{ // sektor składowy kwadratu kilometrowego
public:
bounding_area m_area;
int iTracks = 0; // ilość torów w (tTracks)
TTrack **tTracks = nullptr; // tory do renderowania pojazdów
protected:
@@ -209,7 +216,6 @@ class TSubRect : public Resource, public CMesh
public:
void LoadNodes(); // utworzenie VBO sektora
public:
// TSubRect() = default;
virtual ~TSubRect();
virtual void Release(); // zwalnianie VBO sektora
void NodeAdd(TGroundNode *Node); // dodanie obiektu do sektora na etapie rozdzielania na sektory
@@ -246,16 +252,12 @@ class TGroundRect : public TSubRect
// Ra: 2012-02 doszły submodele terenu
private:
int iLastDisplay; // numer klatki w której był ostatnio wyświetlany
TSubRect *pSubRects;
void Init()
{
pSubRects = new TSubRect[iNumSubRects * iNumSubRects];
};
TSubRect *pSubRects{ nullptr };
void Init();
public:
static int iFrameNumber; // numer kolejny wyświetlanej klatki
TGroundNode *nTerrain; // model terenu z E3D - użyć nRootMesh?
TGroundRect();
TGroundNode *nTerrain{ nullptr }; // model terenu z E3D - użyć nRootMesh?
virtual ~TGroundRect();
TSubRect * SafeGetRect(int iCol, int iRow)
@@ -282,6 +284,8 @@ class TGroundRect : public TSubRect
class TGround
{
friend class opengl_renderer;
vector3 CameraDirection; // zmienna robocza przy renderowaniu
int const *iRange = nullptr; // tabela widoczności
// TGroundNode *nRootNode; //lista wszystkich węzłów
@@ -361,7 +365,7 @@ class TGround
void Update_Lights(); // updates scene lights array
bool AddToQuery(TEvent *Event, TDynamicObject *Node);
bool GetTraction(TDynamicObject *model);
bool Render( Math3D::vector3 const &Camera );
bool Render_Hidden( Math3D::vector3 const &Camera );
bool RenderDL(vector3 pPosition);
bool RenderAlphaDL(vector3 pPosition);
/*

View File

@@ -1004,51 +1004,37 @@ bool TWorld::Update()
--iCheckFPS;
else
{ // jak doszło do zera, to sprawdzamy wydajność
if (Timer::GetFPS() < Global::fFpsMin)
{
Global::iSegmentsRendered -=
Random(10); // floor(0.5+Global::iSegmentsRendered/Global::fRadiusFactor);
if (Global::iSegmentsRendered < 10) // jeśli jest co zmniejszać
Global::iSegmentsRendered = 10; // 10=minimalny promień to 600m
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 (Timer::GetFPS() > Global::fFpsMax) // jeśli jest dużo FPS
if (Global::iSegmentsRendered < Global::iFpsRadiusMax) // jeśli jest co zwiększać
{
Global::iSegmentsRendered +=
Random(5); // floor(0.5+Global::iSegmentsRendered*Global::fRadiusFactor);
if (Global::iSegmentsRendered > Global::iFpsRadiusMax) // 5.6km (22*22*M_PI)
Global::iSegmentsRendered = Global::iFpsRadiusMax;
}
if ((Timer::GetFPS() < 12) && (Global::iSlowMotion < 7))
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 ((Timer::GetFPS() > 20) && Global::iSlowMotion)
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);
}
/*
if (!Global::bPause)
if (GetFPS()<=5)
{//zwiększenie kroku fizyki przy słabym FPS
if (fMaxDt<0.05)
{fMaxDt=0.05; //Ra: tak nie może być, bo są problemy na sprzęgach
WriteLog("Phisics step switched to 0.05s!");
}
}
else if (GetFPS()>12)
if (fMaxDt>0.01)
{//powrót do podstawowego kroku fizyki
fMaxDt=0.01;
WriteLog("Phisics step switched to 0.01s!");
}
*/
iCheckFPS = 0.25 * Timer::GetFPS(); // tak za 0.25 sekundy sprawdzić ponownie (jeszcze przycina?)
}
Timer::UpdateTimers(Global::iPause != 0);
@@ -1728,14 +1714,12 @@ TWorld::Render_UI() {
if( Global::iTextMode == GLFW_KEY_F8 ) {
Global::iViewMode = GLFW_KEY_F8;
OutText1 = "FPS: " + to_string( Timer::GetFPS(), 2 );
OutText1 = "Draw range x " + to_string( Global::fDistanceFactor, 1 ) + "; FPS: " + to_string( Timer::GetFPS(), 2 );
//OutText1 += sprintf();
if( Global::iSlowMotion )
OutText1 += " (slowmotion " + to_string( Global::iSlowMotion ) + ")";
OutText1 += ", sectors: " + to_string( Ground.iRendered );
if( DebugModeFlag ) {
OutText1 += " FoV: " + to_string( Global::FieldOfView / Global::ZoomFactor, 1 );
}
OutText1 += ", sectors: " + to_string( Ground.iRendered ) + "/" + to_string( Global::iSegmentsRendered );
OutText1 += "; FoV: " + to_string( Global::FieldOfView / Global::ZoomFactor, 1 );
}
// if (Console::Pressed(VK_F7))

View File

@@ -14,6 +14,12 @@ http://mozilla.org/MPL/2.0/.
#include "dynobj.h"
// returns true if specified object is within camera frustum, false otherwise
bool
opengl_camera::visible( bounding_area const &Area ) const {
return ( m_frustum.sphere_inside( Area.center, Area.radius ) > 0.0f );
}
bool
opengl_camera::visible( TDynamicObject const *Dynamic ) const {
@@ -63,7 +69,7 @@ opengl_renderer::Render() {
Global::FieldOfView / Global::ZoomFactor,
(GLdouble)Global::ScreenWidth / std::max( (GLdouble)Global::ScreenHeight, 1.0 ),
0.1f * Global::ZoomFactor,
m_drawrange );
m_drawrange * Global::fDistanceFactor );
::glMatrixMode( GL_MODELVIEW ); // Select The Modelview Matrix
::glLoadIdentity();
@@ -75,7 +81,10 @@ opengl_renderer::Render() {
World.Environment.render();
}
if( false == World.Ground.Render( World.Camera.Pos ) ) { return false; }
World.Ground.Render_Hidden( World.Camera.Pos );
Render( &World.Ground );
World.Ground.RenderDL( World.Camera.Pos );
World.Ground.RenderAlphaDL( World.Camera.Pos );
World.Render_Cab();
World.Render_UI();
@@ -83,6 +92,33 @@ opengl_renderer::Render() {
return true; // for now always succeed
}
bool
opengl_renderer::Render( TGround *Ground ) {
glDisable( GL_BLEND );
glAlphaFunc( GL_GREATER, 0.35f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
glEnable( GL_LIGHTING );
glColor3f( 1.0f, 1.0f, 1.0f );
float3 const cameraposition = float3( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z );
int const camerax = std::floor( cameraposition.x / 1000.0f ) + iNumRects / 2;
int const cameraz = std::floor( cameraposition.z / 1000.0f ) + iNumRects / 2;
int const segmentcount = 2 * static_cast<int>(std::ceil( m_drawrange * Global::fDistanceFactor / 1000.0f ));
int const originx = std::max( 0, camerax - segmentcount / 2 );
int const originz = std::max( 0, cameraz - segmentcount / 2 );
for( int column = originx; column <= originx + segmentcount; ++column ) {
for( int row = originz; row <= originz + segmentcount; ++row ) {
auto &rectangle = Ground->Rects[ column ][ row ];
if( m_camera.visible( rectangle.m_area ) ) {
rectangle.RenderDL();
}
}
}
return true;
}
bool
opengl_renderer::Render( TDynamicObject *Dynamic ) {

View File

@@ -14,6 +14,7 @@ http://mozilla.org/MPL/2.0/.
#include "lightarray.h"
#include "dumb3d.h"
#include "frustum.h"
#include "ground.h"
struct opengl_light {
@@ -78,6 +79,8 @@ public:
inline
void
update_frustum() { m_frustum.calculate(); }
bool
visible( bounding_area const &Area ) const;
bool
visible( TDynamicObject const *Dynamic ) const;
@@ -98,6 +101,8 @@ public:
// main draw call. returns false on error
bool
Render();
bool
Render( TGround *Ground );
bool
Render( TDynamicObject *Dynamic );
bool