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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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