16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-22 15:09:19 +02:00

build 170517. minor ai tweaks, scan direction update fix

This commit is contained in:
tmj-fstate
2017-05-18 01:52:04 +02:00
parent 23f4892bcc
commit c6fbfbbb29
10 changed files with 332 additions and 664 deletions

View File

@@ -82,8 +82,8 @@ Tutaj łączymy teorię z praktyką - tu nic nie działa i nikt nie wie dlaczego
// stałe // stałe
const double EasyReactionTime = 0.5; //[s] przebłyski świadomości dla zwykłej jazdy const double EasyReactionTime = 0.5; //[s] przebłyski świadomości dla zwykłej jazdy
const double HardReactionTime = 0.2; const double HardReactionTime = 0.2;
const double EasyAcceleration = 0.5; //[m/ss] const double EasyAcceleration = 0.85; //[m/ss]
const double HardAcceleration = 0.9; const double HardAcceleration = 9.81;
const double PrepareTime = 2.0; //[s] przebłyski świadomości przy odpalaniu const double PrepareTime = 2.0; //[s] przebłyski świadomości przy odpalaniu
bool WriteLogFlag = false; bool WriteLogFlag = false;
@@ -450,7 +450,7 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
TEvent *pEvent{ nullptr }; TEvent *pEvent{ nullptr };
double fLastDir{ 0.0 }; double fLastDir{ 0.0 };
if (iTableDirection != iDirection) { if (iTableDirection != iDirection ) {
// jeśli zmiana kierunku, zaczynamy od toru ze wskazanym pojazdem // jeśli zmiana kierunku, zaczynamy od toru ze wskazanym pojazdem
iTableDirection = iDirection; // ustalenie w jakim kierunku jest wypełniana tabelka względem pojazdu iTableDirection = iDirection; // ustalenie w jakim kierunku jest wypełniana tabelka względem pojazdu
pTrack = pVehicle->RaTrackGet(); // odcinek, na którym stoi pTrack = pVehicle->RaTrackGet(); // odcinek, na którym stoi
@@ -468,6 +468,7 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
SemNextStopIndex = -1; SemNextStopIndex = -1;
} }
else { else {
if( iTableDirection == 0 ) { return; }
// kontynuacja skanowania od ostatnio sprawdzonego toru (w ostatniej pozycji zawsze jest tor) // kontynuacja skanowania od ostatnio sprawdzonego toru (w ostatniej pozycji zawsze jest tor)
if( ( SemNextStopIndex != -1 ) if( ( SemNextStopIndex != -1 )
&& ( sSpeedTable[SemNextStopIndex].fVelNext < 1.0 ) ) { && ( sSpeedTable[SemNextStopIndex].fVelNext < 1.0 ) ) {
@@ -501,6 +502,11 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
pTrack->Length() ); pTrack->Length() );
} }
if( iTableDirection == 0 ) {
// don't bother
return;
}
if( fCurrentDistance >= fDistance ) { if( fCurrentDistance >= fDistance ) {
// all done // all done
return; 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) bool TController::CheckVehicles(TOrders user)
{ // sprawdzenie stanu posiadanych pojazdów w składzie i zapalenie świateł { // sprawdzenie stanu posiadanych pojazdów w składzie i zapalenie świateł
TDynamicObject *p; // roboczy wskaźnik na pojazd TDynamicObject *p; // roboczy wskaźnik na pojazd
iVehicles = 0; // ilość pojazdów w składzie iVehicles = 0; // ilość pojazdów w składzie
int d = mvOccupied->DirAbsolute; // który sprzęg jest z przodu int d = CheckDirection();
if (!d) // jeśli nie ma ustalonego kierunku
d = mvOccupied->CabNo; // to jedziemy wg aktualnej kabiny
iDirection = d; // ustalenie kierunku jazdy (powinno zrobić PrepareEngine?)
d = d >= 0 ? 0 : 1; // kierunek szukania czoła (numer sprzęgu) d = d >= 0 ? 0 : 1; // kierunek szukania czoła (numer sprzęgu)
pVehicles[0] = p = pVehicle->FirstFind(d); // pojazd na czele składu pVehicles[0] = p = pVehicle->FirstFind(d); // pojazd na czele składu
// liczenie pojazdów w składzie i ustalenie parametrów // liczenie pojazdów w składzie i ustalenie parametrów
@@ -2058,20 +2070,22 @@ bool TController::PrepareEngine()
mvOccupied->BatterySwitch(true); mvOccupied->BatterySwitch(true);
if (mvControlling->EnginePowerSource.SourceType == CurrentCollector) if (mvControlling->EnginePowerSource.SourceType == CurrentCollector)
{ // jeśli silnikowy jest pantografującym { // jeśli silnikowy jest pantografującym
if (mvControlling->PantPress > 4.3) mvControlling->PantFront( true );
{ // jeżeli jest wystarczające ciśnienie w pantografach 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) || if ((!mvControlling->bPantKurek3) ||
(mvControlling->PantPress <= (mvControlling->PantPress <=
mvControlling->ScndPipePress)) // kurek przełączony albo główna już pompuje mvControlling->ScndPipePress)) // kurek przełączony albo główna już pompuje
mvControlling->PantCompFlag = false; // sprężarkę pantografów można już wyłączyć 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) // if (mvOccupied->TrainType==dt_EZT)
@@ -2352,11 +2366,19 @@ bool TController::IncSpeed()
if (tsGuardSignal->GetStatus() & DSBSTATUS_PLAYING) // jeśli gada, to nie jedziemy if (tsGuardSignal->GetStatus() & DSBSTATUS_PLAYING) // jeśli gada, to nie jedziemy
return false; return false;
bool OK = true; bool OK = true;
if ( ( iDrivigFlags & moveDoorOpened ) if( ( iDrivigFlags & moveDoorOpened )
&& ( VelDesired > 0.0 ) ) // to prevent door shuffle on stop && ( VelDesired > 0.0 ) ) { // to prevent door shuffle on stop
Doors(false); // zamykanie drzwi - tutaj wykonuje tylko AI (zmienia fActionTime) // zamykanie drzwi - tutaj wykonuje tylko AI (zmienia fActionTime)
if (fActionTime < 0.0) // gdy jest nakaz poczekać z jazdą, to nie ruszać Doors( false );
}
if( fActionTime < 0.0 ) {
// gdy jest nakaz poczekać z jazdą, to nie ruszać
return false; return false;
}
if( true == mvOccupied->DepartureSignal ) {
// shut off departure warning
mvOccupied->DepartureSignal = false;
}
if (mvControlling->SlippingWheels) if (mvControlling->SlippingWheels)
return false; // jak poślizg, to nie przyspieszamy return false; // jak poślizg, to nie przyspieszamy
switch (mvOccupied->EngineType) switch (mvOccupied->EngineType)
@@ -2528,8 +2550,6 @@ void TController::SpeedSet()
switch (mvOccupied->EngineType) switch (mvOccupied->EngineType)
{ {
case None: // McZapkie-041003: wagon sterowniczy case None: // McZapkie-041003: wagon sterowniczy
if (fActionTime >= -1.0)
mvOccupied->DepartureSignal = false; // trochę niech pobuczy, zanim pojedzie
if (mvControlling->MainCtrlPosNo > 0) if (mvControlling->MainCtrlPosNo > 0)
{ // jeśli ma czym kręcić { // jeśli ma czym kręcić
// TODO: sprawdzanie innego czlonu //if (!FuseFlagCheck()) // TODO: sprawdzanie innego czlonu //if (!FuseFlagCheck())
@@ -2714,17 +2734,24 @@ void TController::Doors(bool what)
{ // zamykanie { // zamykanie
if (mvOccupied->DoorOpenCtrl == 1) if (mvOccupied->DoorOpenCtrl == 1)
{ // jeśli drzwi sterowane z kabiny { // jeśli drzwi sterowane z kabiny
if (AIControllFlag) if( AIControllFlag ) {
if (mvOccupied->DoorLeftOpened || mvOccupied->DoorRightOpened) if( mvOccupied->DoorLeftOpened || mvOccupied->DoorRightOpened ) { // AI zamyka drzwi przed odjazdem
{ // AI zamyka drzwi przed odjazdem if( ( true == mvOccupied->DoorClosureWarning )
if (mvOccupied->DoorClosureWarning) && ( false == mvOccupied->DepartureSignal )
&& ( true == TestFlag( iDrivigFlags, moveDoorOpened ) ) ) {
mvOccupied->DepartureSignal = true; // załącenie bzyczka mvOccupied->DepartureSignal = true; // załącenie bzyczka
mvOccupied->DoorLeft(false); // zamykanie drzwi fActionTime = -3.0 - 0.1 * Random( 10 ); // 3-4 second wait
mvOccupied->DoorRight(false); }
if( fActionTime > -0.5 ) {
// Ra: trzeba by ustawić jakiś czas oczekiwania na zamknięcie się drzwi // 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 mvOccupied->DoorLeft( false ); // zamykanie drzwi
iDrivigFlags &= ~moveDoorOpened; // nie wykonywać drugi raz mvOccupied->DoorRight( false );
iDrivigFlags &= ~moveDoorOpened;
// 1.5-2.5 sec wait, +potentially 0.5 remaining
fActionTime = -1.5 - 0.1 * Random( 10 );
}
} }
}
} }
else else
{ // jeśli nie, to zamykanie w składzie wagonowym { // 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) 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 // 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 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 (mvControlling->EnginePowerSource.SourceType == CurrentCollector)
{ {
if (mvOccupied->ScndPipePress > 4.3) // gdy główna sprężarka bezpiecznie nabije if (mvOccupied->ScndPipePress > 4.3) // gdy główna sprężarka bezpiecznie nabije ciśnienie
// ciśnienie mvControlling->bPantKurek3 = true; // to można przestawić kurek na zasilanie pantografów z głównej pneumatyki
mvControlling->bPantKurek3 =
true; // to można przestawić kurek na zasilanie pantografów z głównej pneumatyki
fVoltage = fVoltage =
0.5 * (fVoltage + 0.5 * (fVoltage +
fabs(mvControlling->RunningTraction.TractionVoltage)); // uśrednione napięcie fabs(mvControlling->RunningTraction.TractionVoltage)); // uśrednione napięcie
// sieci: przy spadku // sieci: przy spadku poniżej wartości minimalnej opóźnić rozruch o losowy czas
// poniżej wartości
// minimalnej opóźnić
// rozruch o losowy
// czas
if (fVoltage < mvControlling->EnginePowerSource.CollectorParameters if (fVoltage < mvControlling->EnginePowerSource.CollectorParameters
.MinV) // gdy rozłączenie WS z powodu niskiego napięcia .MinV) // gdy rozłączenie WS z powodu niskiego napięcia
if (fActionTime >= 0) // jeśli czas oczekiwania nie został ustawiony if (fActionTime >= 0) // jeśli czas oczekiwania nie został ustawiony

View File

@@ -320,9 +320,11 @@ class TController
// procedury dotyczace rozkazow dla maszynisty // procedury dotyczace rozkazow dla maszynisty
void SetVelocity(double NewVel, double NewVelNext, void SetVelocity(double NewVel, double NewVelNext,
TStopReason r = stopNone); // uaktualnia informacje o prędkości TStopReason r = stopNone); // uaktualnia informacje o prędkości
/*
bool SetProximityVelocity( bool SetProximityVelocity(
double NewDist, double NewDist,
double NewVelNext); // uaktualnia informacje o prędkości przy nastepnym semaforze double NewVelNext); // uaktualnia informacje o prędkości przy nastepnym semaforze
*/
public: public:
void JumpToNextOrder(); void JumpToNextOrder();
void JumpToFirstOrder(); void JumpToFirstOrder();
@@ -331,6 +333,7 @@ class TController
inline TOrders OrderCurrentGet(); inline TOrders OrderCurrentGet();
inline TOrders OrderNextGet(); inline TOrders OrderNextGet();
bool CheckVehicles(TOrders user = Wait_for_orders); bool CheckVehicles(TOrders user = Wait_for_orders);
int CheckDirection();
private: private:
void CloseLog(); void CloseLog();
@@ -351,21 +354,22 @@ class TController
void DirectionForward(bool forward); void DirectionForward(bool forward);
int OrderDirectionChange(int newdir, TMoverParameters *Vehicle); int OrderDirectionChange(int newdir, TMoverParameters *Vehicle);
void Lights(int head, int rear); 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 private: // Ra: metody obsługujące skanowanie toru
TEvent *CheckTrackEvent(double fDirection, TTrack *Track); TEvent *CheckTrackEvent(double fDirection, TTrack *Track);
bool TableCheckEvent(TEvent *e); // bool TableCheckEvent(TEvent *e);
bool TableAddNew(); bool TableAddNew();
bool TableNotFound(TEvent const *Event) const; 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 TableTraceRoute(double fDistance, TDynamicObject *pVehicle = NULL);
void TableCheck(double fDistance); void TableCheck(double fDistance);
TCommandType TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc); TCommandType TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc);
void TablePurger(); void TablePurger();
public: public:
std::size_t TableSize() const { return sSpeedTable.size(); } 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 private: // Ra: stare funkcje skanujące, używane do szukania sygnalizatora z tyłu
bool BackwardTrackBusy(TTrack *Track); bool BackwardTrackBusy(TTrack *Track);

View File

@@ -50,6 +50,9 @@ extern "C"
bool bCondition; // McZapkie: do testowania warunku na event multiple bool bCondition; // McZapkie: do testowania warunku na event multiple
std::string LogComment; 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, // Obiekt renderujący siatkę jest sztucznie tworzonym obiektem pomocniczym,
// grupującym siatki obiektów dla danej tekstury. Obiektami składowymi mogą // 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 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) void TGroundNode::Compile(bool many)
{ // tworzenie skompilowanej listy w wyświetlaniu DL { // tworzenie skompilowanej listy w wyświetlaniu DL
if (!many) if (!many)
@@ -444,34 +308,32 @@ void TGroundNode::Compile(bool many)
if ((iType == GL_LINES) || (iType == GL_LINE_STRIP) || (iType == GL_LINE_LOOP)) if ((iType == GL_LINES) || (iType == GL_LINE_STRIP) || (iType == GL_LINE_LOOP))
{ {
glBegin(iType); glBegin(iType);
for (int i = 0; i < iNumPts; i++) for (int i = 0; i < iNumPts; ++i)
glVertex3dv(&Points[i].x); glVertex3dv(&Points[i].x);
glEnd(); glEnd();
} }
else if (iType == GL_TRIANGLE_STRIP || iType == GL_TRIANGLE_FAN || iType == GL_TRIANGLES) else if (iType == GL_TRIANGLE_STRIP || iType == GL_TRIANGLE_FAN || iType == GL_TRIANGLES)
{ // jak nie linie, to trójkąty { // jak nie linie, to trójkąty
TGroundNode *tri = this; // TODO: eliminate these calls, they're duplicated by setup part in the unified render function
do #ifdef EU07_USE_OLD_RENDERCODE
{ // pętla po obiektach w grupie w celu połączenia siatek glColor3ub(Diffuse[0], Diffuse[1], Diffuse[2]);
// TODO: eliminate these calls, they're duplicated by setup part in the unified render function GfxRenderer.Bind(TextureID);
glColor3ub(tri->Diffuse[0], tri->Diffuse[1], tri->Diffuse[2]); #endif
GfxRenderer.Bind(Global::bWireFrame ? 0 : tri->TextureID); glBegin(iType);
for (int i = 0; i < iNumVerts; ++i)
glBegin(Global::bWireFrame ? GL_LINE_LOOP : tri->iType); {
for (int i = 0; i < tri->iNumVerts; i++) glNormal3dv(&Vertices[i].Normal.x);
{ glTexCoord2f(Vertices[i].tu, Vertices[i].tv);
glNormal3dv(&tri->Vertices[i].Normal.x); glVertex3dv(&Vertices[i].Point.x);
glTexCoord2f(tri->Vertices[i].tu, tri->Vertices[i].tv); };
glVertex3dv(&tri->Vertices[i].Point.x); glEnd();
};
glEnd();
tri = NULL; // a jak nie, to koniec
} while (tri);
} }
else if (iType == TP_MESH) else if (iType == TP_MESH)
{ // grupa ze wspólną teksturą - wrzucanie do wspólnego Display List { // grupa ze wspólną teksturą - wrzucanie do wspólnego Display List
#ifdef EU07_USE_OLD_RENDERCODE
if (TextureID) if (TextureID)
GfxRenderer.Bind(TextureID); // Ustaw aktywną teksturę GfxRenderer.Bind(TextureID); // Ustaw aktywną teksturę
#endif
TGroundNode *n = nNode; TGroundNode *n = nNode;
while (n ? n->TextureID == TextureID : false) while (n ? n->TextureID == TextureID : false)
{ // wszystkie obiekty o tej samej testurze { // 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 ----------------------- //------------------ 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ą // 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 // nRenderWires - lista grup renderowanych z własnych VBO albo DL - druty i linie
// nMeshed - obiekty do pogrupowania wg tekstur // nMeshed - obiekty do pogrupowania wg tekstur
GLuint t; // pomocniczy kod tekstury
switch (Node->iType) switch (Node->iType)
{ {
case TP_SOUND: // te obiekty są sprawdzanie niezależnie od kierunku patrzenia case TP_SOUND: // te obiekty są sprawdzanie niezależnie od kierunku patrzenia
@@ -720,7 +426,7 @@ void TSubRect::NodeAdd(TGroundNode *Node)
else else
{ // tory nieruchome mogą być pogrupowane wg tekstury, przy VBO wszystkie { // tory nieruchome mogą być pogrupowane wg tekstury, przy VBO wszystkie
Node->TextureID = Node->pTrack->TextureGet(0); // pobranie tekstury do sortowania 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 (Node->TextureID) // jeżeli jest pierwsza
{ {
if (t && (Node->TextureID != t)) if (t && (Node->TextureID != t))
@@ -757,6 +463,7 @@ void TSubRect::NodeAdd(TGroundNode *Node)
Node->nNext3 = nRenderRectAlpha; Node->nNext3 = nRenderRectAlpha;
nRenderRectAlpha = Node; nRenderRectAlpha = Node;
} // DL: do przezroczystych z sektora } // DL: do przezroczystych z sektora
#ifdef EU07_USE_OLD_RENDERCODE
else if (Global::bUseVBO) else if (Global::bUseVBO)
{ {
Node->nNext3 = nRenderRect; Node->nNext3 = nRenderRect;
@@ -767,23 +474,12 @@ void TSubRect::NodeAdd(TGroundNode *Node)
Node->nNext3 = nRender; Node->nNext3 = nRender;
nRender = Node; nRender = Node;
} // DL: do nieprzezroczystych wszelakich } // DL: do nieprzezroczystych wszelakich
/* #else
//Ra: na razie wyłączone do testów VBO else {
//if Node->nNext3 = nRenderRect;
((Node->iType==GL_TRIANGLE_STRIP)||(Node->iType==GL_TRIANGLE_FAN)||(Node->iType==GL_TRIANGLES)) nRenderRect = Node;
if (Node->fSquareMinRadius==0.0) //znikające z bliska nie mogą być optymalizowane } // do nieprzezroczystych z sektora
if (Node->fSquareRadius>=160000.0) //tak od 400m to już normalne trójkąty muszą być #endif
//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
}
*/
break; break;
case TP_TRACTION: case TP_TRACTION:
case GL_LINES: case GL_LINES:
@@ -834,6 +530,7 @@ void TSubRect::RaNodeAdd(TGroundNode *Node)
switch (Node->iType) switch (Node->iType)
{ {
case TP_TRACK: case TP_TRACK:
#ifdef EU07_USE_OLD_RENDERCODE
if (Global::bUseVBO) if (Global::bUseVBO)
{ {
Node->nNext3 = nRenderRect; Node->nNext3 = nRenderRect;
@@ -844,6 +541,10 @@ void TSubRect::RaNodeAdd(TGroundNode *Node)
Node->nNext3 = nRender; Node->nNext3 = nRender;
nRender = Node; nRender = Node;
} // DL: do nieprzezroczystych } // DL: do nieprzezroczystych
#else
Node->nNext3 = nRenderRect;
nRenderRect = Node;
#endif
break; break;
case GL_TRIANGLE_STRIP: case GL_TRIANGLE_STRIP:
case GL_TRIANGLE_FAN: case GL_TRIANGLE_FAN:
@@ -853,6 +554,7 @@ void TSubRect::RaNodeAdd(TGroundNode *Node)
Node->nNext3 = nRenderRectAlpha; Node->nNext3 = nRenderRectAlpha;
nRenderRectAlpha = Node; nRenderRectAlpha = Node;
} // DL: do przezroczystych z sektora } // DL: do przezroczystych z sektora
#ifdef EU07_USE_OLD_RENDERCODE
else if (Global::bUseVBO) else if (Global::bUseVBO)
{ {
Node->nNext3 = nRenderRect; Node->nNext3 = nRenderRect;
@@ -863,6 +565,12 @@ void TSubRect::RaNodeAdd(TGroundNode *Node)
Node->nNext3 = nRender; Node->nNext3 = nRender;
nRender = Node; nRender = Node;
} // DL: do nieprzezroczystych wszelakich } // DL: do nieprzezroczystych wszelakich
#else
else {
Node->nNext3 = nRenderRect;
nRenderRect = Node;
} // do nieprzezroczystych z sektora
#endif
break; break;
case TP_MODEL: // modele zawsze wyświetlane z własnego VBO case TP_MODEL: // modele zawsze wyświetlane z własnego VBO
if ((Node->iFlags & 0x20200020) == 0) // czy brak przezroczystości? if ((Node->iFlags & 0x20200020) == 0) // czy brak przezroczystości?
@@ -1003,7 +711,7 @@ bool TSubRect::RaTrackAnimAdd(TTrack *t)
void TSubRect::RaAnimate() void TSubRect::RaAnimate()
{ // wykonanie animacji { // wykonanie animacji
if( !tTrackAnim ) { if( tTrackAnim == nullptr ) {
// nie ma nic do animowania // nie ma nic do animowania
return; return;
} }
@@ -1075,7 +783,7 @@ void TSubRect::LoadNodes()
} }
n = n->nNext2; // następny z sektora 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 return; // jeśli nie ma obiektów do wyświetlenia z VBO, to koniec
if (Global::bUseVBO) if (Global::bUseVBO)
{ // tylko liczenie wierzchołów, gdy nie ma VBO { // tylko liczenie wierzchołów, gdy nie ma VBO
@@ -1146,6 +854,12 @@ void TSubRect::RenderDL()
{ // renderowanie nieprzezroczystych (DL) { // renderowanie nieprzezroczystych (DL)
TGroundNode *node; TGroundNode *node;
RaAnimate(); // przeliczenia animacji torów w sektorze 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 ) for( node = nRender; node; node = node->nNext3 )
GfxRenderer.Render( node ); // nieprzezroczyste obiekty (oprócz pojazdów) GfxRenderer.Render( node ); // nieprzezroczyste obiekty (oprócz pojazdów)
for (node = nRenderMixed; node; node = node->nNext3) for (node = nRenderMixed; node; node = node->nNext3)
@@ -1160,44 +874,6 @@ void TSubRect::RenderDL()
} }
} }
#endif #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() void TSubRect::RenderAlphaDL()
@@ -1215,7 +891,9 @@ void TSubRect::RenderVBO()
{ // renderowanie nieprzezroczystych (VBO) { // renderowanie nieprzezroczystych (VBO)
TGroundNode *node; TGroundNode *node;
RaAnimate(); // przeliczenia animacji torów w sektorze RaAnimate(); // przeliczenia animacji torów w sektorze
/*
LoadNodes(); // czemu tutaj? LoadNodes(); // czemu tutaj?
*/
if (StartVBO()) if (StartVBO())
{ {
for( node = nRenderRect; node; node = node->nNext3 ) for( node = nRenderRect; node; node = node->nNext3 )
@@ -1285,6 +963,7 @@ TGroundRect::Init() {
void TGroundRect::RenderDL() void TGroundRect::RenderDL()
{ // renderowanie kwadratu kilometrowego (DL), jeśli jeszcze nie zrobione { // renderowanie kwadratu kilometrowego (DL), jeśli jeszcze nie zrobione
#ifdef EU07_USE_OLD_RENDERCODE
if (iLastDisplay != iFrameNumber) if (iLastDisplay != iFrameNumber)
{ // tylko jezeli dany kwadrat nie był jeszcze renderowany { // tylko jezeli dany kwadrat nie był jeszcze renderowany
// for (TGroundNode* node=pRender;node;node=node->pNext3) // for (TGroundNode* node=pRender;node;node=node->pNext3)
@@ -1307,6 +986,18 @@ void TGroundRect::RenderDL()
GfxRenderer.Render( nRootMesh ); GfxRenderer.Render( nRootMesh );
iLastDisplay = iFrameNumber; // drugi raz nie potrzeba 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() void TGroundRect::RenderVBO()
@@ -1314,10 +1005,14 @@ void TGroundRect::RenderVBO()
if (iLastDisplay != iFrameNumber) if (iLastDisplay != iFrameNumber)
{ // tylko jezeli dany kwadrat nie był jeszcze renderowany { // tylko jezeli dany kwadrat nie był jeszcze renderowany
LoadNodes(); // ewentualne tworzenie siatek LoadNodes(); // ewentualne tworzenie siatek
if (StartVBO()) if ( nRenderRect && StartVBO())
{ {
for (TGroundNode *node = nRenderRect; node; node = node->nNext3) // następny tej grupy 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 node->RaRenderVBO(); // nieprzezroczyste trójkąty kwadratu kilometrowego
#else
GfxRenderer.Render( node ); // nieprzezroczyste trójkąty kwadratu kilometrowego
#endif
EndVBO(); EndVBO();
iLastDisplay = iFrameNumber; iLastDisplay = iFrameNumber;
} }
@@ -4619,220 +4314,6 @@ bool TGround::GetTraction(TDynamicObject *model)
return true; 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 #ifdef _WINDOWS
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void TGround::Navigate(std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam) void TGround::Navigate(std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam)

View File

@@ -97,8 +97,6 @@ struct TGroundVertex
} }
}; };
class TSubRect; // sektor (aktualnie 200m×200m, ale może być zmieniony)
class TGroundNode : public Resource class TGroundNode : public Resource
{ // obiekt scenerii { // obiekt scenerii
@@ -216,8 +214,7 @@ class TSubRect : public Resource, public CMesh
void Sort(); // optymalizacja obiektów w sektorze (sortowanie wg tekstur) void Sort(); // optymalizacja obiektów w sektorze (sortowanie wg tekstur)
TTrack * FindTrack(vector3 *Point, int &iConnection, TTrack *Exclude); TTrack * FindTrack(vector3 *Point, int &iConnection, TTrack *Exclude);
TTraction * FindTraction(vector3 *Point, int &iConnection, TTraction *Exclude); TTraction * FindTraction(vector3 *Point, int &iConnection, TTraction *Exclude);
bool StartVBO(); // ustwienie VBO sektora dla (nRenderRect), (nRenderRectAlpha) i bool StartVBO(); // ustwienie VBO sektora dla (nRenderRect), (nRenderRectAlpha) i (nRenderWires)
// (nRenderWires)
bool RaTrackAnimAdd(TTrack *t); // zgłoszenie toru do animacji bool RaTrackAnimAdd(TTrack *t); // zgłoszenie toru do animacji
void RaAnimate(); // przeliczenie animacji torów void RaAnimate(); // przeliczenie animacji torów
void RenderDL(); // renderowanie nieprzezroczystych w Display Lists void RenderDL(); // renderowanie nieprzezroczystych w Display Lists
@@ -335,11 +332,6 @@ class TGround
void Update_Lights(); // updates scene lights array void Update_Lights(); // updates scene lights array
bool AddToQuery(TEvent *Event, TDynamicObject *Node); bool AddToQuery(TEvent *Event, TDynamicObject *Node);
bool GetTraction(TDynamicObject *model); 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(); bool CheckQuery();
TGroundNode * DynamicFindAny(std::string asNameToFind); TGroundNode * DynamicFindAny(std::string asNameToFind);
TGroundNode * DynamicFind(std::string asNameToFind); TGroundNode * DynamicFind(std::string asNameToFind);

View File

@@ -2659,8 +2659,8 @@ bool TTrack::Switch(int i, double t, double d)
true) // jeśli nie dodane do animacji true) // jeśli nie dodane do animacji
{ // nie ma się co bawić { // nie ma się co bawić
SwitchExtension->fOffset = SwitchExtension->fDesiredOffset; SwitchExtension->fOffset = SwitchExtension->fDesiredOffset;
RaAnimate(); // przeliczenie położenia iglic; czy zadziała na niewyświetlanym // przeliczenie położenia iglic; czy zadziała na niewyświetlanym sektorze w VBO?
// sektorze w VBO? RaAnimate();
} }
return true; return true;
} }
@@ -2809,8 +2809,8 @@ void TTrack::RaAnimListAdd(TTrack *t)
TTrack * TTrack::RaAnimate(GLuint const Vertexbuffer) TTrack * TTrack::RaAnimate(GLuint const Vertexbuffer)
{ // wykonanie rekurencyjne animacji, wywoływane przed wyświetleniem sektora { // wykonanie rekurencyjne animacji, wywoływane przed wyświetleniem sektora
// zwraca wskaźnik toru wymagającego dalszej animacji // zwraca wskaźnik toru wymagającego dalszej animacji
if (SwitchExtension->pNextAnim) if( SwitchExtension->pNextAnim )
SwitchExtension->pNextAnim = SwitchExtension->pNextAnim->RaAnimate(); SwitchExtension->pNextAnim = SwitchExtension->pNextAnim->RaAnimate( Vertexbuffer );
bool m = true; // animacja trwa bool m = true; // animacja trwa
if (eType == tt_Switch) // dla zwrotnicy tylko szyny if (eType == tt_Switch) // dla zwrotnicy tylko szyny
{ {

View File

@@ -5802,14 +5802,12 @@ bool TTrain::CabChange(int iDirection)
DynamicObject->asBaseDir + DynamicObject->MoverParameters->TypeName + DynamicObject->asBaseDir + DynamicObject->MoverParameters->TypeName +
".mmd")) ".mmd"))
{ // zmiana kabiny w ramach tego samego pojazdu { // zmiana kabiny w ramach tego samego pojazdu
DynamicObject->MoverParameters DynamicObject->MoverParameters->CabActivisation(); // załączenie rozrządu (wirtualne kabiny)
->CabActivisation(); // załączenie rozrządu (wirtualne kabiny) DynamicObject->Mechanik->CheckVehicles( Change_direction );
return true; // udało się zmienić kabinę return true; // udało się zmienić kabinę
} }
DynamicObject->MoverParameters->CabActivisation(); // aktywizacja // aktywizacja poprzedniej, bo jeszcze nie wiadomo, czy jakiś pojazd jest
// poprzedniej, bo DynamicObject->MoverParameters->CabActivisation();
// jeszcze nie wiadomo,
// czy jakiś pojazd jest
} }
return false; // ewentualna zmiana pojazdu return false; // ewentualna zmiana pojazdu
} }

View File

@@ -620,10 +620,6 @@ void TWorld::OnKeyDown(int cKey)
else { else {
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
} }
/*
++Global::iReCompile; // odświeżyć siatki
// Ra: jeszcze usunąć siatki ze skompilowanych obiektów!
*/
} }
} }
break; break;
@@ -1750,9 +1746,12 @@ TWorld::Update_UI() {
UITable->text_lines.emplace_back( UITable->text_lines.emplace_back(
Global::Bezogonkow( "| " + station + " | " + arrival + " | " + departure + " | " + vmax + " | " + tableline->StationWare, true ), Global::Bezogonkow( "| " + station + " | " + arrival + " | " + departure + " | " + vmax + " | " + tableline->StationWare, true ),
( ( owner->iStationStart < table->StationIndex ) && ( i < table->StationIndex ) ? ( ( owner->iStationStart < table->StationIndex )
float4( 0.0f, 1.0f, 0.0f, 1.0f ) :// czas minął i odjazd był, to nazwa stacji będzie na zielono && ( i < table->StationIndex )
Global::UITextColor ) && ( 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 // divider/footer
UITable->text_lines.emplace_back( "+----------------------------+-------+-------+-----+", Global::UITextColor ); UITable->text_lines.emplace_back( "+----------------------------+-------+-------+-----+", Global::UITextColor );
@@ -1995,9 +1994,11 @@ TWorld::Update_UI() {
+ GfxRenderer.Info(); + GfxRenderer.Info();
// dump last opengl error, if any // dump last opengl error, if any
GLenum glerror = glGetError(); GLenum glerror = ::glGetError();
if( glerror != GL_NO_ERROR ) { 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() ) { if( false == Global::LastGLError.empty() ) {
uitextline3 = uitextline3 =

View File

@@ -13,6 +13,7 @@ http://mozilla.org/MPL/2.0/.
#include "globals.h" #include "globals.h"
#include "timer.h" #include "timer.h"
#include "world.h" #include "world.h"
#include "data.h"
#include "dynobj.h" #include "dynobj.h"
#include "animmodel.h" #include "animmodel.h"
#include "traction.h" #include "traction.h"
@@ -146,7 +147,7 @@ opengl_renderer::Render() {
m_camera.update_frustum(); m_camera.update_frustum();
Render( &World.Environment ); Render( &World.Environment );
World.Ground.Render( World.Camera.Pos ); Render( &World.Ground );
World.Render_Cab(); World.Render_Cab();
@@ -293,7 +294,7 @@ opengl_renderer::Render( world_environment *Environment ) {
bool bool
opengl_renderer::Render( TGround *Ground ) { opengl_renderer::Render( TGround *Ground ) {
/*
glDisable( GL_BLEND ); glDisable( GL_BLEND );
glAlphaFunc( GL_GREATER, 0.50f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f glAlphaFunc( GL_GREATER, 0.50f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
glEnable( GL_LIGHTING ); 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 bool
@@ -431,7 +526,12 @@ opengl_renderer::Render( TGroundNode *Node ) {
} }
else { else {
// display list render path // display list render path
::glCallList( Node->DisplayListID ); if( Node->DisplayListID != 0 ) {
::glCallList( Node->DisplayListID );
}
else {
return false;
}
} }
return true; return true;
} }
@@ -730,6 +830,75 @@ opengl_renderer::Render( TMemCell *Memcell ) {
::glPopAttrib(); ::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 // NOTE: legacy render system switch
#define _PROBLEND #define _PROBLEND

View File

@@ -136,6 +136,8 @@ public:
Render( TSubModel *Submodel ); Render( TSubModel *Submodel );
void void
Render( TMemCell *Memcell ); Render( TMemCell *Memcell );
bool
Render_Alpha( TGround *Ground );
bool bool
Render_Alpha( TGroundNode *Node ); Render_Alpha( TGroundNode *Node );
bool bool

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#define VERSION_MAJOR 17 #define VERSION_MAJOR 17
#define VERSION_MINOR 516 #define VERSION_MINOR 517
#define VERSION_REVISION 0 #define VERSION_REVISION 0