This commit is contained in:
VB
2017-03-20 22:37:49 +01:00
46 changed files with 3170 additions and 2508 deletions

View File

@@ -128,6 +128,10 @@ void TAdvancedSound::Update(bool ListenerInside, vector3 NewPosition)
void TAdvancedSound::UpdateAF(double A, double F, bool ListenerInside, vector3 NewPosition)
{ // update, ale z amplituda i czestotliwoscia
if( State == ss_Off ) {
return;
}
if ((State == ss_Commencing) && (SoundCommencing.AM > 0))
{
SoundShut.Stop(); // hunter-311211

View File

@@ -411,11 +411,13 @@ TAnimModel::TAnimModel()
pModel = NULL;
iNumLights = 0;
fBlinkTimer = 0;
ReplacableSkinId[0] = 0;
ReplacableSkinId[1] = 0;
ReplacableSkinId[2] = 0;
ReplacableSkinId[3] = 0;
ReplacableSkinId[4] = 0;
#ifdef EU07_USE_OLD_RENDERCODE
ReplacableSkinId[ 0 ] = 0;
ReplacableSkinId[ 1 ] = 0;
ReplacableSkinId[ 2 ] = 0;
ReplacableSkinId[ 3 ] = 0;
ReplacableSkinId[ 4 ] = 0;
#endif
for (int i = 0; i < iMaxNumLights; i++)
{
LightsOn[i] = LightsOff[i] = NULL; // normalnie nie ma
@@ -441,7 +443,7 @@ bool TAnimModel::Init(TModel3d *pNewModel)
pModel = pNewModel;
return (pModel != NULL);
}
#ifdef EU07_USE_OLD_RENDERCODE
bool TAnimModel::Init(std::string const &asName, std::string const &asReplacableTexture)
{
if (asReplacableTexture.substr(0, 1) ==
@@ -462,6 +464,28 @@ bool TAnimModel::Init(std::string const &asName, std::string const &asReplacable
// przezroczystych
return (Init(TModelsManager::GetModel(asName)));
}
#else
bool TAnimModel::Init(std::string const &asName, std::string const &asReplacableTexture)
{
if (asReplacableTexture.substr(0, 1) ==
"*") // od gwiazdki zaczynają się teksty na wyświetlaczach
asText = asReplacableTexture.substr(1, asReplacableTexture.length() - 1); // zapamiętanie tekstu
else if (asReplacableTexture != "none")
m_materialdata.replacable_skins[1] =
GfxRenderer.GetTextureId( asReplacableTexture, "" );
if( ( m_materialdata.replacable_skins[ 1 ] != 0 )
&& ( GfxRenderer.Texture( m_materialdata.replacable_skins[ 1 ] ).has_alpha ) ) {
// tekstura z kanałem alfa - nie renderować w cyklu nieprzezroczystych
m_materialdata.textures_alpha = 0x31310031;
}
else{
// tekstura nieprzezroczysta - nie renderować w cyklu
m_materialdata.textures_alpha = 0x30300030;
}
// przezroczystych
return (Init(TModelsManager::GetModel(asName)));
}
#endif
bool TAnimModel::Load(cParser *parser, bool ter)
{ // rozpoznanie wpisu modelu i ustawienie świateł
@@ -629,6 +653,7 @@ void TAnimModel::RenderAlphaDL(vector3 pPosition, double fAngle)
pModel->RenderAlpha(pPosition, fAngle, ReplacableSkinId, iTexAlpha);
};
*/
#ifdef EU07_USE_OLD_RENDERCODE
int TAnimModel::Flags()
{ // informacja dla TGround, czy ma być w Render, RenderAlpha, czy RenderMixed
int i = pModel ? pModel->Flags() : 0; // pobranie flag całego modelu
@@ -642,6 +667,21 @@ int TAnimModel::Flags()
// i|=(i&0x08080008)*((iTexAlpha&1)?0x04:0x02);
return i;
};
#else
int TAnimModel::Flags()
{ // informacja dla TGround, czy ma być w Render, RenderAlpha, czy RenderMixed
int i = pModel ? pModel->Flags() : 0; // pobranie flag całego modelu
if( m_materialdata.replacable_skins[ 1 ] > 0 ) // jeśli ma wymienną teksturę 0
i |= (i & 0x01010001) * ((m_materialdata.textures_alpha & 1) ? 0x20 : 0x10);
// if (ReplacableSkinId[2]>0) //jeśli ma wymienną teksturę 1
// i|=(i&0x02020002)*((iTexAlpha&1)?0x10:0x08);
// if (ReplacableSkinId[3]>0) //jeśli ma wymienną teksturę 2
// i|=(i&0x04040004)*((iTexAlpha&1)?0x08:0x04);
// if (ReplacableSkinId[4]>0) //jeśli ma wymienną teksturę 3
// i|=(i&0x08080008)*((iTexAlpha&1)?0x04:0x02);
return i;
};
#endif
//-----------------------------------------------------------------------------
// 2011-03-16 cztery nowe funkcje renderowania z możliwością pochylania obiektów
@@ -651,29 +691,39 @@ void TAnimModel::RenderDL(vector3 *vPosition)
{
RaAnimate(); // jednorazowe przeliczenie animacji
RaPrepare();
if (pModel) // renderowanie rekurencyjne submodeli
if( pModel ) // renderowanie rekurencyjne submodeli
#ifdef EU07_USE_OLD_RENDERCODE
pModel->Render(vPosition, &vAngle, ReplacableSkinId, iTexAlpha);
#else
GfxRenderer.Render( pModel, Material(), *vPosition, vAngle );
#endif
};
void TAnimModel::RenderAlphaDL(vector3 *vPosition)
{
RaPrepare();
if (pModel) // renderowanie rekurencyjne submodeli
#ifdef EU07_USE_OLD_RENDERCODE
pModel->RenderAlpha(vPosition, &vAngle, ReplacableSkinId, iTexAlpha);
#else
GfxRenderer.Render_Alpha( pModel, Material(), *vPosition, vAngle );
#endif
};
void TAnimModel::RenderVBO(vector3 *vPosition)
{
RaAnimate(); // jednorazowe przeliczenie animacji
RaPrepare();
if (pModel) // renderowanie rekurencyjne submodeli
pModel->RaRender(vPosition, &vAngle, ReplacableSkinId, iTexAlpha);
pModel->RaRender(vPosition, &vAngle, Material()->replacable_skins, Material()->textures_alpha);
};
void TAnimModel::RenderAlphaVBO(vector3 *vPosition)
{
RaPrepare();
if (pModel) // renderowanie rekurencyjne submodeli
pModel->RaRenderAlpha(vPosition, &vAngle, ReplacableSkinId, iTexAlpha);
pModel->RaRenderAlpha(vPosition, &vAngle, Material()->replacable_skins, Material()->textures_alpha);
};
//---------------------------------------------------------------------------
bool TAnimModel::TerrainLoaded()
{ // zliczanie kwadratów kilometrowych (główna linia po Next) do tworznia tablicy

View File

@@ -17,6 +17,7 @@ http://mozilla.org/MPL/2.0/.
#include "Model3d.h"
#include "Texture.h"
#include "DynObj.h"
const int iMaxNumLights = 8;
@@ -138,7 +139,12 @@ class TAnimModel
TSubModel *LightsOn[iMaxNumLights]; // Ra: te wskaźniki powinny być w ramach TModel3d
TSubModel *LightsOff[iMaxNumLights];
vector3 vAngle; // bazowe obroty egzemplarza względem osi
#ifdef EU07_USE_OLD_RENDERCODE
int iTexAlpha; //żeby nie sprawdzać za każdym razem, dla 4 wymiennych tekstur
#else
material_data m_materialdata;
#endif
std::string asText; // tekst dla wyświetlacza znakowego
TAnimAdvanced *pAdvanced;
void Advanced();
@@ -149,9 +155,15 @@ class TAnimModel
void RaAnimate(); // przeliczenie animacji egzemplarza
void RaPrepare(); // ustawienie animacji egzemplarza na wzorcu
public:
#ifdef EU07_USE_OLD_RENDERCODE
texture_manager::size_type ReplacableSkinId[5]; // McZapkie-020802: zmienialne skory
static TAnimContainer *acAnimList; // lista animacji z eventem, które muszą być przeliczane
// również bez wyświetlania
#endif
static TAnimContainer *acAnimList; // lista animacji z eventem, które muszą być przeliczane również bez wyświetlania
#ifndef EU07_USE_OLD_RENDERCODE
inline
material_data const *Material() const { return &m_materialdata; }
#endif
TAnimModel();
~TAnimModel();
bool Init(TModel3d *pNewModel);

View File

@@ -63,6 +63,7 @@ set(SOURCES
"Spring.cpp"
"shader.cpp"
"frustum.cpp"
"uilayer.cpp"
)
if (WIN32)

View File

@@ -111,41 +111,52 @@ vector3 TCamera::GetDirection()
return (Normalize(Vec));
}
// bool TCamera::GetMatrix(matrix4x4 &Matrix)
/*
bool TCamera::SetMatrix()
{
glRotated(-Roll * 180.0f / M_PI, 0, 0, 1); // po wyłączeniu tego kręci się pojazd, a sceneria
// nie
glRotated(-Pitch * 180.0f / M_PI, 1, 0, 0);
glRotated(-Yaw * 180.0f / M_PI, 0, 1, 0); // w zewnętrznym widoku: kierunek patrzenia
glRotated( -Roll * 180.0f / M_PI, 0, 0, 1 ); // po wyłączeniu tego kręci się pojazd, a sceneria nie
glRotated( -Pitch * 180.0f / M_PI, 1, 0, 0 );
glRotated( -Yaw * 180.0f / M_PI, 0, 1, 0 ); // w zewnętrznym widoku: kierunek patrzenia
if (Type == tp_Follow)
if( Type == tp_Follow )
{
// gluLookAt(Pos.x+pOffset.x,Pos.y+pOffset.y,Pos.z+pOffset.z,
// LookAt.x+pOffset.x,LookAt.y+pOffset.y,LookAt.z+pOffset.z,vUp.x,vUp.y,vUp.z);
// gluLookAt(Pos.x+pOffset.x,Pos.y+pOffset.y,Pos.z+pOffset.z,
// LookAt.x+pOffset.x,LookAt.y+pOffset.y,LookAt.z+pOffset.z,vUp.x,vUp.y,vUp.z);
gluLookAt(Pos.x, Pos.y, Pos.z, LookAt.x, LookAt.y, LookAt.z, vUp.x, vUp.y,
vUp.z); // Ra: pOffset is zero
// gluLookAt(Pos.x,Pos.y,Pos.z,Pos.x+Velocity.x,Pos.y+Velocity.y,Pos.z+Velocity.z,0,1,0);
// return true;
gluLookAt(
Pos.x, Pos.y, Pos.z,
LookAt.x, LookAt.y, LookAt.z,
vUp.x, vUp.y, vUp.z); // Ra: pOffset is zero
}
if (Type == tp_Satelite)
Pitch = M_PI * 0.5;
if (Type != tp_Follow)
{
glTranslated(-Pos.x, -Pos.y, -Pos.z); // nie zmienia kierunku patrzenia
else {
glTranslated( -Pos.x, -Pos.y, -Pos.z ); // nie zmienia kierunku patrzenia
}
Global::SetCameraPosition(Pos); // było +pOffset
return true;
}
*/
bool TCamera::SetMatrix( glm::mat4 &Matrix ) {
Matrix = glm::rotate( Matrix, (float)-Roll, glm::vec3( 0.0f, 0.0f, 1.0f ) ); // po wyłączeniu tego kręci się pojazd, a sceneria nie
Matrix = glm::rotate( Matrix, (float)-Pitch, glm::vec3( 1.0f, 0.0f, 0.0f ) );
Matrix = glm::rotate( Matrix, (float)-Yaw, glm::vec3( 0.0f, 1.0f, 0.0f ) ); // w zewnętrznym widoku: kierunek patrzenia
if( Type == tp_Follow ) {
Matrix *= glm::lookAt(
glm::vec3( Pos.x, Pos.y, Pos.z ),
glm::vec3( LookAt.x, LookAt.y, LookAt.z ),
glm::vec3( vUp.x, vUp.y, vUp.z ) );
}
else {
Matrix = glm::translate( Matrix, glm::vec3( -Pos.x, -Pos.y, -Pos.z ) ); // nie zmienia kierunku patrzenia
}
Global::SetCameraPosition( Pos ); // było +pOffset
return true;
}
void TCamera::SetCabMatrix(vector3 &p)
{ // ustawienie widoku z kamery bez przesunięcia robionego przez OpenGL - nie powinno tak trząść
glRotated(-Roll * 180.0f / M_PI, 0, 0, 1);
glRotated(-Pitch * 180.0f / M_PI, 1, 0, 0);
glRotated(-Yaw * 180.0f / M_PI, 0, 1, 0); // w zewnętrznym widoku: kierunek patrzenia
@@ -170,16 +181,3 @@ void TCamera::Stop()
Velocity = vector3(0, 0, 0);
};
// returns true if specified object is within camera frustum, false otherwise
bool
TCamera::IsVisible( TDynamicObject const *Dynamic ) const {
// sphere test is faster than AABB, so we'll use it here
float3 diagonal(
Dynamic->MoverParameters->Dim.L,
Dynamic->MoverParameters->Dim.H,
Dynamic->MoverParameters->Dim.W );
float const radius = static_cast<float>(diagonal.Length()) * 0.5f;
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), radius ) > 0.0f );
}

View File

@@ -7,11 +7,9 @@ obtain one at
http://mozilla.org/MPL/2.0/.
*/
#ifndef CameraH
#define CameraH
#pragma once
#include "dumb3d.h"
#include "frustum.h"
#include "dynobj.h"
using namespace Math3D;
@@ -28,7 +26,6 @@ class TCamera
{
private:
vector3 pOffset; // nie używane (zerowe)
cFrustum m_frustum;
public: // McZapkie: potrzebuje do kiwania na boki
double Pitch;
@@ -51,17 +48,13 @@ class TCamera
void Update();
vector3 GetDirection();
// vector3 inline GetCrossPos() { return Pos+GetDirection()*CrossDist+CrossPos; };
/*
bool SetMatrix();
void SetCabMatrix(vector3 &p);
*/
bool SetMatrix(glm::mat4 &Matrix);
void SetCabMatrix( vector3 &p );
void RaLook();
void Stop();
inline
void
SetFrustum() { m_frustum.calculate(); }
bool
IsVisible( TDynamicObject const *Dynamic ) const;
// bool GetMatrix(matrix4x4 &Matrix);
vector3 PtNext, PtPrev;
};
#endif

View File

@@ -480,22 +480,11 @@ float Console::AnalogCalibrateGet(int x)
if (iMode == 4 && PoKeys55[0])
{
float b = PoKeys55[0]->fAnalog[x];
/*return (((((Global::fCalibrateIn[x][5] * b) + Global::fCalibrateIn[x][4]) * b +
Global::fCalibrateIn[x][3]) *
b +
Global::fCalibrateIn[x][2]) *
b +
Global::fCalibrateIn[x][1]) *
b +
Global::fCalibrateIn[x][0];*/
b = (((((Global::fCalibrateIn[x][5] * b) + Global::fCalibrateIn[x][4]) * b +
Global::fCalibrateIn[x][3]) *
b +
Global::fCalibrateIn[x][2]) *
b +
Global::fCalibrateIn[x][1]) *
b +
Global::fCalibrateIn[x][0];
b = (((((Global::fCalibrateIn[x][5] * b) + Global::fCalibrateIn[x][4]) * b +
Global::fCalibrateIn[x][3]) * b +
Global::fCalibrateIn[x][2]) * b +
Global::fCalibrateIn[x][1]) * b +
Global::fCalibrateIn[x][0];
if (x == 0) return (b + 2) / 8;
if (x == 1) return b/10;
else return b;

View File

@@ -223,78 +223,84 @@ bool TMWDComm::Run() // wywoływanie obsługi MWD + generacja większego opóźn
void TMWDComm::CheckData() // sprawdzanie wejść cyfrowych i odpowiednie sterowanie maszyną
{
int i = 0;
while (i < 6)
{
maskData[i] = ReadDataBuff[i] ^ lastStateData[i];
lastStateData[i] = ReadDataBuff[i];
i++;
}
/*
Rozpiska portów!
Port0: 0 NC odblok. przek. sprężarki i wentyl. oporów
1 M wyłącznik wył. szybkiego
2 Shift+M impuls załączający wył. szybki
3 N odblok. przekaźników nadmiarowych
i różnicowego obwodu głównego
4 NC rezerwa
5 Ctrl+N odblok. przek. nadmiarowych
przetwornicy, ogrzewania pociągu i różnicowych obw. pomocniczych
6 L wył. styczników liniowych
7 SPACE kasowanie czuwaka
int i = 0;
while (i < 6)
{
maskData[i] = ReadDataBuff[i] ^ lastStateData[i];
lastStateData[i] = ReadDataBuff[i];
i++;
}
/*
Rozpiska portów!
Port0: 0 NC odblok. przek. sprężarki i wentyl. oporów
1 M wyłącznik wył. szybkiego
2 Shift+M impuls załączający wył. szybki
3 N odblok. przekaźników nadmiarowych
i różnicowego obwodu głównegoMMm
4 NC rezerwa
5 Ctrl+N odblok. przek. nadmiarowych
przetwornicy, ogrzewania pociągu i różnicowych obw. pomocniczych
6 L wył. styczników liniowych
7 SPACE kasowanie czuwaka
Port1: 0 NC
1 (Shift) X przetwornica
2 (Shift) C sprężarka
3 S piasecznice
4 (Shift) H ogrzewanie składu
5 przel. hamowania Shift+B
pspbpwy Ctrl+B pospieszny B towarowy
6 przel. hamowania
7 (Shift) F rozruch w/n
Port1: 0 NC
1 (Shift) X przetwornica
2 (Shift) C sprężarka
3 S piasecznice
4 (Shift) H ogrzewanie składu
5 przel. hamowania Shift+B
pspbpwy Ctrl+B pospieszny B towarowy
6 przel. hamowania
7 (Shift) F rozruch w/n
Port2: 0 (Shift) P pantograf przedni
1 (Shift) O pantograf tylni
2 ENTER przyhamowanie przy poślizgu
3 () przyciemnienie świateł
4 () przyciemnienie świateł
5 NUM6 odluźniacz
6 a syrena lok W
7 A syrena lok N
Port2: 0 (Shift) P pantograf przedni
1 (Shift) O pantograf tylni
2 ENTER przyhamowanie przy poślizgu
3 () przyciemnienie świateł
4 () przyciemnienie świateł
5 NUM6 odluźniacz
6 a syrena lok W
7 A syrena lok N
Port3: 0 Shift+J bateria
1
2
3
4
5
6
7
*/
Port3: 0 Shift+J bateria
1
2
3
4
5
6
7
*/
/* po przełączeniu bistabilnego najpierw wciskamy klawisz i przy następnym
wejściu w pętlę MWD puszczamy bo inaczej nie działa
*/
/* po przełączeniu bistabilnego najpierw wciskamy klawisz i przy następnym
wejściu w pętlę MWD puszczamy bo inaczej nie działa
*/
// wciskanie przycisków klawiatury
/*PORT0*/
if (maskData[0] & 0x02) if (lastStateData[0] & 0x02) KeyBoard('M', 1); // wyłączenie wyłącznika szybkiego
else KeyBoard('M', 0); // monostabilny
if (maskData[0] & 0x04) if (lastStateData[0] & 0x04) { // impuls załączający wyłącznik szybki
// wciskanie przycisków klawiatury
/*PORT0*/
if (maskData[0] & 0x02) if (lastStateData[0] & 0x02)
KeyBoard('M', 1); // wyłączenie wyłącznika szybkiego
else KeyBoard('M', 0); // monostabilny
if (maskData[0] & 0x04) if (lastStateData[0] & 0x04) // impuls załączający wyłącznik szybki
{
KeyBoard(0x10, 1); // monostabilny
KeyBoard('M', 1);
}
else {
else
{
KeyBoard('M', 0);
KeyBoard(0x10, 0);
}
if (maskData[0] & 0x08) if (lastStateData[0] & 0x08) KeyBoard('N', 1); // odblok nadmiarowego silników trakcyjnych
else KeyBoard('N', 0); // monostabilny
if (maskData[0] & 0x20) if (lastStateData[0] & 0x20) { // odblok nadmiarowego przetwornicy, ogrzewania poc.
KeyBoard(0x11, 1); // różnicowego obwodów pomocniczych
KeyBoard('N', 1); // monostabilny
if (maskData[0] & 0x08) if (lastStateData[0] & 0x08)
KeyBoard('N', 1); // odblok nadmiarowego silników trakcyjnych
else KeyBoard('N', 0); // monostabilny
if (maskData[0] & 0x20) if (lastStateData[0] & 0x20)
{ // odblok nadmiarowego przetwornicy, ogrzewania poc.
KeyBoard(0x11, 1); // różnicowego obwodów pomocniczych
KeyBoard('N', 1); // monostabilny
}
else {
else
{
KeyBoard('N', 0);
KeyBoard(0x11, 0);
}
@@ -303,16 +309,18 @@ void TMWDComm::CheckData() // sprawdzanie wejść cyfrowych i odpowiednie sterow
if (maskData[0] & 0x80) if (lastStateData[0] & 0x80) KeyBoard(0x20, 1); // kasowanie czuwaka/SHP
else KeyBoard(0x20, 0); // kasowanie czuwaka/SHP
/*PORT1*/
/*PORT1*/
// puszczanie przycisku bistabilnego klawiatury
if (maskSwitch[1] & 0x02) {
if (bitSwitch[1] & 0x02) {
// puszczanie przycisku bistabilnego klawiatury
if (maskSwitch[1] & 0x02)
{
if (bitSwitch[1] & 0x02)
{
KeyBoard('X', 0);
KeyBoard(0x10, 0);
}
else KeyBoard('X', 0);
maskSwitch[1] &= ~0x02;
maskSwitch[1] &= ~0x02;
}
if (maskSwitch[1] & 0x04) {
if (bitSwitch[1] & 0x04) {
@@ -345,61 +353,78 @@ void TMWDComm::CheckData() // sprawdzanie wejść cyfrowych i odpowiednie sterow
maskSwitch[1] &= ~0x80;
}
if (maskData[1] & 0x02) if (lastStateData[1] & 0x02) { // przetwornica
// przetwornica
if (maskData[1] & 0x02) if (lastStateData[1] & 0x02)
{
KeyBoard(0x10, 1); // bistabilny
KeyBoard('X', 1);
maskSwitch[1] |= 0x02;
bitSwitch[1] |= 0x02;
}
else {
else
{
maskSwitch[1] |= 0x02;
bitSwitch[1] &= ~0x02;
KeyBoard('X', 1);
}
if (maskData[1] & 0x04) if (lastStateData[1] & 0x04) { // sprężarka
// sprężarka
if (maskData[1] & 0x04) if (lastStateData[1] & 0x04)
{
KeyBoard(0x10, 1); // bistabilny
KeyBoard('C', 1);
maskSwitch[1] |= 0x04;
bitSwitch[1] |= 0x04;
}
else {
else
{
maskSwitch[1] |= 0x04;
bitSwitch[1] &= ~0x04;
KeyBoard('C', 1);
}
if (maskData[1] & 0x08) if (lastStateData[1] & 0x08) KeyBoard('S', 1); // piasecznica
else KeyBoard('S', 0); // monostabilny
if (maskData[1] & 0x10) if (lastStateData[1] & 0x10) { // ogrzewanie składu
// piasecznica
if (maskData[1] & 0x08) if (lastStateData[1] & 0x08)
KeyBoard('S', 1);
else
KeyBoard('S', 0); // monostabilny
// ogrzewanie składu
if (maskData[1] & 0x10) if (lastStateData[1] & 0x10)
{
KeyBoard(0x11, 1); // bistabilny
KeyBoard('H', 1);
maskSwitch[1] |= 0x10;
bitSwitch[1] |= 0x10;
}
else {
else
{
maskSwitch[1] |= 0x10;
bitSwitch[1] &= ~0x10;
KeyBoard('H', 1);
}
if (maskData[1] & 0x20 || maskData[1] & 0x40) { // przełącznik hamowania
if (lastStateData[1] & 0x20) { // Shift+B
// przełącznik hamowania
if (maskData[1] & 0x20 || maskData[1] & 0x40)
{
if (lastStateData[1] & 0x20)
{ // Shift+B
KeyBoard(0x10, 1);
maskSwitch[1] |= 0x20;
}
else if (lastStateData[1] & 0x40) { // Ctrl+B
else if (lastStateData[1] & 0x40)
{ // Ctrl+B
KeyBoard(0x11, 1);
maskSwitch[1] |= 0x40;
}
KeyBoard('B', 1);
}
if (maskData[1] & 0x80) if (lastStateData[1] & 0x80) { // rozruch wysoki/niski
// rozruch wysoki/niski
if (maskData[1] & 0x80) if (lastStateData[1] & 0x80)
{
KeyBoard(0x10, 1); // bistabilny
KeyBoard('F', 1);
maskSwitch[1] |= 0x80;
bitSwitch[1] |= 0x80;
}
else {
else
{
maskSwitch[1] |= 0x80;
bitSwitch[1] &= ~0x80;
KeyBoard('F', 1);
@@ -407,16 +432,20 @@ void TMWDComm::CheckData() // sprawdzanie wejść cyfrowych i odpowiednie sterow
//PORT2
if (maskSwitch[2] & 0x01) {
if (bitSwitch[2] & 0x01) {
if (maskSwitch[2] & 0x01)
{
if (bitSwitch[2] & 0x01)
{
KeyBoard('P', 0);
KeyBoard(0x10, 0);
}
else KeyBoard('P', 0);
maskSwitch[2] &= ~0x01;
}
if (maskSwitch[2] & 0x02) {
if (bitSwitch[2] & 0x02) {
if (maskSwitch[2] & 0x02)
{
if (bitSwitch[2] & 0x02)
{
KeyBoard('O', 0);
KeyBoard(0x10, 0);
}
@@ -424,35 +453,41 @@ void TMWDComm::CheckData() // sprawdzanie wejść cyfrowych i odpowiednie sterow
maskSwitch[2] &= ~0x02;
}
if (maskData[2] & 0x01) if (lastStateData[2] & 0x01) { // pantograf przedni
// pantograf przedni
if (maskData[2] & 0x01) if (lastStateData[2] & 0x01)
{
KeyBoard(0x10, 1); // bistabilny
KeyBoard('P', 1);
maskSwitch[2] |= 0x01;
bitSwitch[2] |= 0x01;
}
else {
else
{
maskSwitch[2] |= 0x01;
bitSwitch[2] &= ~0x01;
KeyBoard('P', 1);
}
if (maskData[2] & 0x02) if (lastStateData[2] & 0x02) { // pantograf tylni
// pantograf tylni
if (maskData[2] & 0x02) if (lastStateData[2] & 0x02)
{
KeyBoard(0x10, 1); // bistabilny
KeyBoard('O', 1);
maskSwitch[2] |= 0x02;
bitSwitch[2] |= 0x02;
}
else {
else
{
maskSwitch[2] |= 0x02;
bitSwitch[2] &= ~0x02;
KeyBoard('O', 1);
}
if (maskData[2] & 0x04) if (lastStateData[2] & 0x04) { // przyhamowanie przy poślizgu
// przyhamowanie przy poślizgu
if (maskData[2] & 0x04) if (lastStateData[2] & 0x04) {
KeyBoard(0x10, 1); // monostabilny
KeyBoard(0x0D, 1);
}
else {
else
{
KeyBoard(0x0D, 0);
KeyBoard(0x10, 0);
}
@@ -474,178 +509,129 @@ void TMWDComm::CheckData() // sprawdzanie wejść cyfrowych i odpowiednie sterow
KeyBoard(0x11,0);
KeyBoard(' ',1);
}*/
if (maskData[2] & 0x20) if (lastStateData[2] & 0x20) KeyBoard(0x66, 1); // odluźniacz
else KeyBoard(0x66, 0); // monostabilny
if (maskData[2] & 0x40) if (lastStateData[2] & 0x40) { // syrena wysoka
// odluźniacz
if (maskData[2] & 0x20) if (lastStateData[2] & 0x20)
KeyBoard(0x66, 1);
else
KeyBoard(0x66, 0); // monostabilny
// syrena wysoka
if (maskData[2] & 0x40) if (lastStateData[2] & 0x40)
{
KeyBoard(0x10, 1); // monostabilny
KeyBoard('A', 1);
}
else {
else
{
KeyBoard('A', 0);
KeyBoard(0x10, 0);
}
if (maskData[2] & 0x80) if (lastStateData[2] & 0x80) KeyBoard('A', 1); // syrena niska
else KeyBoard('A', 0); // monostabilny
if (maskData[2] & 0x80) if (lastStateData[2] & 0x80)
KeyBoard('A', 1); // syrena niska
else
KeyBoard('A', 0); // monostabilny
//PORT3
//PORT3
if (maskSwitch[3] & 0x01) {
if (bitSwitch[3] & 0x01) {
if (maskSwitch[3] & 0x01)
{
if (bitSwitch[3] & 0x01)
{
KeyBoard('J', 0);
KeyBoard(0x10, 0);
}
else KeyBoard('J', 0);
maskSwitch[3] &= ~0x01;
}
if (maskSwitch[3] & 0x02)
{
if (bitSwitch[3] & 0x02)
{
KeyBoard('Y', 0);
KeyBoard(0x10, 0);
}
else KeyBoard('Y', 0);
maskSwitch[3] &= ~0x02;
}
if (maskSwitch[3] & 0x04)
{
if (bitSwitch[3] & 0x04)
{
KeyBoard('U', 0);
KeyBoard(0x10, 0);
}
else KeyBoard('U', 0);
maskSwitch[3] &= ~0x04;
}
if (maskSwitch[3] & 0x08)
{
if (bitSwitch[3] & 0x08)
{
KeyBoard('I', 0);
KeyBoard(0x10, 0);
}
else KeyBoard('I', 0);
maskSwitch[3] &= ~0x08;
}
if (maskData[3] & 0x01) if (lastStateData[3] & 0x01) { // bateria
// bateria
if (maskData[3] & 0x01) if (lastStateData[3] & 0x01)
{
KeyBoard(0x10, 1); // bistabilny
KeyBoard('J', 1);
maskSwitch[3] |= 0x01;
bitSwitch[3] |= 0x01;
}
else {
else
{
maskSwitch[3] |= 0x01;
bitSwitch[3] &= ~0x01;
KeyBoard('J', 1);
}
/*
if(maskData[3] & 0x04 && lastStateData[1] & 0x04) { KeyBoard(0x10,1);
KeyBoard('C',1); //
KeyBoard('C',0);
KeyBoard(0x10,0);
}else{ KeyBoard('C',1); //
KeyBoard('C',0);
}
if(maskData[3] & 0x08 && lastStateData[1] & 0x08) KeyBoard('S',1); //
else KeyBoard('S',0);
//Światło lewe
if (maskData[3] & 0x02) if (lastStateData[3] & 0x02)
{
KeyBoard(0x10, 1); // bistabilny
KeyBoard('Y', 1);
maskSwitch[3] |= 0x02;
bitSwitch[3] |= 0x02;
}else
{
maskSwitch[3] |= 0x02;
bitSwitch[3] &= ~0x02;
KeyBoard('Y', 1);
}
//światło górne
if (maskData[3] & 0x04) if (lastStateData[3] & 0x04)
{
KeyBoard(0x10, 1); // bistabilny
KeyBoard('U', 1);
maskSwitch[3] |= 0x04;
bitSwitch[3] |= 0x04;
}
else
{
maskSwitch[3] |= 0x04;
bitSwitch[3] &= ~0x04;
KeyBoard('U', 1);
}
//światło prawe
if (maskData[3] & 0x08) if (lastStateData[3] & 0x08)
{
KeyBoard(0x10, 1); // bistabilny
KeyBoard('I', 1);
maskSwitch[3] |= 0x08;
bitSwitch[3] |= 0x08;
}
else
{
maskSwitch[3] |= 0x08;
bitSwitch[3] &= ~0x08;
KeyBoard('I', 1);
}
if(maskData[3] & 0x10 && lastStateData[1] & 0x10) {
KeyBoard(0x11,1);
KeyBoard('H',1);
}else{ KeyBoard('H',0);
KeyBoard(0x11,0);
}
if(maskData[3] & 0x20 && lastStateData[1] & 0x20) {
KeyBoard(0x11,1);
KeyBoard(' ',1);
}else{ KeyBoard(' ',0);
KeyBoard(0x11,0);
}
if(maskData[3] & 0x40 && lastStateData[1] & 0x40) {
KeyBoard(0x10,1);
KeyBoard(' ',1);
}else{ KeyBoard(' ',0);
KeyBoard(0x10,0);
}
if(maskData[3] & 0x80 && lastStateData[1] & 0x80) {
KeyBoard(0x10,1);
KeyBoard('F',1);
}else{ KeyBoard('F',0);
KeyBoard(0x10,0);
}
/*PORT4*/ /*
if(maskData[4] & 0x02 && lastStateData[1] & 0x02) {
KeyBoard(0x10,1);
KeyBoard('X',1); //
KeyBoard('X',0);
KeyBoard(0x10,0);
}else{ KeyBoard('X',1); //
KeyBoard('X',0);
}
if(maskData[4] & 0x04 && lastStateData[1] & 0x04) {
KeyBoard(0x10,1);
KeyBoard('C',1); //
KeyBoard('C',0);
KeyBoard(0x10,0);
}else{ KeyBoard('C',1); //
KeyBoard('C',0);
}
if(maskData[4] & 0x08 && lastStateData[1] & 0x08) KeyBoard('S',1); //
else KeyBoard('S',0);
if(maskData[4] & 0x10 && lastStateData[1] & 0x10) {
KeyBoard(0x11,1);
KeyBoard('H',1);
}else{ KeyBoard('H',0);
KeyBoard(0x11,0);
}
if(maskData[4] & 0x20 && lastStateData[1] & 0x20) {
KeyBoard(0x11,1);
KeyBoard(' ',1);
}else{ KeyBoard(' ',0);
KeyBoard(0x11,0);
}
if(maskData[4] & 0x40 && lastStateData[1] & 0x40) {
KeyBoard(0x10,1);
KeyBoard(' ',1);
}else{ KeyBoard(' ',0);
KeyBoard(0x10,0);
}
if(maskData[4] & 0x80 && lastStateData[1] & 0x80) {
KeyBoard(0x10,1);
KeyBoard('F',1);
}else{ KeyBoard('F',0);
KeyBoard(0x10,0);
}
/*PORT5*/ /*
if(maskData[5] & 0x02 && lastStateData[1] & 0x02) {
KeyBoard(0x10,1);
KeyBoard('X',1); //
KeyBoard('X',0);
KeyBoard(0x10,0);
}else{
KeyBoard('X',1); //
KeyBoard('X',0);
}
if(maskData[5] & 0x04 && lastStateData[1] & 0x04) {
KeyBoard(0x10,1);
KeyBoard('C',1); //
KeyBoard('C',0);
KeyBoard(0x10,0);
}else{
KeyBoard('C',1); //
KeyBoard('C',0);
}
if(maskData[5] & 0x08 && lastStateData[1] & 0x08) KeyBoard('S',1); //
else
KeyBoard('S',0);
if(maskData[5] & 0x10 && lastStateData[1] & 0x10) {
KeyBoard(0x11,1);
KeyBoard('H',1);
}else{
KeyBoard('H',0);
KeyBoard(0x11,0);
}
if(maskData[5] & 0x20 && lastStateData[1] & 0x20) {
KeyBoard(0x11,1);
KeyBoard(' ',1);
}else{
KeyBoard(' ',0);
KeyBoard(0x11,0);
}
if(maskData[5] & 0x40 && lastStateData[1] & 0x40) {
KeyBoard(0x10,1);
KeyBoard(' ',1);
}else{
KeyBoard(' ',0);
KeyBoard(0x10,0);
}
if(maskData[5] & 0x80 && lastStateData[1] & 0x80) {
KeyBoard(0x10,1);
KeyBoard('F',1);
}else{
KeyBoard('F',0);
KeyBoard(0x10,0);
}//*/
/* NASTAWNIK, BOCZNIK i KIERUNEK */

View File

@@ -399,4 +399,5 @@ class TController
int CrossRoute(TTrack *tr);
void RouteSwitch(int d);
std::string OwnerName();
TMoverParameters const *Controlling() const { return mvControlling; }
};

View File

@@ -523,7 +523,7 @@ void TDynamicObject::UpdateLeverEnum(TAnim *pAnim)
};
// ABu 29.01.05 przeklejone z render i renderalpha: *********************
void __inline TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
{ // ABu290105: pozbierane i uporzadkowane powtarzajace
// sie rzeczy z Render i RenderAlpha
// dodatkowy warunek, if (ObjSqrDist<...) zeby niepotrzebnie nie zmianiec w
@@ -557,8 +557,6 @@ void __inline TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
mdLoad->GetSMRoot()->SetTranslate(modelShake + vFloor);
if (mdLowPolyInt)
mdLowPolyInt->GetSMRoot()->SetTranslate(modelShake);
if (mdPrzedsionek)
mdPrzedsionek->GetSMRoot()->SetTranslate(modelShake);
// ABu: koniec rzucania
// ABu011104: liczenie obrotow wozkow
ABuBogies();
@@ -1694,12 +1692,14 @@ TDynamicObject::TDynamicObject()
//}
mdModel = NULL;
mdKabina = NULL;
ReplacableSkinID[0] = 0;
ReplacableSkinID[1] = 0;
ReplacableSkinID[2] = 0;
ReplacableSkinID[3] = 0;
ReplacableSkinID[4] = 0;
#ifdef EU07_USE_OLD_RENDERCODE
ReplacableSkinID[ 0 ] = 0;
ReplacableSkinID[ 1 ] = 0;
ReplacableSkinID[ 2 ] = 0;
ReplacableSkinID[ 3 ] = 0;
ReplacableSkinID[ 4 ] = 0;
iAlpha = 0x30300030; // tak gdy tekstury wymienne nie mają przezroczystości
#endif
// smWiazary[0]=smWiazary[1]=NULL;
smWahacze[0] = smWahacze[1] = smWahacze[2] = smWahacze[3] = NULL;
fWahaczeAmp = 0;
@@ -1707,7 +1707,6 @@ TDynamicObject::TDynamicObject()
smLoadMode = NULL;
mdLoad = NULL;
mdLowPolyInt = NULL;
mdPrzedsionek = NULL;
//smMechanik0 = smMechanik1 = NULL;
smBuforLewy[0] = smBuforLewy[1] = NULL;
smBuforPrawy[0] = smBuforPrawy[1] = NULL;
@@ -2341,8 +2340,7 @@ void TDynamicObject::Move(double fDistance)
{ // przeliczenie cienia
TTrack *t0 = Axle0.GetTrack(); // już po przesunięciu
TTrack *t1 = Axle1.GetTrack();
if ((t0->eEnvironment == e_flat) && (t1->eEnvironment == e_flat)) // może być
// e_bridge...
if ((t0->eEnvironment == e_flat) && (t1->eEnvironment == e_flat)) // może być e_bridge...
fShade = 0.0; // standardowe oświetlenie
else
{ // jeżeli te tory mają niestandardowy stopień zacienienia
@@ -2365,6 +2363,21 @@ void TDynamicObject::Move(double fDistance)
if (Axle0.GetDirection() < 0)
d = t0->fTrackLength - d; // od drugiej strony liczona długość
d /= fAxleDist; // rozsataw osi procentowe znajdowanie się na torze
float shadefrom = 1.0f, shadeto = 1.0f;
// NOTE, TODO: calculating brightness level is used enough times to warrant encapsulation into a function
switch( t0->eEnvironment ) {
case e_canyon: { shadeto = 0.65f; break; }
case e_tunnel: { shadeto = 0.2f; break; }
default: {break; }
}
switch( t1->eEnvironment ) {
case e_canyon: { shadefrom = 0.65f; break; }
case e_tunnel: { shadefrom = 0.2f; break; }
default: {break; }
}
fShade = interpolate( shadefrom, shadeto, static_cast<float>( d ) );
/*
switch (t0->eEnvironment)
{ // typ zmiany oświetlenia - zakładam, że
// drugi tor ma e_flat
@@ -2385,6 +2398,7 @@ void TDynamicObject::Move(double fDistance)
fShade = d + (1.0 - d) * 0.20;
break; // zacienienie w tunelu
}
*/
}
}
}
@@ -3699,39 +3713,12 @@ void TDynamicObject::TurnOff()
btMechanik1.TurnOff();
btMechanik2.TurnOff();
};
#ifdef EU07_USE_OLD_RENDERCODE
void TDynamicObject::Render()
{ // rysowanie elementów nieprzezroczystych
// youBy - sprawdzamy, czy jest sens renderowac
/*
double modelrotate;
vector3 tempangle;
// zmienne
renderme = false;
// przeklejka
double ObjSqrDist = SquareMagnitude(Global::pCameraPosition - vPosition) / Global::ZoomFactor;
// koniec przeklejki
if (ObjSqrDist < 500) // jak jest blisko - do 70m
modelrotate = 0.01; // mały kąt, żeby nie znikało
else
{ // Global::pCameraRotation to kąt bewzględny w świecie (zero - na północ)
tempangle = (vPosition - Global::pCameraPosition); // wektor od kamery
modelrotate = ABuAcos(tempangle); // określenie kąta
// if (modelrotate>M_PI) modelrotate-=(2*M_PI);
modelrotate += Global::pCameraRotation;
}
if (modelrotate > M_PI)
modelrotate -= (2 * M_PI);
if (modelrotate < -M_PI)
modelrotate += (2 * M_PI);
ModCamRot = modelrotate;
modelrotate = abs(modelrotate);
if (modelrotate < maxrot)
renderme = true;
*/
if (Global::pCamera->IsVisible(this))
if (GfxRenderer.Visible(this))
{
TSubModel::iInstance = (size_t)this; //żeby nie robić cudzych animacji
// AnsiString asLoadName="";
@@ -3776,7 +3763,6 @@ void TDynamicObject::Render()
vPosition.z); // standardowe przesunięcie względem początku scenerii
glMultMatrixd(mMatrix.getArray());
#ifdef EU07_USE_OLD_LIGHTING_MODEL
// TODO: re-implement this
if (fShade > 0.0)
{ // Ra: zmiana oswietlenia w tunelu, wykopie
GLfloat ambientLight[4] = {0.5f, 0.5f, 0.5f, 1.0f};
@@ -3793,6 +3779,11 @@ void TDynamicObject::Render()
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
}
#else
if( fShade > 0.0f ) {
// change light level based on light level of the occupied track
Global::DayLight.apply_intensity( fShade );
}
#endif
if (Global::bUseVBO)
{ // wersja VBO
@@ -3802,8 +3793,6 @@ void TDynamicObject::Render()
mdModel->RaRender(ObjSqrDist, ReplacableSkinID, iAlpha);
if (mdLoad) // renderowanie nieprzezroczystego ładunku
mdLoad->RaRender(ObjSqrDist, ReplacableSkinID, iAlpha);
if (mdPrzedsionek)
mdPrzedsionek->RaRender(ObjSqrDist, ReplacableSkinID, iAlpha);
}
else
{ // wersja Display Lists
@@ -3830,8 +3819,6 @@ void TDynamicObject::Render()
mdModel->Render(ObjSqrDist, ReplacableSkinID, iAlpha);
if (mdLoad) // renderowanie nieprzezroczystego ładunku
mdLoad->Render(ObjSqrDist, ReplacableSkinID, iAlpha);
if (mdPrzedsionek)
mdPrzedsionek->Render(ObjSqrDist, ReplacableSkinID, iAlpha);
}
// Ra: czy ta kabina tu ma sens?
@@ -3898,6 +3885,11 @@ void TDynamicObject::Render()
glLightfv(GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, Global::specularDayLight);
}
#else
if( fShade > 0.0f ) {
// restore regular light level
Global::DayLight.apply_intensity();
}
#endif
glPopMatrix();
if (btnOn)
@@ -3905,10 +3897,83 @@ void TDynamicObject::Render()
} // yB - koniec mieszania z grafika
};
void TDynamicObject::RenderAlpha()
{ // rysowanie elementów półprzezroczystych
if (renderme)
{
TSubModel::iInstance = (size_t)this; //żeby nie robić cudzych animacji
double ObjSqrDist = SquareMagnitude(Global::pCameraPosition - vPosition);
ABuLittleUpdate(ObjSqrDist); // ustawianie zmiennych submodeli dla wspólnego modelu
glPushMatrix();
if (this == Global::pUserDynamic)
{ // specjalne ustawienie, aby nie trzęsło
glPopMatrix(); // to trzeba zebrać przed wyściem
return;
glLoadIdentity(); // zacząć od macierzy jedynkowej
Global::pCamera->SetCabMatrix(vPosition); // specjalne ustawienie kamery
}
else
glTranslated(vPosition.x, vPosition.y,
vPosition.z); // standardowe przesunięcie względem początku scenerii
glMultMatrixd(mMatrix.getArray());
#ifdef EU07_USE_OLD_LIGHTING_MODEL
// TODO: re-implement this
if (fShade > 0.0)
{ // Ra: zmiana oswietlenia w tunelu, wykopie
GLfloat ambientLight[4] = {0.5f, 0.5f, 0.5f, 1.0f};
GLfloat diffuseLight[4] = {0.5f, 0.5f, 0.5f, 1.0f};
GLfloat specularLight[4] = {0.5f, 0.5f, 0.5f, 1.0f};
// trochę problem z ambientem w wykopie...
for (int li = 0; li < 3; li++)
{
ambientLight[li] = Global::ambientDayLight[li] * fShade;
diffuseLight[li] = Global::diffuseDayLight[li] * fShade;
specularLight[li] = Global::specularDayLight[li] * fShade;
}
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
}
#endif
if (Global::bUseVBO)
{ // wersja VBO
if (mdLowPolyInt)
if (FreeFlyModeFlag ? true : !mdKabina || !bDisplayCab)
mdLowPolyInt->RaRenderAlpha(ObjSqrDist, ReplacableSkinID, iAlpha);
mdModel->RaRenderAlpha(ObjSqrDist, ReplacableSkinID, iAlpha);
if (mdLoad)
mdLoad->RaRenderAlpha(ObjSqrDist, ReplacableSkinID, iAlpha);
}
else
{ // wersja Display Lists
if (mdLowPolyInt)
if (FreeFlyModeFlag ? true : !mdKabina || !bDisplayCab)
mdLowPolyInt->RenderAlpha(ObjSqrDist, ReplacableSkinID, iAlpha);
mdModel->RenderAlpha(ObjSqrDist, ReplacableSkinID, iAlpha);
if (mdLoad)
mdLoad->RenderAlpha(ObjSqrDist, ReplacableSkinID, iAlpha);
}
#ifdef EU07_USE_OLD_LIGHTING_MODEL
// TODO: re-implement this
if (fShade != 0.0) // tylko jeśli było zmieniane
{ // przywrócenie standardowego oświetlenia
glLightfv(GL_LIGHT0, GL_AMBIENT, Global::ambientDayLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, Global::specularDayLight);
}
#endif
glPopMatrix();
if (btnOn)
TurnOff(); // przywrócenie domyślnych pozycji submodeli
}
return;
} // koniec renderalpha
#endif
void TDynamicObject::RenderSounds()
{ // przeliczanie dźwięków, bo będzie
// słychać bez wyświetlania sektora z
// pojazdem
{ // przeliczanie dźwięków, bo będzie słychać bez wyświetlania sektora z pojazdem
// if( Global::iPause > 0 ) { return; }
// McZapkie-010302: ulepszony dzwiek silnika
double freq;
double vol = 0;
@@ -3919,11 +3984,10 @@ void TDynamicObject::RenderSounds()
if (MoverParameters->Power > 0)
{
if ((rsSilnik.AM != 0) && ((MoverParameters->Mains) || (MoverParameters->EngineType ==
DieselEngine))) // McZapkie-280503:
// zeby dla dumb
// dzialal silnik na
// jalowych obrotach
if ((rsSilnik.AM != 0)
&& ((MoverParameters->Mains)
// McZapkie-280503: zeby dla dumb dzialal silnik na jalowych obrotach
|| (MoverParameters->EngineType == DieselEngine)))
{
if ((fabs(MoverParameters->enrot) > 0.01) ||
(MoverParameters->EngineType == Dumb)) //&& (MoverParameters->EnginePower>0.1))
@@ -4128,9 +4192,8 @@ void TDynamicObject::RenderSounds()
sSmallCompressor.Update(MechInside, GetPosition());
// youBy - przenioslem, bo diesel tez moze miec turbo
if ((MoverParameters->MainCtrlPos) >=
(MoverParameters->TurboTest)) // hunter-250312: dlaczego zakomentowane?
// Ra: bo nie działało dobrze
if( (MoverParameters->TurboTest > 0)
&& (MoverParameters->MainCtrlPos >= MoverParameters->TurboTest))
{
// udawanie turbo: (6.66*(eng_vol-0.85))
if (eng_turbo > 6.66 * (enginevolume - 0.8) + 0.2 * dt)
@@ -4274,85 +4337,6 @@ void TDynamicObject::RenderSounds()
*/
};
void TDynamicObject::RenderAlpha()
{ // rysowanie elementów półprzezroczystych
if (renderme)
{
TSubModel::iInstance = (size_t)this; //żeby nie robić cudzych animacji
double ObjSqrDist = SquareMagnitude(Global::pCameraPosition - vPosition);
ABuLittleUpdate(ObjSqrDist); // ustawianie zmiennych submodeli dla wspólnego modelu
glPushMatrix();
if (this == Global::pUserDynamic)
{ // specjalne ustawienie, aby nie trzęsło
if (Global::bSmudge)
{ // jak smuga, to rysować po smudze
glPopMatrix(); // to trzeba zebrać przed wyściem
return;
}
glLoadIdentity(); // zacząć od macierzy jedynkowej
Global::pCamera->SetCabMatrix(vPosition); // specjalne ustawienie kamery
}
else
glTranslated(vPosition.x, vPosition.y,
vPosition.z); // standardowe przesunięcie względem początku scenerii
glMultMatrixd(mMatrix.getArray());
#ifdef EU07_USE_OLD_LIGHTING_MODEL
// TODO: re-implement this
if (fShade > 0.0)
{ // Ra: zmiana oswietlenia w tunelu, wykopie
GLfloat ambientLight[4] = {0.5f, 0.5f, 0.5f, 1.0f};
GLfloat diffuseLight[4] = {0.5f, 0.5f, 0.5f, 1.0f};
GLfloat specularLight[4] = {0.5f, 0.5f, 0.5f, 1.0f};
// trochę problem z ambientem w wykopie...
for (int li = 0; li < 3; li++)
{
ambientLight[li] = Global::ambientDayLight[li] * fShade;
diffuseLight[li] = Global::diffuseDayLight[li] * fShade;
specularLight[li] = Global::specularDayLight[li] * fShade;
}
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
}
#endif
if (Global::bUseVBO)
{ // wersja VBO
if (mdLowPolyInt)
if (FreeFlyModeFlag ? true : !mdKabina || !bDisplayCab)
mdLowPolyInt->RaRenderAlpha(ObjSqrDist, ReplacableSkinID, iAlpha);
mdModel->RaRenderAlpha(ObjSqrDist, ReplacableSkinID, iAlpha);
if (mdLoad)
mdLoad->RaRenderAlpha(ObjSqrDist, ReplacableSkinID, iAlpha);
// if (mdPrzedsionek) //Ra: przedsionków tu wcześniej nie było - włączyć?
// mdPrzedsionek->RaRenderAlpha(ObjSqrDist,ReplacableSkinID,iAlpha);
}
else
{ // wersja Display Lists
if (mdLowPolyInt)
if (FreeFlyModeFlag ? true : !mdKabina || !bDisplayCab)
mdLowPolyInt->RenderAlpha(ObjSqrDist, ReplacableSkinID, iAlpha);
mdModel->RenderAlpha(ObjSqrDist, ReplacableSkinID, iAlpha);
if (mdLoad)
mdLoad->RenderAlpha(ObjSqrDist, ReplacableSkinID, iAlpha);
// if (mdPrzedsionek) //Ra: przedsionków tu wcześniej nie było - włączyć?
// mdPrzedsionek->RenderAlpha(ObjSqrDist,ReplacableSkinID,iAlpha);
}
#ifdef EU07_USE_OLD_LIGHTING_MODEL
// TODO: re-implement this
if (fShade != 0.0) // tylko jeśli było zmieniane
{ // przywrócenie standardowego oświetlenia
glLightfv(GL_LIGHT0, GL_AMBIENT, Global::ambientDayLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, Global::specularDayLight);
}
#endif
glPopMatrix();
if (btnOn)
TurnOff(); // przywrócenie domyślnych pozycji submodeli
}
return;
} // koniec renderalpha
// McZapkie-250202
// wczytywanie pliku z danymi multimedialnymi (dzwieki)
void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
@@ -4378,6 +4362,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
if( token == "models:") {
// modele i podmodele
#ifdef EU07_USE_OLD_RENDERCODE
iMultiTex = 0; // czy jest wiele tekstur wymiennych?
parser.getTokens();
parser >> asModel;
@@ -4388,10 +4373,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
}
std::size_t i = asModel.find( ',' );
if ( i != std::string::npos )
{ // Ra 2015-01: może szukać przecinka w
// nazwie modelu, a po przecinku była by
// liczba
// tekstur?
{ // Ra 2015-01: może szukać przecinka w nazwie modelu, a po przecinku była by liczba tekstur?
if (i < asModel.length())
iMultiTex = asModel[i + 1] - '0';
if (iMultiTex < 0)
@@ -4399,78 +4381,37 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
else if (iMultiTex > 1)
iMultiTex = 1; // na razie ustawiamy na 1
}
#else
m_materialdata.multi_textures = 0; // czy jest wiele tekstur wymiennych?
parser.getTokens();
parser >> asModel;
if( asModel[asModel.size() - 1] == '#' ) // Ra 2015-01: nie podoba mi siê to
{ // model wymaga wielu tekstur wymiennych
m_materialdata.multi_textures = 1;
asModel.erase( asModel.length() - 1 );
}
std::size_t i = asModel.find( ',' );
if ( i != std::string::npos )
{ // Ra 2015-01: może szukać przecinka w nazwie modelu, a po przecinku była by liczba tekstur?
if (i < asModel.length())
m_materialdata.multi_textures = asModel[i + 1] - '0';
m_materialdata.multi_textures = clamp( m_materialdata.multi_textures, 0, 1 ); // na razie ustawiamy na 1
}
#endif
asModel = BaseDir + asModel; // McZapkie 2002-07-20: dynamics maja swoje
// modele w dynamics/basedir
Global::asCurrentTexturePath = BaseDir; // biezaca sciezka do tekstur to dynamic/...
mdModel = TModelsManager::GetModel(asModel, true);
assert( mdModel != nullptr ); // TODO: handle this more gracefully than all going to shit
if (ReplacableSkin != "none")
#ifdef EU07_USE_OLD_RENDERCODE
{ // tekstura wymienna jest raczej jedynie w "dynamic\"
ReplacableSkin =
Global::asCurrentTexturePath + ReplacableSkin; // skory tez z dynamic/...
std::string x = TextureTest(Global::asCurrentTexturePath + "nowhere"); // na razie prymitywnie
if (!x.empty())
ReplacableSkinID[4] = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + "nowhere", "", 9);
/*
if ((i = ReplacableSkin.Pos("|")) > 0) // replacable dzielone
{
iMultiTex = -1;
ReplacableSkinID[-iMultiTex] = TTexturesManager::GetTextureID(
NULL, NULL, ReplacableSkin.SubString(1, i - 1).c_str(),
Global::iDynamicFiltering);
ReplacableSkin.Delete(1, i); // usunięcie razem z pionową kreską
ReplacableSkin = Global::asCurrentTexturePath +
ReplacableSkin; // odtworzenie początku ścieżki
// sprawdzić, ile jest i ustawić iMultiTex na liczbę podanych tekstur
if (!ReplacableSkin.IsEmpty())
{ // próba wycięcia drugiej nazwy
iMultiTex = -2; // skoro zostało coś po kresce, to są co najmniej dwie
if ((i = ReplacableSkin.Pos("|")) == 0) // gdy nie ma już kreski
ReplacableSkinID[-iMultiTex] = TTexturesManager::GetTextureID(
NULL, NULL, ReplacableSkin.SubString(1, i - 1).c_str(),
Global::iDynamicFiltering);
else
{ // jak jest kreska, to wczytać drugą i próbować trzecią
ReplacableSkinID[-iMultiTex] = TTexturesManager::GetTextureID(
NULL, NULL, ReplacableSkin.SubString(1, i - 1).c_str(),
Global::iDynamicFiltering);
ReplacableSkin.Delete(1, i); // usunięcie razem z pionową kreską
ReplacableSkin = Global::asCurrentTexturePath +
ReplacableSkin; // odtworzenie początku ścieżki
if (!ReplacableSkin.IsEmpty())
{ // próba wycięcia trzeciej nazwy
iMultiTex =
-3; // skoro zostało coś po kresce, to są co najmniej trzy
if ((i = ReplacableSkin.Pos("|")) == 0) // gdy nie ma już kreski
ReplacableSkinID[-iMultiTex] = TTexturesManager::GetTextureID(
NULL, NULL, ReplacableSkin.SubString(1, i - 1).c_str(),
Global::iDynamicFiltering);
else
{ // jak jest kreska, to wczytać trzecią i próbować czwartą
ReplacableSkinID[-iMultiTex] = TTexturesManager::GetTextureID(
NULL, NULL, ReplacableSkin.SubString(1, i - 1).c_str(),
Global::iDynamicFiltering);
ReplacableSkin.Delete(1, i); // usunięcie razem z pionową kreską
ReplacableSkin = Global::asCurrentTexturePath +
ReplacableSkin; // odtworzenie początku ścieżki
if (!ReplacableSkin.IsEmpty())
{ // próba wycięcia trzeciej nazwy
iMultiTex = -4; // skoro zostało coś po kresce, to są co
// najmniej cztery
ReplacableSkinID[-iMultiTex] =
TTexturesManager::GetTextureID(
NULL, NULL,
ReplacableSkin.SubString(1, i - 1).c_str(),
Global::iDynamicFiltering);
// więcej na razie nie zadziała, a u tak trzeba to do modeli
// przenieść
}
}
}
}
}
}
*/
std::string x = TextureTest(Global::asCurrentTexturePath + "nowhere"); // na razie prymitywnie
if (!x.empty())
ReplacableSkinID[4] = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + "nowhere", "", 9);
if (iMultiTex > 0)
{ // jeśli model ma 4 tekstury
ReplacableSkinID[1] = GfxRenderer.GetTextureId(
@@ -4490,8 +4431,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
ReplacableSkinID[4] = GfxRenderer.GetTextureId(
ReplacableSkin + ",4", "", Global::iDynamicFiltering);
if (ReplacableSkinID[4])
iMultiTex = 4; // jak są cztery, to blokujemy podmianę tekstury
// rozkładem
iMultiTex = 4; // jak są cztery, to blokujemy podmianę tekstury rozkładem
}
}
}
@@ -4506,37 +4446,75 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
ReplacableSkinID[1] = GfxRenderer.GetTextureId(
ReplacableSkin, "", Global::iDynamicFiltering);
if (GfxRenderer.Texture(ReplacableSkinID[1]).has_alpha)
iAlpha = 0x31310031; // tekstura -1 z kanałem alfa - nie renderować w cyklu
// nieprzezroczystych
iAlpha = 0x31310031; // tekstura -1 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
else
iAlpha = 0x30300030; // wszystkie tekstury nieprzezroczyste - nie
// renderować w
// cyklu przezroczystych
iAlpha = 0x30300030; // wszystkie tekstury nieprzezroczyste - nie renderować w cyklu przezroczystych
if (ReplacableSkinID[2])
if (GfxRenderer.Texture(ReplacableSkinID[2]).has_alpha)
iAlpha |= 0x02020002; // tekstura -2 z kanałem alfa - nie renderować
// w cyklu
// nieprzezroczystych
iAlpha |= 0x02020002; // tekstura -2 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
if (ReplacableSkinID[3])
if (GfxRenderer.Texture(ReplacableSkinID[3]).has_alpha)
iAlpha |= 0x04040004; // tekstura -3 z kanałem alfa - nie renderować
// w cyklu
// nieprzezroczystych
iAlpha |= 0x04040004; // tekstura -3 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
if (ReplacableSkinID[4])
if (GfxRenderer.Texture(ReplacableSkinID[4]).has_alpha)
iAlpha |= 0x08080008; // tekstura -4 z kanałem alfa - nie renderować
// w cyklu
// nieprzezroczystych
iAlpha |= 0x08080008; // tekstura -4 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
}
/*
// Winger 040304 - ladowanie przedsionkow dla EZT
if (MoverParameters->TrainType == dt_EZT)
{
asModel = "przedsionki.t3d";
asModel = BaseDir + asModel;
mdPrzedsionek = TModelsManager::GetModel(asModel, true);
#else
{ // tekstura wymienna jest raczej jedynie w "dynamic\"
ReplacableSkin = Global::asCurrentTexturePath + ReplacableSkin; // skory tez z dynamic/...
std::string x = TextureTest(Global::asCurrentTexturePath + "nowhere"); // na razie prymitywnie
if (!x.empty())
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + "nowhere", "", 9 );
if (m_materialdata.multi_textures > 0)
{ // jeśli model ma 4 tekstury
m_materialdata.replacable_skins[ 1 ] = GfxRenderer.GetTextureId(
ReplacableSkin + ",1", "", Global::iDynamicFiltering);
if( m_materialdata.replacable_skins[ 1 ] )
{ // pierwsza z zestawu znaleziona
m_materialdata.replacable_skins[ 2 ] = GfxRenderer.GetTextureId(
ReplacableSkin + ",2", "", Global::iDynamicFiltering);
if( m_materialdata.replacable_skins[ 2 ] )
{
m_materialdata.multi_textures = 2; // już są dwie
m_materialdata.replacable_skins[ 3 ] = GfxRenderer.GetTextureId(
ReplacableSkin + ",3", "", Global::iDynamicFiltering);
if( m_materialdata.replacable_skins[ 3 ] )
{
m_materialdata.multi_textures = 3; // a teraz nawet trzy
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.GetTextureId(
ReplacableSkin + ",4", "", Global::iDynamicFiltering);
if( m_materialdata.replacable_skins[ 4 ] )
m_materialdata.multi_textures = 4; // jak są cztery, to blokujemy podmianę tekstury
// rozkładem
}
}
}
else
{ // zestaw nie zadziałał, próbujemy normanie
m_materialdata.multi_textures = 0;
m_materialdata.replacable_skins[ 1 ] = GfxRenderer.GetTextureId(
ReplacableSkin, "", Global::iDynamicFiltering);
}
}
else
m_materialdata.replacable_skins[ 1 ] = GfxRenderer.GetTextureId(
ReplacableSkin, "", Global::iDynamicFiltering);
if( GfxRenderer.Texture( m_materialdata.replacable_skins[ 1 ] ).has_alpha )
m_materialdata.textures_alpha = 0x31310031; // tekstura -1 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
else
m_materialdata.textures_alpha = 0x30300030; // wszystkie tekstury nieprzezroczyste - nie renderować w cyklu przezroczystych
if( m_materialdata.replacable_skins[ 2 ] )
if( GfxRenderer.Texture( m_materialdata.replacable_skins[ 2 ] ).has_alpha )
m_materialdata.textures_alpha |= 0x02020002; // tekstura -2 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
if( m_materialdata.replacable_skins[ 3 ] )
if( GfxRenderer.Texture( m_materialdata.replacable_skins[ 3 ] ).has_alpha )
m_materialdata.textures_alpha |= 0x04040004; // tekstura -3 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
if( m_materialdata.replacable_skins[ 4 ] )
if( GfxRenderer.Texture( m_materialdata.replacable_skins[ 4 ] ).has_alpha )
m_materialdata.textures_alpha |= 0x08080008; // tekstura -4 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
}
*/
#endif
if (!MoverParameters->LoadAccepted.empty())
// if (MoverParameters->LoadAccepted!=AnsiString("")); // &&
// MoverParameters->LoadType!=AnsiString("passengers"))
@@ -5449,8 +5427,6 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
// binarnego
if (mdLoad)
mdLoad->Init();
if (mdPrzedsionek)
mdPrzedsionek->Init();
if (mdLowPolyInt)
mdLowPolyInt->Init();
// sHorn2.CopyIfEmpty(sHorn1); ///żeby jednak trąbił też drugim
@@ -5820,6 +5796,7 @@ std::string TDynamicObject::TextureTest(std::string const &name)
return ""; // nie znaleziona
};
#ifdef EU07_USE_OLD_RENDERCODE
void TDynamicObject::DestinationSet(std::string to, std::string numer)
{ // ustawienie stacji
// docelowej oraz wymiennej
@@ -5866,6 +5843,51 @@ void TDynamicObject::DestinationSet(std::string to, std::string numer)
// Ra 2015-01: żeby zalogować błąd, trzeba by mieć pewność, że model używa
// tekstury nr 4
};
#else
void TDynamicObject::DestinationSet(std::string to, std::string numer)
{ // ustawienie stacji docelowej oraz wymiennej tekstury 4, jeśli istnieje plik
// w zasadzie, to każdy wagon mógłby mieć inną stację docelową
// zwłaszcza w towarowych, pod kątem zautomatyzowania maewrów albo pracy górki
// ale to jeszcze potrwa, zanim będzie możliwe, na razie można wpisać stację z
// rozkładu
if( std::abs( m_materialdata.multi_textures ) >= 4 )
return; // jak są 4 tekstury wymienne, to nie zmieniać rozkładem
numer = Global::Bezogonkow(numer);
asDestination = to;
to = Global::Bezogonkow(to); // do szukania pliku obcinamy ogonki
std::string x = TextureTest(asBaseDir + numer + "@" + MoverParameters->TypeName);
if (!x.empty())
{
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.GetTextureId( x, "", 9 ); // rozmywania 0,1,4,5 nie nadają się
return;
}
x = TextureTest(asBaseDir + numer );
if (!x.empty())
{
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.GetTextureId( x, "", 9 ); // rozmywania 0,1,4,5 nie nadają się
return;
}
if (to.empty())
to = "nowhere";
x = TextureTest(asBaseDir + to + "@" + MoverParameters->TypeName); // w pierwszej kolejności z nazwą FIZ/MMD
if (!x.empty())
{
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.GetTextureId( x, "", 9 ); // rozmywania 0,1,4,5 nie nadają się
return;
}
x = TextureTest(asBaseDir + to); // na razie prymitywnie
if (!x.empty())
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.GetTextureId( x, "", 9 ); // rozmywania 0,1,4,5 nie nadają się
else
{
x = TextureTest(asBaseDir + "nowhere"); // jak nie znalazł dedykowanej, to niech daje nowhere
if (!x.empty())
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.GetTextureId( x, "", 9 );
}
// Ra 2015-01: żeby zalogować błąd, trzeba by mieć pewność, że model używa
// tekstury nr 4
};
#endif
void TDynamicObject::OverheadTrack(float o)
{ // ewentualne wymuszanie jazdy

View File

@@ -18,6 +18,7 @@ http://mozilla.org/MPL/2.0/.
#include "AdvSound.h"
#include "Button.h"
#include "AirCoupler.h"
#include "texture.h"
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
@@ -140,7 +141,24 @@ class TAnim
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#ifndef EU07_USE_OLD_RENDERCODE
// parameters for the material object, as currently used by various simulator models
struct material_data {
int textures_alpha{ 0x30300030 }; // maska przezroczystości tekstur. default: tekstury wymienne nie mają przezroczystości
texture_manager::size_type replacable_skins[ 5 ]; // McZapkie:zmienialne nadwozie
int multi_textures{ 0 }; //<0 tekstury wskazane wpisem, >0 tekstury z przecinkami, =0 jedna
material_data() {
::SecureZeroMemory( replacable_skins, sizeof( replacable_skins ) );
}
};
#endif
class TDynamicObject { // klasa pojazdu
friend class opengl_renderer;
private: // położenie pojazdu w świecie oraz parametry ruchu
vector3 vPosition; // Ra: pozycja pojazdu liczona zaraz po przesunięciu
vector3 vCoulpler[ 2 ]; // współrzędne sprzęgów do liczenia zderzeń czołowych
@@ -172,12 +190,9 @@ public: // parametry położenia pojazdu dostępne publicznie
TPowerSource ConnectedEnginePowerSource( TDynamicObject const *Caller ) const;
private:
// returns type of the nearest functional power source present in the trainset
public: // modele składowe pojazdu
TModel3d *mdModel; // model pudła
TModel3d *mdLoad; // model zmiennego ładunku
TModel3d *mdPrzedsionek; // model przedsionków dla EZT - może użyć mdLoad zamiast?
TModel3d *mdKabina; // model kabiny dla użytkownika; McZapkie-030303: to z train.h
TModel3d *mdLowPolyInt; // ABu 010305: wnetrze lowpoly
float3 InteriorLight{ 0.9f * 255.0f / 255.0f, 0.9f * 216.0f / 255.0f, 0.9f * 176.0f / 255.0f }; // tungsten light. TODO: allow definition of light type?
@@ -185,8 +200,17 @@ public: // modele składowe pojazdu
float fShade; // zacienienie: 0:normalnie, -1:w ciemności, +1:dodatkowe światło (brak koloru?)
private: // zmienne i metody do animacji submodeli; Ra: sprzatam animacje w pojeździe
public: // tymczasowo udostępnione do wyszukiwania drutu
int iAnimType[ ANIM_TYPES ]; // 0-osie,1-drzwi,2-obracane,3-zderzaki,4-wózki,5-pantografy,6-tłoki
#ifndef EU07_USE_OLD_RENDERCODE
material_data m_materialdata;
#endif
public:
#ifndef EU07_USE_OLD_RENDERCODE
inline
material_data const *Material() const { return &m_materialdata; }
#endif
// tymczasowo udostępnione do wyszukiwania drutu
int iAnimType[ ANIM_TYPES ]; // 0-osie,1-drzwi,2-obracane,3-zderzaki,4-wózki,5-pantografy,6-tłoki
private:
int iAnimations; // liczba obiektów animujących
/*
@@ -343,6 +367,7 @@ public: // modele składowe pojazdu
public:
int *iLights; // wskaźnik na bity zapalonych świateł (własne albo innego członu)
bool DimHeadlights{ false }; // status of the headlight dimming toggle. NOTE: single toggle for all lights is a simplification. TODO: separate per-light switches
double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym
// pojazdem)
TDynamicObject * PrevAny();
@@ -396,9 +421,11 @@ public: // modele składowe pojazdu
int iCabs; // maski bitowe modeli kabin
TTrack *MyTrack; // McZapkie-030303: tor na ktorym stoi, ABu
std::string asBaseDir;
#ifdef EU07_USE_OLD_RENDERCODE
texture_manager::size_type ReplacableSkinID[5]; // McZapkie:zmienialne nadwozie
int iAlpha; // maska przezroczystości tekstur
int iMultiTex; //<0 tekstury wskazane wpisem, >0 tekstury z przecinkami, =0 jedna
#endif
int iOverheadMask; // maska przydzielana przez AI pojazdom posiadającym pantograf, aby wymuszały
// jazdę bezprądową
TTractionParam tmpTraction;
@@ -417,8 +444,10 @@ public: // modele składowe pojazdu
bool FastUpdate(double dt);
void Move(double fDistance);
void FastMove(double fDistance);
#ifdef EU07_USE_OLD_RENDERCODE
void Render();
void RenderAlpha();
#endif
void RenderSounds();
inline vector3 GetPosition() const
{

View File

@@ -28,6 +28,9 @@ Stele, firleju, szociu, hunter, ZiomalCl, OLI_EU and others
#include "World.h"
#include "Mover.h"
#include "usefull.h"
#include "timer.h"
#include "resource.h"
#include "uilayer.h"
#pragma comment (lib, "glu32.lib")
#pragma comment (lib, "dsound.lib")
@@ -78,8 +81,10 @@ void make_screenshot()
void window_resize_callback(GLFWwindow *window, int w, int h)
{
Global::ScreenWidth = w;
Global::ScreenHeight = h;
// NOTE: we have two variables which basically do the same thing as we don't have dynamic fullscreen toggle
// TBD, TODO: merge them?
Global::ScreenWidth = Global::iWindowWidth = w;
Global::ScreenHeight = Global::iWindowHeight = h;
Global::fDistanceFactor = std::max( 0.5f, h / 768.0f ); // not sure if this is really something we want to use
glViewport(0, 0, w, h);
}
@@ -115,21 +120,33 @@ void key_callback( GLFWwindow *window, int key, int scancode, int action, int mo
make_screenshot();
break;
case GLFW_KEY_ESCAPE: {
//[Esc] pauzuje tylko bez Debugmode
if( DebugModeFlag )
/*
if( ( DebugModeFlag ) //[Esc] pauzuje tylko bez Debugmode
&& ( Global::iPause == 0 ) ) { // but unpausing should work always
break;
}
*/
if( Global::iPause & 1 ) // jeśli pauza startowa
Global::iPause &= ~1; // odpauzowanie, gdy po wczytaniu miało nie startować
else if( !( Global::iMultiplayer & 2 ) ) // w multiplayerze pauza nie ma sensu
if( !Global::ctrlState ) // z [Ctrl] to radiostop jest
Global::iPause ^= 2; // zmiana stanu zapauzowania
if( Global::iPause ) // jak pauza
if( Global::iPause ) {// jak pauza
Global::iTextMode = GLFW_KEY_F1; // to wyświetlić zegar i informację
}
break;
}
case GLFW_KEY_F7:
if( DebugModeFlag ) { // siatki wyświetlane tyko w trybie testowym
if( DebugModeFlag ) {
if( Global::ctrlState ) {
// ctrl + f7 toggles static daylight
World.ToggleDaylight();
break;
}
// f7: wireframe toggle
// siatki wyświetlane tyko w trybie testowym
Global::bWireFrame = !Global::bWireFrame;
if( true == Global::bWireFrame ) {
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
@@ -158,6 +175,14 @@ void focus_callback( GLFWwindow *window, int focus )
Global::iPause |= 4; // włączenie pauzy, gdy nieaktywy
}
void scroll_callback( GLFWwindow* window, double xoffset, double yoffset ) {
if( Global::ctrlState ) {
// ctrl + scroll wheel adjusts fov in debug mode
Global::FieldOfView = clamp( static_cast<float>(Global::FieldOfView - yoffset * 20.0 / Global::fFpsAverage), 15.0f, 75.0f );
}
}
#ifdef _WINDOWS
extern "C"
{
@@ -230,9 +255,11 @@ int main(int argc, char *argv[])
glfwWindowHint(GLFW_REFRESH_RATE, vmode->refreshRate);
glfwWindowHint(GLFW_AUTO_ICONIFY, GLFW_FALSE);
glfwWindowHint(GLFW_SAMPLES, 1 << Global::iMultisampling);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
if( Global::iMultisampling > 0 ) {
glfwWindowHint( GLFW_SAMPLES, 1 << Global::iMultisampling );
}
if (Global::bFullScreen)
{
@@ -243,7 +270,7 @@ int main(int argc, char *argv[])
GLFWwindow *window =
glfwCreateWindow( Global::iWindowWidth, Global::iWindowHeight,
"EU07++NG", Global::bFullScreen ? monitor : nullptr, nullptr );
Global::AppName.c_str(), Global::bFullScreen ? monitor : nullptr, nullptr );
if (!window)
{
@@ -257,6 +284,7 @@ int main(int argc, char *argv[])
glfwSetFramebufferSizeCallback(window, window_resize_callback);
glfwSetCursorPosCallback(window, cursor_pos_callback);
glfwSetKeyCallback(window, key_callback);
glfwSetScrollCallback( window, scroll_callback );
glfwSetWindowFocusCallback(window, focus_callback);
{
int width, height;
@@ -276,9 +304,23 @@ int main(int argc, char *argv[])
BaseWindowProc = (WNDPROC)::SetWindowLongPtr( Hwnd, GWLP_WNDPROC, (LONG_PTR)WndProc );
// switch off the topmost flag
::SetWindowPos( Hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
const HANDLE icon = ::LoadImage(
::GetModuleHandle( 0 ),
MAKEINTRESOURCE( IDI_ICON1 ),
IMAGE_ICON,
::GetSystemMetrics( SM_CXSMICON ),
::GetSystemMetrics( SM_CYSMICON ),
0 );
if( icon )
::SendMessage( Hwnd, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>( icon ) );
#endif
GfxRenderer.Init();
if( ( false == GfxRenderer.Init( window ) )
|| ( false == UILayer.init( window ) ) ) {
return -1;
}
Global::pWorld = &World; // Ra: wskaźnik potrzebny do usuwania pojazdów
try
@@ -311,9 +353,10 @@ int main(int argc, char *argv[])
} // po zrobieniu E3D odpalamy normalnie scenerię, by ją zobaczyć
Console::On(); // włączenie konsoli
while (!glfwWindowShouldClose(window) && World.Update())
while (!glfwWindowShouldClose(window)
&& World.Update()
&& GfxRenderer.Render())
{
glfwSwapBuffers(window);
glfwPollEvents();
}
Console::Off(); // wyłączenie konsoli (komunikacji zwrotnej)

View File

@@ -23,7 +23,8 @@ class float3
y = b;
z = c;
};
double inline Length() const;
float Length() const;
float LengthSquared() const;
};
inline bool operator==(const float3 &v1, const float3 &v2)
@@ -49,10 +50,13 @@ inline float3 operator+(const float3 &v1, const float3 &v2)
{
return float3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
};
double inline float3::Length() const
inline float float3::Length() const
{
return sqrt(x * x + y * y + z * z);
return std::sqrt(LengthSquared());
};
inline float float3::LengthSquared() const {
return ( x * x + y * y + z * z );
}
inline float3 operator*( float3 const &v, float const k ) {
return float3( v.x * k, v.y * k, v.z * k );
};
@@ -212,7 +216,7 @@ public:
{
return &e[i << 2];
}
const float * readArray(void)
const float * readArray(void) const
{
return e;
}

View File

@@ -28,24 +28,15 @@ http://mozilla.org/MPL/2.0/.
// parametry do użytku wewnętrznego
// double Global::tSinceStart=0;
TGround *Global::pGround = NULL;
// char Global::CreatorName1[30]="2001-2004 Maciej Czapkiewicz <McZapkie>";
// char Global::CreatorName2[30]="2001-2003 Marcin Woźniak <Marcin_EU>";
// char Global::CreatorName3[20]="2004-2005 Adam Bugiel <ABu>";
// char Global::CreatorName4[30]="2004 Arkadiusz Ślusarczyk <Winger>";
// char Global::CreatorName5[30]="2003-2009 Łukasz Kirchner <Nbmx>";
std::string Global::AppName{ "EU07" };
std::string Global::asCurrentSceneryPath = "scenery/";
std::string Global::asCurrentTexturePath = std::string(szTexturePath);
std::string Global::asCurrentDynamicPath = "";
int Global::iSlowMotion =
0; // info o malym FPS: 0-OK, 1-wyłączyć multisampling, 3-promień 1.5km, 7-1km
TDynamicObject *Global::changeDynObj = NULL; // info o zmianie pojazdu
bool Global::detonatoryOK; // info o nowych detonatorach
double Global::ABuDebug = 0;
std::string Global::asSky = "1";
double Global::fOpenGL = 0.0; // wersja OpenGL - do sprawdzania obecności rozszerzeń
/*
bool Global::bOpenGL_1_5 = false; // czy są dostępne funkcje OpenGL 1.5
*/
double Global::fLuminance = 1.0; // jasność światła do automatycznego zapalania
float Global::SunAngle = 0.0f;
int Global::iReCompile = 0; // zwiększany, gdy trzeba odświeżyć siatki
@@ -59,18 +50,15 @@ bool Global::ctrlState;
int Global::iCameraLast = -1;
std::string Global::asRelease = "NG";
std::string Global::asVersion = "EU07++NG";
int Global::iViewMode = 0; // co aktualnie widać: 0-kabina, 1-latanie, 2-sprzęgi, 3-dokumenty
int Global::iTextMode = 0; // tryb pracy wyświetlacza tekstowego
int Global::iScreenMode[12] = {0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0}; // numer ekranu wyświetlacza tekstowego
int Global::iScreenMode[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // numer ekranu wyświetlacza tekstowego
double Global::fSunDeclination = 0.0; // deklinacja Słońca
double Global::fTimeAngleDeg = 0.0; // godzina w postaci kąta
float Global::fClockAngleDeg[6]; // kąty obrotu cylindrów dla zegara cyfrowego
std::string Global::szTexturesTGA = ".tga"; // lista tekstur od TGA
std::string Global::szTexturesDDS = ".dds"; // lista tekstur od DDS
int Global::iKeyLast = 0; // ostatnio naciśnięty klawisz w celu logowania
GLuint Global::iTextureId = 0; // ostatnio użyta tekstura 2D
int Global::iPause = 0x10; // globalna pauza ruchu
int Global::iPause = 0; // 0x10; // globalna pauza ruchu
int Global::iErorrCounter = 0; // licznik sprawdzań do śledzenia błędów OpenGL
int Global::iTextures = 0; // licznik użytych tekstur
TWorld *Global::pWorld = NULL;
@@ -78,11 +66,11 @@ cParser *Global::pParser = NULL;
int Global::iSegmentsRendered = 90; // ilość segmentów do regulacji wydajności
TCamera *Global::pCamera = NULL; // parametry kamery
TDynamicObject *Global::pUserDynamic = NULL; // pojazd użytkownika, renderowany bez trzęsienia
bool Global::bSmudge = false; // czy wyświetlać smugę, a pojazd użytkownika na końcu
/*
std::string Global::asTranscript[5]; // napisy na ekranie (widoczne)
*/
TTranscripts Global::tranTexts; // obiekt obsługujący stenogramy dźwięków na ekranie
float4 Global::UITextColor = float4( 225.0f / 255.0f, 225.0f / 255.0f, 225.0f / 255.0f, 1.0f );
// parametry scenerii
vector3 Global::pCameraPosition;
@@ -122,7 +110,7 @@ int Global::iFeedbackMode = 1; // tryb pracy informacji zwrotnej
int Global::iFeedbackPort = 0; // dodatkowy adres dla informacji zwrotnych
bool Global::bFreeFly = false;
bool Global::bFullScreen = false;
bool Global::VSync{ true };
bool Global::VSync{ false };
bool Global::bInactivePause = true; // automatyczna pauza, gdy okno nieaktywne
float Global::fMouseXScale = 1.5f;
float Global::fMouseYScale = 0.2f;
@@ -130,6 +118,7 @@ std::string Global::SceneryFile = "td.scn";
std::string Global::asHumanCtrlVehicle = "EU07-424";
int Global::iMultiplayer = 0; // blokada działania niektórych funkcji na rzecz komunikacji
double Global::fMoveLight = -1; // ruchome światło
bool Global::FakeLight{ false }; // toggle between fixed and dynamic daylight
double Global::fLatitudeDeg = 52.0; // szerokość geograficzna
float Global::fFriction = 1.0; // mnożnik tarcia - KURS90
double Global::fBrakeStep = 1.0; // krok zmiany hamulca dla klawiszy [Num3] i [Num9]
@@ -146,10 +135,12 @@ int Global::iBallastFiltering = 9; // domyślne rozmywanie tekstur podsypki
int Global::iRailProFiltering = 5; // domyślne rozmywanie tekstur szyn
int Global::iDynamicFiltering = 5; // domyślne rozmywanie tekstur pojazdów
bool Global::bUseVBO = true; // czy jest VBO w karcie graficznej (czy użyć)
GLint Global::iMaxTextureSize = 16384; // maksymalny rozmiar tekstury
std::string Global::LastGLError;
GLint Global::iMaxTextureSize = 4096; // maksymalny rozmiar tekstury
bool Global::bSmoothTraction = false; // wygładzanie drutów starym sposobem
std::string Global::szDefaultExt = Global::szTexturesDDS; // domyślnie od DDS
int Global::iMultisampling = 2; // tryb antyaliasingu: 0=brak,1=2px,2=4px,3=8px,4=16px
bool Global::DLFont{ false }; // switch indicating presence of basic font
bool Global::bGlutFont = false; // czy tekst generowany przez GLUT32.DLL
//int Global::iConvertModels = 7; // tworzenie plików binarnych, +2-optymalizacja transformów
int Global::iConvertModels{ 0 }; // temporary override, to prevent generation of .e3d not compatible with old exe
@@ -160,8 +151,8 @@ TAnimModel *Global::pTerrainCompact = NULL; // do zapisania terenu w pliku
std::string Global::asTerrainModel = ""; // nazwa obiektu terenu do zapisania w pliku
double Global::fFpsAverage = 20.0; // oczekiwana wartosć FPS
double Global::fFpsDeviation = 5.0; // odchylenie standardowe FPS
double Global::fFpsMin = 0.0; // dolna granica FPS, przy której promień scenerii będzie zmniejszany
double Global::fFpsMax = 0.0; // górna granica FPS, przy której promień scenerii będzie zwiększany
double Global::fFpsMin = 30.0; // dolna granica FPS, przy której promień scenerii będzie zmniejszany
double Global::fFpsMax = 65.0; // górna granica FPS, przy której promień scenerii będzie zwiększany
double Global::fFpsRadiusMax = 3000.0; // maksymalny promień renderowania
int Global::iFpsRadiusMax = 225; // maksymalny promień renderowania
double Global::fRadiusFactor = 1.1; // współczynnik jednorazowej zmiany promienia scenerii
@@ -281,8 +272,7 @@ void Global::ConfigParse(cParser &Parser)
Parser.getTokens( 1, false );
Parser >> Global::FieldOfView;
// guard against incorrect values
Global::FieldOfView = std::min( 75.0f, Global::FieldOfView );
Global::FieldOfView = std::max( 15.0f, Global::FieldOfView );
Global::FieldOfView = clamp( Global::FieldOfView, 15.0f, 75.0f );
}
else if (token == "width")
{
@@ -521,42 +511,15 @@ void Global::ConfigParse(cParser &Parser)
Parser.getTokens(1, false);
int size;
Parser >> size;
if (size <= 64)
{
Global::iMaxTextureSize = 64;
}
else if (size <= 128)
{
Global::iMaxTextureSize = 128;
}
else if (size <= 256)
{
Global::iMaxTextureSize = 256;
}
else if (size <= 512)
{
Global::iMaxTextureSize = 512;
}
else if (size <= 1024)
{
Global::iMaxTextureSize = 1024;
}
else if (size <= 2048)
{
Global::iMaxTextureSize = 2048;
}
else if (size <= 4096)
{
Global::iMaxTextureSize = 4096;
}
else if (size <= 8192)
{
Global::iMaxTextureSize = 8192;
}
else
{
Global::iMaxTextureSize = 16384;
}
if (size <= 64) { Global::iMaxTextureSize = 64; }
else if (size <= 128) { Global::iMaxTextureSize = 128; }
else if (size <= 256) { Global::iMaxTextureSize = 256; }
else if (size <= 512) { Global::iMaxTextureSize = 512; }
else if (size <= 1024) { Global::iMaxTextureSize = 1024; }
else if (size <= 2048) { Global::iMaxTextureSize = 2048; }
else if (size <= 4096) { Global::iMaxTextureSize = 4096; }
else if (size <= 8192) { Global::iMaxTextureSize = 8192; }
else { Global::iMaxTextureSize = 16384; }
}
else if (token == "doubleambient")
{
@@ -581,8 +544,8 @@ void Global::ConfigParse(cParser &Parser)
Parser.getTokens( 1, false );
Parser >> Global::DynamicLightCount;
// clamp the light number
Global::DynamicLightCount = std::min( 7, Global::DynamicLightCount ); // max 8 lights per opengl specs, and one used for sun
Global::DynamicLightCount = std::max( 1, Global::DynamicLightCount ); // at least one light for controlled vehicle
// max 8 lights per opengl specs, minus one used for sun. at least one light for controlled vehicle
Global::DynamicLightCount = clamp( Global::DynamicLightCount, 1, 7 );
}
else if (token == "smoothtraction")
{
@@ -690,7 +653,8 @@ void Global::ConfigParse(cParser &Parser)
in = 5; // na ostatni, bo i tak trzeba pominąć wartości
}
Parser.getTokens(4, false);
Parser >> Global::fCalibrateIn[in][0] // wyraz wolny
Parser
>> Global::fCalibrateIn[in][0] // wyraz wolny
>> Global::fCalibrateIn[in][1] // mnożnik
>> Global::fCalibrateIn[in][2] // mnożnik dla kwadratu
>> Global::fCalibrateIn[in][3]; // mnożnik dla sześcianu
@@ -805,11 +769,18 @@ void Global::ConfigParse(cParser &Parser)
Parser.getTokens(1, false);
Parser >> Global::asLang;
}
else if (token == "opengl")
{
// deklarowana wersja OpenGL, żeby powstrzymać błędy
Parser.getTokens(1, false);
Parser >> Global::fOpenGL;
else if( token == "uitextcolor" ) {
// color of the ui text. NOTE: will be obsolete once the real ui is in place
Parser.getTokens( 3, false );
Parser
>> Global::UITextColor.x
>> Global::UITextColor.y
>> Global::UITextColor.z;
Global::UITextColor.x = clamp( Global::UITextColor.x, 0.0f, 255.0f );
Global::UITextColor.y = clamp( Global::UITextColor.y, 0.0f, 255.0f );
Global::UITextColor.z = clamp( Global::UITextColor.z, 0.0f, 255.0f );
Global::UITextColor = Global::UITextColor / 255.0f;
Global::UITextColor.w = 1.0f;
}
else if (token == "pyscreenrendererpriority")
{
@@ -929,8 +900,6 @@ void Global::ConfigParse(cParser &Parser)
bEnableTraction = false; // false = pantograf się nie połamie
bLiveTraction = false; // false = pantografy zawsze zbierają 95% MaxVoltage
}
// if (fMoveLight>0) bDoubleAmbient=false; //wtedy tylko jedno światło ruchome
// if (fOpenGL<1.3) iMultisampling=0; //można by z góry wyłączyć, ale nie mamy jeszcze fOpenGL
if (iMultisampling)
{ // antyaliasing całoekranowy wyłącza rozmywanie drutów
bSmoothTraction = false;
@@ -941,10 +910,12 @@ void Global::ConfigParse(cParser &Parser)
// pauzowanie jest zablokowane dla (iMultiplayer&2)>0, więc iMultiplayer=1 da się zapauzować
// (tryb instruktora)
}
/*
fFpsMin = fFpsAverage -
fFpsDeviation; // dolna granica FPS, przy której promień scenerii będzie zmniejszany
fFpsMax = fFpsAverage +
fFpsDeviation; // górna granica FPS, przy której promień scenerii będzie zwiększany
*/
if (iPause)
iTextMode = GLFW_KEY_F1; // jak pauza, to pokazać zegar
/* this won't execute anymore with the old parser removed
@@ -1043,9 +1014,12 @@ void Global::InitKeys()
Keys[k_PantRearDown] = 'O';
// Winger 020304 - ogrzewanie
Keys[k_Heating] = 'H';
// headlights
Keys[k_LeftSign] = 'Y';
Keys[k_UpperSign] = 'U';
Keys[k_RightSign] = 'I';
Keys[k_DimHeadlights] = 'L';
// tail lights
Keys[k_EndSign] = 'T';
Keys[k_SmallCompressor] = 'V';
@@ -1078,14 +1052,6 @@ void Global::SetCameraRotation(double Yaw)
pCameraRotationDeg = pCameraRotation * 180.0 / M_PI;
}
void Global::BindTexture(GLuint t)
{ // ustawienie aktualnej tekstury, tylko gdy się zmienia
if (t != iTextureId)
{
iTextureId = t;
}
};
void Global::TrainDelete(TDynamicObject *d)
{ // usunięcie pojazdu prowadzonego przez użytkownika
if (pWorld)

View File

@@ -110,7 +110,8 @@ const int k_Active = 71;
// Winger 020304
const int k_Battery = 72;
const int k_WalkMode = 73;
const int MaxKeys = 74;
int const k_DimHeadlights = 74;
const int MaxKeys = 75;
// klasy dla wskaźników globalnych
class TGround;
@@ -162,7 +163,6 @@ private:
class Global
{
private:
static GLuint iTextureId; // ostatnio użyta tekstura 2D
public:
// double Global::tSinceStart;
static int Keys[MaxKeys];
@@ -199,11 +199,7 @@ class Global
static TGround *pGround;
static std::string szDefaultExt;
static std::string SceneryFile;
static char CreatorName1[20];
static char CreatorName2[20];
static char CreatorName3[20];
static char CreatorName4[30];
static char CreatorName5[30];
static std::string AppName;
static std::string asCurrentSceneryPath;
static std::string asCurrentTexturePath;
static std::string asCurrentDynamicPath;
@@ -243,7 +239,6 @@ class Global
static int iSlowMotion;
static TDynamicObject *changeDynObj;
static double ABuDebug;
static bool detonatoryOK;
static std::string asSky;
static bool bnewAirCouplers;
// Ra: nowe zmienne globalne
@@ -254,12 +249,9 @@ class Global
static int iDynamicFiltering; // domyślne rozmywanie tekstur pojazdów
static int iReCompile; // zwiększany, gdy trzeba odświeżyć siatki
static bool bUseVBO; // czy jest VBO w karcie graficznej
static std::string LastGLError;
static int iFeedbackMode; // tryb pracy informacji zwrotnej
static int iFeedbackPort; // dodatkowy adres dla informacji zwrotnych
static double fOpenGL; // wersja OpenGL - przyda się
/*
static bool bOpenGL_1_5; // czy są dostępne funkcje OpenGL 1.5
*/
static double fLuminance; // jasność światła do automatycznego zapalania
static float SunAngle; // angle of the sun relative to horizon
static int iMultiplayer; // blokada działania niektórych eventów na rzecz kominikacji
@@ -273,13 +265,12 @@ class Global
static int iCameraLast;
static std::string asRelease; // numer
static std::string asVersion; // z opisem
static int
iViewMode; // co aktualnie widać: 0-kabina, 1-latanie, 2-sprzęgi, 3-dokumenty, 4-obwody
static GLint iMaxTextureSize; // maksymalny rozmiar tekstury
static int iTextMode; // tryb pracy wyświetlacza tekstowego
static int iScreenMode[12]; // numer ekranu wyświetlacza tekstowego
static bool bDoubleAmbient; // podwójna jasność ambient
static double fMoveLight; // numer dnia w roku albo -1
static bool FakeLight; // toggle between fixed and dynamic daylight
static bool bSmoothTraction; // wygładzanie drutów
static double fSunDeclination; // deklinacja Słońca
static double fTimeSpeed; // przyspieszenie czasu, zmienna do testów
@@ -289,6 +280,7 @@ class Global
static std::string szTexturesTGA; // lista tekstur od TGA
static std::string szTexturesDDS; // lista tekstur od DDS
static int iMultisampling; // tryb antyaliasingu: 0=brak,1=2px,2=4px,3=8px,4=16px
static bool DLFont; // switch indicating presence of basic font
static bool bGlutFont; // tekst generowany przez GLUT
static int iKeyLast; // ostatnio naciśnięty klawisz w celu logowania
static int iPause; // globalna pauza ruchu: b0=start,b1=klawisz,b2=tło,b3=lagi,b4=wczytywanie
@@ -324,11 +316,11 @@ class Global
// informacje podczas kalibracji
static double fBrakeStep; // krok zmiany hamulca dla klawiszy [Num3] i [Num9]
static bool bJoinEvents; // czy grupować eventy o tych samych nazwach
static bool bSmudge; // czy wyświetlać smugę, a pojazd użytkownika na końcu
/*
static std::string asTranscript[5]; // napisy na ekranie (widoczne)
*/
static TTranscripts tranTexts; // obiekt obsługujący stenogramy dźwięków na ekranie
static float4 UITextColor; // base color of UI text
static std::string asLang; // domyślny język - http://tools.ietf.org/html/bcp47
static int iHiddenEvents; // czy łączyć eventy z torami poprzez nazwę toru
static TTextSound *tsRadioBusy[10]; // zajętość kanałów radiowych (wskaźnik na odgrywany dźwięk)
@@ -372,6 +364,7 @@ class Global
float3 direction;
float3 color;
float3 ambient;
float intensity;
};
static daylight_s daylight;

View File

@@ -36,6 +36,7 @@ http://mozilla.org/MPL/2.0/.
#include "Driver.h"
#include "Console.h"
#include "Names.h"
#include "uilayer.h"
#define _PROBLEND 1
//---------------------------------------------------------------------------
@@ -702,8 +703,7 @@ void TGroundNode::RenderAlphaDL()
if ((PROBLEND)) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
{
glEnable(GL_BLEND);
glAlphaFunc(GL_GREATER, 0.04f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glAlphaFunc(GL_GREATER, 0.02f);
};
#endif
}
@@ -1168,6 +1168,45 @@ void TSubRect::RenderDL()
node->RenderDL(); // nieprzezroczyste z mieszanych modeli
for (int j = 0; j < iTracks; ++j)
tTracks[j]->RenderDyn(); // nieprzezroczyste fragmenty pojazdów na torach
/*
float width = 100.0f;
float height = 25.0f;
float3 vTopLeftFront( m_area.center.x - width, m_area.center.y + height, m_area.center.z + width );
float3 vTopLeftBack( m_area.center.x - width, m_area.center.y + height, m_area.center.z - width );
float3 vTopRightBack( m_area.center.x + width, m_area.center.y + height, m_area.center.z - width );
float3 vTopRightFront( m_area.center.x + width, m_area.center.y + height, m_area.center.z + width );
float3 vBottom_LeftFront( m_area.center.x - width, m_area.center.y - height, m_area.center.z + width );
float3 vBottom_LeftBack( m_area.center.x - width, m_area.center.y - height, m_area.center.z - width );
float3 vBottomRightBack( m_area.center.x + width, m_area.center.y - height, m_area.center.z - width );
float3 vBottomRightFront( m_area.center.x + width, m_area.center.y - height, m_area.center.z + width );
glDisable( GL_LIGHTING );
glDisable( GL_TEXTURE_2D );
glColor3ub( 255, 255, (iTracks ? 0 : 255) );
glBegin( GL_LINE_LOOP );
glVertex3fv( &vTopLeftFront.x );
glVertex3fv( &vTopLeftBack.x );
glVertex3fv( &vTopRightBack.x );
glVertex3fv( &vTopRightFront.x );
glEnd();
glBegin( GL_LINE_LOOP );
glVertex3fv( &vBottom_LeftFront.x );
glVertex3fv( &vBottom_LeftBack.x );
glVertex3fv( &vBottomRightBack.x );
glVertex3fv( &vBottomRightFront.x );
glEnd();
glBegin( GL_LINES );
glVertex3fv( &vTopLeftFront.x ); glVertex3fv( &vBottom_LeftFront.x );
glVertex3fv( &vTopLeftBack.x ); glVertex3fv( &vBottom_LeftBack.x );
glVertex3fv( &vTopRightBack.x ); glVertex3fv( &vBottomRightBack.x );
glVertex3fv( &vTopRightFront.x ); glVertex3fv( &vBottomRightFront.x );
glEnd();
glColor3ub( 255, 255, 255 );
glEnable( GL_TEXTURE_2D );
glEnable( GL_LIGHTING );
*/
};
void TSubRect::RenderAlphaDL()
@@ -1228,17 +1267,31 @@ void TSubRect::RenderSounds()
//---------------------------------------------------------------------------
int TGroundRect::iFrameNumber = 0; // licznik wyświetlanych klatek
TGroundRect::TGroundRect()
{
pSubRects = NULL;
nTerrain = NULL;
};
//TGroundRect::TGroundRect( float3 const &Position, float const Radius = 1000.0f * M_SQRT2 ) :
TGroundRect::~TGroundRect()
{
SafeDeleteArray(pSubRects);
};
void
TGroundRect::Init() {
pSubRects = new TSubRect[ iNumSubRects * iNumSubRects ];
float const subrectsize = 1000.0f / iNumSubRects;
for( int column = 0; column < iNumSubRects; ++column ) {
for( int row = 0; row < iNumSubRects; ++row ) {
auto &area = FastGetRect(column, row)->m_area;
area.center =
m_area.center
- float3( 500.0f, 0.0f, 500.0f ) // 'upper left' corner of rectangle
+ float3( subrectsize * 0.5f, 0.0f, subrectsize * 0.5f ) // center of sub-rectangle
+ float3( subrectsize * column, 0.0f, subrectsize * row );
area.radius = subrectsize * (float)M_SQRT2;
}
}
};
void TGroundRect::RenderDL()
{ // renderowanie kwadratu kilometrowego (DL), jeśli jeszcze nie zrobione
if (iLastDisplay != iFrameNumber)
@@ -1263,6 +1316,44 @@ void TGroundRect::RenderDL()
nRootMesh->RenderDL();
iLastDisplay = iFrameNumber; // drugi raz nie potrzeba
}
/*
float width = 500.0f;
float height = 50.0f;
float3 vTopLeftFront( m_area.center.x - width, m_area.center.y + height, m_area.center.z + width );
float3 vTopLeftBack( m_area.center.x - width, m_area.center.y + height, m_area.center.z - width );
float3 vTopRightBack( m_area.center.x + width, m_area.center.y + height, m_area.center.z - width );
float3 vTopRightFront( m_area.center.x + width, m_area.center.y + height, m_area.center.z + width );
float3 vBottom_LeftFront( m_area.center.x - width, m_area.center.y - height, m_area.center.z + width );
float3 vBottom_LeftBack( m_area.center.x - width, m_area.center.y - height, m_area.center.z - width );
float3 vBottomRightBack( m_area.center.x + width, m_area.center.y - height, m_area.center.z - width );
float3 vBottomRightFront( m_area.center.x + width, m_area.center.y - height, m_area.center.z + width );
glDisable( GL_LIGHTING );
glDisable( GL_TEXTURE_2D );
glColor3ub( 0, 255, 255 );
glBegin( GL_LINE_LOOP );
glVertex3fv( &vTopLeftFront.x );
glVertex3fv( &vTopLeftBack.x );
glVertex3fv( &vTopRightBack.x );
glVertex3fv( &vTopRightFront.x );
glEnd();
glBegin( GL_LINE_LOOP );
glVertex3fv( &vBottom_LeftFront.x );
glVertex3fv( &vBottom_LeftBack.x );
glVertex3fv( &vBottomRightBack.x );
glVertex3fv( &vBottomRightFront.x );
glEnd();
glBegin( GL_LINES );
glVertex3fv( &vTopLeftFront.x ); glVertex3fv( &vBottom_LeftFront.x );
glVertex3fv( &vTopLeftBack.x ); glVertex3fv( &vBottom_LeftBack.x );
glVertex3fv( &vTopRightBack.x ); glVertex3fv( &vBottomRightBack.x );
glVertex3fv( &vTopRightFront.x ); glVertex3fv( &vBottomRightFront.x );
glEnd();
glColor3ub( 255, 255, 255 );
glEnable( GL_TEXTURE_2D );
glEnable( GL_LIGHTING );
*/
};
void TGroundRect::RenderVBO()
@@ -1340,6 +1431,22 @@ TGround::TGround()
#endif
::SecureZeroMemory( TempConnectionType, sizeof( TempConnectionType ) );
::SecureZeroMemory( pRendered, sizeof( pRendered ) );
// set bounding area information for ground rectangles
float const rectsize = 1000.0f;
float3 const worldcenter( 0.0f, 0.0f, 0.0f );
for( int column = 0; column < iNumRects; ++column ) {
for( int row = 0; row < iNumRects; ++row ) {
auto &area = Rects[ column ][ row ].m_area;
// NOTE: in current implementation triangles can stick out to ~200m from the area, so we add extra padding
area.radius = 200.0f + rectsize * 0.5f * (float)M_SQRT2;
area.center =
worldcenter
- float3( (iNumRects / 2) * rectsize, 0.0f, (iNumRects / 2) * rectsize ) // 'upper left' corner of the world
+ float3( rectsize * 0.5f, 0.0f, rectsize * 0.5f ) // center of the rectangle
+ float3( rectsize * column, 0.0f, rectsize * row );
}
}
}
TGround::~TGround()
@@ -1978,9 +2085,12 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
// if the vehicle has defined light source, it can (potentially) emit light, so add it to the light array
*/
if( ( tmp != nullptr )
&& ( tmp->DynamicObject->MoverParameters->SecuritySystem.SystemType != 0 ) ) {
// we check for presence of security system, as a way to determine whether the vehicle is a controllable engine
// NOTE: this isn't 100% precise, e.g. middle EZT module comes with security system, while it has no lights
&& ( tmp->DynamicObject->MoverParameters->CategoryFlag == 1 ) // trains only
&& ( ( tmp->DynamicObject->MoverParameters->SecuritySystem.SystemType != 0 )
|| ( tmp->DynamicObject->MoverParameters->SandCapacity > 0.0 ) ) ) {
// we check for presence of security system or sand load, as a way to determine whether the vehicle is a controllable engine
// NOTE: this isn't 100% precise, e.g. middle EZT module comes with security system, while it has no lights, and some engines
// don't have security systems fitted
m_lights.insert( tmp->DynamicObject );
}
@@ -2446,66 +2556,17 @@ void TGround::FirstInit()
for (j = 0; j < iNumRects; ++j)
Rects[i][j].Optimize(); // optymalizacja obiektów w sektorach
WriteLog("InitNormals OK");
WriteLog("InitTracks");
InitTracks(); //łączenie odcinków ze sobą i przyklejanie eventów
WriteLog("InitTracks OK");
WriteLog("InitTraction");
InitTraction(); //łączenie drutów ze sobą
WriteLog("InitTraction OK");
WriteLog("InitEvents");
InitEvents();
WriteLog("InitEvents OK");
WriteLog("InitLaunchers");
InitLaunchers();
WriteLog("InitLaunchers OK");
WriteLog("InitGlobalTime");
// ABu 160205: juz nie TODO :)
Mtable::GlobalTime = std::make_shared<TMTableTime>( hh, mm, srh, srm, ssh, ssm ); // McZapkie-300302: inicjacja czasu rozkladowego - TODO: czytac z trasy!
WriteLog("InitGlobalTime OK");
// jeszcze ustawienie pogody, gdyby nie było w scenerii wpisów
glClearColor(Global::AtmoColor[0], Global::AtmoColor[1], Global::AtmoColor[2],
0.0); // Background Color
if (Global::fFogEnd > 0)
{
glFogi(GL_FOG_MODE, GL_LINEAR);
glFogfv(GL_FOG_COLOR, Global::FogColor); // set fog color
glFogf(GL_FOG_START, Global::fFogStart); // fog start depth
glFogf(GL_FOG_END, Global::fFogEnd); // fog end depth
glEnable(GL_FOG);
}
else
glDisable(GL_FOG);
glDisable(GL_LIGHTING);
#ifdef EU07_USE_OLD_LIGHTING_MODEL
// TODO, TBD: re-implement this
glLightfv(GL_LIGHT0, GL_POSITION, Global::lightPos); // daylight position
glLightfv(GL_LIGHT0, GL_AMBIENT, Global::ambientDayLight); // kolor wszechobceny
glLightfv(GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight); // kolor padający
glLightfv(GL_LIGHT0, GL_SPECULAR, Global::specularDayLight); // kolor odbity
// musi być tutaj, bo wcześniej nie mieliśmy wartości światła
#endif
/*
if (Global::fMoveLight >= 0.0) // albo tak, albo niech ustala minimum ciemności w nocy
{
*/
#ifdef EU07_USE_OLD_LIGHTING_MODEL
// TODO, TBD: re-implement this
Global::fLuminance = // obliczenie luminacji "światła w ciemności"
+0.150 * Global::ambientDayLight[0] // R
+ 0.295 * Global::ambientDayLight[1] // G
+ 0.055 * Global::ambientDayLight[2]; // B
if (Global::fLuminance > 0.1) // jeśli miało by być za jasno
for (int i = 0; i < 3; i++)
Global::ambientDayLight[i] *=
0.1 / Global::fLuminance; // ograniczenie jasności w nocy
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, Global::ambientDayLight);
#endif
/*
}
else if (Global::bDoubleAmbient) // Ra: wcześniej było ambient dawane na obydwa światła
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, Global::ambientDayLight);
*/
glEnable(GL_LIGHTING);
WriteLog("FirstInit is done");
};
@@ -2556,17 +2617,17 @@ bool TGround::Init(std::string File)
token = "";
parser.getTokens();
parser >> token;
int refresh = 0;
std::size_t processed = 0;
while (token != "") //(!Parser->EndOfFile)
{
if (refresh == 50)
{ // SwapBuffers(hDC); //Ra: bez ogranicznika za bardzo spowalnia :( a u niektórych miga
refresh = 0;
Global::DoEvents();
++processed;
if( processed % 1000 == 0 )
{
UILayer.set_progress( parser.getProgress(), parser.getFullProgress() );
GfxRenderer.Render();
glfwPollEvents();
}
else
++refresh;
str = token;
if (str == "node")
{
@@ -4835,13 +4896,13 @@ TGround::Render( Math3D::vector3 const &Camera ) {
if( !RenderAlphaVBO( Camera ) )
return false;
}
else { // renderowanie przez Display List
else {
// renderowanie przez Display List
if( !RenderDL( Camera ) )
return false;
if( !RenderAlphaDL( Camera ) )
return false;
}
return true;
}
@@ -4893,6 +4954,7 @@ bool TGround::RenderDL(vector3 pPosition)
if (CameraDirection.x * direction.x + CameraDirection.z * direction.z < 0.55)
continue; // pomijanie sektorów poza kątem patrzenia
}
// NOTE: terrain data is disabled, as it's moved to the renderer
Rects[(i + c) / iNumSubRects][(j + r) / iNumSubRects]
.RenderDL(); // kwadrat kilometrowy nie zawsze, bo szkoda FPS
if ((tmp = FastGetSubRect(i + c, j + r)) != NULL)
@@ -4908,7 +4970,7 @@ bool TGround::RenderDL(vector3 pPosition)
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
glAlphaFunc(GL_GREATER, 0.02f); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
TGroundNode *node;
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
TSubRect *tmp;

View File

@@ -181,11 +181,19 @@ class TGroundNode : public Resource
void RaRenderVBO(); // renderowanie (nieprzezroczystych) ze wspólnego VBO
void RenderVBO(); // renderowanie nieprzezroczystych z własnego VBO
void RenderAlphaVBO(); // renderowanie przezroczystych z (własnego) VBO
};
struct bounding_area {
float3 center; // mid point of the rectangle
float radius{ 0.0f }; // radius of the bounding sphere
};
class TSubRect : public Resource, public CMesh
{ // sektor składowy kwadratu kilometrowego
public:
bounding_area m_area;
int iTracks = 0; // ilość torów w (tTracks)
TTrack **tTracks = nullptr; // tory do renderowania pojazdów
protected:
@@ -207,7 +215,6 @@ class TSubRect : public Resource, public CMesh
public:
void LoadNodes(); // utworzenie VBO sektora
public:
// TSubRect() = default;
virtual ~TSubRect();
virtual void Release(); // zwalnianie VBO sektora
void NodeAdd(TGroundNode *Node); // dodanie obiektu do sektora na etapie rozdzielania na sektory
@@ -242,16 +249,12 @@ class TGroundRect : public TSubRect
// Ra: 2012-02 doszły submodele terenu
private:
int iLastDisplay; // numer klatki w której był ostatnio wyświetlany
TSubRect *pSubRects;
void Init()
{
pSubRects = new TSubRect[iNumSubRects * iNumSubRects];
};
TSubRect *pSubRects{ nullptr };
void Init();
public:
static int iFrameNumber; // numer kolejny wyświetlanej klatki
TGroundNode *nTerrain; // model terenu z E3D - użyć nRootMesh?
TGroundRect();
TGroundNode *nTerrain{ nullptr }; // model terenu z E3D - użyć nRootMesh?
virtual ~TGroundRect();
TSubRect * SafeGetRect(int iCol, int iRow)
@@ -276,6 +279,8 @@ class TGroundRect : public TSubRect
class TGround
{
friend class opengl_renderer;
vector3 CameraDirection; // zmienna robocza przy renderowaniu
int const *iRange = nullptr; // tabela widoczności
// TGroundNode *nRootNode; //lista wszystkich węzłów

View File

@@ -1127,6 +1127,7 @@ private:
void LoadFIZ_Circuit( std::string const &Input );
void LoadFIZ_RList( std::string const &Input );
void LoadFIZ_DList( std::string const &Input );
void LoadFIZ_FFList( std::string const &Input );
void LoadFIZ_LightsList( std::string const &Input );
void LoadFIZ_PowerParamsDecode( TPowerParameters &Powerparameters, std::string const Prefix, std::string const &Input );
TPowerType LoadFIZ_PowerDecode( std::string const &Power );

View File

@@ -428,45 +428,47 @@ double TMoverParameters::Distance(const vector3 &s1, const vector3 &s2, const ve
*/
double TMoverParameters::CouplerDist(int Coupler)
{ // obliczenie odległości pomiędzy sprzęgami (kula!)
return Couplers[Coupler].CoupleDist =
Distance(Loc, Couplers[Coupler].Connected->Loc, Dim,
Couplers[Coupler].Connected->Dim); // odległość pomiędzy sprzęgami (kula!)
Couplers[Coupler].CoupleDist =
Distance(
Loc, Couplers[Coupler].Connected->Loc,
Dim, Couplers[Coupler].Connected->Dim); // odległość pomiędzy sprzęgami (kula!)
return Couplers[ Coupler ].CoupleDist;
};
bool TMoverParameters::Attach(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo,
int CouplingType, bool Forced)
bool TMoverParameters::Attach(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Forced)
{ //łączenie do swojego sprzęgu (ConnectNo) pojazdu (ConnectTo) stroną (ConnectToNr)
// Ra: zwykle wykonywane dwukrotnie, dla każdego pojazdu oddzielnie
// Ra: trzeba by odróżnić wymóg dociśnięcia od uszkodzenia sprzęgu przy podczepianiu AI do
// składu
if (ConnectTo) // jeśli nie pusty
{
auto &coupler = Couplers[ ConnectNo ];
if (ConnectToNr != 2)
Couplers[ConnectNo].ConnectedNr = ConnectToNr; // 2=nic nie podłączone
TCouplerType ct = ConnectTo->Couplers[Couplers[ConnectNo].ConnectedNr]
.CouplerType; // typ sprzęgu podłączanego pojazdu
Couplers[ConnectNo].Connected =
ConnectTo; // tak podpiąć (do siebie) zawsze można, najwyżej będzie wirtualny
CouplerDist(ConnectNo); // przeliczenie odległości pomiędzy sprzęgami
coupler.ConnectedNr = ConnectToNr; // 2=nic nie podłączone
coupler.Connected = ConnectTo; // tak podpiąć (do siebie) zawsze można, najwyżej będzie wirtualny
CouplerDist( ConnectNo ); // przeliczenie odległości pomiędzy sprzęgami
if (CouplingType == ctrain_virtual)
return false; // wirtualny więcej nic nie robi
if (Forced ? true : ((Couplers[ConnectNo].CoupleDist <= dEpsilon) &&
(Couplers[ConnectNo].CouplerType != NoCoupler) &&
(Couplers[ConnectNo].CouplerType == ct)))
auto &othercoupler = ConnectTo->Couplers[ coupler.ConnectedNr ];
if( ( Forced )
|| ( ( coupler.CoupleDist <= dEpsilon )
&& ( coupler.CouplerType != NoCoupler )
&& ( coupler.CouplerType == othercoupler.CouplerType ) ) )
{ // stykaja sie zderzaki i kompatybilne typy sprzegow, chyba że łączenie na starcie
if (Couplers[ConnectNo].CouplingFlag ==
ctrain_virtual) // jeśli wcześniej nie było połączone
{ // ustalenie z której strony rysować sprzęg
Couplers[ConnectNo].Render = true; // tego rysować
ConnectTo->Couplers[Couplers[ConnectNo].ConnectedNr].Render = false; // a tego nie
if( coupler.CouplingFlag == ctrain_virtual ) {
// jeśli wcześniej nie było połączone, ustalenie z której strony rysować sprzęg
coupler.Render = true; // tego rysować
othercoupler.Render = false; // a tego nie
};
Couplers[ConnectNo].CouplingFlag = CouplingType; // ustawienie typu sprzęgu
coupler.CouplingFlag = CouplingType; // ustawienie typu sprzęgu
// if (CouplingType!=ctrain_virtual) //Ra: wirtualnego nie łączymy zwrotnie!
//{//jeśli łączenie sprzęgiem niewirtualnym, ustawiamy połączenie zwrotne
ConnectTo->Couplers[Couplers[ConnectNo].ConnectedNr].CouplingFlag = CouplingType;
ConnectTo->Couplers[Couplers[ConnectNo].ConnectedNr].Connected = this;
ConnectTo->Couplers[Couplers[ConnectNo].ConnectedNr].CoupleDist =
Couplers[ConnectNo].CoupleDist;
othercoupler.CouplingFlag = CouplingType;
othercoupler.Connected = this;
othercoupler.CoupleDist = coupler.CoupleDist;
return true;
//}
// podłączenie nie udało się - jest wirtualne
@@ -2421,7 +2423,7 @@ bool TMoverParameters::DecBrakeLevelOld(void)
bool TMoverParameters::IncLocalBrakeLevel(int CtrlSpeed)
{
bool IBL;
if ((LocalBrakePos < LocalBrakePosNo) /*and (BrakeCtrlPos<1)*/)
if ((LocalBrakePos < LocalBrakePosNo) /*and (BrakeCtrlPos<1)*/)
{
while ((LocalBrakePos < LocalBrakePosNo) && (CtrlSpeed > 0))
{
@@ -6139,7 +6141,8 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
if( issection( "ffList:", inputline ) ) {
startBPT = false;
startFFLIST = true; LISTLINE = 0;
continue;
LoadFIZ_FFList( inputline );
continue;
}
if( issection( "WWList:", inputline ) )
@@ -6324,7 +6327,8 @@ void TMoverParameters::LoadFIZ_Wheels( std::string const &line ) {
void TMoverParameters::LoadFIZ_Brake( std::string const &line ) {
BrakeValveDecode( extract_value( "BrakeValve", line ) );
extract_value( BrakeValveParams, "BrakeValve", line, "" );
BrakeValveDecode( BrakeValveParams );
BrakeSubsystemDecode();
extract_value( NBpA, "NBpA", line, "" );
@@ -6951,6 +6955,11 @@ void TMoverParameters::LoadFIZ_DList( std::string const &Input ) {
extract_value( dizel_Mstand, "Mstand", Input, "" );
}
void TMoverParameters::LoadFIZ_FFList( std::string const &Input ) {
extract_value( RlistSize, "Size", Input, "" );
}
void TMoverParameters::LoadFIZ_LightsList( std::string const &Input ) {
extract_value( LightsPosNo, "Size", Input, "" );

View File

@@ -63,10 +63,12 @@ void TPrzekladnik::Update(double dt)
if ( BCP > P() )
dV = -PFVd(BCP, 0, d2A(10), P()) * dt;
else if ( BCP < P() )
dV = PFVa(BVP, BCP, d2A(10), P()) * dt;
else
dV = 0;
else {
if( BCP < P() )
dV = PFVa( BVP, BCP, d2A( 10 ), P() ) * dt;
else
dV = 0;
}
Next->Flow(dV);
if (dV > 0)
@@ -86,8 +88,8 @@ void TRapid::SetRapidParams(double mult, double size)
}
else
{
DN = d2A(5);
DL = d2A(5);
DN = d2A(5.0);
DL = d2A(5.0);
}
}
@@ -117,10 +119,10 @@ void TRapid::Update(double dt)
else if ((BCP * RapidMult) < (P() * ActMult))
dV = PFVa(BVP, BCP, DN, P() * ActMult / RapidMult) * dt;
else
dV = 0;
dV = 0.0;
Next->Flow(dV);
if (dV > 0)
if (dV > 0.0)
BrakeRes->Flow(-dV);
}
@@ -128,7 +130,7 @@ void TRapid::Update(double dt)
void TPrzekCiagly::SetMult(double m)
{
mult = m;
Mult = m;
}
void TPrzekCiagly::Update(double dt)
@@ -137,15 +139,15 @@ void TPrzekCiagly::Update(double dt)
double const BCP{ Next->P() };
double dV;
if ( BCP > (P() * mult))
dV = -PFVd(BCP, 0, d2A(8), P() * mult) * dt;
else if (BCP < (P() * mult))
dV = PFVa(BVP, BCP, d2A(8), P() * mult) * dt;
if ( BCP > (P() * Mult))
dV = -PFVd(BCP, 0, d2A(8.0), P() * Mult) * dt;
else if (BCP < (P() * Mult))
dV = PFVa(BVP, BCP, d2A(8.0), P() * Mult) * dt;
else
dV = 0;
dV = 0.0;
Next->Flow(dV);
if (dV > 0)
if (dV > 0.0)
BrakeRes->Flow(-dV);
}
@@ -165,14 +167,14 @@ void TPrzek_PZZ::Update(double dt)
double dV;
if (BCP > Pgr)
dV = -PFVd(BCP, 0, d2A(8), Pgr) * dt;
dV = -PFVd(BCP, 0, d2A(8.0), Pgr) * dt;
else if (BCP < Pgr)
dV = PFVa(BVP, BCP, d2A(8), Pgr) * dt;
dV = PFVa(BVP, BCP, d2A(8.0), Pgr) * dt;
else
dV = 0;
dV = 0.0;
Next->Flow(dV);
if (dV > 0)
if (dV > 0.0)
BrakeRes->Flow(-dV);
}
@@ -188,11 +190,11 @@ void TPrzekED::Update(double dt)
if (Next->P() > MaxP)
{
BrakeRes->Flow(dVol);
Next->Flow(PFVd(Next->P(), 0, d2A(10) * dt, MaxP));
Next->Flow(PFVd(Next->P(), 0, d2A(10.0) * dt, MaxP));
}
else
Next->Flow(dVol);
dVol = 0;
dVol = 0.0;
}
// ------ OERLIKON EST NA BOGATO ------
@@ -216,15 +218,17 @@ double TNESt3::GetPF( double const PP, double const dt, double const Vel ) // pr
// luzowanie
if ((BrakeStatus & b_hld) == b_off)
dV = PF(0, BCP, Nozzles[dTO] * nastG + (1.0 - nastG) * Nozzles[dOO]) * dt *
(0.1 + 4.9 * std::min(0.2, BCP - ((CVP - 0.05 - VVP) * BVM + 0.1)));
dV =
PF(0.0, BCP, Nozzles[dTO] * nastG + (1.0 - nastG) * Nozzles[dOO])
* dt * (0.1 + 4.9 * std::min(0.2, BCP - ((CVP - 0.05 - VVP) * BVM + 0.1)));
else
dV = 0;
dV = 0.0;
// BrakeCyl.Flow(-dV);
Przekladniki[1]->Flow(-dV);
if ( ((BrakeStatus & b_on) == b_on) && (Przekladniki[1]->P() * HBG300 < MaxBP) )
dV = PF( BVP, BCP, Nozzles[dTN] * (nastG + 2.0 * (BCP < Podskok ? 1.0 : 0.0)) + Nozzles[dON] * (1 - nastG) )
* dt * (0.1 + 4.9 * std::min( 0.2, (CVP - 0.05 - VVP) * BVM - BCP ) );
dV =
PF( BVP, BCP, Nozzles[dTN] * (nastG + 2.0 * (BCP < Podskok ? 1.0 : 0.0)) + Nozzles[dON] * (1.0 - nastG) )
* dt * (0.1 + 4.9 * std::min( 0.2, (CVP - 0.05 - VVP) * BVM - BCP ) );
else
dV = 0;
// BrakeCyl.Flow(-dV);
@@ -236,30 +240,32 @@ double TNESt3::GetPF( double const PP, double const dt, double const Vel ) // pr
Przekladniki[i]->Update(dt);
if (typeid(*Przekladniki[i]) == typeid(TRapid))
{
RapidStatus =
(((BrakeDelayFlag & bdelay_R) == bdelay_R) &&
((abs(Vel) > 70) || ((RapidStatus) && (abs(Vel) > 50)) || (RapidStaly)));
RapidStatus = ( ( ( BrakeDelayFlag & bdelay_R ) == bdelay_R )
&& ( ( std::abs( Vel ) > 70.0 )
|| ( ( std::abs( Vel ) > 50.0 ) && ( RapidStatus ) )
|| ( RapidStaly ) ) );
Przekladniki[i]->SetRapidStatus(RapidStatus);
}
else if (typeid(*Przekladniki[i]) == typeid(TPrzeciwposlizg))
else if( typeid( *Przekladniki[i] ) == typeid( TPrzeciwposlizg ) )
Przekladniki[i]->SetPoslizg((BrakeStatus & b_asb) == b_asb);
else if (typeid(*Przekladniki[i]) == typeid(TPrzekED))
if (Vel < -15)
Przekladniki[i]->SetP(0);
else if( typeid( *Przekladniki[ i ] ) == typeid( TPrzekED ) ) {
if( Vel < -15.0 )
Przekladniki[ i ]->SetP( 0.0 );
else
Przekladniki[i]->SetP(MaxBP * 3);
else if (typeid(*Przekladniki[i]) == typeid(TPrzekCiagly))
Przekladniki[ i ]->SetP( MaxBP * 3.0 );
}
else if( typeid( *Przekladniki[i] ) == typeid( TPrzekCiagly ) )
Przekladniki[i]->SetMult(LoadC);
else if (typeid(*Przekladniki[i]) == typeid(TPrzek_PZZ))
else if( typeid( *Przekladniki[i] ) == typeid( TPrzek_PZZ ) )
Przekladniki[i]->SetLBP(LBP);
}
// przeplyw testowy miedzypojemnosci
dV = PF(MPP, VVP, BVs(BCP)) + PF(MPP, CVP, CVs(BCP));
if ((MPP - 0.05 > BVP))
if ((MPP - 0.05) > BVP)
dV += PF(MPP - 0.05, BVP, Nozzles[dPT] * nastG + (1.0 - nastG) * Nozzles[dPO]);
if (MPP > VVP)
dV += PF(MPP, VVP, d2A(5));
dV += PF(MPP, VVP, d2A(5.0));
Miedzypoj->Flow(dV * dt * 0.15);
// przeplyw ZS <-> PG
@@ -270,10 +276,10 @@ double TNESt3::GetPF( double const PP, double const dt, double const Vel ) // pr
dV1 += 0.98 * dV;
// przeplyw ZP <-> MPJ
if (MPP - 0.05 > BVP)
if ((MPP - 0.05) > BVP)
dV = PF(BVP, MPP - 0.05, Nozzles[dPT] * nastG + (1.0 - nastG) * Nozzles[dPO]) * dt;
else
dV = 0;
dV = 0.0;
BrakeRes->Flow(dV);
dV1 += dV * 0.98;
ValveRes->Flow(-0.02 * dV);
@@ -303,21 +309,23 @@ void TNESt3::Init( double const PP, double const HPP, double const LPP, double c
BrakeCyl->CreatePress(BP);
BrakeRes->CreatePress(PP);
CntrlRes = std::make_shared<TReservoir>();
CntrlRes->CreateCap(15);
CntrlRes->CreateCap(15.0);
CntrlRes->CreatePress(HPP);
BrakeStatus = static_cast<int>(BP > 1.0);
BrakeStatus = (BP > 1.0 ? 1 : 0);
Miedzypoj = std::make_shared<TReservoir>();
Miedzypoj->CreateCap(5);
Miedzypoj->CreateCap(5.0);
Miedzypoj->CreatePress(PP);
BVM = 1.0 / (HPP - 0.05 - LPP) * MaxBP;
BrakeDelayFlag = BDF;
if (!(typeid(*FM) == typeid(TDisk1) || typeid(*FM) == typeid(TDisk2))) // jesli zeliwo to schodz
RapidStaly = false;
else
Zamykajacy = false;
if ( (typeid(*FM) == typeid(TDisk1)) || (typeid(*FM) == typeid(TDisk2)) ) // jesli zeliwo to schodz
RapidStaly = true;
else
RapidStaly = false;
}
double TNESt3::GetCRP()
@@ -339,19 +347,19 @@ void TNESt3::CheckState(double const BCP, double &dV1) // glowny przyrzad rozrza
// sprawdzanie stanu
// if ((BrakeStatus and 1)=1)and(BCP>0.25)then
if ((VVP + 0.01 + BCP / BVM < CVP - 0.05) && (Przys_blok))
if (((VVP + 0.01 + BCP / BVM) < (CVP - 0.05)) && (Przys_blok))
BrakeStatus |= ( b_on | b_hld ); // hamowanie stopniowe;
else if (VVP - 0.01 + (BCP - 0.1) / BVM > CVP - 0.05)
else if ((VVP - 0.01 + (BCP - 0.1) / BVM) > (CVP - 0.05))
BrakeStatus &= ~( b_on | b_hld ); // luzowanie;
else if (VVP + BCP / BVM > CVP - 0.05)
else if ((VVP + BCP / BVM) > (CVP - 0.05))
BrakeStatus &= ~b_on; // zatrzymanie napelaniania;
else if ((VVP + (BCP - 0.1) / BVM < CVP - 0.05) && (BCP > 0.25)) // zatrzymanie luzowania
else if (((VVP + (BCP - 0.1) / BVM) < (CVP - 0.05)) && (BCP > 0.25)) // zatrzymanie luzowania
BrakeStatus |= b_hld;
if( ( BrakeStatus & b_hld ) == 0 )
SoundFlag |= sf_CylU;
if ((VVP + 0.10 < CVP) && (BCP < 0.25)) // poczatek hamowania
if (((VVP + 0.10) < CVP) && (BCP < 0.25)) // poczatek hamowania
if (false == Przys_blok)
{
ValveRes->CreatePress(0.1 * VVP);
@@ -362,7 +370,7 @@ void TNESt3::CheckState(double const BCP, double &dV1) // glowny przyrzad rozrza
if (BCP > 0.5)
Zamykajacy = true;
else if (VVP - 0.6 < MPP)
else if ((VVP - 0.6) < MPP)
Zamykajacy = false;
}
@@ -375,7 +383,7 @@ void TNESt3::CheckReleaser(double const dt) // odluzniacz
if ((BrakeStatus & b_rls) == b_rls)
{
CntrlRes->Flow(PF(CVP, 0, 0.02) * dt);
if ((CVP < VVP + 0.3) || (false == autom))
if ((CVP < (VVP + 0.3)) || (false == autom))
BrakeStatus &= ~b_rls;
}
}
@@ -386,9 +394,9 @@ double TNESt3::CVs(double const BP) // napelniacz sterujacego
double const MPP{ Miedzypoj->P() };
// przeplyw ZS <-> PG
if (MPP < CVP - 0.17)
return 0;
else if (MPP > CVP - 0.08)
if (MPP < (CVP - 0.17))
return 0.0;
else if (MPP > (CVP - 0.08))
return Nozzles[dSd];
else
return Nozzles[dSm];
@@ -400,15 +408,16 @@ double TNESt3::BVs(double const BCP) // napelniacz pomocniczego
double const MPP{ Miedzypoj->P() };
// przeplyw ZP <-> rozdzielacz
if (MPP < CVP - 0.3)
if (MPP < (CVP - 0.3))
return Nozzles[dP];
else if (BCP < 0.5)
if ( true == Zamykajacy)
return Nozzles[dPm]; // 1.25
else if( BCP < 0.5 ) {
if( true == Zamykajacy )
return Nozzles[ dPm ]; // 1.25
else
return Nozzles[dPd];
return Nozzles[ dPd ];
}
else
return 0;
return 0.0;
}
void TNESt3::PLC(double const mass)
@@ -461,7 +470,7 @@ void TNESt3::SetSize( int const size, std::string const &params ) // ustawianie
}
else
{
Podskok = -1;
Podskok = -1.0;
Przekladniki[1] = std::make_shared<TRapid>();
if (params.find("-s216") != std::string::npos)
Przekladniki[1]->SetRapidParams(2, 16);
@@ -489,9 +498,9 @@ void TNESt3::SetSize( int const size, std::string const &params ) // ustawianie
else
autom = true;
if ((params.find("HBG300") != std::string::npos))
HBG300 = 1;
HBG300 = 1.0;
else
HBG300 = 0;
HBG300 = 0.0;
switch (size)
{

View File

@@ -133,7 +133,7 @@ class TRapid : public TPrzekladnik {
class TPrzekCiagly : public TPrzekladnik {
private:
double mult = 0.0;
double Mult = 0.0;
public:
void SetMult(double m);

View File

@@ -193,7 +193,7 @@ double TBrakeCyl::P()
static double const cD = 1;
static double const pD = VD - cD;
double VtoC = ( Cap > 0.0 ) ? Vol / Cap : 0.0; // stosunek cisnienia do objetosci.
double VtoC = ( Cap > 0.0 ? Vol / Cap : 0.0 ); // stosunek cisnienia do objetosci.
// Added div/0 trap for vehicles with incomplete definitions (cars etc)
// P:=VtoC;
if (VtoC < VS)

View File

@@ -137,10 +137,10 @@ static int const i_bcpno = 6;
//klasa obejmujaca pojedyncze zbiorniki
class TReservoir {
protected:
double Cap = 1.0;
double Vol = 0.0;
double dVol = 0.0;
protected:
double Cap{ 1.0 };
double Vol{ 0.0 };
double dVol{ 0.0 };
public:
void CreateCap(double Capacity);
@@ -500,7 +500,7 @@ class TDriverHandle {
public:
bool Time = false;
bool TimeEP = false;
double Sounds[ 5 ]; //wielkosci przeplywow dla dzwiekow
double Sounds[ 5 ]; //wielkosci przeplywow dla dzwiekow
virtual double GetPF(double i_bcp, double PP, double HP, double dt, double ep);
virtual void Init(double Press);
@@ -509,6 +509,8 @@ class TDriverHandle {
virtual double GetSound(int i);
virtual double GetPos(int i);
virtual double GetEP(double pos);
inline TDriverHandle() { ::SecureZeroMemory( Sounds, sizeof( Sounds ) ); }
};
class TFV4a : public TDriverHandle {

View File

@@ -33,7 +33,7 @@ using namespace Mtable;
double TSubModel::fSquareDist = 0;
size_t TSubModel::iInstance; // numer renderowanego egzemplarza obiektu
texture_manager::size_type *TSubModel::ReplacableSkinId = NULL;
texture_manager::size_type const *TSubModel::ReplacableSkinId = NULL;
int TSubModel::iAlpha = 0x30300030; // maska do testowania flag tekstur wymiennych
TModel3d *TSubModel::pRoot; // Ra: tymczasowo wskaźnik na model widoczny z submodelu
std::string *TSubModel::pasText;
@@ -48,7 +48,7 @@ std::string *TSubModel::pasText;
TSubModel::TSubModel()
{
ZeroMemory(this, sizeof(TSubModel)); // istotne przy zapisywaniu wersji binarnej
::SecureZeroMemory(this, sizeof(TSubModel)); // istotne przy zapisywaniu wersji binarnej
FirstInit();
};
@@ -1054,6 +1054,7 @@ void TSubModel::RaAnimation(glm::mat4 &m, TAnimType a)
void TSubModel::RenderDL()
{ // główna procedura renderowania przez DL
return;
if( ( iVisible )
&& ( fSquareDist >= (fSquareMinDist / Global::fDistanceFactor) )
&& ( fSquareDist <= (fSquareMaxDist * Global::fDistanceFactor) ) )
@@ -1153,6 +1154,7 @@ void TSubModel::RenderDL()
void TSubModel::RenderAlphaDL()
{ // renderowanie przezroczystych przez DL
return;
if( ( iVisible )
&& ( fSquareDist >= (fSquareMinDist / Global::fDistanceFactor) )
&& ( fSquareDist <= (fSquareMaxDist * Global::fDistanceFactor) ) )
@@ -2099,39 +2101,7 @@ void TModel3d::BreakHierarhy()
Error("Not implemented yet :(");
};
/*
void TModel3d::Render(vector3 pPosition,double fAngle,GLuint
ReplacableSkinId,int iAlpha)
{
// glColor3f(1.0f,1.0f,1.0f);
// glColor3f(0.0f,0.0f,0.0f);
glPushMatrix();
glTranslated(pPosition.x,pPosition.y,pPosition.z);
if (fAngle!=0)
glRotatef(fAngle,0,1,0);
/*
matrix4x4 Identity;
Identity.Identity();
matrix4x4 CurrentMatrix;
glGetdoublev(GL_MODELVIEW_MATRIX,CurrentMatrix.getArray());
vector3 pos=vector3(0,0,0);
pos=CurrentMatrix*pos;
fSquareDist=SquareMagnitude(pos);
* /
fSquareDist=SquareMagnitude(pPosition-Global::GetCameraPosition());
#ifdef _DEBUG
if (Root)
Root->Render(ReplacableSkinId,iAlpha);
#else
Root->Render(ReplacableSkinId,iAlpha);
#endif
glPopMatrix();
};
*/
#ifdef EU07_USE_OLD_RENDERCODE
void TModel3d::Render(double fSquareDistance, texture_manager::size_type *ReplacableSkinId, int iAlpha)
{
iAlpha ^= 0x0F0F000F; // odwrócenie flag tekstur, aby wyłapać nieprzezroczyste
@@ -2152,42 +2122,8 @@ void TModel3d::RenderAlpha(double fSquareDistance, texture_manager::size_type *R
Root->RenderAlphaDL();
}
};
/*
void TModel3d::RaRender(vector3 pPosition,double fAngle,GLuint
*ReplacableSkinId,int
iAlpha)
{
// glColor3f(1.0f,1.0f,1.0f);
// glColor3f(0.0f,0.0f,0.0f);
glPushMatrix(); //zapamiętanie matrycy przekształcenia
glTranslated(pPosition.x,pPosition.y,pPosition.z);
if (fAngle!=0)
glRotatef(fAngle,0,1,0);
/*
matrix4x4 Identity;
Identity.Identity();
matrix4x4 CurrentMatrix;
glGetdoublev(GL_MODELVIEW_MATRIX,CurrentMatrix.getArray());
vector3 pos=vector3(0,0,0);
pos=CurrentMatrix*pos;
fSquareDist=SquareMagnitude(pos);
*/
/*
fSquareDist=SquareMagnitude(pPosition-Global::GetCameraPosition()); //zmienna
globalna!
if (StartVBO())
{//odwrócenie flag, aby wyłapać nieprzezroczyste
Root->ReplacableSet(ReplacableSkinId,iAlpha^0x0F0F000F);
Root->RaRender();
EndVBO();
}
glPopMatrix(); //przywrócenie ustawień przekształcenia
};
*/
void TModel3d::RaRender(double fSquareDistance, texture_manager::size_type *ReplacableSkinId, int iAlpha)
#endif
void TModel3d::RaRender(double fSquareDistance, texture_manager::size_type const *ReplacableSkinId, int iAlpha)
{ // renderowanie specjalne, np. kabiny
iAlpha ^= 0x0F0F000F; // odwrócenie flag tekstur, aby wyłapać nieprzezroczyste
if (iAlpha & iFlags & 0x1F1F001F) // czy w ogóle jest co robić w tym cyklu?
@@ -2210,7 +2146,7 @@ void TModel3d::RaRender(double fSquareDistance, texture_manager::size_type *Repl
}
};
void TModel3d::RaRenderAlpha(double fSquareDistance, texture_manager::size_type *ReplacableSkinId, int iAlpha)
void TModel3d::RaRenderAlpha(double fSquareDistance, texture_manager::size_type const *ReplacableSkinId, int iAlpha)
{ // renderowanie specjalne, np. kabiny
if (iAlpha & iFlags & 0x2F2F002F) // czy w ogóle jest co robić w tym cyklu?
{
@@ -2231,30 +2167,10 @@ void TModel3d::RaRenderAlpha(double fSquareDistance, texture_manager::size_type
}
};
/*
void TModel3d::RaRenderAlpha(vector3 pPosition,double fAngle,GLuint
*ReplacableSkinId,int
iAlpha)
{
glPushMatrix();
glTranslatef(pPosition.x,pPosition.y,pPosition.z);
if (fAngle!=0)
glRotatef(fAngle,0,1,0);
fSquareDist=SquareMagnitude(pPosition-Global::GetCameraPosition()); //zmienna
globalna!
if (StartVBO())
{Root->ReplacableSet(ReplacableSkinId,iAlpha);
Root->RaRenderAlpha();
EndVBO();
}
glPopMatrix();
};
*/
//-----------------------------------------------------------------------------
// 2011-03-16 cztery nowe funkcje renderowania z możliwością pochylania obiektów
//-----------------------------------------------------------------------------
#ifdef EU07_USE_OLD_RENDERCODE
void TModel3d::Render(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId, int iAlpha)
{ // nieprzezroczyste, Display List
glPushMatrix();
@@ -2289,7 +2205,8 @@ void TModel3d::RenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager:
Root->RenderAlphaDL();
glPopMatrix();
};
void TModel3d::RaRender(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId, int iAlpha)
#endif
void TModel3d::RaRender(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type const *ReplacableSkinId, int iAlpha)
{ // nieprzezroczyste, VBO
glPushMatrix();
glTranslated(vPosition->x, vPosition->y, vPosition->z);
@@ -2316,7 +2233,7 @@ void TModel3d::RaRender(vector3 *vPosition, vector3 *vAngle, texture_manager::si
}
glPopMatrix();
};
void TModel3d::RaRenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId,
void TModel3d::RaRenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type const *ReplacableSkinId,
int iAlpha)
{ // przezroczyste, VBO
glPushMatrix();
@@ -2345,6 +2262,7 @@ void TModel3d::RaRenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manage
glPopMatrix();
};
//-----------------------------------------------------------------------------
// 2012-02 funkcje do tworzenia terenu z E3D
//-----------------------------------------------------------------------------

View File

@@ -131,7 +131,10 @@ class TModel3d;
class TSubModel
{ // klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów
//m7todo: zrobić normalną serializację
//m7todo: zrobić normalną serializację
friend class opengl_renderer;
private:
int iNext;
int iChild;
@@ -222,7 +225,7 @@ private:
public:
static size_t iInstance; // identyfikator egzemplarza, który aktualnie renderuje model
static texture_manager::size_type *ReplacableSkinId;
static texture_manager::size_type const *ReplacableSkinId;
static int iAlpha; // maska bitowa dla danego przebiegu
static double fSquareDist;
static TModel3d *pRoot;
@@ -279,7 +282,7 @@ public:
void DisplayLists();
void BinInit(TSubModel *s, float4x4 *m, float8 *v,
std::vector<std::string> *t, std::vector<std::string> *n, bool dynamic);
void ReplacableSet(texture_manager::size_type *r, int a)
void ReplacableSet(texture_manager::size_type const *r, int a)
{
ReplacableSkinId = r;
iAlpha = a;
@@ -322,6 +325,8 @@ public:
class TModel3d : public CMesh
{
friend class opengl_renderer;
private:
// TMaterial *Materials;
// int MaterialsCount; //Ra: nie używane
@@ -355,32 +360,21 @@ public:
void SaveToBinFile(char const *FileName);
void BreakHierarhy();
// renderowanie specjalne
#ifdef EU07_USE_OLD_RENDERCODE
void Render(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
void RenderAlpha(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
void RaRender(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
void RaRenderAlpha(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
// jeden kąt obrotu
void Render(vector3 pPosition, double fAngle = 0, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
void RenderAlpha(vector3 pPosition, double fAngle = 0, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
void RaRender(vector3 pPosition, double fAngle = 0, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
void RaRenderAlpha(vector3 pPosition, double fAngle = 0, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
void RenderAlpha(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
#endif
void RaRender(double fSquareDistance, texture_manager::size_type const *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
void RaRenderAlpha(double fSquareDistance, texture_manager::size_type const *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
// trzy kąty obrotu
void Render(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
void RenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
void RaRender(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
void RaRenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
#ifdef EU07_USE_OLD_RENDERCODE
void Render( vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030 );
void RenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
#endif
void RaRender(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type const *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
void RaRenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type const *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
// inline int GetSubModelsCount() { return (SubModelsCount); };
int Flags()
int Flags() const
{
return iFlags;
};

View File

@@ -53,6 +53,13 @@ opengl_texture::load() {
// data state will be set by called loader, so we're all done here
if( data_state == resource_state::good ) {
has_alpha = (
data_components == GL_RGBA ?
true :
false );
size = data.size() / 1024;
return;
}
@@ -473,6 +480,16 @@ opengl_texture::load_TGA() {
return;
}
downsize( GL_BGRA );
if( ( data_width > Global::iMaxTextureSize ) || ( data_height > Global::iMaxTextureSize ) ) {
// for non-square textures there's currently possibility the scaling routine will have to abort
// before it gets all work done
data_state = resource_state::failed;
return;
}
// TODO: add horizontal/vertical data flip, based on the descriptor (18th) header byte
// fill remaining data info
data_mapcount = 1;
data_format = GL_BGRA;
@@ -485,82 +502,101 @@ opengl_texture::load_TGA() {
return;
}
void
resource_state
opengl_texture::bind() {
if( false == is_ready ) {
create();
if( data_state != resource_state::good ) {
return data_state;
}
}
::glBindTexture( GL_TEXTURE_2D, id );
return data_state;
}
resource_state
opengl_texture::create() {
if( data_state != resource_state::good ) {
// don't bother until we have useful texture data
return;
return data_state;
}
::glGenTextures( 1, &id );
::glBindTexture( GL_TEXTURE_2D, id );
// TODO: consider creating and storing low-res version of the texture if it's ever unloaded from the gfx card,
// as a placeholder until it can be loaded again
if( id == -1 ) {
// analyze specified texture traits
bool wraps{ true };
bool wrapt{ true };
for( auto const &trait : traits ) {
::glGenTextures( 1, &id );
::glBindTexture( GL_TEXTURE_2D, id );
switch( trait ) {
// analyze specified texture traits
bool wraps{ true };
bool wrapt{ true };
for( auto const &trait : traits ) {
case 's': { wraps = false; break; }
case 't': { wrapt = false; break; }
switch( trait ) {
case 's': { wraps = false; break; }
case 't': { wrapt = false; break; }
}
}
}
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ( wraps == true ? GL_REPEAT : GL_CLAMP_TO_EDGE ) );
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ( wrapt == true ? GL_REPEAT : GL_CLAMP_TO_EDGE ) );
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ( wraps == true ? GL_REPEAT : GL_CLAMP_TO_EDGE ) );
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ( wrapt == true ? GL_REPEAT : GL_CLAMP_TO_EDGE ) );
set_filtering();
set_filtering();
if( data_mapcount == 1 ) {
// fill missing mipmaps if needed
::glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE );
}
// upload texture data
int dataoffset = 0,
datasize = 0,
datawidth = data_width,
dataheight = data_height;
for( int maplevel = 0; maplevel < data_mapcount; ++maplevel ) {
if( data_mapcount == 1 ) {
// fill missing mipmaps if needed
::glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE );
}
// upload texture data
int dataoffset = 0,
datasize = 0,
datawidth = data_width,
dataheight = data_height;
for( int maplevel = 0; maplevel < data_mapcount; ++maplevel ) {
if( ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT )
|| ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT )
|| ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ) ) {
// compressed dds formats
int const datablocksize =
( data_format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ?
if( ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT )
|| ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT )
|| ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ) ) {
// compressed dds formats
int const datablocksize =
( data_format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ?
8 :
16 );
datasize = ( ( std::max(datawidth, 4) + 3 ) / 4 ) * ( ( std::max(dataheight, 4) + 3 ) / 4 ) * datablocksize;
datasize = ( ( std::max( datawidth, 4 ) + 3 ) / 4 ) * ( ( std::max( dataheight, 4 ) + 3 ) / 4 ) * datablocksize;
::glCompressedTexImage2D(
GL_TEXTURE_2D, maplevel, data_format,
datawidth, dataheight, 0,
datasize, (GLubyte *)&data[dataoffset] );
::glCompressedTexImage2D(
GL_TEXTURE_2D, maplevel, data_format,
datawidth, dataheight, 0,
datasize, (GLubyte *)&data[ dataoffset ] );
dataoffset += datasize;
datawidth = std::max( datawidth / 2, 1 );
dataheight = std::max( dataheight / 2, 1 );
}
else{
// uncompressed texture data
::glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA8,
data_width, data_height, 0,
data_format, GL_UNSIGNED_BYTE, (GLubyte *)&data[0] );
dataoffset += datasize;
datawidth = std::max( datawidth / 2, 1 );
dataheight = std::max( dataheight / 2, 1 );
}
else {
// uncompressed texture data
::glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA8,
data_width, data_height, 0,
data_format, GL_UNSIGNED_BYTE, (GLubyte *)&data[ 0 ] );
}
}
data.resize( 0 ); // TBD, TODO: keep the texture data if we start doing some gpu data cleaning down the road
/*
data_state = resource_state::none;
*/
data_state = resource_state::good;
is_ready = true;
}
is_ready = true;
has_alpha = (
data_components == GL_RGBA ?
true :
false );
data.resize( 0 ); // TBD, TODO: keep the texture data if we start doing some gpu data cleaning down the road
data_state = resource_state::none;
return data_state;
}
void
@@ -628,6 +664,31 @@ opengl_texture::set_filtering() {
}
}
void
opengl_texture::downsize( GLuint const Format ) {
while( ( data_width > Global::iMaxTextureSize ) || ( data_height > Global::iMaxTextureSize ) ) {
// scale down the base texture, if it's larger than allowed maximum
// NOTE: scaling is uniform along both axes, meaning non-square textures can drop below the maximum
// TODO: replace with proper scaling function once we have image middleware in place
if( ( data_width < 2 ) || ( data_height < 2 ) ) {
// can't go any smaller
break;
}
switch( Format ) {
case GL_RGB: { downsample< glm::tvec3<std::uint8_t> >( data_width, data_height, data.data() ); break; }
case GL_BGRA:
case GL_RGBA: { downsample< glm::tvec4<std::uint8_t> >( data_width, data_height, data.data() ); break; }
default: { break; }
}
data_width /= 2;
data_height /= 2;
data.resize( data.size() / 4 ); // not strictly needed, but, eh
};
}
void
texture_manager::Init() {
}
@@ -733,7 +794,9 @@ texture_manager::GetTextureId( std::string Filename, std::string const &Dir, int
if( true == Loadnow ) {
Texture( textureindex ).load();
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
Texture( textureindex ).create();
#endif
}
return textureindex;
@@ -753,20 +816,77 @@ texture_manager::Bind( texture_manager::size_type const Id ) {
// TODO: do binding in texture object, add support for other types
if( Id != 0 ) {
auto const &texture = Texture( Id );
if( true == texture.is_ready ) {
::glBindTexture( GL_TEXTURE_2D, texture.id );
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
::glBindTexture( GL_TEXTURE_2D, Id );
m_activetexture = 0;
#else
if( Texture( Id ).bind() == resource_state::good ) {
m_activetexture = Id;
return;
}
else {
// TODO: bind a special 'error' texture on failure
}
#endif
}
else {
::glBindTexture( GL_TEXTURE_2D, 0 );
m_activetexture = 0;
::glBindTexture( GL_TEXTURE_2D, 0 );
m_activetexture = 0;
}
// all done
return;
}
void
texture_manager::Free() {
for( auto const &texture : m_textures ) {
// usunięcie wszyskich tekstur (bez usuwania struktury)
if( ( texture.id > 0 )
&& ( texture.id != -1 ) ) {
::glDeleteTextures( 1, &texture.id );
}
}
}
// debug performance string
std::string
texture_manager::Info() const {
// TODO: cache this data and update only during resource sweep
std::size_t totaltexturecount{ m_textures.size() - 1 };
std::size_t totaltexturesize{ 0 };
#ifdef EU07_DEFERRED_TEXTURE_UPLOAD
std::size_t readytexturecount{ 0 };
std::size_t readytexturesize{ 0 };
#endif
for( auto const& texture : m_textures ) {
totaltexturesize += texture.size;
#ifdef EU07_DEFERRED_TEXTURE_UPLOAD
if( texture.is_ready ) {
++readytexturecount;
readytexturesize += texture.size;
}
#endif
}
return
"Textures: "
#ifdef EU07_DEFERRED_TEXTURE_UPLOAD
+ std::to_string( readytexturecount )
+ " ("
+ to_string( readytexturesize / 1024.0f, 2 ) + " mb)"
+ " in vram, ";
#endif
+ std::to_string( totaltexturecount )
+ " ("
+ to_string( totaltexturesize / 1024.0f, 2 ) + " mb)"
+ " total";
}
// checks whether specified texture is in the texture bank. returns texture id, or npos.
texture_manager::size_type
texture_manager::find_in_databank( std::string const &Texturename ) {
@@ -806,12 +926,3 @@ texture_manager::find_on_disk( std::string const &Texturename ) {
// no results either way, report failure
return "";
}
void
texture_manager::Free()
{
for( auto const &texture : m_textures ) {
// usunięcie wszyskich tekstur (bez usuwania struktury)
::glDeleteTextures( 1, &texture.id );
}
}

View File

@@ -29,13 +29,15 @@ struct opengl_texture {
// methods
void load();
void create();
resource_state bind();
resource_state create();
// members
GLuint id{ (GLuint)-1 }; // associated GL resource
bool has_alpha{ false }; // indicates the texture has alpha channel
bool is_ready{ false }; // indicates the texture was processed and is ready for use
std::string traits; // requested texture attributes: wrapping modes etc
std::string name; // name of the texture source file
std::size_t size{ 0 }; // size of the texture data, in kb
private:
// methods
@@ -44,6 +46,7 @@ private:
void load_TEX();
void load_TGA();
void set_filtering();
void downsize( GLuint const Format );
// members
std::vector<char> data; // texture data
@@ -71,11 +74,19 @@ public:
texture_manager();
~texture_manager() { Free(); }
size_type GetTextureId( std::string Filename, std::string const &Dir, int const Filter = -1, bool const Loadnow = true );
void Bind( size_type const Id );
opengl_texture &Texture( size_type const Id ) { return m_textures.at( Id ); }
void Init();
void Free();
size_type
GetTextureId( std::string Filename, std::string const &Dir, int const Filter = -1, bool const Loadnow = true );
void
Bind( size_type const Id );
opengl_texture &
Texture( size_type const Id ) { return m_textures[ Id ]; }
void
Init();
void
Free();
// debug performance string
std::string
Info() const;
private:
typedef std::unordered_map<std::string, size_type> index_map;
@@ -103,3 +114,60 @@ private:
index_map m_texturemappings;
size_type m_activetexture{ 0 }; // last i.e. currently bound texture
};
// reduces provided data image to half of original size, using basic 2x2 average
template <typename _Colortype>
void
downsample( std::size_t const Width, std::size_t const Height, char *Imagedata ) {
_Colortype *destination = reinterpret_cast<_Colortype*>( Imagedata );
_Colortype *sampler = reinterpret_cast<_Colortype*>( Imagedata );
_Colortype accumulator, color;
/*
_Colortype color;
float component;
*/
for( size_t row = 0; row < Height; row += 2, sampler += Width ) { // column movement advances us down another row
for( size_t column = 0; column < Width; column += 2, sampler += 2 ) {
/*
// straightforward, but won't work with byte data
auto color = (
*sampler
+ *( sampler + 1 )
+ *( sampler + Width )
+ *( sampler + Width + 1 ) );
color /= 4;
*/
// manual version of the above, but drops colour resolution to 6 bits
accumulator = *sampler;
accumulator /= 4;
color = accumulator;
accumulator = *(sampler + 1);
accumulator /= 4;
color += accumulator;
accumulator = *(sampler + Width);
accumulator /= 4;
color += accumulator;
accumulator = *(sampler + Width + 1);
accumulator /= 4;
color += accumulator;
*destination++ = color;
/*
// "full" 8bit resolution
color = _Colortype(); component = 0;
for( int idx = 0; idx < sizeof( _Colortype ); ++idx ) {
component = (
(*sampler)[idx]
+ ( *( sampler + 1 ) )[idx]
+ ( *( sampler + Width ) )[idx]
+ (*( sampler + Width + 1 ))[idx] );
color[ idx ] = component /= 4;
}
*destination++ = color;
*/
}
}
}

View File

@@ -2595,6 +2595,20 @@ void TTrack::EnvironmentSet()
break;
}
}
#else
switch( eEnvironment ) {
case e_canyon: {
Global::daylight.intensity = 0.5f;
break;
}
case e_tunnel: {
Global::daylight.intensity = 0.2f;
break;
}
default: {
break;
}
}
#endif
};
@@ -2610,6 +2624,17 @@ void TTrack::EnvironmentReset()
glLightfv(GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, Global::specularDayLight);
}
#else
switch( eEnvironment ) {
case e_canyon:
case e_tunnel: {
Global::daylight.intensity = 1.0f;
break;
}
default: {
break;
}
}
#endif
};
@@ -2625,7 +2650,11 @@ void TTrack::RenderDyn()
#else
for( auto dynamic : Dynamics ) {
// sam sprawdza, czy VBO; zmienia kontekst VBO!
#ifdef EU07_USE_OLD_RENDERCODE
dynamic->Render();
#else
GfxRenderer.Render( dynamic );
#endif
}
#endif
};
@@ -2642,7 +2671,11 @@ void TTrack::RenderDynAlpha()
#else
for( auto dynamic : Dynamics ) {
// sam sprawdza, czy VBO; zmienia kontekst VBO!
#ifdef EU07_USE_OLD_RENDERCODE
dynamic->RenderAlpha();
#else
GfxRenderer.Render_Alpha( dynamic );
#endif
}
#endif
};

288
Train.cpp
View File

@@ -295,35 +295,58 @@ PyObject *TTrain::GetTrainState() {
return NULL;
}
PyDict_SetItemString( dict, "direction", PyGetInt( DynamicObject->MoverParameters->ActiveDir ) );
PyDict_SetItemString( dict, "cab", PyGetInt( DynamicObject->MoverParameters->ActiveCab ) );
PyDict_SetItemString( dict, "slipping_wheels",
PyGetBool( DynamicObject->MoverParameters->SlippingWheels ) );
PyDict_SetItemString( dict, "converter",
PyGetBool( DynamicObject->MoverParameters->ConverterFlag ) );
PyDict_SetItemString( dict, "main_ctrl_actual_pos",
PyGetInt( DynamicObject->MoverParameters->MainCtrlActualPos ) );
PyDict_SetItemString( dict, "scnd_ctrl_actual_pos",
PyGetInt( DynamicObject->MoverParameters->ScndCtrlActualPos ) );
PyDict_SetItemString( dict, "fuse", PyGetBool( DynamicObject->MoverParameters->FuseFlag ) );
PyDict_SetItemString( dict, "converter_overload",
PyGetBool( DynamicObject->MoverParameters->ConvOvldFlag ) );
PyDict_SetItemString( dict, "voltage", PyGetFloat( DynamicObject->MoverParameters->Voltage ) );
PyDict_SetItemString( dict, "velocity", PyGetFloat( DynamicObject->MoverParameters->Vel ) );
PyDict_SetItemString( dict, "im", PyGetFloat( DynamicObject->MoverParameters->Im ) );
PyDict_SetItemString( dict, "compress",
PyGetBool( DynamicObject->MoverParameters->CompressorFlag ) );
PyDict_SetItemString( dict, "hours", PyGetInt( GlobalTime->hh ) );
PyDict_SetItemString( dict, "minutes", PyGetInt( GlobalTime->mm ) );
PyDict_SetItemString( dict, "seconds", PyGetInt( GlobalTime->mr ) );
PyDict_SetItemString( dict, "velocity_desired", PyGetFloat( DynamicObject->Mechanik->VelDesired ) );
auto const &mover = DynamicObject->MoverParameters;
PyDict_SetItemString( dict, "cab", PyGetInt( mover->ActiveCab ) );
// basic systems state data
PyDict_SetItemString( dict, "battery", PyGetBool( mvControlled->Battery ) );
PyDict_SetItemString( dict, "linebreaker", PyGetBool( mvControlled->Mains ) );
PyDict_SetItemString( dict, "converter", PyGetBool( mover->ConverterFlag ) );
PyDict_SetItemString( dict, "converter_overload", PyGetBool( mover->ConvOvldFlag ) );
PyDict_SetItemString( dict, "compress", PyGetBool( mover->CompressorFlag ) );
// reverser
PyDict_SetItemString( dict, "direction", PyGetInt( mover->ActiveDir ) );
// throttle
PyDict_SetItemString( dict, "mainctrl_pos", PyGetInt( mover->MainCtrlPos ) );
PyDict_SetItemString( dict, "main_ctrl_actual_pos", PyGetInt( mover->MainCtrlActualPos ) );
PyDict_SetItemString( dict, "scndctrl_pos", PyGetInt( mover->ScndCtrlPos ) );
PyDict_SetItemString( dict, "scnd_ctrl_actual_pos", PyGetInt( mover->ScndCtrlActualPos ) );
// brakes
PyDict_SetItemString( dict, "manual_brake", PyGetBool( mvOccupied->ManualBrakePos > 0 ) );
bool const bEP = ( mvControlled->LocHandle->GetCP()>0.2 ) || ( fEIMParams[ 0 ][ 2 ]>0.01 );
PyDict_SetItemString( dict, "dir_brake", PyGetBool( bEP ) );
bool bPN;
if( ( typeid( *mvControlled->Hamulec ) == typeid( TLSt ) )
|| ( typeid( *mvControlled->Hamulec ) == typeid( TEStED ) ) ) {
TBrake* temp_ham = mvControlled->Hamulec.get();
bPN = ( static_cast<TLSt*>( temp_ham )->GetEDBCP()>0.2 );
}
else
bPN = false;
PyDict_SetItemString( dict, "indir_brake", PyGetBool( bPN ) );
// other controls
PyDict_SetItemString( dict, "ca", PyGetBool( TestFlag( mvOccupied->SecuritySystem.Status, s_aware ) ) );
PyDict_SetItemString( dict, "shp", PyGetBool( TestFlag( mvOccupied->SecuritySystem.Status, s_active ) ) );
PyDict_SetItemString( dict, "pantpress", PyGetFloat( mvControlled->PantPress ) );
PyDict_SetItemString( dict, "universal3", PyGetBool( LampkaUniversal3_st ) );
// movement data
PyDict_SetItemString( dict, "velocity", PyGetFloat( mover->Vel ) );
PyDict_SetItemString( dict, "tractionforce", PyGetFloat( mover->Ft ) );
PyDict_SetItemString( dict, "slipping_wheels", PyGetBool( mover->SlippingWheels ) );
// electric current data
PyDict_SetItemString( dict, "traction_voltage", PyGetFloat( mover->RunningTraction.TractionVoltage ) );
PyDict_SetItemString( dict, "voltage", PyGetFloat( mover->Voltage ) );
PyDict_SetItemString( dict, "im", PyGetFloat( mover->Im ) );
PyDict_SetItemString( dict, "fuse", PyGetBool( mover->FuseFlag ) );
// induction motor state data
char* TXTT[ 10 ] = { "fd", "fdt", "fdb", "pd", "pdt", "pdb", "itothv", "1", "2", "3" };
char* TXTC[ 10 ] = { "fr", "frt", "frb", "pr", "prt", "prb", "im", "vm", "ihv", "uhv" };
char* TXTP[ 3 ] = { "bc", "bp", "sp" };
for( int j = 0; j<10; j++ )
for( int j = 0; j < 10; ++j )
PyDict_SetItemString( dict, ( std::string( "eimp_t_" ) + std::string( TXTT[ j ] ) ).c_str(), PyGetFloatS( fEIMParams[ 0 ][ j ] ) );
for( int i = 0; i<8; i++ ) {
for( int j = 0; j<10; j++ )
for( int i = 0; i < 8; ++i ) {
for( int j = 0; j < 10; ++j )
PyDict_SetItemString( dict, ( std::string( "eimp_c" ) + std::to_string( i + 1 ) + std::string( "_" ) + std::string( TXTC[ j ] ) ).c_str(), PyGetFloatS( fEIMParams[ i + 1 ][ j ] ) );
PyDict_SetItemString( dict, ( std::string( "eimp_c" ) + std::to_string( i + 1 ) + std::string( "_ms" ) ).c_str(), PyGetBool( bMains[ i ] ) );
PyDict_SetItemString( dict, ( std::string( "eimp_c" ) + std::to_string( i + 1 ) + std::string( "_cv" ) ).c_str(), PyGetFloatS( fCntVol[ i ] ) );
@@ -337,25 +360,17 @@ PyObject *TTrain::GetTrainState() {
PyDict_SetItemString( dict, ( std::string( "eimp_c" ) + std::to_string( i + 1 ) + std::string( "_heat" ) ).c_str(), PyGetBool( bHeat[ i ] ) );
}
for( int i = 0; i<20; i++ ) {
for( int j = 0; j<3; j++ )
for( int i = 0; i < 20; ++i ) {
for( int j = 0; j < 3; ++j )
PyDict_SetItemString( dict, ( std::string( "eimp_pn" ) + std::to_string( i + 1 ) + std::string( "_" ) + std::string( TXTP[ j ] ) ).c_str(),
PyGetFloatS( fPress[ i ][ j ] ) );
}
bool bEP, bPN;
bEP = ( mvControlled->LocHandle->GetCP()>0.2 ) || ( fEIMParams[ 0 ][ 2 ]>0.01 );
PyDict_SetItemString( dict, "dir_brake", PyGetBool( bEP ) );
if( ( typeid( *mvControlled->Hamulec ) == typeid( TLSt ) )
|| ( typeid( *mvControlled->Hamulec ) == typeid( TEStED ) ) ) {
// multi-unit state data
PyDict_SetItemString( dict, "car_no", PyGetInt( iCarNo ) );
PyDict_SetItemString( dict, "power_no", PyGetInt( iPowerNo ) );
PyDict_SetItemString( dict, "unit_no", PyGetInt( iUnitNo ) );
TBrake* temp_ham = mvControlled->Hamulec.get();
// TLSt* temp_ham2 = temp_ham;
bPN = ( static_cast<TLSt*>( temp_ham )->GetEDBCP()>0.2 );
}
else
bPN = false;
PyDict_SetItemString( dict, "indir_brake", PyGetBool( bPN ) );
for( int i = 0; i<20; i++ ) {
for( int i = 0; i < 20; i++ ) {
PyDict_SetItemString( dict, ( std::string( "doors_" ) + std::to_string( i + 1 ) ).c_str(), PyGetFloatS( bDoors[ i ][ 0 ] ) );
PyDict_SetItemString( dict, ( std::string( "doors_r_" ) + std::to_string( i + 1 ) ).c_str(), PyGetFloatS( bDoors[ i ][ 1 ] ) );
PyDict_SetItemString( dict, ( std::string( "doors_l_" ) + std::to_string( i + 1 ) ).c_str(), PyGetFloatS( bDoors[ i ][ 2 ] ) );
@@ -364,23 +379,21 @@ PyObject *TTrain::GetTrainState() {
cCode[ i ] ).c_str() ) );
PyDict_SetItemString( dict, ( std::string( "car_name" ) + std::to_string( i + 1 ) ).c_str(), PyGetString( asCarName[ i ].c_str() ) );
}
PyDict_SetItemString( dict, "car_no", PyGetInt( iCarNo ) );
PyDict_SetItemString( dict, "power_no", PyGetInt( iPowerNo ) );
PyDict_SetItemString( dict, "unit_no", PyGetInt( iUnitNo ) );
PyDict_SetItemString( dict, "universal3", PyGetBool( LampkaUniversal3_st ) );
PyDict_SetItemString( dict, "ca", PyGetBool( TestFlag( mvOccupied->SecuritySystem.Status, s_aware ) ) );
PyDict_SetItemString( dict, "shp", PyGetBool( TestFlag( mvOccupied->SecuritySystem.Status, s_active ) ) );
PyDict_SetItemString( dict, "manual_brake", PyGetBool( mvOccupied->ManualBrakePos > 0 ) );
PyDict_SetItemString( dict, "pantpress", PyGetFloat( mvControlled->PantPress ) );
PyDict_SetItemString( dict, "trainnumber", PyGetString( DynamicObject->Mechanik->TrainName().c_str() ) );
PyDict_SetItemString( dict, "velnext", PyGetFloat( DynamicObject->Mechanik->VelNext ) );
PyDict_SetItemString( dict, "actualproximitydist", PyGetFloat( DynamicObject->Mechanik->ActualProximityDist ) );
PyDict_SetItemString( dict, "velsignallast", PyGetFloat( DynamicObject->Mechanik->VelSignalLast ) );
PyDict_SetItemString( dict, "vellimitlast", PyGetFloat( DynamicObject->Mechanik->VelLimitLast ) );
PyDict_SetItemString( dict, "velroad", PyGetFloat( DynamicObject->Mechanik->VelRoad ) );
PyDict_SetItemString( dict, "velsignalnext", PyGetFloat( DynamicObject->Mechanik->VelSignalNext ) );
PyDict_SetItemString( dict, "battery", PyGetBool( mvControlled->Battery ) );
PyDict_SetItemString( dict, "tractionforce", PyGetFloat( DynamicObject->MoverParameters->Ft ) );
// ai state data
auto const &driver = DynamicObject->Mechanik;
PyDict_SetItemString( dict, "velocity_desired", PyGetFloat( driver->VelDesired ) );
PyDict_SetItemString( dict, "velroad", PyGetFloat( driver->VelRoad ) );
PyDict_SetItemString( dict, "vellimitlast", PyGetFloat( driver->VelLimitLast ) );
PyDict_SetItemString( dict, "velsignallast", PyGetFloat( driver->VelSignalLast ) );
PyDict_SetItemString( dict, "velsignalnext", PyGetFloat( driver->VelSignalNext ) );
PyDict_SetItemString( dict, "velnext", PyGetFloat( driver->VelNext ) );
PyDict_SetItemString( dict, "actualproximitydist", PyGetFloat( driver->ActualProximityDist ) );
PyDict_SetItemString( dict, "trainnumber", PyGetString( driver->TrainName().c_str() ) );
// world state data
PyDict_SetItemString( dict, "hours", PyGetInt( GlobalTime->hh ) );
PyDict_SetItemString( dict, "minutes", PyGetInt( GlobalTime->mm ) );
PyDict_SetItemString( dict, "seconds", PyGetInt( GlobalTime->mr ) );
return dict;
}
@@ -508,7 +521,7 @@ void TTrain::OnKeyDown(int cKey)
}
}
}
else if (cKey == Global::Keys[k_StLinOff])
else if ((cKey == Global::Keys[k_StLinOff]) && (!Global::shiftState) && (!Global::ctrlState)) // shift&ctrl are used for light dimming
{
if (mvControlled->TrainType == dt_EZT)
{
@@ -1792,21 +1805,18 @@ if
{ // tryb freefly
int CouplNr = -1; // normalnie żaden ze sprzęgów
TDynamicObject *tmp;
tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), 1, 1500,
CouplNr);
if (tmp == NULL)
tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), -1,
1500, CouplNr);
if (tmp && (CouplNr != -1))
tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), 1, 1500, CouplNr);
if (tmp == nullptr)
tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), -1, 1500, CouplNr);
if( ( CouplNr != -1 )
&& ( tmp != nullptr )
&& ( tmp->MoverParameters->Couplers[ CouplNr ].Connected != nullptr ) )
{
if (tmp->MoverParameters->Couplers[CouplNr].CouplingFlag ==
0) // najpierw hak
if (tmp->MoverParameters->Couplers[CouplNr].CouplingFlag == 0) // najpierw hak
{
if ((tmp->MoverParameters->Couplers[CouplNr]
.Connected->Couplers[CouplNr]
.AllowedFlag &
tmp->MoverParameters->Couplers[CouplNr].AllowedFlag &
ctrain_coupler) == ctrain_coupler)
if ((tmp->MoverParameters->Couplers[CouplNr].Connected->Couplers[CouplNr].AllowedFlag
& tmp->MoverParameters->Couplers[CouplNr].AllowedFlag
& ctrain_coupler) == ctrain_coupler)
if (tmp->MoverParameters->Attach(
CouplNr, 2,
tmp->MoverParameters->Couplers[CouplNr].Connected,
@@ -1815,46 +1825,37 @@ if
// tmp->MoverParameters->Couplers[CouplNr].Render=true;
// //podłączony sprzęg będzie widoczny
if (DynamicObject->Mechanik) // na wszelki wypadek
DynamicObject->Mechanik->CheckVehicles(
Connect); // aktualizacja flag kierunku w składzie
DynamicObject->Mechanik->CheckVehicles(Connect); // aktualizacja flag kierunku w składzie
dsbCouplerAttach->SetVolume(DSBVOLUME_MAX);
dsbCouplerAttach->Play(0, 0, 0);
}
else
WriteLog("Mechanical coupling failed.");
}
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag,
ctrain_pneumatic)) // pneumatyka
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_pneumatic)) // pneumatyka
{
if ((tmp->MoverParameters->Couplers[CouplNr]
.Connected->Couplers[CouplNr]
.AllowedFlag &
tmp->MoverParameters->Couplers[CouplNr].AllowedFlag &
ctrain_pneumatic) == ctrain_pneumatic)
if ((tmp->MoverParameters->Couplers[CouplNr].Connected->Couplers[CouplNr].AllowedFlag
& tmp->MoverParameters->Couplers[CouplNr].AllowedFlag
& ctrain_pneumatic) == ctrain_pneumatic)
if (tmp->MoverParameters->Attach(
CouplNr, 2,
tmp->MoverParameters->Couplers[CouplNr].Connected,
tmp->MoverParameters->Couplers[CouplNr].CouplingFlag +
ctrain_pneumatic))
(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag | ctrain_pneumatic)))
{
rsHiss.Play(1, DSBPLAY_LOOPING, true, tmp->GetPosition());
DynamicObject->SetPneumatic(CouplNr != 0, true); // Ra: to mi się nie podoba !!!!
tmp->SetPneumatic(CouplNr != 0, true);
}
}
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag,
ctrain_scndpneumatic)) // zasilajacy
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_scndpneumatic)) // zasilajacy
{
if ((tmp->MoverParameters->Couplers[CouplNr]
.Connected->Couplers[CouplNr]
.AllowedFlag &
tmp->MoverParameters->Couplers[CouplNr].AllowedFlag &
ctrain_scndpneumatic) == ctrain_scndpneumatic)
if ((tmp->MoverParameters->Couplers[CouplNr].Connected->Couplers[CouplNr].AllowedFlag
& tmp->MoverParameters->Couplers[CouplNr].AllowedFlag
& ctrain_scndpneumatic) == ctrain_scndpneumatic)
if (tmp->MoverParameters->Attach(
CouplNr, 2,
tmp->MoverParameters->Couplers[CouplNr].Connected,
tmp->MoverParameters->Couplers[CouplNr].CouplingFlag +
ctrain_scndpneumatic))
(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag | ctrain_scndpneumatic)))
{
// rsHiss.Play(1,DSBPLAY_LOOPING,true,tmp->GetPosition());
dsbCouplerDetach->SetVolume(DSBVOLUME_MAX);
@@ -1863,8 +1864,7 @@ if
tmp->SetPneumatic(CouplNr != 0, false);
}
}
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag,
ctrain_controll)) // ukrotnionko
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_controll)) // ukrotnionko
{
if ((tmp->MoverParameters->Couplers[CouplNr]
.Connected->Couplers[CouplNr]
@@ -1874,15 +1874,13 @@ if
if (tmp->MoverParameters->Attach(
CouplNr, 2,
tmp->MoverParameters->Couplers[CouplNr].Connected,
tmp->MoverParameters->Couplers[CouplNr].CouplingFlag +
ctrain_controll))
(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag | ctrain_controll)))
{
dsbCouplerAttach->SetVolume(DSBVOLUME_MAX);
dsbCouplerAttach->Play(0, 0, 0);
}
}
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag,
ctrain_passenger)) // mostek
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_passenger)) // mostek
{
if ((tmp->MoverParameters->Couplers[CouplNr]
.Connected->Couplers[CouplNr]
@@ -1892,8 +1890,7 @@ if
if (tmp->MoverParameters->Attach(
CouplNr, 2,
tmp->MoverParameters->Couplers[CouplNr].Connected,
tmp->MoverParameters->Couplers[CouplNr].CouplingFlag +
ctrain_passenger))
(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag | ctrain_passenger)))
{
// rsHiss.Play(1,DSBPLAY_LOOPING,true,tmp->GetPosition());
dsbCouplerDetach->SetVolume(DSBVOLUME_MAX);
@@ -1912,8 +1909,7 @@ if
// odlegle wagony
if (iCabn > 0)
{
if (!FreeFlyModeFlag) // tryb 'kabinowy' (pozwala również rozłączyć
// sprzęgi zablokowane)
if (!FreeFlyModeFlag) // tryb 'kabinowy' (pozwala również rozłączyć sprzęgi zablokowane)
{
if (DynamicObject->DettachStatus(iCabn - 1) < 0) // jeśli jest co odczepić
if (DynamicObject->Dettach(iCabn - 1)) // iCab==1:przód,iCab==2:tył
@@ -1926,15 +1922,12 @@ if
{ // tryb freefly
int CouplNr = -1;
TDynamicObject *tmp;
tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), 1, 1500,
CouplNr);
tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), 1, 1500, CouplNr);
if (tmp == NULL)
tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), -1,
1500, CouplNr);
tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), -1, 1500, CouplNr);
if (tmp && (CouplNr != -1))
{
if ((tmp->MoverParameters->Couplers[CouplNr].CouplingFlag & ctrain_depot) ==
0) // jeżeli sprzęg niezablokowany
if ((tmp->MoverParameters->Couplers[CouplNr].CouplingFlag & ctrain_depot) == 0) // jeżeli sprzęg niezablokowany
if (tmp->DettachStatus(CouplNr) < 0) // jeśli jest co odczepić i się da
if (!tmp->Dettach(CouplNr))
{ // dźwięk odczepiania
@@ -2352,7 +2345,7 @@ if
}
}
}
else if (cKey == Global::Keys[k_StLinOff]) // Winger 110904: wylacznik st.
else if ((cKey == Global::Keys[k_StLinOff]) && (!Global::shiftState) && (!Global::ctrlState)) // Winger 110904: wylacznik st.
// liniowych
{
if ((mvControlled->TrainType != dt_EZT) && (mvControlled->TrainType != dt_EP05) &&
@@ -2481,6 +2474,29 @@ if
++iRadioChannel; // 0=wyłączony
}
}
// TODO: break the mess above into individual command-based routines.
// TODO: test for modifiers inside the routines, instead of grouping by the modifier
// TODO: do away with the modifier tests, each command should be separate and issued by input processor(s) up the chain
if( cKey == Global::Keys[ k_DimHeadlights ] ) {
// headlight strength toggle
if( !Global::ctrlState ) {
// switch uses either ctrl, or ctrl+shift, so we can bail early here
return;
}
if( DynamicObject->DimHeadlights && (!Global::shiftState)) {
DynamicObject->DimHeadlights = false;
// switch sound
dsbSwitch->SetVolume( DSBVOLUME_MAX );
dsbSwitch->Play( 0, 0, 0 );
}
else if( (!DynamicObject->DimHeadlights) && (Global::shiftState)) {
DynamicObject->DimHeadlights = true;
// switch sound
dsbSwitch->SetVolume( DSBVOLUME_MAX );
dsbSwitch->Play( 0, 0, 0 );
}
}
}
void TTrain::OnKeyUp(int cKey)
@@ -2490,7 +2506,7 @@ void TTrain::OnKeyUp(int cKey)
}
else
{
if (cKey == Global::Keys[k_StLinOff]) // Winger 110904: wylacznik st. liniowych
if ((cKey == Global::Keys[k_StLinOff]) && (!Global::shiftState) && (!Global::ctrlState)) // Winger 110904: wylacznik st. liniowych
{ // zwolnienie klawisza daje powrót przycisku do zwykłego stanu
if ((mvControlled->TrainType != dt_EZT) && (mvControlled->TrainType != dt_EP05) &&
(mvControlled->TrainType != dt_ET40))
@@ -2686,10 +2702,9 @@ bool TTrain::Update( double const Deltatime )
iSekunda=floor(GlobalTime->mr);
}
*/
// Ra 2014-09: napięcia i prądy muszą być ustalone najpierw, bo wysyłane są
// ewentualnie na
// PoKeys
if ((mvControlled->EngineType != DieselElectric) && (mvControlled->EngineType != ElectricInductionMotor)) // Ra 2014-09: czy taki rozdzia? ma sens?
// Ra 2014-09: napięcia i prądy muszą być ustalone najpierw, bo wysyłane są ewentualnie na PoKeys
if ((mvControlled->EngineType != DieselElectric)
&& (mvControlled->EngineType != ElectricInductionMotor)) // Ra 2014-09: czy taki rozdzia? ma sens?
fHVoltage = mvControlled->RunningTraction.TractionVoltage; // Winger czy to nie jest zle?
// *mvControlled->Mains);
else
@@ -3901,41 +3916,6 @@ bool TTrain::Update( double const Deltatime )
ggLeftEndLightButton.PutValue(0);
}
//---------
// hunter-101211: poprawka na zle obracajace sie przelaczniki
/*
if (((DynamicObject->iLights[0]&1)==1)
||((DynamicObject->iLights[1]&1)==1))
ggLeftLightButton.PutValue(1);
if (((DynamicObject->iLights[0]&16)==16)
||((DynamicObject->iLights[1]&16)==16))
ggRightLightButton.PutValue(1);
if (((DynamicObject->iLights[0]&4)==4)
||((DynamicObject->iLights[1]&4)==4))
ggUpperLightButton.PutValue(1);
if (((DynamicObject->iLights[0]&2)==2)
||((DynamicObject->iLights[1]&2)==2))
if (ggLeftEndLightButton.SubModel)
{
ggLeftEndLightButton.PutValue(1);
ggLeftLightButton.PutValue(0);
}
else
ggLeftLightButton.PutValue(-1);
if (((DynamicObject->iLights[0]&32)==32)
||((DynamicObject->iLights[1]&32)==32))
if (ggRightEndLightButton.SubModel)
{
ggRightEndLightButton.PutValue(1);
ggRightLightButton.PutValue(0);
}
else
ggRightLightButton.PutValue(-1);
*/
//--------------
// hunter-230112
// REFLEKTOR LEWY
@@ -4073,6 +4053,11 @@ bool TTrain::Update( double const Deltatime )
ggLightsButton.PutValue(mvOccupied->LightsPos - 1);
ggLightsButton.Update();
}
if( ggDimHeadlightsButton.SubModel ) {
ggDimHeadlightsButton.PutValue( DynamicObject->DimHeadlights ? 1.0 : 0.0 );
ggDimHeadlightsButton.Update();
}
//---------
// Winger 010304 - pantografy
@@ -5879,6 +5864,7 @@ void TTrain::clear_cab_controls()
ggLeftLightButton.Clear();
ggRightLightButton.Clear();
ggUpperLightButton.Clear();
ggDimHeadlightsButton.Clear();
ggLeftEndLightButton.Clear();
ggRightEndLightButton.Clear();
ggLightsButton.Clear();
@@ -6283,7 +6269,11 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
// swiatlo
ggRightLightButton.Load(Parser, DynamicObject->mdKabina);
}
else if (Label == "leftend_sw:")
else if( Label == "dimheadlights_sw:" ) {
// swiatlo
ggDimHeadlightsButton.Load( Parser, DynamicObject->mdKabina );
}
else if( Label == "leftend_sw:" )
{
// swiatlo
ggLeftEndLightButton.Load(Parser, DynamicObject->mdKabina);

View File

@@ -177,6 +177,7 @@ class TTrain
TGauge ggLeftEndLightButton;
TGauge ggRightEndLightButton;
TGauge ggLightsButton; // przelacznik reflektorow (wszystkich)
TGauge ggDimHeadlightsButton; // headlights dimming switch
// hunter-230112: przelacznik swiatel tylnich
TGauge ggRearUpperLightButton;
@@ -251,8 +252,7 @@ class TTrain
TButton btLampkaOpory;
TButton btLampkaWysRozr;
TButton btLampkaUniversal3;
int LampkaUniversal3_typ; // ABu 030405 - swiecenie uzaleznione od: 0-nic,
// 1-obw.gl, 2-przetw.
int LampkaUniversal3_typ; // ABu 030405 - swiecenie uzaleznione od: 0-nic, 1-obw.gl, 2-przetw.
bool LampkaUniversal3_st;
TButton btLampkaWentZaluzje; // ET22
TButton btLampkaOgrzewanieSkladu;

2014
World.cpp

File diff suppressed because it is too large Load Diff

21
World.h
View File

@@ -18,7 +18,7 @@ http://mozilla.org/MPL/2.0/.
#include "stars.h"
#include "skydome.h"
#include "mczapkie/mover.h"
#include "glfw/glfw3.h"
#include "renderer.h"
// wrapper for environment elements -- sky, sun, stars, clouds etc
class world_environment {
@@ -27,6 +27,7 @@ public:
void init();
void update();
void render();
void time( int const Hour = -1, int const Minute = -1, int const Second = -1 );
private:
CSkyDome m_skydome;
@@ -37,6 +38,9 @@ private:
class TWorld
{
// NOTE: direct access is a shortcut, but world etc needs some restructuring regardless
friend opengl_renderer;
void InOutKey( bool const Near = true );
void FollowView(bool wycisz = true);
void DistantView( bool const Near = false );
@@ -53,6 +57,8 @@ class TWorld
void OnCommandGet(DaneRozkaz *pRozkaz);
bool Update();
void TrainDelete(TDynamicObject *d = NULL);
// switches between static and dynamic daylight calculation
void ToggleDaylight();
TWorld();
~TWorld();
// double Aspect;
@@ -63,27 +69,24 @@ class TWorld
std::string OutText4;
void Update_Environment();
void Update_Camera( const double Deltatime );
bool Render();
void Update_UI();
void ResourceSweep();
void Render_Cab();
void Render_UI();
TCamera Camera;
TGround Ground;
world_environment Environment;
TTrain *Train;
TDynamicObject *pDynamicNearest;
bool Paused{ true };
GLuint base; // numer DL dla znaków w napisach
texture_manager::size_type light; // numer tekstury dla smugi
TEvent *KeyEvents[10]; // eventy wyzwalane z klawiaury
TMoverParameters *mvControlled; // wskaźnik na człon silnikowy, do wyświetlania jego parametrów
int iCheckFPS; // kiedy znów sprawdzić FPS, żeby wyłączać optymalizacji od razu do zera
double fTime50Hz; // bufor czasu dla komunikacji z PoKeys
double fTimeBuffer; // bufor czasu aktualizacji dla stałego kroku fizyki
double fMaxDt; //[s] krok czasowy fizyki (0.01 dla normalnych warunków)
double m_primaryupdaterate{ 1.0 / 100.0 };
double m_primaryupdateaccumulator{ 0.0 }; // keeps track of elapsed simulation time, for core fixed step routines
double m_secondaryupdaterate{ 1.0 / 50.0 };
double m_secondaryupdateaccumulator{ 0.0 }; // keeps track of elapsed simulation time, for less important fixed step routines
double m_primaryupdateaccumulator{ m_secondaryupdaterate }; // keeps track of elapsed simulation time, for core fixed step routines
double m_secondaryupdateaccumulator{ m_secondaryupdaterate }; // keeps track of elapsed simulation time, for less important fixed step routines
int iPause; // wykrywanie zmian w zapauzowaniu
double VelPrev; // poprzednia prędkość
int tprev; // poprzedni czas
@@ -94,6 +97,8 @@ class TWorld
void ModifyTGA(std::string const &dir = "");
void CreateE3D(std::string const &dir = "", bool dyn = false);
void CabChange(TDynamicObject *old, TDynamicObject *now);
// handles vehicle change flag
void ChangeDynamic();
gl_program_light shader; //m7todo: tmp
};

View File

@@ -11,15 +11,12 @@ http://mozilla.org/MPL/2.0/.
#include "frustum.h"
void
cFrustum::calculate() {
cFrustum::calculate( glm::mat4 &Projection, glm::mat4 &Modelview ) {
float proj[ 16 ];
float modl[ 16 ];
float *proj = &Projection[ 0 ][ 0 ];
float *modl = &Modelview[ 0 ][ 0 ];
float clip[ 16 ];
glGetFloatv( GL_PROJECTION_MATRIX, proj );
glGetFloatv( GL_MODELVIEW_MATRIX, modl );
// multiply the matrices to retrieve clipping planes
clip[ 0 ] = modl[ 0 ] * proj[ 0 ] + modl[ 1 ] * proj[ 4 ] + modl[ 2 ] * proj[ 8 ] + modl[ 3 ] * proj[ 12 ];
clip[ 1 ] = modl[ 0 ] * proj[ 1 ] + modl[ 1 ] * proj[ 5 ] + modl[ 2 ] * proj[ 9 ] + modl[ 3 ] * proj[ 13 ];

View File

@@ -22,7 +22,7 @@ public:
// methods:
// update the frustum to match current view orientation
void
calculate();
calculate(glm::mat4 &Projection, glm::mat4 &Modelview);
// returns true if specified point is inside of the frustum
inline
bool

View File

@@ -46,12 +46,12 @@ light_array::update() {
// update light parameters to match current data of the owner
if( light.index == 0 ) {
// front light set
light.position = light.owner->GetPosition() + ( light.owner->VectorFront() * light.owner->GetLength() * 0.45 );
light.position = light.owner->GetPosition() + ( light.owner->VectorFront() * light.owner->GetLength() * 0.4 );
light.direction = light.owner->VectorFront();
}
else {
// rear light set
light.position = light.owner->GetPosition() - ( light.owner->VectorFront() * light.owner->GetLength() * 0.45 );
light.position = light.owner->GetPosition() - ( light.owner->VectorFront() * light.owner->GetLength() * 0.4 );
light.direction = light.owner->VectorFront();
light.direction.x = -light.direction.x;
light.direction.z = -light.direction.z;
@@ -67,8 +67,8 @@ light_array::update() {
if( light.count > 0 ) {
// TODO: intensity can be affected further by dim switch or other factors
light.intensity = std::max( 0.0f, std::log( (float)light.count + 1.0f ) );
// light.intensity = std::max( 0.0f, std::log( (float)light.count + 3.0f ) );
light.intensity = std::max( 0.0f, std::log( (float)light.count + 1.0f ) );
light.intensity *= ( light.owner->DimHeadlights ? 0.6f : 1.0f );
}
else {
light.intensity = 0.0f;

View File

@@ -238,6 +238,32 @@ int cParser::getProgress() const
return static_cast<int>( mStream->rdbuf()->pubseekoff(0, std::ios_base::cur) * 100 / mSize );
}
int cParser::getFullProgress() const {
int progress = getProgress();
if( mIncludeParser ) return progress + ( ( 100 - progress )*( mIncludeParser->getProgress() ) / 100 );
else return progress;
}
std::size_t cParser::countTokens( std::string const &Stream, std::string Path ) {
return cParser( Stream, buffer_FILE, Path ).count();
}
std::size_t cParser::count() {
std::string token;
size_t count{ 0 };
do {
token = "";
token = readToken( false );
++count;
} while( false == token.empty() );
return count - 1;
}
void cParser::addCommentStyle( std::string const &Commentstart, std::string const &Commentend ) {
mComments.insert( commentmap::value_type(Commentstart, Commentend) );

View File

@@ -80,6 +80,9 @@ class cParser //: public std::stringstream
bool getTokens(unsigned int Count = 1, bool ToLower = true, const char *Break = "\n\r\t ;");
// returns percentage of file processed so far
int getProgress() const;
int getFullProgress() const;
//
static std::size_t countTokens( std::string const &Stream, std::string Path = "" );
// add custom definition of text which should be ignored when retrieving tokens
void addCommentStyle( std::string const &Commentstart, std::string const &Commentend );
@@ -91,6 +94,7 @@ class cParser //: public std::stringstream
// std::string trtest;
bool findQuotes( std::string &String );
bool trimComments( std::string &String );
std::size_t count();
// members:
bool LoadTraction; // load traction?
std::istream *mStream; // relevant kind of buffer is attached on creation.

View File

@@ -1,4 +1,4 @@
/*
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
@@ -8,16 +8,499 @@ http://mozilla.org/MPL/2.0/.
*/
#include "stdafx.h"
#include "renderer.h"
#include "globals.h"
#include "World.h"
#include "dynobj.h"
#include "uilayer.h"
#include "logs.h"
opengl_renderer GfxRenderer;
extern TWorld World;
void
opengl_renderer::Init() {
// returns true if specified object is within camera frustum, false otherwise
bool
opengl_camera::visible( bounding_area const &Area ) const {
return ( m_frustum.sphere_inside( Area.center, Area.radius ) > 0.0f );
}
bool
opengl_camera::visible( TDynamicObject const *Dynamic ) const {
// sphere test is faster than AABB, so we'll use it here
float3 diagonal(
Dynamic->MoverParameters->Dim.L,
Dynamic->MoverParameters->Dim.H,
Dynamic->MoverParameters->Dim.W );
float const radius = diagonal.Length() * 0.5f;
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), radius ) > 0.0f );
}
bool
opengl_renderer::Init( GLFWwindow *Window ) {
if( false == Init_caps() ) {
return false;
}
m_window = Window;
glClearDepth( 1.0f );
glClearColor( 51.0f / 255.0f, 102.0f / 255.0f, 85.0f / 255.0f, 1.0f ); // initial background Color
glPolygonMode( GL_FRONT, GL_FILL );
glFrontFace( GL_CCW ); // Counter clock-wise polygons face out
glEnable( GL_CULL_FACE ); // Cull back-facing triangles
glShadeModel( GL_SMOOTH ); // Enable Smooth Shading
glEnable( GL_DEPTH_TEST );
glAlphaFunc( GL_GREATER, 0.04f );
glEnable( GL_ALPHA_TEST );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glEnable( GL_BLEND );
glEnable( GL_TEXTURE_2D ); // Enable Texture Mapping
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); // Really Nice Perspective Calculations
glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST );
glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
glLineWidth( 1.0f );
glPointSize( 3.0f );
glEnable( GL_POINT_SMOOTH );
glEnable( GL_COLOR_MATERIAL );
glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
// setup lighting
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
// directional light
// TODO, TBD: test omni-directional variant
// rgb value for 5780 kelvin
Global::daylight.color.x = 255.0f / 255.0f;
Global::daylight.color.y = 242.0f / 255.0f;
Global::daylight.color.z = 231.0f / 255.0f;
// setup fog
if( Global::fFogEnd > 0 ) {
// fog setup
::glFogi( GL_FOG_MODE, GL_LINEAR );
::glFogfv( GL_FOG_COLOR, Global::FogColor );
::glFogf( GL_FOG_START, Global::fFogStart );
::glFogf( GL_FOG_END, Global::fFogEnd );
::glEnable( GL_FOG );
}
else { ::glDisable( GL_FOG ); }
World.shader = gl_program_light({ gl_shader("lighting.vert"), gl_shader("blinnphong.frag") });
Global::daylight.intensity = 1.0f; //m7todo: przenieść
return true;
}
bool
opengl_renderer::Render() {
auto timestart = std::chrono::steady_clock::now();
glUseProgram(World.shader);
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
::glDepthFunc( GL_LEQUAL );
::glMatrixMode( GL_PROJECTION ); // select the Projection Matrix
glm::mat4 projection = glm::perspective(
Global::FieldOfView / Global::ZoomFactor * 0.0174532925f,
std::max( 1.0f, (float)Global::ScreenWidth ) / std::max( 1.0f, (float)Global::ScreenHeight ),
0.1f * Global::ZoomFactor,
m_drawrange * Global::fDistanceFactor );
::glLoadMatrixf( &projection[0][0] );
::glMatrixMode( GL_MODELVIEW ); // Select The Modelview Matrix
glm::mat4 modelview( 1.0f );
::glLoadIdentity();
if( World.InitPerformed() ) {
World.Camera.SetMatrix( modelview );
::glLoadMatrixf( &modelview[ 0 ][ 0 ] );
m_camera.update_frustum( projection, modelview );
if( !Global::bWireFrame ) {
// bez nieba w trybie rysowania linii
World.Environment.render();
}
glDebug("rendering ground");
World.Ground.Render( World.Camera.Pos );
glDebug("rendering cab");
World.Render_Cab();
// accumulate last 20 frames worth of render time (cap at 1000 fps to prevent calculations going awry)
m_drawtime = std::max( 20.0f, 0.95f * m_drawtime + std::chrono::duration_cast<std::chrono::milliseconds>( ( std::chrono::steady_clock::now() - timestart ) ).count());
}
glUseProgram(0);
UILayer.render();
glfwSwapBuffers( m_window );
return true; // for now always succeed
}
#ifndef EU07_USE_OLD_RENDERCODE
bool
opengl_renderer::Render( TGround *Ground ) {
glDisable( GL_BLEND );
glAlphaFunc( GL_GREATER, 0.35f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
glEnable( GL_LIGHTING );
glColor3f( 1.0f, 1.0f, 1.0f );
float3 const cameraposition = float3( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z );
int const camerax = std::floor( cameraposition.x / 1000.0f ) + iNumRects / 2;
int const cameraz = std::floor( cameraposition.z / 1000.0f ) + iNumRects / 2;
int const segmentcount = 2 * static_cast<int>(std::ceil( m_drawrange * Global::fDistanceFactor / 1000.0f ));
int const originx = std::max( 0, camerax - segmentcount / 2 );
int const originz = std::max( 0, cameraz - segmentcount / 2 );
for( int column = originx; column <= originx + segmentcount; ++column ) {
for( int row = originz; row <= originz + segmentcount; ++row ) {
auto &rectangle = Ground->Rects[ column ][ row ];
if( m_camera.visible( rectangle.m_area ) ) {
rectangle.RenderDL();
}
}
}
return true;
}
bool
opengl_renderer::Render( TDynamicObject *Dynamic ) {
if( false == m_camera.visible( Dynamic ) ) {
Dynamic->renderme = false;
return false;
}
Dynamic->renderme = true;
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
double squaredistance = SquareMagnitude( Global::pCameraPosition - Dynamic->vPosition ) / Global::ZoomFactor;
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
::glPushMatrix();
if( Dynamic == Global::pUserDynamic ) {
//specjalne ustawienie, aby nie trzęsło
//tu trzeba by ustawić animacje na modelu zewnętrznym
::glLoadIdentity(); // zacząć od macierzy jedynkowej
Global::pCamera->SetCabMatrix( Dynamic->vPosition ); // specjalne ustawienie kamery
}
else
::glTranslated( Dynamic->vPosition.x, Dynamic->vPosition.y, Dynamic->vPosition.z ); // standardowe przesunięcie względem początku scenerii
::glMultMatrixd( Dynamic->mMatrix.getArray() );
if( Dynamic->fShade > 0.0f ) {
// change light level based on light level of the occupied track
Global::daylight.intensity = Dynamic->fShade;
}
// TODO: implement universal render path down the road
if( Global::bUseVBO ) {
// wersja VBO
if( Dynamic->mdLowPolyInt ) {
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
// enable cab light if needed
if( Dynamic->InteriorLightLevel > 0.0f ) {
// crude way to light the cabin, until we have something more complete in place
auto const cablight = Dynamic->InteriorLight * Dynamic->InteriorLightLevel;
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
}
Dynamic->mdLowPolyInt->RaRender( squaredistance, Dynamic->Material()->replacable_skins, Dynamic->Material()->textures_alpha );
if( Dynamic->InteriorLightLevel > 0.0f ) {
// reset the overall ambient
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
}
}
}
Dynamic->mdModel->RaRender( squaredistance, Dynamic->Material()->replacable_skins, Dynamic->Material()->textures_alpha );
if( Dynamic->mdLoad ) // renderowanie nieprzezroczystego ładunku
Dynamic->mdLoad->RaRender( squaredistance, Dynamic->Material()->replacable_skins, Dynamic->Material()->textures_alpha );
}
else {
// wersja Display Lists
if( Dynamic->mdLowPolyInt ) {
// low poly interior
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
// enable cab light if needed
if( Dynamic->InteriorLightLevel > 0.0f ) {
// crude way to light the cabin, until we have something more complete in place
auto const cablight = Dynamic->InteriorLight * Dynamic->InteriorLightLevel;
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
}
Render( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
if( Dynamic->InteriorLightLevel > 0.0f ) {
// reset the overall ambient
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
}
}
}
Render( Dynamic->mdModel, Dynamic->Material(), squaredistance );
if( Dynamic->mdLoad ) // renderowanie nieprzezroczystego ładunku
Render( Dynamic->mdLoad, Dynamic->Material(), squaredistance );
}
if( Dynamic->fShade > 0.0f ) {
// restore regular light level
Global::daylight.intensity = 1.0f;
}
::glPopMatrix();
// TODO: check if this reset is needed. In theory each object should render all parts based on its own instance data anyway?
if( Dynamic->btnOn )
Dynamic->TurnOff(); // przywrócenie domyślnych pozycji submodeli
return true;
}
bool
opengl_renderer::Render( TModel3d *Model, material_data const *Material, double const Squaredistance ) {
auto alpha =
( Material != nullptr ?
Material->textures_alpha :
0x30300030 );
alpha ^= 0x0F0F000F; // odwrócenie flag tekstur, aby wyłapać nieprzezroczyste
if( 0 == ( alpha & Model->iFlags & 0x1F1F001F ) ) {
// czy w ogóle jest co robić w tym cyklu?
return false;
}
Model->Root->fSquareDist = Squaredistance; // zmienna globalna!
Model->Root->ReplacableSet(
( Material != nullptr ?
Material->replacable_skins :
nullptr ),
alpha );
Model->Root->RenderDL();
return true;
}
bool
opengl_renderer::Render( TModel3d *Model, material_data const *Material, Math3D::vector3 const &Position, Math3D::vector3 const &Angle ) {
::glPushMatrix();
::glTranslated( Position.x, Position.y, Position.z );
if( Angle.y != 0.0 )
::glRotated( Angle.y, 0.0, 1.0, 0.0 );
if( Angle.x != 0.0 )
::glRotated( Angle.x, 1.0, 0.0, 0.0 );
if( Angle.z != 0.0 )
::glRotated( Angle.z, 0.0, 0.0, 1.0 );
auto const result = Render( Model, Material, SquareMagnitude( Position - Global::GetCameraPosition() ) );
::glPopMatrix();
return result;
}
bool
opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
if( false == Dynamic->renderme ) {
return false;
}
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
double squaredistance = SquareMagnitude( Global::pCameraPosition - Dynamic->vPosition );
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
::glPushMatrix();
if( Dynamic == Global::pUserDynamic ) { // specjalne ustawienie, aby nie trzęsło
::glLoadIdentity(); // zacząć od macierzy jedynkowej
Global::pCamera->SetCabMatrix( Dynamic->vPosition ); // specjalne ustawienie kamery
}
else
::glTranslated( Dynamic->vPosition.x, Dynamic->vPosition.y, Dynamic->vPosition.z ); // standardowe przesunięcie względem początku scenerii
::glMultMatrixd( Dynamic->mMatrix.getArray() );
// wersja Display Lists
// NOTE: VBO path is removed
// TODO: implement universal render path down the road
if( Dynamic->mdLowPolyInt ) {
// low poly interior
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
// enable cab light if needed
if( Dynamic->InteriorLightLevel > 0.0f ) {
// crude way to light the cabin, until we have something more complete in place
auto const cablight = Dynamic->InteriorLight * Dynamic->InteriorLightLevel;
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
}
Render_Alpha( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
if( Dynamic->InteriorLightLevel > 0.0f ) {
// reset the overall ambient
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
}
}
}
Render_Alpha( Dynamic->mdModel, Dynamic->Material(), squaredistance );
if( Dynamic->mdLoad ) // renderowanie nieprzezroczystego ładunku
Render_Alpha( Dynamic->mdLoad, Dynamic->Material(), squaredistance );
::glPopMatrix();
if( Dynamic->btnOn )
Dynamic->TurnOff(); // przywrócenie domyślnych pozycji submodeli
return true;
}
bool
opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, double const Squaredistance ) {
auto alpha =
( Material != nullptr ?
Material->textures_alpha :
0x30300030 );
if( 0 == ( alpha & Model->iFlags & 0x2F2F002F ) ) {
// nothing to render
return false;
}
Model->Root->fSquareDist = Squaredistance; // zmienna globalna!
Model->Root->ReplacableSet(
( Material != nullptr ?
Material->replacable_skins :
nullptr ),
alpha );
Model->Root->RenderAlphaDL();
return true;
}
bool
opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, Math3D::vector3 const &Position, Math3D::vector3 const &Angle ) {
::glPushMatrix();
::glTranslated( Position.x, Position.y, Position.z );
if( Angle.y != 0.0 )
::glRotated( Angle.y, 0.0, 1.0, 0.0 );
if( Angle.x != 0.0 )
::glRotated( Angle.x, 1.0, 0.0, 0.0 );
if( Angle.z != 0.0 )
::glRotated( Angle.z, 0.0, 0.0, 1.0 );
auto const result = Render_Alpha( Model, Material, SquareMagnitude( Position - Global::GetCameraPosition() ) );
::glPopMatrix();
return result;
}
#endif
void
opengl_renderer::Update ( double const Deltatime ) {
m_updateaccumulator += Deltatime;
if( m_updateaccumulator < 1.0 ) {
// too early for any work
return;
}
m_updateaccumulator = 0.0;
// adjust draw ranges etc, based on recent performance
auto const framerate = 1000.0f / (m_drawtime / 20.0f);
// NOTE: until we have quadtree in place we have to rely on the legacy rendering
// once this is resolved we should be able to simply adjust draw range
int targetsegments;
float targetfactor;
if( framerate > 65.0 ) { targetsegments = 400; targetfactor = 3.0f; }
else if( framerate > 40.0 ) { targetsegments = 225; targetfactor = 1.5f; }
else if( framerate > 15.0 ) { targetsegments = 90; targetfactor = Global::ScreenHeight / 768.0f; }
else { targetsegments = 9; targetfactor = Global::ScreenHeight / 768.0f * 0.75f; }
if( targetsegments > Global::iSegmentsRendered ) {
Global::iSegmentsRendered = std::min( targetsegments, Global::iSegmentsRendered + 5 );
}
else if( targetsegments < Global::iSegmentsRendered ) {
Global::iSegmentsRendered = std::max( targetsegments, Global::iSegmentsRendered - 5 );
}
if( targetfactor > Global::fDistanceFactor ) {
Global::fDistanceFactor = std::min( targetfactor, Global::fDistanceFactor + 0.05f );
}
else if( targetfactor < Global::fDistanceFactor ) {
Global::fDistanceFactor = std::max( targetfactor, Global::fDistanceFactor - 0.05f );
}
if( ( framerate < 15.0 ) && ( Global::iSlowMotion < 7 ) ) {
Global::iSlowMotion = ( Global::iSlowMotion << 1 ) + 1; // zapalenie kolejnego bitu
if( Global::iSlowMotionMask & 1 )
if( Global::iMultisampling ) // a multisampling jest włączony
::glDisable( GL_MULTISAMPLE ); // wyłączenie multisamplingu powinno poprawić FPS
}
else if( ( framerate > 20.0 ) && Global::iSlowMotion ) { // FPS się zwiększył, można włączyć bajery
Global::iSlowMotion = ( Global::iSlowMotion >> 1 ); // zgaszenie bitu
if( Global::iSlowMotion == 0 ) // jeśli jest pełna prędkość
if( Global::iMultisampling ) // a multisampling jest włączony
::glEnable( GL_MULTISAMPLE );
}
// TODO: add garbage collection and other less frequent works here
if( DebugModeFlag )
m_debuginfo = m_textures.Info();
};
// debug performance string
std::string const &
opengl_renderer::Info() const {
return m_debuginfo;
}
void
@@ -66,4 +549,35 @@ opengl_renderer::Disable_Lights() {
World.shader.set_light_count(0);
}
bool
opengl_renderer::Init_caps() {
std::string oglversion = ( (char *)glGetString( GL_VERSION ) );
WriteLog(
"Gfx Renderer: " + std::string( (char *)glGetString( GL_RENDERER ) )
+ " Vendor: " + std::string( (char *)glGetString( GL_VENDOR ) )
+ " OpenGL Version: " + oglversion );
if( !GLEW_VERSION_1_4 ) {
ErrorLog( "Requires openGL >= 1.4" );
return false;
}
WriteLog( "Supported extensions:" + std::string((char *)glGetString( GL_EXTENSIONS )) );
if( Global::iMultisampling )
WriteLog( "Using multisampling x" + std::to_string( 1 << Global::iMultisampling ) );
{ // ograniczenie maksymalnego rozmiaru tekstur - parametr dla skalowania tekstur
GLint i;
glGetIntegerv( GL_MAX_TEXTURE_SIZE, &i );
if( i < Global::iMaxTextureSize )
Global::iMaxTextureSize = i;
WriteLog( "Texture sizes capped at " + std::to_string( Global::iMaxTextureSize ) + " pixels" );
}
return true;
}
//---------------------------------------------------------------------------

View File

@@ -1,4 +1,4 @@
/*
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
@@ -9,10 +9,13 @@ http://mozilla.org/MPL/2.0/.
#pragma once
#include "GL/glew.h"
#include <GL/glew.h>
#include "texture.h"
#include "lightarray.h"
#include "dumb3d.h"
#include "frustum.h"
#include "ground.h"
#include "shader.h"
// encapsulates basic rendering setup.
// for modern opengl this translates to a specific collection of glsl shaders,
@@ -28,6 +31,24 @@ struct opengl_material {
};
// simple camera object. paired with 'virtual camera' in the scene
class opengl_camera {
public:
// methods:
inline
void
update_frustum(glm::mat4 &Projection, glm::mat4 &Modelview) { m_frustum.calculate(Projection, Modelview); }
bool
visible( bounding_area const &Area ) const;
bool
visible( TDynamicObject const *Dynamic ) const;
private:
// members:
cFrustum m_frustum;
};
// bare-bones render controller, in lack of anything better yet
class opengl_renderer {
@@ -35,14 +56,40 @@ public:
// types
// methods
bool
Init( GLFWwindow *Window );
// main draw call. returns false on error
bool
Render();
#ifndef EU07_USE_OLD_RENDERCODE
bool
Render( TGround *Ground );
bool
Render( TDynamicObject *Dynamic );
bool
Render( TModel3d *Model, material_data const *Material, double const Squaredistance );
bool
Render( TModel3d *Model, material_data const *Material, Math3D::vector3 const &Position, Math3D::vector3 const &Angle );
bool
Render_Alpha( TDynamicObject *Dynamic );
bool
Render_Alpha( TModel3d *Model, material_data const *Material, double const Squaredistance );
bool
Render_Alpha( TModel3d *Model, material_data const *Material, Math3D::vector3 const &Position, Math3D::vector3 const &Angle );
#endif
// maintenance jobs
void
Init();
Update( double const Deltatime);
void
Update_Lights( light_array const &Lights );
void
Disable_Lights();
inline
bool
Visible( TDynamicObject const *Dynamic ) const { return m_camera.visible( Dynamic ); }
// debug performance string
std::string const &
Info() const;
texture_manager::size_type
GetTextureId( std::string Filename, std::string const &Dir, int const Filter = -1, bool const Loadnow = true ) {
@@ -70,10 +117,19 @@ private:
enum class rendermode {
color
};
// methods
bool Init_caps();
// members
rendermode renderpass{ rendermode::color };
texture_manager m_textures;
opengl_camera m_camera;
float m_drawrange{ 2500.0f }; // current drawing range
float m_drawtime{ 1000.0f / 30.0f * 20.0f }; // start with presumed 'neutral' average of 30 fps
double m_updateaccumulator{ 0.0 };
std::string m_debuginfo;
GLFWwindow *m_window{ nullptr };
};
extern opengl_renderer GfxRenderer;

View File

@@ -41,13 +41,18 @@ void TSky::Render( float3 const &Tint )
#endif
if (Global::bUseVBO)
{ // renderowanie z VBO
mdCloud->RaRender(100, 0);
mdCloud->RaRender( 100, 0 );
mdCloud->RaRenderAlpha(100, 0);
}
else
{ // renderowanie z Display List
#ifdef EU07_USE_OLD_RENDERCODE
mdCloud->Render(100, 0);
mdCloud->RenderAlpha(100, 0);
#else
GfxRenderer.Render( mdCloud, nullptr, 100.0 );
GfxRenderer.Render_Alpha( mdCloud, nullptr, 100.0 );
#endif
}
#ifdef EU07_USE_OLD_LIGHTING_MODEL
glPopMatrix();

View File

@@ -21,7 +21,11 @@ cStars::render() {
::glRotatef( -std::fmod( Global::fTimeAngleDeg, 360.0f ), 0.0f, 1.0f, 0.0f ); // obrót dobowy osi OX
::glPointSize( 2.0f );
#ifdef EU07_USE_OLD_RENDERCODE
m_stars.Render( 1.0 );
#else
GfxRenderer.Render( &m_stars, nullptr, 1.0 );
#endif
::glPointSize( 3.0f );
::glPopMatrix();

View File

@@ -60,14 +60,24 @@
#include <condition_variable>
#include <typeinfo>
#ifdef EU07_BUILD_STATIC
#define GLEW_STATIC
#else
#ifdef _WINDOWS
#define GLFW_DLL
#endif // _windows
#endif // build_static
#include "GL/glew.h"
#ifdef _WINDOWS
#include "GL/wglew.h"
#define GLFW_DLL
#endif
#define GLFW_INCLUDE_GLU
//m7todo: jest tu bo nie chcia³o mi siê wpychaæ do wszystkich plików
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/type_ptr.hpp>
#define STRINGIZE_DETAIL(x) #x
#define STRINGIZE(x) STRINGIZE_DETAIL(x)
#define glDebug(x) if (GLEW_GREMEDY_string_marker) glStringMarkerGREMEDY(0, __FILE__ ":" STRINGIZE(__LINE__) ": " x);

13
sun.cpp
View File

@@ -3,6 +3,7 @@
#include "sun.h"
#include "globals.h"
#include "mtable.h"
#include "usefull.h"
//////////////////////////////////////////////////////////////////////////////////////////
// cSun -- class responsible for dynamic calculation of position and intensity of the Sun,
@@ -94,6 +95,14 @@ void cSun::setLocation( float const Longitude, float const Latitude ) {
m_observer.latitude = (int)Latitude + (Latitude - (int)(Latitude)) * 100.0 / 60.0 ;
}
// sets current time, overriding one acquired from the system clock
void cSun::setTime( int const Hour, int const Minute, int const Second ) {
m_observer.hour = clamp( Hour, -1, 23 );
m_observer.minute = clamp( Minute, 0, 59 );
m_observer.second = clamp( Second, 0, 59 );
}
void cSun::setTemperature( float const Temperature ) {
m_observer.temp = Temperature;
@@ -112,6 +121,10 @@ void cSun::move() {
SYSTEMTIME localtime; // time for the calculation
time( &localtime );
if( m_observer.hour >= 0 ) { localtime.wHour = m_observer.hour; }
if( m_observer.minute >= 0 ) { localtime.wMinute = m_observer.minute; }
if( m_observer.second >= 0 ) { localtime.wSecond = m_observer.second; }
double ut = localtime.wHour
+ localtime.wMinute / 60.0 // too low resolution, noticeable skips
+ localtime.wSecond / 3600.0; // good enough in normal circumstances

7
sun.h
View File

@@ -27,6 +27,8 @@ public:
float getAngle();
// returns current intensity of the sun
float getIntensity();
// sets current time, overriding one acquired from the system clock
void setTime( int const Hour, int const Minute, int const Second );
// sets current geographic location
void setLocation( float const Longitude, float const Latitude );
// sets ambient temperature in degrees C.
@@ -87,7 +89,10 @@ protected:
double latitude; // latitude, degrees north (south negative)
double longitude; // longitude, degrees east (west negative)
double utime; // universal (Greenwich) standard time
int hour{ -1 }; // current time, used for calculation of utime. if set to -1, time for
int minute{ -1 };// calculation will be obtained from the local clock
int second{ -1 };
double utime; // universal (Greenwich) standard time
double timezone; // time zone, east (west negative). USA: Mountain = -7, Central = -6, etc.
double gmst; // Greenwich mean sidereal time, hours
double lmst; // local mean sidereal time, degrees

232
uilayer.cpp Normal file
View File

@@ -0,0 +1,232 @@
#include "stdafx.h"
#include "uilayer.h"
#include "globals.h"
#include "usefull.h"
#include "renderer.h"
#include "logs.h"
#include <GL/glut.h>
ui_layer UILayer;
extern "C"
{
GLFWAPI HWND glfwGetWin32Window( GLFWwindow* window ); //m7todo: potrzebne do directsound
}
ui_layer::~ui_layer() {
/*
// this should be invoked manually, or we risk trying to delete the lists after the context is gone
if( m_fontbase != -1 )
::glDeleteLists( m_fontbase, 96 );
*/
}
bool
ui_layer::init( GLFWwindow *Window ) {
if (Global::bGlutFont)
{
int zi = 0;
char zc = 0;
char *zcp = &zc;
glutInit(&zi, &zcp);
WriteLog("Used font from GLUT.");
Global::DLFont = true;
return true;
}
HFONT font; // Windows Font ID
m_fontbase = ::glGenLists(96); // storage for 96 characters
HDC hDC = ::GetDC( glfwGetWin32Window( Window ) );
font = ::CreateFont( -MulDiv( 10, ::GetDeviceCaps( hDC, LOGPIXELSY ), 72 ), // height of font
0, // width of font
0, // angle of escapement
0, // orientation angle
FW_MEDIUM, // font weight
FALSE, // italic
FALSE, // underline
FALSE, // strikeout
DEFAULT_CHARSET, // character set identifier
OUT_DEFAULT_PRECIS, // output precision
CLIP_DEFAULT_PRECIS, // clipping precision
CLEARTYPE_QUALITY, // output quality
DEFAULT_PITCH | FF_DONTCARE, // family and pitch
"Lucida Console"); // font name
::SelectObject(hDC, font); // selects the font we want
if (wglUseFontBitmaps( hDC, 32, 96, m_fontbase )) {
// builds 96 characters starting at character 32
WriteLog( "Display Lists font used" ); //+AnsiString(glGetError())
WriteLog( "Font init OK" ); //+AnsiString(glGetError())
Global::DLFont = true;
return true;
}
else {
ErrorLog( "Font init failed" );
// return false;
// NOTE: we report success anyway, given some cards can't produce fonts in this manner
Global::DLFont = false;
return true;
}
}
void
ui_layer::render() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho( 0.f, Global::ScreenWidth, Global::ScreenHeight, 0.f, -1.f, 1.f );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT );
glDisable( GL_LIGHTING );
glDisable( GL_DEPTH_TEST );
glDisable( GL_ALPHA_TEST );
glEnable( GL_BLEND );
// render code here
render_background();
render_progress();
render_panels();
glPopAttrib();
}
void
ui_layer::set_progress( float const Progress, float const Subtaskprogress ) {
m_progress = Progress * 0.01f;
m_subtaskprogress = Subtaskprogress * 0.01f;
}
void
ui_layer::set_background( std::string const &Filename ) {
if( false == Filename.empty() ) {
m_background = GfxRenderer.GetTextureId( Filename, szTexturePath );
}
else {
m_background = 0;
}
}
/*
void cGuiLayer::setNote( const std::string Note ) { mNote = Note; }
std::string cGuiLayer::getNote() { return mNote; }
*/
void
ui_layer::render_progress() {
if( (m_progress == 0.0f) && (m_subtaskprogress == 0.0f) ) return;
glPushAttrib( GL_ENABLE_BIT );
glDisable( GL_TEXTURE_2D );
quad( float4( 75.0f, 640.0f, 75.0f + 320.0f, 640.0f + 16.0f ), float4(0.0f, 0.0f, 0.0f, 0.25f) );
// secondary bar
if( m_subtaskprogress ) {
quad(
float4( 75.0f, 640.0f, 75.0f + 320.0f * m_subtaskprogress, 640.0f + 16.0f),
float4( 8.0f/255.0f, 160.0f/255.0f, 8.0f/255.0f, 0.35f ) );
}
// primary bar
if( m_progress ) {
quad(
float4( 75.0f, 640.0f, 75.0f + 320.0f * m_progress, 640.0f + 16.0f ),
float4( 8.0f / 255.0f, 160.0f / 255.0f, 8.0f / 255.0f, 1.0f ) );
}
glPopAttrib();
}
void
ui_layer::render_panels() {
if( m_panels.empty() ) { return; }
glPushAttrib( GL_ENABLE_BIT );
glDisable( GL_TEXTURE_2D );
float const width = std::min( 4.0f / 3.0f, static_cast<float>(Global::iWindowWidth) / Global::iWindowHeight ) * Global::iWindowHeight;
float const height = Global::iWindowHeight / 768.0;
for( auto const &panel : m_panels ) {
int lineidx = 0;
for( auto const &line : panel->text_lines ) {
::glColor4fv( &line.color.x );
::glRasterPos2f(
0.5 * ( Global::iWindowWidth - width ) + panel->origin_x * height,
panel->origin_y * height + 20.0 * lineidx );
print( line.data );
++lineidx;
}
}
glPopAttrib();
}
void
ui_layer::render_background() {
if( m_background == 0 ) return;
// NOTE: we limit/expect the background to come with 4:3 ratio.
// TODO, TBD: if we expose texture width or ratio from texture object, this limitation could be lifted
GfxRenderer.Bind( m_background );
quad( float4( 0.0f, 0.0f, 1024.0f, 768.0f ), float4( 1.0f, 1.0f, 1.0f, 1.0f ) );
}
void
ui_layer::print( std::string const &Text )
{
if( (false == Global::DLFont)
|| (true == Text.empty()) )
return;
if (Global::bGlutFont)
{
for (size_t i = 0; i < Text.size(); i++)
glutBitmapCharacter(GLUT_BITMAP_8_BY_13, Text[i]);
}
else
{
::glPushAttrib(GL_LIST_BIT);
::glListBase(m_fontbase - 32);
::glCallLists((GLsizei)Text.size(), GL_UNSIGNED_BYTE, Text.c_str());
::glPopAttrib();
}
}
void
ui_layer::quad( float4 const &Coordinates, float4 const &Color ) {
float const screenratio = static_cast<float>( Global::iWindowWidth ) / Global::iWindowHeight;
float const width =
( screenratio >= (4.0f/3.0f) ?
( 4.0f / 3.0f ) * Global::iWindowHeight :
Global::iWindowWidth );
float const heightratio =
( screenratio >= ( 4.0f / 3.0f ) ?
Global::iWindowHeight / 768.0 :
Global::iWindowHeight / 768.0 * screenratio / ( 4.0f / 3.0f ) );
float const height = 768.0f * heightratio;
glColor4fv(&Color.x);
glBegin( GL_TRIANGLE_STRIP );
glTexCoord2f( 0.0f, 1.0f ); glVertex2f( 0.5 * ( Global::iWindowWidth - width ) + Coordinates.x * heightratio, 0.5 * ( Global::iWindowHeight - height ) + Coordinates.y * heightratio );
glTexCoord2f( 0.0f, 0.0f ); glVertex2f( 0.5 * ( Global::iWindowWidth - width ) + Coordinates.x * heightratio, 0.5 * ( Global::iWindowHeight - height ) + Coordinates.w * heightratio );
glTexCoord2f( 1.0f, 1.0f ); glVertex2f( 0.5 * ( Global::iWindowWidth - width ) + Coordinates.z * heightratio, 0.5 * ( Global::iWindowHeight - height ) + Coordinates.y * heightratio );
glTexCoord2f( 1.0f, 0.0f ); glVertex2f( 0.5 * ( Global::iWindowWidth - width ) + Coordinates.z * heightratio, 0.5 * ( Global::iWindowHeight - height ) + Coordinates.w * heightratio );
glEnd();
}

86
uilayer.h Normal file
View File

@@ -0,0 +1,86 @@
#pragma once
#include <string>
#include "texture.h"
#include "float3d.h"
// GuiLayer -- basic user interface class. draws requested information on top of openGL screen
struct ui_panel {
struct text_line {
float4 color;
std::string data;
text_line( std::string const &Data, float4 const &Color):
data(Data), color(Color)
{}
};
ui_panel( const int X, const int Y):
origin_x(X), origin_y(Y)
{}
std::vector<text_line> text_lines;
float origin_x;
float origin_y;
};
class ui_layer {
public:
// parameters:
// constructors:
// destructor:
~ui_layer();
// methods:
bool
init( GLFWwindow *Window );
// draws requested UI elements
void
render();
// stores operation progress
void
set_progress( float const Progress = 0.0f, float const Subtaskprogress = 0.0f );
// sets the ui background texture, if any
void
set_background( std::string const &Filename = "" );
void
clear_texts() { m_panels.clear(); }
void
push_back( std::shared_ptr<ui_panel> Panel ) { m_panels.emplace_back( Panel ); }
// members:
private:
// methods:
// draws background quad with specified earlier texture
void
render_background();
// draws a progress bar in defined earlier state
void
render_progress();
void
render_panels();
// prints specified text, using display lists font
void
print( std::string const &Text );
// draws a quad between coordinates x,y and z,w with uv-coordinates spanning 0-1
void
quad( float4 const &Coordinates, float4 const &Color );
// members:
GLuint m_fontbase{ (GLuint)-1 }; // numer DL dla znaków w napisach
float m_progress{ 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
float m_subtaskprogress{ 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
texture_manager::size_type m_background; // path to texture used as the background. size depends on mAspect.
std::vector<std::shared_ptr<ui_panel> > m_panels;
};
extern ui_layer UILayer;