diff --git a/Driver.cpp b/Driver.cpp index cf192ad7..5dc88575 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -82,8 +82,8 @@ Tutaj łączymy teorię z praktyką - tu nic nie działa i nikt nie wie dlaczego // stałe const double EasyReactionTime = 0.5; //[s] przebłyski świadomości dla zwykłej jazdy const double HardReactionTime = 0.2; -const double EasyAcceleration = 0.5; //[m/ss] -const double HardAcceleration = 0.9; +const double EasyAcceleration = 0.85; //[m/ss] +const double HardAcceleration = 9.81; const double PrepareTime = 2.0; //[s] przebłyski świadomości przy odpalaniu bool WriteLogFlag = false; @@ -450,7 +450,7 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) TEvent *pEvent{ nullptr }; double fLastDir{ 0.0 }; - if (iTableDirection != iDirection) { + if (iTableDirection != iDirection ) { // jeśli zmiana kierunku, zaczynamy od toru ze wskazanym pojazdem iTableDirection = iDirection; // ustalenie w jakim kierunku jest wypełniana tabelka względem pojazdu pTrack = pVehicle->RaTrackGet(); // odcinek, na którym stoi @@ -468,6 +468,7 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) SemNextStopIndex = -1; } else { + if( iTableDirection == 0 ) { return; } // kontynuacja skanowania od ostatnio sprawdzonego toru (w ostatniej pozycji zawsze jest tor) if( ( SemNextStopIndex != -1 ) && ( sSpeedTable[SemNextStopIndex].fVelNext < 1.0 ) ) { @@ -501,6 +502,11 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) pTrack->Length() ); } + if( iTableDirection == 0 ) { + // don't bother + return; + } + if( fCurrentDistance >= fDistance ) { // all done return; @@ -1664,14 +1670,20 @@ void TController::AutoRewident() } }; +int TController::CheckDirection() { + + int d = mvOccupied->DirAbsolute; // który sprzęg jest z przodu + if( !d ) // jeśli nie ma ustalonego kierunku + d = mvOccupied->CabNo; // to jedziemy wg aktualnej kabiny + iDirection = d; // ustalenie kierunku jazdy (powinno zrobić PrepareEngine?) + return d; +} + bool TController::CheckVehicles(TOrders user) { // sprawdzenie stanu posiadanych pojazdów w składzie i zapalenie świateł TDynamicObject *p; // roboczy wskaźnik na pojazd iVehicles = 0; // ilość pojazdów w składzie - int d = mvOccupied->DirAbsolute; // który sprzęg jest z przodu - if (!d) // jeśli nie ma ustalonego kierunku - d = mvOccupied->CabNo; // to jedziemy wg aktualnej kabiny - iDirection = d; // ustalenie kierunku jazdy (powinno zrobić PrepareEngine?) + int d = CheckDirection(); d = d >= 0 ? 0 : 1; // kierunek szukania czoła (numer sprzęgu) pVehicles[0] = p = pVehicle->FirstFind(d); // pojazd na czele składu // liczenie pojazdów w składzie i ustalenie parametrów @@ -2058,20 +2070,22 @@ bool TController::PrepareEngine() mvOccupied->BatterySwitch(true); if (mvControlling->EnginePowerSource.SourceType == CurrentCollector) { // jeśli silnikowy jest pantografującym - if (mvControlling->PantPress > 4.3) - { // jeżeli jest wystarczające ciśnienie w pantografach + mvControlling->PantFront( true ); + mvControlling->PantRear( true ); + if (mvControlling->PantPress < 4.2) { + // załączenie małej sprężarki + if( mvControlling->TrainType != dt_EZT ) { + // odłączenie zbiornika głównego, bo z nim nie da rady napompować + mvControlling->bPantKurek3 = false; + } + mvControlling->PantCompFlag = true; // załączenie sprężarki pantografów + } + else { + // jeżeli jest wystarczające ciśnienie w pantografach if ((!mvControlling->bPantKurek3) || (mvControlling->PantPress <= mvControlling->ScndPipePress)) // kurek przełączony albo główna już pompuje mvControlling->PantCompFlag = false; // sprężarkę pantografów można już wyłączyć - mvControlling->PantFront(true); - mvControlling->PantRear(true); - } - else if (mvControlling->PantPress < 4.2) //żeby nie załączał zaraz po przekroczeniu 4.0 - { // załączenie małej sprężarki - mvControlling->bPantKurek3 = - false; // odłączenie zbiornika głównego, bo z nim nie da rady napompować - mvControlling->PantCompFlag = true; // załączenie sprężarki pantografów } } // if (mvOccupied->TrainType==dt_EZT) @@ -2352,11 +2366,19 @@ bool TController::IncSpeed() if (tsGuardSignal->GetStatus() & DSBSTATUS_PLAYING) // jeśli gada, to nie jedziemy return false; bool OK = true; - if ( ( iDrivigFlags & moveDoorOpened ) - && ( VelDesired > 0.0 ) ) // to prevent door shuffle on stop - Doors(false); // zamykanie drzwi - tutaj wykonuje tylko AI (zmienia fActionTime) - if (fActionTime < 0.0) // gdy jest nakaz poczekać z jazdą, to nie ruszać + if( ( iDrivigFlags & moveDoorOpened ) + && ( VelDesired > 0.0 ) ) { // to prevent door shuffle on stop + // zamykanie drzwi - tutaj wykonuje tylko AI (zmienia fActionTime) + Doors( false ); + } + if( fActionTime < 0.0 ) { + // gdy jest nakaz poczekać z jazdą, to nie ruszać return false; + } + if( true == mvOccupied->DepartureSignal ) { + // shut off departure warning + mvOccupied->DepartureSignal = false; + } if (mvControlling->SlippingWheels) return false; // jak poślizg, to nie przyspieszamy switch (mvOccupied->EngineType) @@ -2528,8 +2550,6 @@ void TController::SpeedSet() switch (mvOccupied->EngineType) { case None: // McZapkie-041003: wagon sterowniczy - if (fActionTime >= -1.0) - mvOccupied->DepartureSignal = false; // trochę niech pobuczy, zanim pojedzie if (mvControlling->MainCtrlPosNo > 0) { // jeśli ma czym kręcić // TODO: sprawdzanie innego czlonu //if (!FuseFlagCheck()) @@ -2714,17 +2734,24 @@ void TController::Doors(bool what) { // zamykanie if (mvOccupied->DoorOpenCtrl == 1) { // jeśli drzwi sterowane z kabiny - if (AIControllFlag) - if (mvOccupied->DoorLeftOpened || mvOccupied->DoorRightOpened) - { // AI zamyka drzwi przed odjazdem - if (mvOccupied->DoorClosureWarning) + if( AIControllFlag ) { + if( mvOccupied->DoorLeftOpened || mvOccupied->DoorRightOpened ) { // AI zamyka drzwi przed odjazdem + if( ( true == mvOccupied->DoorClosureWarning ) + && ( false == mvOccupied->DepartureSignal ) + && ( true == TestFlag( iDrivigFlags, moveDoorOpened ) ) ) { mvOccupied->DepartureSignal = true; // załącenie bzyczka - mvOccupied->DoorLeft(false); // zamykanie drzwi - mvOccupied->DoorRight(false); + fActionTime = -3.0 - 0.1 * Random( 10 ); // 3-4 second wait + } + if( fActionTime > -0.5 ) { // Ra: trzeba by ustawić jakiś czas oczekiwania na zamknięcie się drzwi - fActionTime = -1.5 - 0.1 * Random(10); // czekanie sekundę, może trochę dłużej - iDrivigFlags &= ~moveDoorOpened; // nie wykonywać drugi raz + mvOccupied->DoorLeft( false ); // zamykanie drzwi + mvOccupied->DoorRight( false ); + iDrivigFlags &= ~moveDoorOpened; + // 1.5-2.5 sec wait, +potentially 0.5 remaining + fActionTime = -1.5 - 0.1 * Random( 10 ); + } } + } } else { // jeśli nie, to zamykanie w składzie wagonowym @@ -2736,7 +2763,7 @@ void TController::Doors(bool what) p = p->Next(); // pojazd podłączony z tyłu (patrząc od czoła) } // WaitingSet(5); //10 sekund tu to za długo, opóźnia odjazd o pół minuty - fActionTime = -1.5 - 0.1 * Random(10); // czekanie sekundę, może trochę dłużej + fActionTime = -3.0 - 0.1 * Random(10); // czekanie sekundę, może trochę dłużej iDrivigFlags &= ~moveDoorOpened; // zostały zamknięte - nie wykonywać drugi raz } } @@ -3261,18 +3288,12 @@ bool TController::UpdateSituation(double dt) { if (mvControlling->EnginePowerSource.SourceType == CurrentCollector) { - if (mvOccupied->ScndPipePress > 4.3) // gdy główna sprężarka bezpiecznie nabije - // ciśnienie - mvControlling->bPantKurek3 = - true; // to można przestawić kurek na zasilanie pantografów z głównej pneumatyki + if (mvOccupied->ScndPipePress > 4.3) // gdy główna sprężarka bezpiecznie nabije ciśnienie + mvControlling->bPantKurek3 = true; // to można przestawić kurek na zasilanie pantografów z głównej pneumatyki fVoltage = 0.5 * (fVoltage + fabs(mvControlling->RunningTraction.TractionVoltage)); // uśrednione napięcie - // sieci: przy spadku - // poniżej wartości - // minimalnej opóźnić - // rozruch o losowy - // czas + // sieci: przy spadku poniżej wartości minimalnej opóźnić rozruch o losowy czas if (fVoltage < mvControlling->EnginePowerSource.CollectorParameters .MinV) // gdy rozłączenie WS z powodu niskiego napięcia if (fActionTime >= 0) // jeśli czas oczekiwania nie został ustawiony diff --git a/Driver.h b/Driver.h index d33a2510..ea961098 100644 --- a/Driver.h +++ b/Driver.h @@ -320,9 +320,11 @@ class TController // procedury dotyczace rozkazow dla maszynisty void SetVelocity(double NewVel, double NewVelNext, TStopReason r = stopNone); // uaktualnia informacje o prędkości +/* bool SetProximityVelocity( double NewDist, double NewVelNext); // uaktualnia informacje o prędkości przy nastepnym semaforze +*/ public: void JumpToNextOrder(); void JumpToFirstOrder(); @@ -331,6 +333,7 @@ class TController inline TOrders OrderCurrentGet(); inline TOrders OrderNextGet(); bool CheckVehicles(TOrders user = Wait_for_orders); + int CheckDirection(); private: void CloseLog(); @@ -351,21 +354,22 @@ class TController void DirectionForward(bool forward); int OrderDirectionChange(int newdir, TMoverParameters *Vehicle); void Lights(int head, int rear); - double Distance(vector3 &p1, vector3 &n, vector3 &p2); +// double Distance(vector3 &p1, vector3 &n, vector3 &p2); private: // Ra: metody obsługujące skanowanie toru TEvent *CheckTrackEvent(double fDirection, TTrack *Track); - bool TableCheckEvent(TEvent *e); +// bool TableCheckEvent(TEvent *e); bool TableAddNew(); bool TableNotFound(TEvent const *Event) const; - void TableClear(); - TEvent *TableCheckTrackEvent(double fDirection, TTrack *Track); +// TEvent *TableCheckTrackEvent(double fDirection, TTrack *Track); void TableTraceRoute(double fDistance, TDynamicObject *pVehicle = NULL); void TableCheck(double fDistance); TCommandType TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc); void TablePurger(); public: std::size_t TableSize() const { return sSpeedTable.size(); } + void TableClear(); + int TableDirection() { return iTableDirection; } private: // Ra: stare funkcje skanujące, używane do szukania sygnalizatora z tyłu bool BackwardTrackBusy(TTrack *Track); diff --git a/Ground.cpp b/Ground.cpp index 7c6ab766..2ba293fa 100644 --- a/Ground.cpp +++ b/Ground.cpp @@ -50,6 +50,9 @@ extern "C" bool bCondition; // McZapkie: do testowania warunku na event multiple std::string LogComment; +// TODO: switch to the new unified code after we have in place merging of individual triangle nodes into material-based soups +#define EU07_USE_OLD_RENDERCODE + //--------------------------------------------------------------------------- // Obiekt renderujący siatkę jest sztucznie tworzonym obiektem pomocniczym, // grupującym siatki obiektów dla danej tekstury. Obiektami składowymi mogą @@ -289,145 +292,6 @@ void TGroundNode::RaRenderVBO() glDrawArrays(iType, iVboPtr, iNumVerts); // Narysuj naraz wszystkie trójkąty } -#ifdef EU07_USE_OLD_RENDERCODE -void TGroundNode::RenderVBO() { // renderowanie obiektu z VBO - faza nieprzezroczystych - - switch( iType ) { // obiekty renderowane niezależnie od odległości - case TP_SUBMODEL: - TSubModel::fSquareDist = 0; - GfxRenderer.Render( smTerrain ); - } - - double distancesquared = SquareMagnitude( pCenter - Global::pCameraPosition ) / Global::ZoomFactor; - if( ( distancesquared > ( fSquareRadius * Global::fDistanceFactor ) ) - || ( distancesquared < ( fSquareMinRadius / Global::fDistanceFactor ) ) ) { - return; - } - - switch( iType ) { - case TP_TRACK: { - if( iNumVerts ) - pTrack->RaRenderVBO( iVboPtr ); - return; - } - case TP_MODEL: { - Model->Render( &pCenter ); - return; - } - case TP_MEMCELL: { - GfxRenderer.Render( MemCell ); - return; - } - } - - if( ( iFlags & 0x10 ) || ( fLineThickness < 0 ) ) { - - if( ( iType == GL_LINES ) || ( iType == GL_LINE_STRIP ) || ( iType == GL_LINE_LOOP ) ) { - - if( iNumPts ) { - - float linealpha = 255000 * fLineThickness / ( distancesquared + 1.0 ); - if( linealpha > 255 ) - linealpha = 255; - float r, g, b; - r = floor( Diffuse[ 0 ] * Global::DayLight.ambient[ 0 ] ); // w zaleznosci od koloru swiatla - g = floor( Diffuse[ 1 ] * Global::DayLight.ambient[ 1 ] ); - b = floor( Diffuse[ 2 ] * Global::DayLight.ambient[ 2 ] ); - glColor4ub( r, g, b, linealpha ); // przezroczystosc dalekiej linii - GfxRenderer.Bind( 0 ); - - glDrawArrays( iType, iVboPtr, iNumPts ); // rysowanie linii - } - } - // GL_TRIANGLE etc - else { - if( iVboPtr >= 0 ) { - RaRenderVBO(); - } - } - - SetLastUsage( Timer::GetSimulationTime() ); - } -}; - -void TGroundNode::RenderAlphaVBO() -{ // renderowanie obiektu z VBO - faza przezroczystych - - double distancesquared = SquareMagnitude( pCenter - Global::pCameraPosition ) / Global::ZoomFactor; - if( ( distancesquared > ( fSquareRadius * Global::fDistanceFactor ) ) - || ( distancesquared < ( fSquareMinRadius / Global::fDistanceFactor ) ) ) { - return; - } - - switch( iType ) { - case TP_TRACTION: { - if( bVisible ) { - hvTraction->RenderVBO( distancesquared, iVboPtr ); - } - return; - } - case TP_MODEL: { - Model->RenderAlpha( &pCenter ); - return; - } - } - - // TODO: sprawdzic czy jest potrzebny warunek fLineThickness < 0 - if( ( iNumVerts && ( iFlags & 0x20 ) ) - || ( iNumPts && ( fLineThickness > 0 ) ) ) { - -#ifdef _PROBLEND - if( ( PROBLEND ) ) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012 - { - glDisable( GL_BLEND ); - glAlphaFunc( GL_GREATER, 0.50f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f - }; -#endif - - if( ( iType == GL_LINES ) - || ( iType == GL_LINE_STRIP ) - || ( iType == GL_LINE_LOOP ) ) { - - if( iNumPts ) { - - float linealpha = 255000 * fLineThickness / (distancesquared + 1.0); - if (linealpha > 255) - linealpha = 255; -#ifdef EU07_USE_OLD_LIGHTING_MODEL - r = Diffuse[ 0 ] * Global::ambientDayLight[ 0 ]; // w zaleznosci od koloru swiatla - g = Diffuse[ 1 ] * Global::ambientDayLight[ 1 ]; - b = Diffuse[ 2 ] * Global::ambientDayLight[ 2 ]; -#else - float r = Diffuse[ 0 ] * Global::DayLight.ambient[ 0 ]; // w zaleznosci od koloru swiatla - float g = Diffuse[ 1 ] * Global::DayLight.ambient[ 1 ]; - float b = Diffuse[ 2 ] * Global::DayLight.ambient[ 2 ]; -#endif - glColor4ub( r, g, b, linealpha ); // przezroczystosc dalekiej linii - GfxRenderer.Bind( 0 ); - - glDrawArrays( iType, iVboPtr, iNumPts ); // rysowanie linii - } - } - else { - if( iVboPtr >= 0 ) { - RaRenderVBO(); - } - } - - SetLastUsage( Timer::GetSimulationTime() ); - } - -#ifdef _PROBLEND - if( ( PROBLEND ) ) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012 - { - glEnable( GL_BLEND ); - glAlphaFunc( GL_GREATER, 0.04f ); - } -#endif -} - -#endif - void TGroundNode::Compile(bool many) { // tworzenie skompilowanej listy w wyświetlaniu DL if (!many) @@ -444,34 +308,32 @@ void TGroundNode::Compile(bool many) if ((iType == GL_LINES) || (iType == GL_LINE_STRIP) || (iType == GL_LINE_LOOP)) { glBegin(iType); - for (int i = 0; i < iNumPts; i++) + for (int i = 0; i < iNumPts; ++i) glVertex3dv(&Points[i].x); glEnd(); } else if (iType == GL_TRIANGLE_STRIP || iType == GL_TRIANGLE_FAN || iType == GL_TRIANGLES) { // jak nie linie, to trójkąty - TGroundNode *tri = this; - do - { // pętla po obiektach w grupie w celu połączenia siatek - // TODO: eliminate these calls, they're duplicated by setup part in the unified render function - glColor3ub(tri->Diffuse[0], tri->Diffuse[1], tri->Diffuse[2]); - GfxRenderer.Bind(Global::bWireFrame ? 0 : tri->TextureID); - - glBegin(Global::bWireFrame ? GL_LINE_LOOP : tri->iType); - for (int i = 0; i < tri->iNumVerts; i++) - { - glNormal3dv(&tri->Vertices[i].Normal.x); - glTexCoord2f(tri->Vertices[i].tu, tri->Vertices[i].tv); - glVertex3dv(&tri->Vertices[i].Point.x); - }; - glEnd(); - tri = NULL; // a jak nie, to koniec - } while (tri); + // TODO: eliminate these calls, they're duplicated by setup part in the unified render function +#ifdef EU07_USE_OLD_RENDERCODE + glColor3ub(Diffuse[0], Diffuse[1], Diffuse[2]); + GfxRenderer.Bind(TextureID); +#endif + glBegin(iType); + for (int i = 0; i < iNumVerts; ++i) + { + glNormal3dv(&Vertices[i].Normal.x); + glTexCoord2f(Vertices[i].tu, Vertices[i].tv); + glVertex3dv(&Vertices[i].Point.x); + }; + glEnd(); } else if (iType == TP_MESH) { // grupa ze wspólną teksturą - wrzucanie do wspólnego Display List +#ifdef EU07_USE_OLD_RENDERCODE if (TextureID) GfxRenderer.Bind(TextureID); // Ustaw aktywną teksturę +#endif TGroundNode *n = nNode; while (n ? n->TextureID == TextureID : false) { // wszystkie obiekty o tej samej testurze @@ -523,161 +385,6 @@ void TGroundNode::RenderHidden() } }; -#ifdef EU07_USE_OLD_RENDERCODE -void TGroundNode::RenderDL() -{ // wyświetlanie obiektu przez Display List - switch (iType) - { // obiekty renderowane niezależnie od odległości - case TP_SUBMODEL: - TSubModel::fSquareDist = 0; - GfxRenderer.Render( smTerrain ); - } - - double distancesquared = SquareMagnitude(pCenter - Global::pCameraPosition) / Global::ZoomFactor; - if( ( distancesquared > ( fSquareRadius * Global::fDistanceFactor ) ) - || ( distancesquared < ( fSquareMinRadius / Global::fDistanceFactor ) ) ) { - return; - } - - switch (iType) - { - case TP_TRACK: { - pTrack->Render(); - return; - } - case TP_MODEL: { - Model->Render( &pCenter ); - return; - } - case TP_MEMCELL: { - GfxRenderer.Render( MemCell ); - return; - } - } - - // TODO: sprawdzic czy jest potrzebny warunek fLineThickness < 0 - if ((iFlags & 0x10) || (fLineThickness < 0)) - { - if (!DisplayListID || (iVersion != Global::iReCompile)) // Ra: wymuszenie rekompilacji - { - Compile(); - if (Global::bManageNodes) - ResourceManager::Register(this); - }; - - if ((iType == GL_LINES) || (iType == GL_LINE_STRIP) || (iType == GL_LINE_LOOP)) - { // wszelkie linie są rysowane na samym końcu - if( iNumPts ) { - - float linealpha = 255000 * fLineThickness / ( distancesquared + 1.0 ); - if( linealpha > 255 ) - linealpha = 255; - float r, g, b; - r = floor( Diffuse[ 0 ] * Global::DayLight.ambient[ 0 ] ); // w zaleznosci od koloru swiatla - g = floor( Diffuse[ 1 ] * Global::DayLight.ambient[ 1 ] ); - b = floor( Diffuse[ 2 ] * Global::DayLight.ambient[ 2 ] ); - glColor4ub( r, g, b, linealpha ); // przezroczystosc dalekiej linii - GfxRenderer.Bind( 0 ); - - glCallList( DisplayListID ); - } - } - // GL_TRIANGLE etc - else - glCallList(DisplayListID); - - SetLastUsage(Timer::GetSimulationTime()); - }; -}; - -void TGroundNode::RenderAlphaDL() -{ - // SPOSOB NA POZBYCIE SIE RAMKI DOOKOLA TEXTURY ALPHA DLA OBIEKTOW ZAGNIEZDZONYCH W SCN JAKO - // NODE - - // W GROUND.H dajemy do klasy TGroundNode zmienna bool PROBLEND to samo robimy w klasie TGround - // nastepnie podczas wczytywania textury dla TRIANGLES w TGround::AddGroundNode - // sprawdzamy czy w nazwie jest @ i wg tego - // ustawiamy PROBLEND na true dla wlasnie wczytywanego trojkata (kazdy trojkat jest osobnym - // nodem) - // nastepnie podczas renderowania w bool TGroundNode::RenderAlpha() - // na poczatku ustawiamy standardowe GL_GREATER = 0.04 - // pozniej sprawdzamy czy jest wlaczony PROBLEND dla aktualnie renderowanego noda TRIANGLE, - // wlasciwie dla kazdego node'a - // i jezeli tak to odpowiedni GL_GREATER w przeciwnym wypadku standardowy 0.04 - - double distancesquared = SquareMagnitude( pCenter - Global::pCameraPosition ) / Global::ZoomFactor; - if( ( distancesquared > ( fSquareRadius * Global::fDistanceFactor ) ) - || ( distancesquared < ( fSquareMinRadius / Global::fDistanceFactor ) ) ) { - return; - } - - switch( iType ) { - case TP_TRACTION: { - if( bVisible ) - hvTraction->RenderDL( distancesquared ); - return; - } - case TP_MODEL: { - Model->RenderAlpha( &pCenter ); - return; - } - }; - - // TODO: sprawdzic czy jest potrzebny warunek fLineThickness < 0 - if( ( iNumVerts && ( iFlags & 0x20 ) ) - || ( iNumPts && ( fLineThickness > 0 ) ) ) { - -#ifdef _PROBLEND - if ((PROBLEND)) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012 - { - glDisable(GL_BLEND); - glAlphaFunc(GL_GREATER, 0.50f); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f - }; -#endif - if (!DisplayListID) //||Global::bReCompile) //Ra: wymuszenie rekompilacji - { - Compile(); - if (Global::bManageNodes) - ResourceManager::Register(this); - }; - - if( ( iType == GL_LINES ) - || ( iType == GL_LINE_STRIP ) - || ( iType == GL_LINE_LOOP ) ) { - - if( iNumPts ) { - - float linealpha = 255000 * fLineThickness / ( distancesquared + 1.0 ); - if (linealpha > 255) - linealpha = 255; - float r = Diffuse[ 0 ] * Global::DayLight.ambient[ 0 ]; // w zaleznosci od koloru swiatla - float g = Diffuse[ 1 ] * Global::DayLight.ambient[ 1 ]; - float b = Diffuse[ 2 ] * Global::DayLight.ambient[ 2 ]; - glColor4ub( r, g, b, linealpha ); // przezroczystosc dalekiej linii - GfxRenderer.Bind( 0 ); - - glCallList( DisplayListID ); - } - } - // GL_TRIANGLE etc - else { - glCallList( DisplayListID ); - } - - SetLastUsage(Timer::GetSimulationTime()); - } - -#ifdef _PROBLEND - if ((PROBLEND)) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012 - { - glEnable(GL_BLEND); - glAlphaFunc(GL_GREATER, 0.04f); - } -#endif -} -#endif - //------------------------------------------------------------------------------ //------------------ Podstawowy pojemnik terenu - sektor ----------------------- //------------------------------------------------------------------------------ @@ -701,7 +408,6 @@ void TSubRect::NodeAdd(TGroundNode *Node) // nRenderAlpha - lista grup renderowanych z własnych VBO albo DL z przezroczystością // nRenderWires - lista grup renderowanych z własnych VBO albo DL - druty i linie // nMeshed - obiekty do pogrupowania wg tekstur - GLuint t; // pomocniczy kod tekstury switch (Node->iType) { case TP_SOUND: // te obiekty są sprawdzanie niezależnie od kierunku patrzenia @@ -720,7 +426,7 @@ void TSubRect::NodeAdd(TGroundNode *Node) else { // tory nieruchome mogą być pogrupowane wg tekstury, przy VBO wszystkie Node->TextureID = Node->pTrack->TextureGet(0); // pobranie tekstury do sortowania - t = Node->pTrack->TextureGet(1); + GLuint t = Node->pTrack->TextureGet(1); if (Node->TextureID) // jeżeli jest pierwsza { if (t && (Node->TextureID != t)) @@ -757,6 +463,7 @@ void TSubRect::NodeAdd(TGroundNode *Node) Node->nNext3 = nRenderRectAlpha; nRenderRectAlpha = Node; } // DL: do przezroczystych z sektora +#ifdef EU07_USE_OLD_RENDERCODE else if (Global::bUseVBO) { Node->nNext3 = nRenderRect; @@ -767,23 +474,12 @@ void TSubRect::NodeAdd(TGroundNode *Node) Node->nNext3 = nRender; nRender = Node; } // DL: do nieprzezroczystych wszelakich - /* - //Ra: na razie wyłączone do testów VBO - //if - ((Node->iType==GL_TRIANGLE_STRIP)||(Node->iType==GL_TRIANGLE_FAN)||(Node->iType==GL_TRIANGLES)) - if (Node->fSquareMinRadius==0.0) //znikające z bliska nie mogą być optymalizowane - if (Node->fSquareRadius>=160000.0) //tak od 400m to już normalne trójkąty muszą być - //if (Node->iFlags&0x10) //i nieprzezroczysty - {if (pTriGroup) //jeżeli był już jakiś grupujący - {if (pTriGroup->fSquareRadius>Node->fSquareRadius) //i miał większy zasięg - Node->fSquareRadius=pTriGroup->fSquareRadius; //zwiększenie zakresu widoczności - grupującego - pTriGroup->pTriGroup=Node; //poprzedniemu doczepiamy nowy - } - Node->pTriGroup=Node; //nowy lider ma się sam wyświetlać - wskaźnik na siebie - pTriGroup=Node; //zapamiętanie lidera - } - */ +#else + else { + Node->nNext3 = nRenderRect; + nRenderRect = Node; + } // do nieprzezroczystych z sektora +#endif break; case TP_TRACTION: case GL_LINES: @@ -834,6 +530,7 @@ void TSubRect::RaNodeAdd(TGroundNode *Node) switch (Node->iType) { case TP_TRACK: +#ifdef EU07_USE_OLD_RENDERCODE if (Global::bUseVBO) { Node->nNext3 = nRenderRect; @@ -844,6 +541,10 @@ void TSubRect::RaNodeAdd(TGroundNode *Node) Node->nNext3 = nRender; nRender = Node; } // DL: do nieprzezroczystych +#else + Node->nNext3 = nRenderRect; + nRenderRect = Node; +#endif break; case GL_TRIANGLE_STRIP: case GL_TRIANGLE_FAN: @@ -853,6 +554,7 @@ void TSubRect::RaNodeAdd(TGroundNode *Node) Node->nNext3 = nRenderRectAlpha; nRenderRectAlpha = Node; } // DL: do przezroczystych z sektora +#ifdef EU07_USE_OLD_RENDERCODE else if (Global::bUseVBO) { Node->nNext3 = nRenderRect; @@ -863,6 +565,12 @@ void TSubRect::RaNodeAdd(TGroundNode *Node) Node->nNext3 = nRender; nRender = Node; } // DL: do nieprzezroczystych wszelakich +#else + else { + Node->nNext3 = nRenderRect; + nRenderRect = Node; + } // do nieprzezroczystych z sektora +#endif break; case TP_MODEL: // modele zawsze wyświetlane z własnego VBO if ((Node->iFlags & 0x20200020) == 0) // czy brak przezroczystości? @@ -1003,7 +711,7 @@ bool TSubRect::RaTrackAnimAdd(TTrack *t) void TSubRect::RaAnimate() { // wykonanie animacji - if( !tTrackAnim ) { + if( tTrackAnim == nullptr ) { // nie ma nic do animowania return; } @@ -1075,7 +783,7 @@ void TSubRect::LoadNodes() } n = n->nNext2; // następny z sektora } - if (!m_nVertexCount) + if (m_nVertexCount <= 0) return; // jeśli nie ma obiektów do wyświetlenia z VBO, to koniec if (Global::bUseVBO) { // tylko liczenie wierzchołów, gdy nie ma VBO @@ -1146,6 +854,12 @@ 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) @@ -1160,44 +874,6 @@ void TSubRect::RenderDL() } } #endif -/* - 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() @@ -1215,7 +891,9 @@ 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 ) @@ -1285,6 +963,7 @@ 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) @@ -1307,6 +986,18 @@ void TGroundRect::RenderDL() GfxRenderer.Render( nRootMesh ); iLastDisplay = iFrameNumber; // drugi raz nie potrzeba } +#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() @@ -1314,10 +1005,14 @@ void TGroundRect::RenderVBO() if (iLastDisplay != iFrameNumber) { // tylko jezeli dany kwadrat nie był jeszcze renderowany LoadNodes(); // ewentualne tworzenie siatek - if (StartVBO()) + 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; } @@ -4619,220 +4314,6 @@ bool TGround::GetTraction(TDynamicObject *model) return true; }; -bool -TGround::Render( 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; - } - return true; -} - -bool TGround::RenderDL(vector3 pPosition) -{ // renderowanie scenerii z Display List - faza nieprzezroczystych - glDisable(GL_BLEND); - glAlphaFunc(GL_GREATER, 0.50f); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f - ++TGroundRect::iFrameNumber; // zwięszenie licznika ramek (do usuwniania nadanimacji) - CameraDirection.x = sin(Global::pCameraRotation); // wektor kierunkowy - CameraDirection.z = cos(Global::pCameraRotation); - TGroundNode *node; - glColor3f(1.0f, 1.0f, 1.0f); - glEnable(GL_LIGHTING); - int n = 2 * iNumSubRects; //(2*==2km) promień wyświetlanej mapy w sektorach - int c = GetColFromX(pPosition.x); - int r = GetRowFromZ(pPosition.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 - } - // renderowanie progresywne - zależne od FPS oraz kierunku patrzenia - iRendered = 0; // ilość renderowanych sektorów - vector3 direction; - for (k = 0; k < Global::iSegmentsRendered; ++k) // sektory w kolejności odległości - { // przerobione na użycie SectorOrder - i = SectorOrder[k].x; // na starcie oba >=0 - j = SectorOrder[k].y; - do - { - if (j <= 0) - i = -i; // pierwszy przebieg: j<=0, i>=0; drugi: j>=0, i<=0; trzeci: j<=0, i<=0 - // czwarty: j>=0, i>=0; - j = -j; // i oraz j musi być zmienione wcześniej, żeby continue działało - direction = vector3(i, 0, j); // wektor od kamery do danego sektora - if (LengthSquared3(direction) > 5) // te blisko są zawsze wyświetlane - { - direction = SafeNormalize(direction); // normalizacja - 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 - } while ((i < 0) || (j < 0)); // są 4 przypadki, oprócz i=j=0 - } - for (i = 0; i < iRendered; i++) - pRendered[i]->RenderDL(); // renderowanie nieprzezroczystych - return true; -} - -bool TGround::RenderAlphaDL(vector3 pPosition) -{ // renderowanie scenerii z Display List - faza przezroczystych - glEnable(GL_BLEND); - glAlphaFunc(GL_GREATER, 0.04f); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f - TGroundNode *node; - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - TSubRect *tmp; - // Ra: renderowanie progresywne - zależne od FPS oraz kierunku patrzenia - int i; - for (i = iRendered - 1; i >= 0; --i) // od najdalszych - { // przezroczyste trójkąty w oddzielnym cyklu przed modelami - tmp = pRendered[i]; - for( node = tmp->nRenderRectAlpha; node; node = node->nNext3 ) - GfxRenderer.Render_Alpha( node ); // przezroczyste modele - } - for (i = iRendered - 1; i >= 0; --i) // od najdalszych - { // renderowanie przezroczystych modeli oraz pojazdów - pRendered[i]->RenderAlphaDL(); - } - glDisable(GL_LIGHTING); // linie nie powinny świecić - for (i = iRendered - 1; i >= 0; --i) // od najdalszych - { // druty na końcu, żeby się nie robiły białe plamy na tle lasu - tmp = pRendered[i]; - for( node = tmp->nRenderWires; node; node = node->nNext3 ) - GfxRenderer.Render_Alpha( node ); // druty - } - return true; -} - -bool TGround::RenderVBO(vector3 pPosition) -{ // renderowanie scenerii z VBO - faza nieprzezroczystych - glDisable(GL_BLEND); - glAlphaFunc(GL_GREATER, 0.50f); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f - ++TGroundRect::iFrameNumber; // zwięszenie licznika ramek - CameraDirection.x = sin(Global::pCameraRotation); // wektor kierunkowy - CameraDirection.z = cos(Global::pCameraRotation); - TGroundNode *node; - glColor3f(1.0f, 1.0f, 1.0f); - glEnable(GL_LIGHTING); - int n = 2 * iNumSubRects; //(2*==2km) promień wyświetlanej mapy w sektorach - int c = GetColFromX(pPosition.x); - int r = GetRowFromZ(pPosition.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) - { - 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 - } - } - // renderowanie progresywne - zależne od FPS oraz kierunku patrzenia - iRendered = 0; // ilość renderowanych sektorów - vector3 direction; - for (k = 0; k < Global::iSegmentsRendered; ++k) // sektory w kolejności odległości - { // przerobione na użycie SectorOrder - i = SectorOrder[k].x; // na starcie oba >=0 - j = SectorOrder[k].y; - do - { - if (j <= 0) - i = -i; // pierwszy przebieg: j<=0, i>=0; drugi: j>=0, i<=0; trzeci: j<=0, i<=0 - // czwarty: j>=0, i>=0; - j = -j; // i oraz j musi być zmienione wcześniej, żeby continue działało - direction = vector3(i, 0, j); // wektor od kamery do danego sektora - if (LengthSquared3(direction) > 5) // te blisko są zawsze wyświetlane - { - direction = SafeNormalize(direction); // normalizacja - if (CameraDirection.x * direction.x + CameraDirection.z * direction.z < 0.55) - continue; // pomijanie sektorów poza kątem patrzenia - } - Rects[(i + c) / iNumSubRects][(j + r) / iNumSubRects] - .RenderVBO(); // kwadrat kilometrowy nie zawsze, bo szkoda FPS - if ((tmp = FastGetSubRect(i + c, j + r)) != NULL) - if (tmp->iNodeCount) // jeżeli są jakieś obiekty, bo po co puste sektory przelatywać - pRendered[iRendered++] = tmp; // tworzenie listy sektorów do renderowania - } while ((i < 0) || (j < 0)); // są 4 przypadki, oprócz i=j=0 - } - // dodać rednerowanie terenu z E3D - jedno VBO jest używane dla całego modelu, chyba że jest ich - // więcej - if (Global::pTerrainCompact) - Global::pTerrainCompact->TerrainRenderVBO(TGroundRect::iFrameNumber); - for (i = 0; i < iRendered; i++) - { // renderowanie nieprzezroczystych - pRendered[i]->RenderVBO(); - } - return true; -} - -bool TGround::RenderAlphaVBO(vector3 pPosition) -{ // renderowanie scenerii z VBO - faza przezroczystych - glEnable(GL_BLEND); - glAlphaFunc(GL_GREATER, 0.04f); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f - TGroundNode *node; - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - TSubRect *tmp; - int i; - for (i = iRendered - 1; i >= 0; --i) // od najdalszych - { // renderowanie przezroczystych trójkątów sektora - tmp = pRendered[i]; - tmp->LoadNodes(); // ewentualne tworzenie siatek - if (tmp->StartVBO()) - { - for( node = tmp->nRenderRectAlpha; node; node = node->nNext3 ) - if( node->iVboPtr >= 0 ) - GfxRenderer.Render_Alpha( node ); // nieprzezroczyste obiekty terenu - tmp->EndVBO(); - } - } - for (i = iRendered - 1; i >= 0; --i) // od najdalszych - pRendered[i]->RenderAlphaVBO(); // przezroczyste modeli oraz pojazdy - glDisable(GL_LIGHTING); // linie nie powinny świecić - for (i = iRendered - 1; i >= 0; --i) // od najdalszych - { // druty na końcu, żeby się nie robiły białe plamy na tle lasu - tmp = pRendered[i]; - if (tmp->StartVBO()) - { - for( node = tmp->nRenderWires; node; node = node->nNext3 ) - GfxRenderer.Render_Alpha( node ); // przezroczyste modele - tmp->EndVBO(); - } - } - return true; -}; - #ifdef _WINDOWS //--------------------------------------------------------------------------- void TGround::Navigate(std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam) diff --git a/Ground.h b/Ground.h index 2fe2b4d6..ee20b738 100644 --- a/Ground.h +++ b/Ground.h @@ -97,8 +97,6 @@ struct TGroundVertex } }; -class TSubRect; // sektor (aktualnie 200m×200m, ale może być zmieniony) - class TGroundNode : public Resource { // obiekt scenerii @@ -216,8 +214,7 @@ class TSubRect : public Resource, public CMesh void Sort(); // optymalizacja obiektów w sektorze (sortowanie wg tekstur) TTrack * FindTrack(vector3 *Point, int &iConnection, TTrack *Exclude); TTraction * FindTraction(vector3 *Point, int &iConnection, TTraction *Exclude); - bool StartVBO(); // ustwienie VBO sektora dla (nRenderRect), (nRenderRectAlpha) i - // (nRenderWires) + 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 @@ -335,11 +332,6 @@ 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 RenderDL(vector3 pPosition); - bool RenderAlphaDL(vector3 pPosition); - bool RenderVBO(vector3 pPosition); - bool RenderAlphaVBO(vector3 pPosition); bool CheckQuery(); TGroundNode * DynamicFindAny(std::string asNameToFind); TGroundNode * DynamicFind(std::string asNameToFind); diff --git a/Track.cpp b/Track.cpp index 9769f613..17cbef7f 100644 --- a/Track.cpp +++ b/Track.cpp @@ -2659,8 +2659,8 @@ bool TTrack::Switch(int i, double t, double d) true) // jeśli nie dodane do animacji { // nie ma się co bawić SwitchExtension->fOffset = SwitchExtension->fDesiredOffset; - RaAnimate(); // przeliczenie położenia iglic; czy zadziała na niewyświetlanym - // sektorze w VBO? + // przeliczenie położenia iglic; czy zadziała na niewyświetlanym sektorze w VBO? + RaAnimate(); } return true; } @@ -2809,8 +2809,8 @@ void TTrack::RaAnimListAdd(TTrack *t) TTrack * TTrack::RaAnimate(GLuint const Vertexbuffer) { // wykonanie rekurencyjne animacji, wywoływane przed wyświetleniem sektora // zwraca wskaźnik toru wymagającego dalszej animacji - if (SwitchExtension->pNextAnim) - SwitchExtension->pNextAnim = SwitchExtension->pNextAnim->RaAnimate(); + if( SwitchExtension->pNextAnim ) + SwitchExtension->pNextAnim = SwitchExtension->pNextAnim->RaAnimate( Vertexbuffer ); bool m = true; // animacja trwa if (eType == tt_Switch) // dla zwrotnicy tylko szyny { diff --git a/Train.cpp b/Train.cpp index b5525474..262f1c0c 100644 --- a/Train.cpp +++ b/Train.cpp @@ -5802,14 +5802,12 @@ bool TTrain::CabChange(int iDirection) DynamicObject->asBaseDir + DynamicObject->MoverParameters->TypeName + ".mmd")) { // zmiana kabiny w ramach tego samego pojazdu - DynamicObject->MoverParameters - ->CabActivisation(); // załączenie rozrządu (wirtualne kabiny) + DynamicObject->MoverParameters->CabActivisation(); // załączenie rozrządu (wirtualne kabiny) + DynamicObject->Mechanik->CheckVehicles( Change_direction ); return true; // udało się zmienić kabinę } - DynamicObject->MoverParameters->CabActivisation(); // aktywizacja - // poprzedniej, bo - // jeszcze nie wiadomo, - // czy jakiś pojazd jest + // aktywizacja poprzedniej, bo jeszcze nie wiadomo, czy jakiś pojazd jest + DynamicObject->MoverParameters->CabActivisation(); } return false; // ewentualna zmiana pojazdu } diff --git a/World.cpp b/World.cpp index b7a11860..5ca62383 100644 --- a/World.cpp +++ b/World.cpp @@ -620,10 +620,6 @@ void TWorld::OnKeyDown(int cKey) else { glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); } -/* - ++Global::iReCompile; // odświeżyć siatki - // Ra: jeszcze usunąć siatki ze skompilowanych obiektów! -*/ } } break; @@ -1750,9 +1746,12 @@ TWorld::Update_UI() { UITable->text_lines.emplace_back( Global::Bezogonkow( "| " + station + " | " + arrival + " | " + departure + " | " + vmax + " | " + tableline->StationWare, true ), - ( ( owner->iStationStart < table->StationIndex ) && ( i < table->StationIndex ) ? - float4( 0.0f, 1.0f, 0.0f, 1.0f ) :// czas minął i odjazd był, to nazwa stacji będzie na zielono - Global::UITextColor ) + ( ( owner->iStationStart < table->StationIndex ) + && ( i < table->StationIndex ) + && ( time.wHour >= tableline->Dh ) + && ( time.wMinute >= tableline->Dm ) ? + float4( 0.0f, 1.0f, 0.0f, 1.0f ) :// czas minął i odjazd był, to nazwa stacji będzie na zielono + Global::UITextColor ) ); // divider/footer UITable->text_lines.emplace_back( "+----------------------------+-------+-------+-----+", Global::UITextColor ); @@ -1995,9 +1994,11 @@ TWorld::Update_UI() { + GfxRenderer.Info(); // dump last opengl error, if any - GLenum glerror = glGetError(); + GLenum glerror = ::glGetError(); if( glerror != GL_NO_ERROR ) { - Global::LastGLError = to_string( glerror ) + " (" + Global::Bezogonkow( (char *)gluErrorString( glerror ) ) + ")"; + std::string glerrorstring( (char *)::gluErrorString( glerror ) ); + win1250_to_ascii( glerrorstring ); + Global::LastGLError = std::to_string( glerror ) + " (" + glerrorstring + ")"; } if( false == Global::LastGLError.empty() ) { uitextline3 = diff --git a/renderer.cpp b/renderer.cpp index bf92c7b9..2fe2ede1 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -13,6 +13,7 @@ http://mozilla.org/MPL/2.0/. #include "globals.h" #include "timer.h" #include "world.h" +#include "data.h" #include "dynobj.h" #include "animmodel.h" #include "traction.h" @@ -146,7 +147,7 @@ opengl_renderer::Render() { m_camera.update_frustum(); Render( &World.Environment ); - World.Ground.Render( World.Camera.Pos ); + Render( &World.Ground ); World.Render_Cab(); @@ -293,7 +294,7 @@ opengl_renderer::Render( world_environment *Environment ) { bool opengl_renderer::Render( TGround *Ground ) { - +/* glDisable( GL_BLEND ); glAlphaFunc( GL_GREATER, 0.50f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f glEnable( GL_LIGHTING ); @@ -315,8 +316,102 @@ opengl_renderer::Render( TGround *Ground ) { } } } +*/ + ::glEnable( GL_LIGHTING ); + ::glDisable( GL_BLEND ); + ::glAlphaFunc( GL_GREATER, 0.50f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f + ::glColor3f( 1.0f, 1.0f, 1.0f ); + + ++TGroundRect::iFrameNumber; // zwięszenie licznika ramek (do usuwniania nadanimacji) + + Update_Lights( Ground->m_lights ); + + Ground->CameraDirection.x = std::sin( Global::pCameraRotation ); // wektor kierunkowy + Ground->CameraDirection.z = std::cos( Global::pCameraRotation ); + TGroundNode *node; + // rednerowanie globalnych (nie za często?) + for( node = Ground->srGlobal.nRenderHidden; node; node = node->nNext3 ) { + node->RenderHidden(); + } + // renderowanie czołgowe dla obiektów aktywnych a niewidocznych + int n = 2 * iNumSubRects; //(2*==2km) promień wyświetlanej mapy w sektorach + int c = Ground->GetColFromX( Global::pCameraPosition.x ); + int r = Ground->GetRowFromZ( Global::pCameraPosition.z ); + TSubRect *tmp; + int i, j, k; + for( j = r - n; j <= r + n; j++ ) { + for( i = c - n; i <= c + n; i++ ) { + if( ( tmp = Ground->FastGetSubRect( i, j ) ) != nullptr ) { + // oznaczanie aktywnych sektorów + tmp->LoadNodes(); + + for( node = tmp->nRenderHidden; node; node = node->nNext3 ) { + node->RenderHidden(); + } + // jeszcze dźwięki pojazdów by się przydały, również niewidocznych + tmp->RenderSounds(); + } + } + } + // renderowanie progresywne - zależne od FPS oraz kierunku patrzenia + Ground->iRendered = 0; // ilość renderowanych sektorów + Math3D::vector3 direction; + for( k = 0; k < Global::iSegmentsRendered; ++k ) // sektory w kolejności odległości + { // przerobione na użycie SectorOrder + i = SectorOrder[ k ].x; // na starcie oba >=0 + j = SectorOrder[ k ].y; + do { + // pierwszy przebieg: j<=0, i>=0; drugi: j>=0, i<=0; trzeci: j<=0, i<=0 czwarty: j>=0, i>=0; + if( j <= 0 ) + i = -i; + j = -j; // i oraz j musi być zmienione wcześniej, żeby continue działało + direction = Math3D::vector3( i, 0, j ); // wektor od kamery do danego sektora + if( Math3D::LengthSquared3( direction ) > 5 ) // te blisko są zawsze wyświetlane + { + direction = Math3D::SafeNormalize( direction ); // normalizacja + if( Ground->CameraDirection.x * direction.x + Ground->CameraDirection.z * direction.z < 0.55 ) + continue; // pomijanie sektorów poza kątem patrzenia + } + // kwadrat kilometrowy nie zawsze, bo szkoda FPS + if( Global::bUseVBO ) { + // vbo render path + Ground->Rects[ ( i + c ) / iNumSubRects ][ ( j + r ) / iNumSubRects ].RenderVBO(); + } + else { + // display list render path + Ground->Rects[ ( i + c ) / iNumSubRects ][ ( j + r ) / iNumSubRects ].RenderDL(); + } + if( ( tmp = Ground->FastGetSubRect( i + c, j + r ) ) != nullptr ) { + if( tmp->iNodeCount ) { + // o ile są jakieś obiekty, bo po co puste sektory przelatywać + Ground->pRendered[ Ground->iRendered++ ] = tmp; // tworzenie listy sektorów do renderowania + } + } + } while( ( i < 0 ) || ( j < 0 ) ); // są 4 przypadki, oprócz i=j=0 + } + + // dodać renderowanie terenu z E3D - jedno VBO jest używane dla całego modelu, chyba że jest ich więcej + if( Global::bUseVBO ) { + if( Global::pTerrainCompact ) { + Global::pTerrainCompact->TerrainRenderVBO( TGroundRect::iFrameNumber ); + } + } + + // 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(); + } + } + + // regular render takes care of all solid geometry present in the scene, thus we can launch alpha parts render here + return Render_Alpha( Ground ); - return true; } bool @@ -431,7 +526,12 @@ opengl_renderer::Render( TGroundNode *Node ) { } else { // display list render path - ::glCallList( Node->DisplayListID ); + if( Node->DisplayListID != 0 ) { + ::glCallList( Node->DisplayListID ); + } + else { + return false; + } } return true; } @@ -730,6 +830,75 @@ opengl_renderer::Render( TMemCell *Memcell ) { ::glPopAttrib(); } +bool +opengl_renderer::Render_Alpha( TGround *Ground ) { + + // legacy version of the code: + ::glEnable( GL_BLEND ); + ::glAlphaFunc( GL_GREATER, 0.04f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f + ::glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); + + TGroundNode *node; + TSubRect *tmp; + // Ra: renderowanie progresywne - zależne od FPS oraz kierunku patrzenia + for( int i = Ground->iRendered - 1; i >= 0; --i ) // od najdalszych + { // przezroczyste trójkąty w oddzielnym cyklu przed modelami + tmp = Ground->pRendered[ i ]; + if( Global::bUseVBO ) { + // vbo render path + if( tmp->StartVBO() ) { + for( node = tmp->nRenderRectAlpha; node; node = node->nNext3 ) { + if( node->iVboPtr >= 0 ) { + Render_Alpha( node ); + } + } + tmp->EndVBO(); + } + } + else { + // display list render path + for( node = tmp->nRenderRectAlpha; node; node = node->nNext3 ) { + Render_Alpha( node ); + } + } + } + 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(); + } + } + + ::glDisable( GL_LIGHTING ); // linie nie powinny świecić + + for( int i = Ground->iRendered - 1; i >= 0; --i ) // od najdalszych + { // druty na końcu, żeby się nie robiły białe plamy na tle lasu + tmp = Ground->pRendered[ i ]; + if( Global::bUseVBO ) { + // vbo render path + if( tmp->StartVBO() ) { + for( node = tmp->nRenderWires; node; node = node->nNext3 ) { + Render_Alpha( node ); + } + tmp->EndVBO(); + } + } + else { + // display list render path + for( node = tmp->nRenderWires; node; node = node->nNext3 ) { + Render_Alpha( node ); // druty + } + } + } + + return true; +} + // NOTE: legacy render system switch #define _PROBLEND diff --git a/renderer.h b/renderer.h index d14f2995..65531612 100644 --- a/renderer.h +++ b/renderer.h @@ -136,6 +136,8 @@ public: Render( TSubModel *Submodel ); void Render( TMemCell *Memcell ); + bool + Render_Alpha( TGround *Ground ); bool Render_Alpha( TGroundNode *Node ); bool diff --git a/version.h b/version.h index 866a8597..5ecf5416 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #pragma once #define VERSION_MAJOR 17 -#define VERSION_MINOR 516 +#define VERSION_MINOR 517 #define VERSION_REVISION 0