16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-18 01:59:19 +02:00

ground cells render code moved to renderer and partially unified; fix for slipping wheels calculation logic

This commit is contained in:
tmj-fstate
2017-05-29 00:41:09 +02:00
parent 3068cc669e
commit d2a9f7080e
6 changed files with 166 additions and 195 deletions

View File

@@ -840,84 +840,6 @@ void TSubRect::Release()
CMesh::Clear(); // usuwanie buforów
};
void TSubRect::RenderDL()
{ // renderowanie nieprzezroczystych (DL)
TGroundNode *node;
RaAnimate(); // przeliczenia animacji torów w sektorze
/*
LoadNodes(); // czemu tutaj?
*/
for( node = nRenderRect; node; node = node->nNext3 ) {
GfxRenderer.Render( node ); // nieprzezroczyste obiekty terenu
}
for( node = nRender; node; node = node->nNext3 )
GfxRenderer.Render( node ); // nieprzezroczyste obiekty (oprócz pojazdów)
for (node = nRenderMixed; node; node = node->nNext3)
GfxRenderer.Render( node ); // nieprzezroczyste z mieszanych modeli
for (int j = 0; j < iTracks; ++j)
tTracks[j]->RenderDyn(); // nieprzezroczyste fragmenty pojazdów na torach
#ifdef EU07_SCENERY_EDITOR
// memcells
if( DebugModeFlag ) {
for( auto const memcell : m_memcells ) {
memcell->RenderDL();
}
}
#endif
};
void TSubRect::RenderAlphaDL()
{ // renderowanie przezroczystych modeli oraz pojazdów (DL)
TGroundNode *node;
for( node = nRenderMixed; node; node = node->nNext3 )
GfxRenderer.Render_Alpha( node ); // przezroczyste z mieszanych modeli
for( node = nRenderAlpha; node; node = node->nNext3 )
GfxRenderer.Render_Alpha( node ); // przezroczyste modele
for (int j = 0; j < iTracks; ++j)
tTracks[j]->RenderDynAlpha(); // przezroczyste fragmenty pojazdów na torach
};
void TSubRect::RenderVBO()
{ // renderowanie nieprzezroczystych (VBO)
TGroundNode *node;
RaAnimate(); // przeliczenia animacji torów w sektorze
/*
LoadNodes(); // czemu tutaj?
*/
if (StartVBO())
{
for( node = nRenderRect; node; node = node->nNext3 )
if( node->iVboPtr >= 0 )
GfxRenderer.Render( node ); // nieprzezroczyste obiekty terenu
EndVBO();
}
for( node = nRender; node; node = node->nNext3 )
GfxRenderer.Render( node ); // nieprzezroczyste obiekty (oprócz pojazdów)
for (node = nRenderMixed; node; node = node->nNext3)
GfxRenderer.Render( node ); // nieprzezroczyste z mieszanych modeli
for (int j = 0; j < iTracks; ++j)
tTracks[j]->RenderDyn(); // nieprzezroczyste fragmenty pojazdów na torach
#ifdef EU07_SCENERY_EDITOR
// memcells
if( DebugModeFlag ) {
for( auto const memcell : m_memcells ) {
memcell->RenderVBO();
}
}
#endif
};
void TSubRect::RenderAlphaVBO()
{ // renderowanie przezroczystych modeli oraz pojazdów (VBO)
TGroundNode *node;
for( node = nRenderMixed; node; node = node->nNext3 )
GfxRenderer.Render_Alpha( node ); // przezroczyste z mieszanych modeli
for( node = nRenderAlpha; node; node = node->nNext3 )
GfxRenderer.Render_Alpha( node ); // przezroczyste modele
for (int j = 0; j < iTracks; ++j)
tTracks[j]->RenderDynAlpha(); // przezroczyste fragmenty pojazdów na torach
};
void TSubRect::RenderSounds()
{ // aktualizacja dźwięków w pojazdach sektora (sektor może nie być wyświetlany)
for (int j = 0; j < iTracks; ++j)
@@ -955,75 +877,6 @@ TGroundRect::Init() {
}
};
void TGroundRect::RenderDL()
{ // renderowanie kwadratu kilometrowego (DL), jeśli jeszcze nie zrobione
#ifdef EU07_USE_OLD_RENDERCODE
if (iLastDisplay != iFrameNumber)
{ // tylko jezeli dany kwadrat nie był jeszcze renderowany
// for (TGroundNode* node=pRender;node;node=node->pNext3)
// node->Render(); //nieprzezroczyste trójkąty kwadratu kilometrowego
if (nRender)
{ //łączenie trójkątów w jedną listę - trochę wioska
if (!nRender->DisplayListID || (nRender->iVersion != Global::iReCompile))
{ // jeżeli nie skompilowany, kompilujemy wszystkie trójkąty w jeden
nRender->fSquareRadius = 5000.0 * 5000.0; // aby agregat nigdy nie znikał
nRender->DisplayListID = glGenLists(1);
glNewList(nRender->DisplayListID, GL_COMPILE);
nRender->iVersion = Global::iReCompile; // aktualna wersja siatek
auto const origin = Math3D::vector3( m_area.center.x, m_area.center.y, m_area.center.z );
for (TGroundNode *node = nRender; node; node = node->nNext3) // następny tej grupy
node->Compile(origin, true);
glEndList();
}
GfxRenderer.Render( nRender ); // nieprzezroczyste trójkąty kwadratu kilometrowego
}
// submodels geometry is world-centric, so at least for the time being we need to pop the stack early
::glPopMatrix();
if( nRootMesh ) {
GfxRenderer.Render( nRootMesh );
}
iLastDisplay = iFrameNumber; // drugi raz nie potrzeba
}
else {
::glPopMatrix();
}
#else
if( iLastDisplay != iFrameNumber ) { // tylko jezeli dany kwadrat nie był jeszcze renderowany
LoadNodes(); // ewentualne tworzenie siatek
if( nRenderRect ) {
for( TGroundNode *node = nRenderRect; node; node = node->nNext3 ) // następny tej grupy
GfxRenderer.Render( node ); // nieprzezroczyste trójkąty kwadratu kilometrowego
}
if( nRootMesh )
GfxRenderer.Render( nRootMesh );
iLastDisplay = iFrameNumber;
}
#endif
};
void TGroundRect::RenderVBO()
{ // renderowanie kwadratu kilometrowego (VBO), jeśli jeszcze nie zrobione
if (iLastDisplay != iFrameNumber)
{ // tylko jezeli dany kwadrat nie był jeszcze renderowany
LoadNodes(); // ewentualne tworzenie siatek
if ( nRenderRect && StartVBO())
{
for (TGroundNode *node = nRenderRect; node; node = node->nNext3) // następny tej grupy
#ifdef EU07_USE_OLD_RENDERCODE
node->RaRenderVBO(); // nieprzezroczyste trójkąty kwadratu kilometrowego
#else
GfxRenderer.Render( node ); // nieprzezroczyste trójkąty kwadratu kilometrowego
#endif
EndVBO();
iLastDisplay = iFrameNumber;
}
if (nTerrain)
nTerrain->smTerrain->iVisible = iFrameNumber; // ma się wyświetlić w tej ramce
}
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
std::vector<TGroundVertex> TempVerts;

View File

@@ -192,8 +192,8 @@ class TSubRect : public Resource, public CMesh
TGroundNode *nRootMesh = nullptr; // obiekty renderujące wg tekstury (wtórne, lista po nNext2)
TGroundNode *nMeshed = nullptr; // lista obiektów dla których istnieją obiekty renderujące grupowo
public:
TGroundNode * nRootNode = nullptr; // wszystkie obiekty w sektorze, z wyjątkiem renderujących i pojazdów (nNext2)
TGroundNode * nRenderHidden = nullptr; // lista obiektów niewidocznych, "renderowanych" również z tyłu (nNext3)
TGroundNode *nRootNode = nullptr; // wszystkie obiekty w sektorze, z wyjątkiem renderujących i pojazdów (nNext2)
TGroundNode *nRenderHidden = nullptr; // lista obiektów niewidocznych, "renderowanych" również z tyłu (nNext3)
TGroundNode *nRenderRect = nullptr; // z poziomu sektora - nieprzezroczyste (nNext3)
TGroundNode *nRenderRectAlpha = nullptr; // z poziomu sektora - przezroczyste (nNext3)
TGroundNode *nRenderWires = nullptr; // z poziomu sektora - druty i inne linie (nNext3)
@@ -217,11 +217,6 @@ class TSubRect : public Resource, public CMesh
bool StartVBO(); // ustwienie VBO sektora dla (nRenderRect), (nRenderRectAlpha) i (nRenderWires)
bool RaTrackAnimAdd(TTrack *t); // zgłoszenie toru do animacji
void RaAnimate(); // przeliczenie animacji torów
void RenderDL(); // renderowanie nieprzezroczystych w Display Lists
void RenderAlphaDL(); // renderowanie przezroczystych w Display Lists
// (McZapkie-131202)
void RenderVBO(); // renderowanie nieprzezroczystych z własnego VBO
void RenderAlphaVBO(); // renderowanie przezroczystych z (własnego) VBO
void RenderSounds(); // dźwięki pojazdów z niewidocznych sektorów
};
@@ -238,6 +233,8 @@ class TGroundRect : public TSubRect
{ // kwadrat kilometrowy
// obiekty o niewielkiej ilości wierzchołków będą renderowane stąd
// Ra: 2012-02 doszły submodele terenu
friend class opengl_renderer;
private:
int iLastDisplay; // numer klatki w której był ostatnio wyświetlany
TSubRect *pSubRects{ nullptr };
@@ -264,8 +261,6 @@ class TGroundRect : public TSubRect
for (int i = iNumSubRects * iNumSubRects - 1; i >= 0; --i)
pSubRects[i].Sort(); // optymalizacja obiektów w sektorach
};
void RenderDL();
void RenderVBO();
};
class TGround

View File

@@ -3685,7 +3685,8 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer)
else
FTrain = 0;
Fb = BrakeForce(RunningTrack);
if( std::max( std::abs( FTrain ), Fb ) > TotalMassxg * Adhesive( RunningTrack.friction ) ) // poslizg
if( ( Vel > 0.001 ) // crude trap, to prevent braked stationary vehicles from passing fb > mass * adhesive test
&& ( std::max( std::abs( FTrain ), Fb ) > TotalMassxg * Adhesive( RunningTrack.friction ) ) ) // poslizg
{
SlippingWheels = true;
}

View File

@@ -82,9 +82,9 @@ typedef std::vector<opengl_stack> openglstack_array;
public:
// constructors:
opengl_matrices() {
m_stacks.emplace_back(); // projection
m_stacks.emplace_back(); // modelview
}
m_stacks.emplace_back(); // projection
m_stacks.emplace_back(); // modelview
}
// methods:
void

View File

@@ -322,9 +322,9 @@ opengl_renderer::Render( TGround *Ground ) {
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();
auto *rectangle = &Ground->Rects[ column ][ row ];
if( m_camera.visible( rectangle->m_area ) ) {
Render( rectangle );
}
}
}
@@ -386,21 +386,7 @@ opengl_renderer::Render( TGround *Ground ) {
continue; // pomijanie sektorów poza kątem patrzenia
}
// kwadrat kilometrowy nie zawsze, bo szkoda FPS
// TODO: unify all math objects
::glPushMatrix();
auto const &cellorigin = Ground->Rects[ ( i + c ) / iNumSubRects ][ ( j + r ) / iNumSubRects ].m_area.center;
auto const originoffset = Math3D::vector3( cellorigin.x, cellorigin.y, cellorigin.z ) - Global::pCameraPosition;
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
if( Global::bUseVBO ) {
// vbo render path
Ground->Rects[ ( i + c ) / iNumSubRects ][ ( j + r ) / iNumSubRects ].RenderVBO();
::glPopMatrix();
}
else {
// display list render path
Ground->Rects[ ( i + c ) / iNumSubRects ][ ( j + r ) / iNumSubRects ].RenderDL();
}
Render( &Ground->Rects[ ( i + c ) / iNumSubRects ][ ( j + r ) / iNumSubRects ] );
if( ( tmp = Ground->FastGetSubRect( i + c, j + r ) ) != nullptr ) {
if( tmp->iNodeCount ) {
@@ -418,20 +404,143 @@ opengl_renderer::Render( TGround *Ground ) {
}
// renderowanie nieprzezroczystych
for( i = 0; i < Ground->iRendered; ++i ) {
if( Global::bUseVBO ) {
// vbo render path
Ground->pRendered[ i ]->RenderVBO();
}
else {
// display list render path
Ground->pRendered[ i ]->RenderDL();
}
Render( Ground->pRendered[ i ] );
}
// regular render takes care of all solid geometry present in the scene, thus we can launch alpha parts render here
return Render_Alpha( Ground );
}
// TODO: unify ground render code, until then old version is in place
#define EU07_USE_OLD_RENDERCODE
bool
opengl_renderer::Render( TGroundRect *Groundcell ) {
::glPushMatrix();
auto const &cellorigin = Groundcell->m_area.center;
// TODO: unify all math objects
auto const originoffset = Math3D::vector3( cellorigin.x, cellorigin.y, cellorigin.z ) - Global::pCameraPosition;
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
bool result{ false }; // will be true if we do any rendering
// TODO: unify render paths
if( Global::bUseVBO ) {
if ( Groundcell->iLastDisplay != Groundcell->iFrameNumber)
{ // tylko jezeli dany kwadrat nie był jeszcze renderowany
Groundcell->LoadNodes(); // ewentualne tworzenie siatek
if ( Groundcell->nRenderRect && Groundcell->StartVBO())
{
for (TGroundNode *node = Groundcell->nRenderRect; node; node = node->nNext3) // następny tej grupy
#ifdef EU07_USE_OLD_RENDERCODE
node->RaRenderVBO(); // nieprzezroczyste trójkąty kwadratu kilometrowego
#else
Render( node ); // nieprzezroczyste trójkąty kwadratu kilometrowego
#endif
Groundcell->EndVBO();
Groundcell->iLastDisplay = Groundcell->iFrameNumber;
result = true;
}
if ( Groundcell->nTerrain)
Groundcell->nTerrain->smTerrain->iVisible = Groundcell->iFrameNumber; // ma się wyświetlić w tej ramce
}
::glPopMatrix();
}
else {
#ifdef EU07_USE_OLD_RENDERCODE
if (Groundcell->iLastDisplay != Groundcell->iFrameNumber)
{ // tylko jezeli dany kwadrat nie był jeszcze renderowany
// for (TGroundNode* node=pRender;node;node=node->pNext3)
// node->Render(); //nieprzezroczyste trójkąty kwadratu kilometrowego
if ( Groundcell->nRender)
{ //łączenie trójkątów w jedną listę - trochę wioska
if (!Groundcell->nRender->DisplayListID || ( Groundcell->nRender->iVersion != Global::iReCompile))
{ // jeżeli nie skompilowany, kompilujemy wszystkie trójkąty w jeden
Groundcell->nRender->fSquareRadius = 5000.0 * 5000.0; // aby agregat nigdy nie znikał
Groundcell->nRender->DisplayListID = glGenLists(1);
glNewList( Groundcell->nRender->DisplayListID, GL_COMPILE);
Groundcell->nRender->iVersion = Global::iReCompile; // aktualna wersja siatek
auto const origin = Math3D::vector3( Groundcell->m_area.center.x, Groundcell->m_area.center.y, Groundcell->m_area.center.z );
for (TGroundNode *node = Groundcell->nRender; node; node = node->nNext3) // następny tej grupy
node->Compile(origin, true);
glEndList();
}
Render( Groundcell->nRender ); // nieprzezroczyste trójkąty kwadratu kilometrowego
}
// submodels geometry is world-centric, so at least for the time being we need to pop the stack early
::glPopMatrix();
if( Groundcell->nRootMesh ) {
Render( Groundcell->nRootMesh );
}
Groundcell->iLastDisplay = Groundcell->iFrameNumber; // drugi raz nie potrzeba
result = true;
}
else {
::glPopMatrix();
}
#else
if( iLastDisplay != iFrameNumber ) { // tylko jezeli dany kwadrat nie był jeszcze renderowany
LoadNodes(); // ewentualne tworzenie siatek
if( nRenderRect ) {
for( TGroundNode *node = nRenderRect; node; node = node->nNext3 ) // następny tej grupy
Render( node ); // nieprzezroczyste trójkąty kwadratu kilometrowego
}
if( nRootMesh )
Render( nRootMesh );
iLastDisplay = iFrameNumber;
}
#endif
}
return result;
}
#undef EU07_USE_OLD_RENDERCODE
bool
opengl_renderer::Render( TSubRect *Groundsubcell ) {
Groundsubcell->RaAnimate(); // przeliczenia animacji torów w sektorze
TGroundNode *node;
// nieprzezroczyste obiekty terenu
if( Global::bUseVBO ) {
// vbo render path
if( Groundsubcell->StartVBO() ) {
for( node = Groundsubcell->nRenderRect; node; node = node->nNext3 ) {
if( node->iVboPtr >= 0 ) {
Render( node );
}
}
Groundsubcell->EndVBO();
}
}
else {
// display list render path
for( node = Groundsubcell->nRenderRect; node; node = node->nNext3 ) {
Render( node ); // nieprzezroczyste obiekty terenu
}
}
// nieprzezroczyste obiekty (oprócz pojazdów)
for( node = Groundsubcell->nRender; node; node = node->nNext3 )
Render( node );
// nieprzezroczyste z mieszanych modeli
for( node = Groundsubcell->nRenderMixed; node; node = node->nNext3 )
Render( node );
// nieprzezroczyste fragmenty pojazdów na torach
for( int j = 0; j < Groundsubcell->iTracks; ++j )
Groundsubcell->tTracks[ j ]->RenderDyn();
#ifdef EU07_SCENERY_EDITOR
// memcells
if( DebugModeFlag ) {
for( auto const memcell : m_memcells ) {
memcell->RenderDL();
}
}
#endif
return true;
}
bool
opengl_renderer::Render( TGroundNode *Node ) {
@@ -901,14 +1010,7 @@ opengl_renderer::Render_Alpha( TGround *Ground ) {
}
for( int i = Ground->iRendered - 1; i >= 0; --i ) // od najdalszych
{ // renderowanie przezroczystych modeli oraz pojazdów
if( Global::bUseVBO ) {
// vbo render path
Ground->pRendered[ i ]->RenderAlphaVBO();
}
else {
// display list render path
Ground->pRendered[ i ]->RenderAlphaDL();
}
Render_Alpha( Ground->pRendered[ i ] );
}
::glDisable( GL_LIGHTING ); // linie nie powinny świecić
@@ -936,6 +1038,20 @@ opengl_renderer::Render_Alpha( TGround *Ground ) {
return true;
}
bool
opengl_renderer::Render_Alpha( TSubRect *Groundsubcell ) {
TGroundNode *node;
for( node = Groundsubcell->nRenderMixed; node; node = node->nNext3 )
Render_Alpha( node ); // przezroczyste z mieszanych modeli
for( node = Groundsubcell->nRenderAlpha; node; node = node->nNext3 )
Render_Alpha( node ); // przezroczyste modele
for( int j = 0; j < Groundsubcell->iTracks; ++j )
Groundsubcell->tTracks[ j ]->RenderDynAlpha(); // przezroczyste fragmenty pojazdów na torach
return true;
}
// NOTE: legacy render system switch
#define _PROBLEND

View File

@@ -124,6 +124,10 @@ public:
Render( world_environment *Environment );
bool
Render( TGround *Ground );
bool
Render( TGroundRect *Groundcell );
bool
Render( TSubRect *Groundsubcell );
bool
Render( TGroundNode *Node );
bool
@@ -138,6 +142,8 @@ public:
Render( TMemCell *Memcell );
bool
Render_Alpha( TGround *Ground );
bool
Render_Alpha( TSubRect *Groundsubcell );
bool
Render_Alpha( TGroundNode *Node );
bool