16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-24 00:49:18 +02:00
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) void TAdvancedSound::UpdateAF(double A, double F, bool ListenerInside, vector3 NewPosition)
{ // update, ale z amplituda i czestotliwoscia { // update, ale z amplituda i czestotliwoscia
if( State == ss_Off ) {
return;
}
if ((State == ss_Commencing) && (SoundCommencing.AM > 0)) if ((State == ss_Commencing) && (SoundCommencing.AM > 0))
{ {
SoundShut.Stop(); // hunter-311211 SoundShut.Stop(); // hunter-311211

View File

@@ -411,11 +411,13 @@ TAnimModel::TAnimModel()
pModel = NULL; pModel = NULL;
iNumLights = 0; iNumLights = 0;
fBlinkTimer = 0; fBlinkTimer = 0;
#ifdef EU07_USE_OLD_RENDERCODE
ReplacableSkinId[ 0 ] = 0; ReplacableSkinId[ 0 ] = 0;
ReplacableSkinId[ 1 ] = 0; ReplacableSkinId[ 1 ] = 0;
ReplacableSkinId[ 2 ] = 0; ReplacableSkinId[ 2 ] = 0;
ReplacableSkinId[ 3 ] = 0; ReplacableSkinId[ 3 ] = 0;
ReplacableSkinId[ 4 ] = 0; ReplacableSkinId[ 4 ] = 0;
#endif
for (int i = 0; i < iMaxNumLights; i++) for (int i = 0; i < iMaxNumLights; i++)
{ {
LightsOn[i] = LightsOff[i] = NULL; // normalnie nie ma LightsOn[i] = LightsOff[i] = NULL; // normalnie nie ma
@@ -441,7 +443,7 @@ bool TAnimModel::Init(TModel3d *pNewModel)
pModel = pNewModel; pModel = pNewModel;
return (pModel != NULL); return (pModel != NULL);
} }
#ifdef EU07_USE_OLD_RENDERCODE
bool TAnimModel::Init(std::string const &asName, std::string const &asReplacableTexture) bool TAnimModel::Init(std::string const &asName, std::string const &asReplacableTexture)
{ {
if (asReplacableTexture.substr(0, 1) == if (asReplacableTexture.substr(0, 1) ==
@@ -462,6 +464,28 @@ bool TAnimModel::Init(std::string const &asName, std::string const &asReplacable
// przezroczystych // przezroczystych
return (Init(TModelsManager::GetModel(asName))); 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) bool TAnimModel::Load(cParser *parser, bool ter)
{ // rozpoznanie wpisu modelu i ustawienie świateł { // rozpoznanie wpisu modelu i ustawienie świateł
@@ -629,6 +653,7 @@ void TAnimModel::RenderAlphaDL(vector3 pPosition, double fAngle)
pModel->RenderAlpha(pPosition, fAngle, ReplacableSkinId, iTexAlpha); pModel->RenderAlpha(pPosition, fAngle, ReplacableSkinId, iTexAlpha);
}; };
*/ */
#ifdef EU07_USE_OLD_RENDERCODE
int TAnimModel::Flags() int TAnimModel::Flags()
{ // informacja dla TGround, czy ma być w Render, RenderAlpha, czy RenderMixed { // informacja dla TGround, czy ma być w Render, RenderAlpha, czy RenderMixed
int i = pModel ? pModel->Flags() : 0; // pobranie flag całego modelu 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); // i|=(i&0x08080008)*((iTexAlpha&1)?0x04:0x02);
return i; 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 // 2011-03-16 cztery nowe funkcje renderowania z możliwością pochylania obiektów
@@ -652,28 +692,38 @@ void TAnimModel::RenderDL(vector3 *vPosition)
RaAnimate(); // jednorazowe przeliczenie animacji RaAnimate(); // jednorazowe przeliczenie animacji
RaPrepare(); RaPrepare();
if( pModel ) // renderowanie rekurencyjne submodeli if( pModel ) // renderowanie rekurencyjne submodeli
#ifdef EU07_USE_OLD_RENDERCODE
pModel->Render(vPosition, &vAngle, ReplacableSkinId, iTexAlpha); pModel->Render(vPosition, &vAngle, ReplacableSkinId, iTexAlpha);
#else
GfxRenderer.Render( pModel, Material(), *vPosition, vAngle );
#endif
}; };
void TAnimModel::RenderAlphaDL(vector3 *vPosition) void TAnimModel::RenderAlphaDL(vector3 *vPosition)
{ {
RaPrepare(); RaPrepare();
if (pModel) // renderowanie rekurencyjne submodeli if (pModel) // renderowanie rekurencyjne submodeli
#ifdef EU07_USE_OLD_RENDERCODE
pModel->RenderAlpha(vPosition, &vAngle, ReplacableSkinId, iTexAlpha); pModel->RenderAlpha(vPosition, &vAngle, ReplacableSkinId, iTexAlpha);
#else
GfxRenderer.Render_Alpha( pModel, Material(), *vPosition, vAngle );
#endif
}; };
void TAnimModel::RenderVBO(vector3 *vPosition) void TAnimModel::RenderVBO(vector3 *vPosition)
{ {
RaAnimate(); // jednorazowe przeliczenie animacji RaAnimate(); // jednorazowe przeliczenie animacji
RaPrepare(); RaPrepare();
if (pModel) // renderowanie rekurencyjne submodeli 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) void TAnimModel::RenderAlphaVBO(vector3 *vPosition)
{ {
RaPrepare(); RaPrepare();
if (pModel) // renderowanie rekurencyjne submodeli if (pModel) // renderowanie rekurencyjne submodeli
pModel->RaRenderAlpha(vPosition, &vAngle, ReplacableSkinId, iTexAlpha); pModel->RaRenderAlpha(vPosition, &vAngle, Material()->replacable_skins, Material()->textures_alpha);
}; };
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool TAnimModel::TerrainLoaded() bool TAnimModel::TerrainLoaded()
{ // zliczanie kwadratów kilometrowych (główna linia po Next) do tworznia tablicy { // 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 "Model3d.h"
#include "Texture.h" #include "Texture.h"
#include "DynObj.h"
const int iMaxNumLights = 8; const int iMaxNumLights = 8;
@@ -138,7 +139,12 @@ class TAnimModel
TSubModel *LightsOn[iMaxNumLights]; // Ra: te wskaźniki powinny być w ramach TModel3d TSubModel *LightsOn[iMaxNumLights]; // Ra: te wskaźniki powinny być w ramach TModel3d
TSubModel *LightsOff[iMaxNumLights]; TSubModel *LightsOff[iMaxNumLights];
vector3 vAngle; // bazowe obroty egzemplarza względem osi 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 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 std::string asText; // tekst dla wyświetlacza znakowego
TAnimAdvanced *pAdvanced; TAnimAdvanced *pAdvanced;
void Advanced(); void Advanced();
@@ -149,9 +155,15 @@ class TAnimModel
void RaAnimate(); // przeliczenie animacji egzemplarza void RaAnimate(); // przeliczenie animacji egzemplarza
void RaPrepare(); // ustawienie animacji egzemplarza na wzorcu void RaPrepare(); // ustawienie animacji egzemplarza na wzorcu
public: public:
#ifdef EU07_USE_OLD_RENDERCODE
texture_manager::size_type ReplacableSkinId[5]; // McZapkie-020802: zmienialne skory texture_manager::size_type ReplacableSkinId[5]; // McZapkie-020802: zmienialne skory
static TAnimContainer *acAnimList; // lista animacji z eventem, które muszą być przeliczane #endif
// również bez wyświetlania 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();
~TAnimModel(); ~TAnimModel();
bool Init(TModel3d *pNewModel); bool Init(TModel3d *pNewModel);

View File

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

View File

@@ -111,33 +111,43 @@ vector3 TCamera::GetDirection()
return (Normalize(Vec)); return (Normalize(Vec));
} }
/*
// bool TCamera::GetMatrix(matrix4x4 &Matrix)
bool TCamera::SetMatrix() bool TCamera::SetMatrix()
{ {
glRotated(-Roll * 180.0f / M_PI, 0, 0, 1); // po wyłączeniu tego kręci się pojazd, a sceneria glRotated( -Roll * 180.0f / M_PI, 0, 0, 1 ); // po wyłączeniu tego kręci się pojazd, a sceneria nie
// nie
glRotated( -Pitch * 180.0f / M_PI, 1, 0, 0 ); 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( -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, gluLookAt(
// LookAt.x+pOffset.x,LookAt.y+pOffset.y,LookAt.z+pOffset.z,vUp.x,vUp.y,vUp.z); Pos.x, Pos.y, Pos.z,
// gluLookAt(Pos.x+pOffset.x,Pos.y+pOffset.y,Pos.z+pOffset.z, LookAt.x, LookAt.y, LookAt.z,
// LookAt.x+pOffset.x,LookAt.y+pOffset.y,LookAt.z+pOffset.z,vUp.x,vUp.y,vUp.z); vUp.x, vUp.y, vUp.z); // Ra: pOffset is zero
gluLookAt(Pos.x, Pos.y, Pos.z, LookAt.x, LookAt.y, LookAt.z, vUp.x, vUp.y, }
vUp.z); // Ra: pOffset is zero else {
// gluLookAt(Pos.x,Pos.y,Pos.z,Pos.x+Velocity.x,Pos.y+Velocity.y,Pos.z+Velocity.z,0,1,0); glTranslated( -Pos.x, -Pos.y, -Pos.z ); // nie zmienia kierunku patrzenia
// return true;
} }
if (Type == tp_Satelite) Global::SetCameraPosition(Pos); // było +pOffset
Pitch = M_PI * 0.5; return true;
}
*/
bool TCamera::SetMatrix( glm::mat4 &Matrix ) {
if (Type != tp_Follow) 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 ) );
glTranslated(-Pos.x, -Pos.y, -Pos.z); // nie zmienia kierunku patrzenia 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 Global::SetCameraPosition( Pos ); // było +pOffset
@@ -146,6 +156,7 @@ bool TCamera::SetMatrix()
void TCamera::SetCabMatrix(vector3 &p) void TCamera::SetCabMatrix(vector3 &p)
{ // ustawienie widoku z kamery bez przesunięcia robionego przez OpenGL - nie powinno tak trząść { // ustawienie widoku z kamery bez przesunięcia robionego przez OpenGL - nie powinno tak trząść
glRotated(-Roll * 180.0f / M_PI, 0, 0, 1); glRotated(-Roll * 180.0f / M_PI, 0, 0, 1);
glRotated(-Pitch * 180.0f / M_PI, 1, 0, 0); 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(-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); 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/. http://mozilla.org/MPL/2.0/.
*/ */
#ifndef CameraH #pragma once
#define CameraH
#include "dumb3d.h" #include "dumb3d.h"
#include "frustum.h"
#include "dynobj.h" #include "dynobj.h"
using namespace Math3D; using namespace Math3D;
@@ -28,7 +26,6 @@ class TCamera
{ {
private: private:
vector3 pOffset; // nie używane (zerowe) vector3 pOffset; // nie używane (zerowe)
cFrustum m_frustum;
public: // McZapkie: potrzebuje do kiwania na boki public: // McZapkie: potrzebuje do kiwania na boki
double Pitch; double Pitch;
@@ -51,17 +48,13 @@ class TCamera
void Update(); void Update();
vector3 GetDirection(); vector3 GetDirection();
// vector3 inline GetCrossPos() { return Pos+GetDirection()*CrossDist+CrossPos; }; // vector3 inline GetCrossPos() { return Pos+GetDirection()*CrossDist+CrossPos; };
/*
bool SetMatrix(); bool SetMatrix();
*/
bool SetMatrix(glm::mat4 &Matrix);
void SetCabMatrix( vector3 &p ); void SetCabMatrix( vector3 &p );
void RaLook(); void RaLook();
void Stop(); void Stop();
inline
void
SetFrustum() { m_frustum.calculate(); }
bool
IsVisible( TDynamicObject const *Dynamic ) const;
// bool GetMatrix(matrix4x4 &Matrix); // bool GetMatrix(matrix4x4 &Matrix);
vector3 PtNext, PtPrev; vector3 PtNext, PtPrev;
}; };
#endif

View File

@@ -480,21 +480,10 @@ float Console::AnalogCalibrateGet(int x)
if (iMode == 4 && PoKeys55[0]) if (iMode == 4 && PoKeys55[0])
{ {
float b = PoKeys55[0]->fAnalog[x]; 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 + b = (((((Global::fCalibrateIn[x][5] * b) + Global::fCalibrateIn[x][4]) * b +
Global::fCalibrateIn[x][3]) * Global::fCalibrateIn[x][3]) * b +
b + Global::fCalibrateIn[x][2]) * b +
Global::fCalibrateIn[x][2]) * Global::fCalibrateIn[x][1]) * b +
b +
Global::fCalibrateIn[x][1]) *
b +
Global::fCalibrateIn[x][0]; Global::fCalibrateIn[x][0];
if (x == 0) return (b + 2) / 8; if (x == 0) return (b + 2) / 8;
if (x == 1) return b/10; if (x == 1) return b/10;

View File

@@ -236,7 +236,7 @@ void TMWDComm::CheckData() // sprawdzanie wejść cyfrowych i odpowiednie sterow
1 M wyłącznik wył. szybkiego 1 M wyłącznik wył. szybkiego
2 Shift+M impuls załączający wył. szybki 2 Shift+M impuls załączający wył. szybki
3 N odblok. przekaźników nadmiarowych 3 N odblok. przekaźników nadmiarowych
i różnicowego obwodu głównego i różnicowego obwodu głównegoMMm
4 NC rezerwa 4 NC rezerwa
5 Ctrl+N odblok. przek. nadmiarowych 5 Ctrl+N odblok. przek. nadmiarowych
przetwornicy, ogrzewania pociągu i różnicowych obw. pomocniczych przetwornicy, ogrzewania pociągu i różnicowych obw. pomocniczych
@@ -278,23 +278,29 @@ void TMWDComm::CheckData() // sprawdzanie wejść cyfrowych i odpowiednie sterow
// wciskanie przycisków klawiatury // wciskanie przycisków klawiatury
/*PORT0*/ /*PORT0*/
if (maskData[0] & 0x02) if (lastStateData[0] & 0x02) KeyBoard('M', 1); // wyłączenie wyłącznika szybkiego if (maskData[0] & 0x02) if (lastStateData[0] & 0x02)
KeyBoard('M', 1); // wyłączenie wyłącznika szybkiego
else KeyBoard('M', 0); // monostabilny else KeyBoard('M', 0); // monostabilny
if (maskData[0] & 0x04) if (lastStateData[0] & 0x04) { // impuls załączający wyłącznik szybki if (maskData[0] & 0x04) if (lastStateData[0] & 0x04) // impuls załączający wyłącznik szybki
{
KeyBoard(0x10, 1); // monostabilny KeyBoard(0x10, 1); // monostabilny
KeyBoard('M', 1); KeyBoard('M', 1);
} }
else { else
{
KeyBoard('M', 0); KeyBoard('M', 0);
KeyBoard(0x10, 0); KeyBoard(0x10, 0);
} }
if (maskData[0] & 0x08) if (lastStateData[0] & 0x08) KeyBoard('N', 1); // odblok nadmiarowego silników trakcyjnych if (maskData[0] & 0x08) if (lastStateData[0] & 0x08)
KeyBoard('N', 1); // odblok nadmiarowego silników trakcyjnych
else KeyBoard('N', 0); // monostabilny else KeyBoard('N', 0); // monostabilny
if (maskData[0] & 0x20) if (lastStateData[0] & 0x20) { // odblok nadmiarowego przetwornicy, ogrzewania poc. if (maskData[0] & 0x20) if (lastStateData[0] & 0x20)
{ // odblok nadmiarowego przetwornicy, ogrzewania poc.
KeyBoard(0x11, 1); // różnicowego obwodów pomocniczych KeyBoard(0x11, 1); // różnicowego obwodów pomocniczych
KeyBoard('N', 1); // monostabilny KeyBoard('N', 1); // monostabilny
} }
else { else
{
KeyBoard('N', 0); KeyBoard('N', 0);
KeyBoard(0x11, 0); KeyBoard(0x11, 0);
} }
@@ -306,8 +312,10 @@ void TMWDComm::CheckData() // sprawdzanie wejść cyfrowych i odpowiednie sterow
/*PORT1*/ /*PORT1*/
// puszczanie przycisku bistabilnego klawiatury // puszczanie przycisku bistabilnego klawiatury
if (maskSwitch[1] & 0x02) { if (maskSwitch[1] & 0x02)
if (bitSwitch[1] & 0x02) { {
if (bitSwitch[1] & 0x02)
{
KeyBoard('X', 0); KeyBoard('X', 0);
KeyBoard(0x10, 0); KeyBoard(0x10, 0);
} }
@@ -345,61 +353,78 @@ void TMWDComm::CheckData() // sprawdzanie wejść cyfrowych i odpowiednie sterow
maskSwitch[1] &= ~0x80; maskSwitch[1] &= ~0x80;
} }
// przetwornica
if (maskData[1] & 0x02) if (lastStateData[1] & 0x02) { // przetwornica if (maskData[1] & 0x02) if (lastStateData[1] & 0x02)
{
KeyBoard(0x10, 1); // bistabilny KeyBoard(0x10, 1); // bistabilny
KeyBoard('X', 1); KeyBoard('X', 1);
maskSwitch[1] |= 0x02; maskSwitch[1] |= 0x02;
bitSwitch[1] |= 0x02; bitSwitch[1] |= 0x02;
} }
else { else
{
maskSwitch[1] |= 0x02; maskSwitch[1] |= 0x02;
bitSwitch[1] &= ~0x02; bitSwitch[1] &= ~0x02;
KeyBoard('X', 1); 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(0x10, 1); // bistabilny
KeyBoard('C', 1); KeyBoard('C', 1);
maskSwitch[1] |= 0x04; maskSwitch[1] |= 0x04;
bitSwitch[1] |= 0x04; bitSwitch[1] |= 0x04;
} }
else { else
{
maskSwitch[1] |= 0x04; maskSwitch[1] |= 0x04;
bitSwitch[1] &= ~0x04; bitSwitch[1] &= ~0x04;
KeyBoard('C', 1); KeyBoard('C', 1);
} }
if (maskData[1] & 0x08) if (lastStateData[1] & 0x08) KeyBoard('S', 1); // piasecznica // piasecznica
else KeyBoard('S', 0); // monostabilny if (maskData[1] & 0x08) if (lastStateData[1] & 0x08)
if (maskData[1] & 0x10) if (lastStateData[1] & 0x10) { // ogrzewanie składu KeyBoard('S', 1);
else
KeyBoard('S', 0); // monostabilny
// ogrzewanie składu
if (maskData[1] & 0x10) if (lastStateData[1] & 0x10)
{
KeyBoard(0x11, 1); // bistabilny KeyBoard(0x11, 1); // bistabilny
KeyBoard('H', 1); KeyBoard('H', 1);
maskSwitch[1] |= 0x10; maskSwitch[1] |= 0x10;
bitSwitch[1] |= 0x10; bitSwitch[1] |= 0x10;
} }
else { else
{
maskSwitch[1] |= 0x10; maskSwitch[1] |= 0x10;
bitSwitch[1] &= ~0x10; bitSwitch[1] &= ~0x10;
KeyBoard('H', 1); KeyBoard('H', 1);
} }
if (maskData[1] & 0x20 || maskData[1] & 0x40) { // przełącznik hamowania // przełącznik hamowania
if (lastStateData[1] & 0x20) { // Shift+B if (maskData[1] & 0x20 || maskData[1] & 0x40)
{
if (lastStateData[1] & 0x20)
{ // Shift+B
KeyBoard(0x10, 1); KeyBoard(0x10, 1);
maskSwitch[1] |= 0x20; maskSwitch[1] |= 0x20;
} }
else if (lastStateData[1] & 0x40) { // Ctrl+B else if (lastStateData[1] & 0x40)
{ // Ctrl+B
KeyBoard(0x11, 1); KeyBoard(0x11, 1);
maskSwitch[1] |= 0x40; maskSwitch[1] |= 0x40;
} }
KeyBoard('B', 1); KeyBoard('B', 1);
} }
// rozruch wysoki/niski
if (maskData[1] & 0x80) if (lastStateData[1] & 0x80) { // rozruch wysoki/niski if (maskData[1] & 0x80) if (lastStateData[1] & 0x80)
{
KeyBoard(0x10, 1); // bistabilny KeyBoard(0x10, 1); // bistabilny
KeyBoard('F', 1); KeyBoard('F', 1);
maskSwitch[1] |= 0x80; maskSwitch[1] |= 0x80;
bitSwitch[1] |= 0x80; bitSwitch[1] |= 0x80;
} }
else { else
{
maskSwitch[1] |= 0x80; maskSwitch[1] |= 0x80;
bitSwitch[1] &= ~0x80; bitSwitch[1] &= ~0x80;
KeyBoard('F', 1); KeyBoard('F', 1);
@@ -407,16 +432,20 @@ void TMWDComm::CheckData() // sprawdzanie wejść cyfrowych i odpowiednie sterow
//PORT2 //PORT2
if (maskSwitch[2] & 0x01) { if (maskSwitch[2] & 0x01)
if (bitSwitch[2] & 0x01) { {
if (bitSwitch[2] & 0x01)
{
KeyBoard('P', 0); KeyBoard('P', 0);
KeyBoard(0x10, 0); KeyBoard(0x10, 0);
} }
else KeyBoard('P', 0); else KeyBoard('P', 0);
maskSwitch[2] &= ~0x01; maskSwitch[2] &= ~0x01;
} }
if (maskSwitch[2] & 0x02) { if (maskSwitch[2] & 0x02)
if (bitSwitch[2] & 0x02) { {
if (bitSwitch[2] & 0x02)
{
KeyBoard('O', 0); KeyBoard('O', 0);
KeyBoard(0x10, 0); KeyBoard(0x10, 0);
} }
@@ -424,35 +453,41 @@ void TMWDComm::CheckData() // sprawdzanie wejść cyfrowych i odpowiednie sterow
maskSwitch[2] &= ~0x02; maskSwitch[2] &= ~0x02;
} }
// pantograf przedni
if (maskData[2] & 0x01) if (lastStateData[2] & 0x01) { // pantograf przedni if (maskData[2] & 0x01) if (lastStateData[2] & 0x01)
{
KeyBoard(0x10, 1); // bistabilny KeyBoard(0x10, 1); // bistabilny
KeyBoard('P', 1); KeyBoard('P', 1);
maskSwitch[2] |= 0x01; maskSwitch[2] |= 0x01;
bitSwitch[2] |= 0x01; bitSwitch[2] |= 0x01;
} }
else { else
{
maskSwitch[2] |= 0x01; maskSwitch[2] |= 0x01;
bitSwitch[2] &= ~0x01; bitSwitch[2] &= ~0x01;
KeyBoard('P', 1); 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(0x10, 1); // bistabilny
KeyBoard('O', 1); KeyBoard('O', 1);
maskSwitch[2] |= 0x02; maskSwitch[2] |= 0x02;
bitSwitch[2] |= 0x02; bitSwitch[2] |= 0x02;
} }
else { else
{
maskSwitch[2] |= 0x02; maskSwitch[2] |= 0x02;
bitSwitch[2] &= ~0x02; bitSwitch[2] &= ~0x02;
KeyBoard('O', 1); 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(0x10, 1); // monostabilny
KeyBoard(0x0D, 1); KeyBoard(0x0D, 1);
} }
else { else
{
KeyBoard(0x0D, 0); KeyBoard(0x0D, 0);
KeyBoard(0x10, 0); KeyBoard(0x10, 0);
} }
@@ -474,178 +509,129 @@ void TMWDComm::CheckData() // sprawdzanie wejść cyfrowych i odpowiednie sterow
KeyBoard(0x11,0); KeyBoard(0x11,0);
KeyBoard(' ',1); KeyBoard(' ',1);
}*/ }*/
if (maskData[2] & 0x20) if (lastStateData[2] & 0x20) KeyBoard(0x66, 1); // odluźniacz // odluźniacz
else KeyBoard(0x66, 0); // monostabilny if (maskData[2] & 0x20) if (lastStateData[2] & 0x20)
if (maskData[2] & 0x40) if (lastStateData[2] & 0x40) { // syrena wysoka KeyBoard(0x66, 1);
else
KeyBoard(0x66, 0); // monostabilny
// syrena wysoka
if (maskData[2] & 0x40) if (lastStateData[2] & 0x40)
{
KeyBoard(0x10, 1); // monostabilny KeyBoard(0x10, 1); // monostabilny
KeyBoard('A', 1); KeyBoard('A', 1);
} }
else { else
{
KeyBoard('A', 0); KeyBoard('A', 0);
KeyBoard(0x10, 0); KeyBoard(0x10, 0);
} }
if (maskData[2] & 0x80) if (lastStateData[2] & 0x80) KeyBoard('A', 1); // syrena niska if (maskData[2] & 0x80) if (lastStateData[2] & 0x80)
else KeyBoard('A', 0); // monostabilny KeyBoard('A', 1); // syrena niska
else
KeyBoard('A', 0); // monostabilny
//PORT3 //PORT3
if (maskSwitch[3] & 0x01) { if (maskSwitch[3] & 0x01)
if (bitSwitch[3] & 0x01) { {
if (bitSwitch[3] & 0x01)
{
KeyBoard('J', 0); KeyBoard('J', 0);
KeyBoard(0x10, 0); KeyBoard(0x10, 0);
} }
else KeyBoard('J', 0); else KeyBoard('J', 0);
maskSwitch[3] &= ~0x01; 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(0x10, 1); // bistabilny
KeyBoard('J', 1); KeyBoard('J', 1);
maskSwitch[3] |= 0x01; maskSwitch[3] |= 0x01;
bitSwitch[3] |= 0x01; bitSwitch[3] |= 0x01;
} }
else { else
{
maskSwitch[3] |= 0x01; maskSwitch[3] |= 0x01;
bitSwitch[3] &= ~0x01; bitSwitch[3] &= ~0x01;
KeyBoard('J', 1); KeyBoard('J', 1);
} }
//Światło lewe
/* if (maskData[3] & 0x02) if (lastStateData[3] & 0x02)
if(maskData[3] & 0x04 && lastStateData[1] & 0x04) { KeyBoard(0x10,1); {
KeyBoard('C',1); // KeyBoard(0x10, 1); // bistabilny
KeyBoard('C',0); KeyBoard('Y', 1);
KeyBoard(0x10,0); maskSwitch[3] |= 0x02;
}else{ KeyBoard('C',1); // bitSwitch[3] |= 0x02;
KeyBoard('C',0); }else
{
maskSwitch[3] |= 0x02;
bitSwitch[3] &= ~0x02;
KeyBoard('Y', 1);
} }
if(maskData[3] & 0x08 && lastStateData[1] & 0x08) KeyBoard('S',1); // //światło górne
else KeyBoard('S',0); if (maskData[3] & 0x04) if (lastStateData[3] & 0x04)
{
KeyBoard(0x10, 1); // bistabilny
if(maskData[3] & 0x10 && lastStateData[1] & 0x10) { KeyBoard('U', 1);
KeyBoard(0x11,1); maskSwitch[3] |= 0x04;
KeyBoard('H',1); bitSwitch[3] |= 0x04;
}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 else
KeyBoard('S',0); {
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[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 */ /* NASTAWNIK, BOCZNIK i KIERUNEK */

View File

@@ -399,4 +399,5 @@ class TController
int CrossRoute(TTrack *tr); int CrossRoute(TTrack *tr);
void RouteSwitch(int d); void RouteSwitch(int d);
std::string OwnerName(); 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: ********************* // 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 { // ABu290105: pozbierane i uporzadkowane powtarzajace
// sie rzeczy z Render i RenderAlpha // sie rzeczy z Render i RenderAlpha
// dodatkowy warunek, if (ObjSqrDist<...) zeby niepotrzebnie nie zmianiec w // dodatkowy warunek, if (ObjSqrDist<...) zeby niepotrzebnie nie zmianiec w
@@ -557,8 +557,6 @@ void __inline TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
mdLoad->GetSMRoot()->SetTranslate(modelShake + vFloor); mdLoad->GetSMRoot()->SetTranslate(modelShake + vFloor);
if (mdLowPolyInt) if (mdLowPolyInt)
mdLowPolyInt->GetSMRoot()->SetTranslate(modelShake); mdLowPolyInt->GetSMRoot()->SetTranslate(modelShake);
if (mdPrzedsionek)
mdPrzedsionek->GetSMRoot()->SetTranslate(modelShake);
// ABu: koniec rzucania // ABu: koniec rzucania
// ABu011104: liczenie obrotow wozkow // ABu011104: liczenie obrotow wozkow
ABuBogies(); ABuBogies();
@@ -1694,12 +1692,14 @@ TDynamicObject::TDynamicObject()
//} //}
mdModel = NULL; mdModel = NULL;
mdKabina = NULL; mdKabina = NULL;
#ifdef EU07_USE_OLD_RENDERCODE
ReplacableSkinID[ 0 ] = 0; ReplacableSkinID[ 0 ] = 0;
ReplacableSkinID[ 1 ] = 0; ReplacableSkinID[ 1 ] = 0;
ReplacableSkinID[ 2 ] = 0; ReplacableSkinID[ 2 ] = 0;
ReplacableSkinID[ 3 ] = 0; ReplacableSkinID[ 3 ] = 0;
ReplacableSkinID[ 4 ] = 0; ReplacableSkinID[ 4 ] = 0;
iAlpha = 0x30300030; // tak gdy tekstury wymienne nie mają przezroczystości iAlpha = 0x30300030; // tak gdy tekstury wymienne nie mają przezroczystości
#endif
// smWiazary[0]=smWiazary[1]=NULL; // smWiazary[0]=smWiazary[1]=NULL;
smWahacze[0] = smWahacze[1] = smWahacze[2] = smWahacze[3] = NULL; smWahacze[0] = smWahacze[1] = smWahacze[2] = smWahacze[3] = NULL;
fWahaczeAmp = 0; fWahaczeAmp = 0;
@@ -1707,7 +1707,6 @@ TDynamicObject::TDynamicObject()
smLoadMode = NULL; smLoadMode = NULL;
mdLoad = NULL; mdLoad = NULL;
mdLowPolyInt = NULL; mdLowPolyInt = NULL;
mdPrzedsionek = NULL;
//smMechanik0 = smMechanik1 = NULL; //smMechanik0 = smMechanik1 = NULL;
smBuforLewy[0] = smBuforLewy[1] = NULL; smBuforLewy[0] = smBuforLewy[1] = NULL;
smBuforPrawy[0] = smBuforPrawy[1] = NULL; smBuforPrawy[0] = smBuforPrawy[1] = NULL;
@@ -2341,8 +2340,7 @@ void TDynamicObject::Move(double fDistance)
{ // przeliczenie cienia { // przeliczenie cienia
TTrack *t0 = Axle0.GetTrack(); // już po przesunięciu TTrack *t0 = Axle0.GetTrack(); // już po przesunięciu
TTrack *t1 = Axle1.GetTrack(); TTrack *t1 = Axle1.GetTrack();
if ((t0->eEnvironment == e_flat) && (t1->eEnvironment == e_flat)) // może być if ((t0->eEnvironment == e_flat) && (t1->eEnvironment == e_flat)) // może być e_bridge...
// e_bridge...
fShade = 0.0; // standardowe oświetlenie fShade = 0.0; // standardowe oświetlenie
else else
{ // jeżeli te tory mają niestandardowy stopień zacienienia { // jeżeli te tory mają niestandardowy stopień zacienienia
@@ -2365,6 +2363,21 @@ void TDynamicObject::Move(double fDistance)
if (Axle0.GetDirection() < 0) if (Axle0.GetDirection() < 0)
d = t0->fTrackLength - d; // od drugiej strony liczona długość d = t0->fTrackLength - d; // od drugiej strony liczona długość
d /= fAxleDist; // rozsataw osi procentowe znajdowanie się na torze 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) switch (t0->eEnvironment)
{ // typ zmiany oświetlenia - zakładam, że { // typ zmiany oświetlenia - zakładam, że
// drugi tor ma e_flat // drugi tor ma e_flat
@@ -2385,6 +2398,7 @@ void TDynamicObject::Move(double fDistance)
fShade = d + (1.0 - d) * 0.20; fShade = d + (1.0 - d) * 0.20;
break; // zacienienie w tunelu break; // zacienienie w tunelu
} }
*/
} }
} }
} }
@@ -3699,39 +3713,12 @@ void TDynamicObject::TurnOff()
btMechanik1.TurnOff(); btMechanik1.TurnOff();
btMechanik2.TurnOff(); btMechanik2.TurnOff();
}; };
#ifdef EU07_USE_OLD_RENDERCODE
void TDynamicObject::Render() void TDynamicObject::Render()
{ // rysowanie elementów nieprzezroczystych { // rysowanie elementów nieprzezroczystych
// youBy - sprawdzamy, czy jest sens renderowac // 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 (GfxRenderer.Visible(this))
if (modelrotate < maxrot)
renderme = true;
*/
if (Global::pCamera->IsVisible(this))
{ {
TSubModel::iInstance = (size_t)this; //żeby nie robić cudzych animacji TSubModel::iInstance = (size_t)this; //żeby nie robić cudzych animacji
// AnsiString asLoadName=""; // AnsiString asLoadName="";
@@ -3776,7 +3763,6 @@ void TDynamicObject::Render()
vPosition.z); // standardowe przesunięcie względem początku scenerii vPosition.z); // standardowe przesunięcie względem początku scenerii
glMultMatrixd(mMatrix.getArray()); glMultMatrixd(mMatrix.getArray());
#ifdef EU07_USE_OLD_LIGHTING_MODEL #ifdef EU07_USE_OLD_LIGHTING_MODEL
// TODO: re-implement this
if (fShade > 0.0) if (fShade > 0.0)
{ // Ra: zmiana oswietlenia w tunelu, wykopie { // Ra: zmiana oswietlenia w tunelu, wykopie
GLfloat ambientLight[4] = {0.5f, 0.5f, 0.5f, 1.0f}; 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_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight); 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 #endif
if (Global::bUseVBO) if (Global::bUseVBO)
{ // wersja VBO { // wersja VBO
@@ -3802,8 +3793,6 @@ void TDynamicObject::Render()
mdModel->RaRender(ObjSqrDist, ReplacableSkinID, iAlpha); mdModel->RaRender(ObjSqrDist, ReplacableSkinID, iAlpha);
if (mdLoad) // renderowanie nieprzezroczystego ładunku if (mdLoad) // renderowanie nieprzezroczystego ładunku
mdLoad->RaRender(ObjSqrDist, ReplacableSkinID, iAlpha); mdLoad->RaRender(ObjSqrDist, ReplacableSkinID, iAlpha);
if (mdPrzedsionek)
mdPrzedsionek->RaRender(ObjSqrDist, ReplacableSkinID, iAlpha);
} }
else else
{ // wersja Display Lists { // wersja Display Lists
@@ -3830,8 +3819,6 @@ void TDynamicObject::Render()
mdModel->Render(ObjSqrDist, ReplacableSkinID, iAlpha); mdModel->Render(ObjSqrDist, ReplacableSkinID, iAlpha);
if (mdLoad) // renderowanie nieprzezroczystego ładunku if (mdLoad) // renderowanie nieprzezroczystego ładunku
mdLoad->Render(ObjSqrDist, ReplacableSkinID, iAlpha); mdLoad->Render(ObjSqrDist, ReplacableSkinID, iAlpha);
if (mdPrzedsionek)
mdPrzedsionek->Render(ObjSqrDist, ReplacableSkinID, iAlpha);
} }
// Ra: czy ta kabina tu ma sens? // 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_DIFFUSE, Global::diffuseDayLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, Global::specularDayLight); glLightfv(GL_LIGHT0, GL_SPECULAR, Global::specularDayLight);
} }
#else
if( fShade > 0.0f ) {
// restore regular light level
Global::DayLight.apply_intensity();
}
#endif #endif
glPopMatrix(); glPopMatrix();
if (btnOn) if (btnOn)
@@ -3905,10 +3897,83 @@ void TDynamicObject::Render()
} // yB - koniec mieszania z grafika } // 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() void TDynamicObject::RenderSounds()
{ // przeliczanie dźwięków, bo będzie { // przeliczanie dźwięków, bo będzie słychać bez wyświetlania sektora z pojazdem
// słychać bez wyświetlania sektora z // if( Global::iPause > 0 ) { return; }
// pojazdem
// McZapkie-010302: ulepszony dzwiek silnika // McZapkie-010302: ulepszony dzwiek silnika
double freq; double freq;
double vol = 0; double vol = 0;
@@ -3919,11 +3984,10 @@ void TDynamicObject::RenderSounds()
if (MoverParameters->Power > 0) if (MoverParameters->Power > 0)
{ {
if ((rsSilnik.AM != 0) && ((MoverParameters->Mains) || (MoverParameters->EngineType == if ((rsSilnik.AM != 0)
DieselEngine))) // McZapkie-280503: && ((MoverParameters->Mains)
// zeby dla dumb // McZapkie-280503: zeby dla dumb dzialal silnik na jalowych obrotach
// dzialal silnik na || (MoverParameters->EngineType == DieselEngine)))
// jalowych obrotach
{ {
if ((fabs(MoverParameters->enrot) > 0.01) || if ((fabs(MoverParameters->enrot) > 0.01) ||
(MoverParameters->EngineType == Dumb)) //&& (MoverParameters->EnginePower>0.1)) (MoverParameters->EngineType == Dumb)) //&& (MoverParameters->EnginePower>0.1))
@@ -4128,9 +4192,8 @@ void TDynamicObject::RenderSounds()
sSmallCompressor.Update(MechInside, GetPosition()); sSmallCompressor.Update(MechInside, GetPosition());
// youBy - przenioslem, bo diesel tez moze miec turbo // youBy - przenioslem, bo diesel tez moze miec turbo
if ((MoverParameters->MainCtrlPos) >= if( (MoverParameters->TurboTest > 0)
(MoverParameters->TurboTest)) // hunter-250312: dlaczego zakomentowane? && (MoverParameters->MainCtrlPos >= MoverParameters->TurboTest))
// Ra: bo nie działało dobrze
{ {
// udawanie turbo: (6.66*(eng_vol-0.85)) // udawanie turbo: (6.66*(eng_vol-0.85))
if (eng_turbo > 6.66 * (enginevolume - 0.8) + 0.2 * dt) 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 // McZapkie-250202
// wczytywanie pliku z danymi multimedialnymi (dzwieki) // wczytywanie pliku z danymi multimedialnymi (dzwieki)
void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName, 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:") { if( token == "models:") {
// modele i podmodele // modele i podmodele
#ifdef EU07_USE_OLD_RENDERCODE
iMultiTex = 0; // czy jest wiele tekstur wymiennych? iMultiTex = 0; // czy jest wiele tekstur wymiennych?
parser.getTokens(); parser.getTokens();
parser >> asModel; parser >> asModel;
@@ -4388,10 +4373,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
} }
std::size_t i = asModel.find( ',' ); std::size_t i = asModel.find( ',' );
if ( i != std::string::npos ) if ( i != std::string::npos )
{ // Ra 2015-01: może szukać przecinka w { // Ra 2015-01: może szukać przecinka w nazwie modelu, a po przecinku była by liczba tekstur?
// nazwie modelu, a po przecinku była by
// liczba
// tekstur?
if (i < asModel.length()) if (i < asModel.length())
iMultiTex = asModel[i + 1] - '0'; iMultiTex = asModel[i + 1] - '0';
if (iMultiTex < 0) if (iMultiTex < 0)
@@ -4399,78 +4381,37 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
else if (iMultiTex > 1) else if (iMultiTex > 1)
iMultiTex = 1; // na razie ustawiamy na 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 asModel = BaseDir + asModel; // McZapkie 2002-07-20: dynamics maja swoje
// modele w dynamics/basedir // modele w dynamics/basedir
Global::asCurrentTexturePath = BaseDir; // biezaca sciezka do tekstur to dynamic/... Global::asCurrentTexturePath = BaseDir; // biezaca sciezka do tekstur to dynamic/...
mdModel = TModelsManager::GetModel(asModel, true); mdModel = TModelsManager::GetModel(asModel, true);
assert( mdModel != nullptr ); // TODO: handle this more gracefully than all going to shit assert( mdModel != nullptr ); // TODO: handle this more gracefully than all going to shit
if (ReplacableSkin != "none") if (ReplacableSkin != "none")
#ifdef EU07_USE_OLD_RENDERCODE
{ // tekstura wymienna jest raczej jedynie w "dynamic\" { // tekstura wymienna jest raczej jedynie w "dynamic\"
ReplacableSkin = ReplacableSkin =
Global::asCurrentTexturePath + ReplacableSkin; // skory tez z dynamic/... Global::asCurrentTexturePath + ReplacableSkin; // skory tez z dynamic/...
std::string x = TextureTest(Global::asCurrentTexturePath + "nowhere"); // na razie prymitywnie std::string x = TextureTest(Global::asCurrentTexturePath + "nowhere"); // na razie prymitywnie
if (!x.empty()) if (!x.empty())
ReplacableSkinID[4] = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + "nowhere", "", 9); 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ść
}
}
}
}
}
}
*/
if (iMultiTex > 0) if (iMultiTex > 0)
{ // jeśli model ma 4 tekstury { // jeśli model ma 4 tekstury
ReplacableSkinID[1] = GfxRenderer.GetTextureId( ReplacableSkinID[1] = GfxRenderer.GetTextureId(
@@ -4490,8 +4431,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
ReplacableSkinID[4] = GfxRenderer.GetTextureId( ReplacableSkinID[4] = GfxRenderer.GetTextureId(
ReplacableSkin + ",4", "", Global::iDynamicFiltering); ReplacableSkin + ",4", "", Global::iDynamicFiltering);
if (ReplacableSkinID[4]) if (ReplacableSkinID[4])
iMultiTex = 4; // jak są cztery, to blokujemy podmianę tekstury iMultiTex = 4; // jak są cztery, to blokujemy podmianę tekstury rozkładem
// rozkładem
} }
} }
} }
@@ -4506,37 +4446,75 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
ReplacableSkinID[1] = GfxRenderer.GetTextureId( ReplacableSkinID[1] = GfxRenderer.GetTextureId(
ReplacableSkin, "", Global::iDynamicFiltering); ReplacableSkin, "", Global::iDynamicFiltering);
if (GfxRenderer.Texture(ReplacableSkinID[1]).has_alpha) if (GfxRenderer.Texture(ReplacableSkinID[1]).has_alpha)
iAlpha = 0x31310031; // tekstura -1 z kanałem alfa - nie renderować w cyklu iAlpha = 0x31310031; // tekstura -1 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
// nieprzezroczystych
else else
iAlpha = 0x30300030; // wszystkie tekstury nieprzezroczyste - nie iAlpha = 0x30300030; // wszystkie tekstury nieprzezroczyste - nie renderować w cyklu przezroczystych
// renderować w
// cyklu przezroczystych
if (ReplacableSkinID[2]) if (ReplacableSkinID[2])
if (GfxRenderer.Texture(ReplacableSkinID[2]).has_alpha) if (GfxRenderer.Texture(ReplacableSkinID[2]).has_alpha)
iAlpha |= 0x02020002; // tekstura -2 z kanałem alfa - nie renderować iAlpha |= 0x02020002; // tekstura -2 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
// w cyklu
// nieprzezroczystych
if (ReplacableSkinID[3]) if (ReplacableSkinID[3])
if (GfxRenderer.Texture(ReplacableSkinID[3]).has_alpha) if (GfxRenderer.Texture(ReplacableSkinID[3]).has_alpha)
iAlpha |= 0x04040004; // tekstura -3 z kanałem alfa - nie renderować iAlpha |= 0x04040004; // tekstura -3 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
// w cyklu
// nieprzezroczystych
if (ReplacableSkinID[4]) if (ReplacableSkinID[4])
if (GfxRenderer.Texture(ReplacableSkinID[4]).has_alpha) if (GfxRenderer.Texture(ReplacableSkinID[4]).has_alpha)
iAlpha |= 0x08080008; // tekstura -4 z kanałem alfa - nie renderować iAlpha |= 0x08080008; // tekstura -4 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
// w cyklu
// nieprzezroczystych
} }
/* #else
// Winger 040304 - ladowanie przedsionkow dla EZT { // tekstura wymienna jest raczej jedynie w "dynamic\"
if (MoverParameters->TrainType == dt_EZT) 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 ] )
{ {
asModel = "przedsionki.t3d"; m_materialdata.multi_textures = 2; // już są dwie
asModel = BaseDir + asModel; m_materialdata.replacable_skins[ 3 ] = GfxRenderer.GetTextureId(
mdPrzedsionek = TModelsManager::GetModel(asModel, true); 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.empty())
// if (MoverParameters->LoadAccepted!=AnsiString("")); // && // if (MoverParameters->LoadAccepted!=AnsiString("")); // &&
// MoverParameters->LoadType!=AnsiString("passengers")) // MoverParameters->LoadType!=AnsiString("passengers"))
@@ -5449,8 +5427,6 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
// binarnego // binarnego
if (mdLoad) if (mdLoad)
mdLoad->Init(); mdLoad->Init();
if (mdPrzedsionek)
mdPrzedsionek->Init();
if (mdLowPolyInt) if (mdLowPolyInt)
mdLowPolyInt->Init(); mdLowPolyInt->Init();
// sHorn2.CopyIfEmpty(sHorn1); ///żeby jednak trąbił też drugim // sHorn2.CopyIfEmpty(sHorn1); ///żeby jednak trąbił też drugim
@@ -5820,6 +5796,7 @@ std::string TDynamicObject::TextureTest(std::string const &name)
return ""; // nie znaleziona return ""; // nie znaleziona
}; };
#ifdef EU07_USE_OLD_RENDERCODE
void TDynamicObject::DestinationSet(std::string to, std::string numer) void TDynamicObject::DestinationSet(std::string to, std::string numer)
{ // ustawienie stacji { // ustawienie stacji
// docelowej oraz wymiennej // 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 // Ra 2015-01: żeby zalogować błąd, trzeba by mieć pewność, że model używa
// tekstury nr 4 // 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) void TDynamicObject::OverheadTrack(float o)
{ // ewentualne wymuszanie jazdy { // ewentualne wymuszanie jazdy

View File

@@ -18,6 +18,7 @@ http://mozilla.org/MPL/2.0/.
#include "AdvSound.h" #include "AdvSound.h"
#include "Button.h" #include "Button.h"
#include "AirCoupler.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 class TDynamicObject { // klasa pojazdu
friend class opengl_renderer;
private: // położenie pojazdu w świecie oraz parametry ruchu private: // położenie pojazdu w świecie oraz parametry ruchu
vector3 vPosition; // Ra: pozycja pojazdu liczona zaraz po przesunięciu vector3 vPosition; // Ra: pozycja pojazdu liczona zaraz po przesunięciu
vector3 vCoulpler[ 2 ]; // współrzędne sprzęgów do liczenia zderzeń czołowych 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; TPowerSource ConnectedEnginePowerSource( TDynamicObject const *Caller ) const;
private:
// returns type of the nearest functional power source present in the trainset
public: // modele składowe pojazdu public: // modele składowe pojazdu
TModel3d *mdModel; // model pudła TModel3d *mdModel; // model pudła
TModel3d *mdLoad; // model zmiennego ładunku 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 *mdKabina; // model kabiny dla użytkownika; McZapkie-030303: to z train.h
TModel3d *mdLowPolyInt; // ABu 010305: wnetrze lowpoly 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? 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,7 +200,16 @@ public: // modele składowe pojazdu
float fShade; // zacienienie: 0:normalnie, -1:w ciemności, +1:dodatkowe światło (brak koloru?) 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 private: // zmienne i metody do animacji submodeli; Ra: sprzatam animacje w pojeździe
public: // tymczasowo udostępnione do wyszukiwania drutu #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 int iAnimType[ ANIM_TYPES ]; // 0-osie,1-drzwi,2-obracane,3-zderzaki,4-wózki,5-pantografy,6-tłoki
private: private:
int iAnimations; // liczba obiektów animujących int iAnimations; // liczba obiektów animujących
@@ -343,6 +367,7 @@ public: // modele składowe pojazdu
public: public:
int *iLights; // wskaźnik na bity zapalonych świateł (własne albo innego członu) 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 double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym
// pojazdem) // pojazdem)
TDynamicObject * PrevAny(); TDynamicObject * PrevAny();
@@ -396,9 +421,11 @@ public: // modele składowe pojazdu
int iCabs; // maski bitowe modeli kabin int iCabs; // maski bitowe modeli kabin
TTrack *MyTrack; // McZapkie-030303: tor na ktorym stoi, ABu TTrack *MyTrack; // McZapkie-030303: tor na ktorym stoi, ABu
std::string asBaseDir; std::string asBaseDir;
#ifdef EU07_USE_OLD_RENDERCODE
texture_manager::size_type ReplacableSkinID[5]; // McZapkie:zmienialne nadwozie texture_manager::size_type ReplacableSkinID[5]; // McZapkie:zmienialne nadwozie
int iAlpha; // maska przezroczystości tekstur int iAlpha; // maska przezroczystości tekstur
int iMultiTex; //<0 tekstury wskazane wpisem, >0 tekstury z przecinkami, =0 jedna 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 int iOverheadMask; // maska przydzielana przez AI pojazdom posiadającym pantograf, aby wymuszały
// jazdę bezprądową // jazdę bezprądową
TTractionParam tmpTraction; TTractionParam tmpTraction;
@@ -417,8 +444,10 @@ public: // modele składowe pojazdu
bool FastUpdate(double dt); bool FastUpdate(double dt);
void Move(double fDistance); void Move(double fDistance);
void FastMove(double fDistance); void FastMove(double fDistance);
#ifdef EU07_USE_OLD_RENDERCODE
void Render(); void Render();
void RenderAlpha(); void RenderAlpha();
#endif
void RenderSounds(); void RenderSounds();
inline vector3 GetPosition() const inline vector3 GetPosition() const
{ {

View File

@@ -28,6 +28,9 @@ Stele, firleju, szociu, hunter, ZiomalCl, OLI_EU and others
#include "World.h" #include "World.h"
#include "Mover.h" #include "Mover.h"
#include "usefull.h" #include "usefull.h"
#include "timer.h"
#include "resource.h"
#include "uilayer.h"
#pragma comment (lib, "glu32.lib") #pragma comment (lib, "glu32.lib")
#pragma comment (lib, "dsound.lib") #pragma comment (lib, "dsound.lib")
@@ -78,8 +81,10 @@ void make_screenshot()
void window_resize_callback(GLFWwindow *window, int w, int h) void window_resize_callback(GLFWwindow *window, int w, int h)
{ {
Global::ScreenWidth = w; // NOTE: we have two variables which basically do the same thing as we don't have dynamic fullscreen toggle
Global::ScreenHeight = h; // 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 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); glViewport(0, 0, w, h);
} }
@@ -115,21 +120,33 @@ void key_callback( GLFWwindow *window, int key, int scancode, int action, int mo
make_screenshot(); make_screenshot();
break; break;
case GLFW_KEY_ESCAPE: { case GLFW_KEY_ESCAPE: {
//[Esc] pauzuje tylko bez Debugmode /*
if( DebugModeFlag ) if( ( DebugModeFlag ) //[Esc] pauzuje tylko bez Debugmode
break; && ( Global::iPause == 0 ) ) { // but unpausing should work always
break;
}
*/
if( Global::iPause & 1 ) // jeśli pauza startowa if( Global::iPause & 1 ) // jeśli pauza startowa
Global::iPause &= ~1; // odpauzowanie, gdy po wczytaniu miało nie startować Global::iPause &= ~1; // odpauzowanie, gdy po wczytaniu miało nie startować
else if( !( Global::iMultiplayer & 2 ) ) // w multiplayerze pauza nie ma sensu else if( !( Global::iMultiplayer & 2 ) ) // w multiplayerze pauza nie ma sensu
if( !Global::ctrlState ) // z [Ctrl] to radiostop jest if( !Global::ctrlState ) // z [Ctrl] to radiostop jest
Global::iPause ^= 2; // zmiana stanu zapauzowania 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ę Global::iTextMode = GLFW_KEY_F1; // to wyświetlić zegar i informację
}
break; break;
} }
case GLFW_KEY_F7: 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; Global::bWireFrame = !Global::bWireFrame;
if( true == Global::bWireFrame ) { if( true == Global::bWireFrame ) {
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); 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 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 #ifdef _WINDOWS
extern "C" extern "C"
{ {
@@ -230,9 +255,11 @@ int main(int argc, char *argv[])
glfwWindowHint(GLFW_REFRESH_RATE, vmode->refreshRate); glfwWindowHint(GLFW_REFRESH_RATE, vmode->refreshRate);
glfwWindowHint(GLFW_AUTO_ICONIFY, GLFW_FALSE); glfwWindowHint(GLFW_AUTO_ICONIFY, GLFW_FALSE);
glfwWindowHint(GLFW_SAMPLES, 1 << Global::iMultisampling);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
if( Global::iMultisampling > 0 ) {
glfwWindowHint( GLFW_SAMPLES, 1 << Global::iMultisampling );
}
if (Global::bFullScreen) if (Global::bFullScreen)
{ {
@@ -243,7 +270,7 @@ int main(int argc, char *argv[])
GLFWwindow *window = GLFWwindow *window =
glfwCreateWindow( Global::iWindowWidth, Global::iWindowHeight, glfwCreateWindow( Global::iWindowWidth, Global::iWindowHeight,
"EU07++NG", Global::bFullScreen ? monitor : nullptr, nullptr ); Global::AppName.c_str(), Global::bFullScreen ? monitor : nullptr, nullptr );
if (!window) if (!window)
{ {
@@ -257,6 +284,7 @@ int main(int argc, char *argv[])
glfwSetFramebufferSizeCallback(window, window_resize_callback); glfwSetFramebufferSizeCallback(window, window_resize_callback);
glfwSetCursorPosCallback(window, cursor_pos_callback); glfwSetCursorPosCallback(window, cursor_pos_callback);
glfwSetKeyCallback(window, key_callback); glfwSetKeyCallback(window, key_callback);
glfwSetScrollCallback( window, scroll_callback );
glfwSetWindowFocusCallback(window, focus_callback); glfwSetWindowFocusCallback(window, focus_callback);
{ {
int width, height; int width, height;
@@ -276,9 +304,23 @@ int main(int argc, char *argv[])
BaseWindowProc = (WNDPROC)::SetWindowLongPtr( Hwnd, GWLP_WNDPROC, (LONG_PTR)WndProc ); BaseWindowProc = (WNDPROC)::SetWindowLongPtr( Hwnd, GWLP_WNDPROC, (LONG_PTR)WndProc );
// switch off the topmost flag // switch off the topmost flag
::SetWindowPos( Hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE ); ::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 #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 Global::pWorld = &World; // Ra: wskaźnik potrzebny do usuwania pojazdów
try try
@@ -311,9 +353,10 @@ int main(int argc, char *argv[])
} // po zrobieniu E3D odpalamy normalnie scenerię, by ją zobaczyć } // po zrobieniu E3D odpalamy normalnie scenerię, by ją zobaczyć
Console::On(); // włączenie konsoli Console::On(); // włączenie konsoli
while (!glfwWindowShouldClose(window) && World.Update()) while (!glfwWindowShouldClose(window)
&& World.Update()
&& GfxRenderer.Render())
{ {
glfwSwapBuffers(window);
glfwPollEvents(); glfwPollEvents();
} }
Console::Off(); // wyłączenie konsoli (komunikacji zwrotnej) Console::Off(); // wyłączenie konsoli (komunikacji zwrotnej)

View File

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

View File

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

View File

@@ -110,7 +110,8 @@ const int k_Active = 71;
// Winger 020304 // Winger 020304
const int k_Battery = 72; const int k_Battery = 72;
const int k_WalkMode = 73; const int k_WalkMode = 73;
const int MaxKeys = 74; int const k_DimHeadlights = 74;
const int MaxKeys = 75;
// klasy dla wskaźników globalnych // klasy dla wskaźników globalnych
class TGround; class TGround;
@@ -162,7 +163,6 @@ private:
class Global class Global
{ {
private: private:
static GLuint iTextureId; // ostatnio użyta tekstura 2D
public: public:
// double Global::tSinceStart; // double Global::tSinceStart;
static int Keys[MaxKeys]; static int Keys[MaxKeys];
@@ -199,11 +199,7 @@ class Global
static TGround *pGround; static TGround *pGround;
static std::string szDefaultExt; static std::string szDefaultExt;
static std::string SceneryFile; static std::string SceneryFile;
static char CreatorName1[20]; static std::string AppName;
static char CreatorName2[20];
static char CreatorName3[20];
static char CreatorName4[30];
static char CreatorName5[30];
static std::string asCurrentSceneryPath; static std::string asCurrentSceneryPath;
static std::string asCurrentTexturePath; static std::string asCurrentTexturePath;
static std::string asCurrentDynamicPath; static std::string asCurrentDynamicPath;
@@ -243,7 +239,6 @@ class Global
static int iSlowMotion; static int iSlowMotion;
static TDynamicObject *changeDynObj; static TDynamicObject *changeDynObj;
static double ABuDebug; static double ABuDebug;
static bool detonatoryOK;
static std::string asSky; static std::string asSky;
static bool bnewAirCouplers; static bool bnewAirCouplers;
// Ra: nowe zmienne globalne // Ra: nowe zmienne globalne
@@ -254,12 +249,9 @@ class Global
static int iDynamicFiltering; // domyślne rozmywanie tekstur pojazdów static int iDynamicFiltering; // domyślne rozmywanie tekstur pojazdów
static int iReCompile; // zwiększany, gdy trzeba odświeżyć siatki static int iReCompile; // zwiększany, gdy trzeba odświeżyć siatki
static bool bUseVBO; // czy jest VBO w karcie graficznej static bool bUseVBO; // czy jest VBO w karcie graficznej
static std::string LastGLError;
static int iFeedbackMode; // tryb pracy informacji zwrotnej static int iFeedbackMode; // tryb pracy informacji zwrotnej
static int iFeedbackPort; // dodatkowy adres dla informacji zwrotnych 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 double fLuminance; // jasność światła do automatycznego zapalania
static float SunAngle; // angle of the sun relative to horizon static float SunAngle; // angle of the sun relative to horizon
static int iMultiplayer; // blokada działania niektórych eventów na rzecz kominikacji static int iMultiplayer; // blokada działania niektórych eventów na rzecz kominikacji
@@ -273,13 +265,12 @@ class Global
static int iCameraLast; static int iCameraLast;
static std::string asRelease; // numer static std::string asRelease; // numer
static std::string asVersion; // z opisem 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 GLint iMaxTextureSize; // maksymalny rozmiar tekstury
static int iTextMode; // tryb pracy wyświetlacza tekstowego static int iTextMode; // tryb pracy wyświetlacza tekstowego
static int iScreenMode[12]; // numer ekranu wyświetlacza tekstowego static int iScreenMode[12]; // numer ekranu wyświetlacza tekstowego
static bool bDoubleAmbient; // podwójna jasność ambient static bool bDoubleAmbient; // podwójna jasność ambient
static double fMoveLight; // numer dnia w roku albo -1 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 bool bSmoothTraction; // wygładzanie drutów
static double fSunDeclination; // deklinacja Słońca static double fSunDeclination; // deklinacja Słońca
static double fTimeSpeed; // przyspieszenie czasu, zmienna do testów 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 szTexturesTGA; // lista tekstur od TGA
static std::string szTexturesDDS; // lista tekstur od DDS static std::string szTexturesDDS; // lista tekstur od DDS
static int iMultisampling; // tryb antyaliasingu: 0=brak,1=2px,2=4px,3=8px,4=16px 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 bool bGlutFont; // tekst generowany przez GLUT
static int iKeyLast; // ostatnio naciśnięty klawisz w celu logowania 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 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 // informacje podczas kalibracji
static double fBrakeStep; // krok zmiany hamulca dla klawiszy [Num3] i [Num9] static double fBrakeStep; // krok zmiany hamulca dla klawiszy [Num3] i [Num9]
static bool bJoinEvents; // czy grupować eventy o tych samych nazwach 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 std::string asTranscript[5]; // napisy na ekranie (widoczne)
*/ */
static TTranscripts tranTexts; // obiekt obsługujący stenogramy dźwięków na ekranie 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 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 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) 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 direction;
float3 color; float3 color;
float3 ambient; float3 ambient;
float intensity;
}; };
static daylight_s daylight; static daylight_s daylight;

View File

@@ -36,6 +36,7 @@ http://mozilla.org/MPL/2.0/.
#include "Driver.h" #include "Driver.h"
#include "Console.h" #include "Console.h"
#include "Names.h" #include "Names.h"
#include "uilayer.h"
#define _PROBLEND 1 #define _PROBLEND 1
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -702,8 +703,7 @@ void TGroundNode::RenderAlphaDL()
if ((PROBLEND)) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012 if ((PROBLEND)) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
{ {
glEnable(GL_BLEND); glEnable(GL_BLEND);
glAlphaFunc(GL_GREATER, 0.04f); glAlphaFunc(GL_GREATER, 0.02f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}; };
#endif #endif
} }
@@ -1168,6 +1168,45 @@ void TSubRect::RenderDL()
node->RenderDL(); // nieprzezroczyste z mieszanych modeli node->RenderDL(); // nieprzezroczyste z mieszanych modeli
for (int j = 0; j < iTracks; ++j) for (int j = 0; j < iTracks; ++j)
tTracks[j]->RenderDyn(); // nieprzezroczyste fragmenty pojazdów na torach 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() void TSubRect::RenderAlphaDL()
@@ -1228,17 +1267,31 @@ void TSubRect::RenderSounds()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
int TGroundRect::iFrameNumber = 0; // licznik wyświetlanych klatek int TGroundRect::iFrameNumber = 0; // licznik wyświetlanych klatek
TGroundRect::TGroundRect() //TGroundRect::TGroundRect( float3 const &Position, float const Radius = 1000.0f * M_SQRT2 ) :
{
pSubRects = NULL;
nTerrain = NULL;
};
TGroundRect::~TGroundRect() TGroundRect::~TGroundRect()
{ {
SafeDeleteArray(pSubRects); 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() void TGroundRect::RenderDL()
{ // renderowanie kwadratu kilometrowego (DL), jeśli jeszcze nie zrobione { // renderowanie kwadratu kilometrowego (DL), jeśli jeszcze nie zrobione
if (iLastDisplay != iFrameNumber) if (iLastDisplay != iFrameNumber)
@@ -1263,6 +1316,44 @@ void TGroundRect::RenderDL()
nRootMesh->RenderDL(); nRootMesh->RenderDL();
iLastDisplay = iFrameNumber; // drugi raz nie potrzeba 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() void TGroundRect::RenderVBO()
@@ -1340,6 +1431,22 @@ TGround::TGround()
#endif #endif
::SecureZeroMemory( TempConnectionType, sizeof( TempConnectionType ) ); ::SecureZeroMemory( TempConnectionType, sizeof( TempConnectionType ) );
::SecureZeroMemory( pRendered, sizeof( pRendered ) ); ::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() 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 the vehicle has defined light source, it can (potentially) emit light, so add it to the light array
*/ */
if( ( tmp != nullptr ) if( ( tmp != nullptr )
&& ( tmp->DynamicObject->MoverParameters->SecuritySystem.SystemType != 0 ) ) { && ( tmp->DynamicObject->MoverParameters->CategoryFlag == 1 ) // trains only
// we check for presence of security system, as a way to determine whether the vehicle is a controllable engine && ( ( tmp->DynamicObject->MoverParameters->SecuritySystem.SystemType != 0 )
// NOTE: this isn't 100% precise, e.g. middle EZT module comes with security system, while it has no lights || ( 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 ); m_lights.insert( tmp->DynamicObject );
} }
@@ -2446,66 +2556,17 @@ void TGround::FirstInit()
for (j = 0; j < iNumRects; ++j) for (j = 0; j < iNumRects; ++j)
Rects[i][j].Optimize(); // optymalizacja obiektów w sektorach Rects[i][j].Optimize(); // optymalizacja obiektów w sektorach
WriteLog("InitNormals OK"); WriteLog("InitNormals OK");
WriteLog("InitTracks");
InitTracks(); //łączenie odcinków ze sobą i przyklejanie eventów InitTracks(); //łączenie odcinków ze sobą i przyklejanie eventów
WriteLog("InitTracks OK"); WriteLog("InitTracks OK");
WriteLog("InitTraction");
InitTraction(); //łączenie drutów ze sobą InitTraction(); //łączenie drutów ze sobą
WriteLog("InitTraction OK"); WriteLog("InitTraction OK");
WriteLog("InitEvents");
InitEvents(); InitEvents();
WriteLog("InitEvents OK"); WriteLog("InitEvents OK");
WriteLog("InitLaunchers");
InitLaunchers(); InitLaunchers();
WriteLog("InitLaunchers OK"); WriteLog("InitLaunchers OK");
WriteLog("InitGlobalTime");
// ABu 160205: juz nie TODO :) // 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! Mtable::GlobalTime = std::make_shared<TMTableTime>( hh, mm, srh, srm, ssh, ssm ); // McZapkie-300302: inicjacja czasu rozkladowego - TODO: czytac z trasy!
WriteLog("InitGlobalTime OK"); 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"); WriteLog("FirstInit is done");
}; };
@@ -2556,17 +2617,17 @@ bool TGround::Init(std::string File)
token = ""; token = "";
parser.getTokens(); parser.getTokens();
parser >> token; parser >> token;
int refresh = 0; std::size_t processed = 0;
while (token != "") //(!Parser->EndOfFile) while (token != "") //(!Parser->EndOfFile)
{ {
if (refresh == 50) ++processed;
{ // SwapBuffers(hDC); //Ra: bez ogranicznika za bardzo spowalnia :( a u niektórych miga if( processed % 1000 == 0 )
refresh = 0; {
Global::DoEvents(); UILayer.set_progress( parser.getProgress(), parser.getFullProgress() );
GfxRenderer.Render();
glfwPollEvents();
} }
else
++refresh;
str = token; str = token;
if (str == "node") if (str == "node")
{ {
@@ -4835,13 +4896,13 @@ TGround::Render( Math3D::vector3 const &Camera ) {
if( !RenderAlphaVBO( Camera ) ) if( !RenderAlphaVBO( Camera ) )
return false; return false;
} }
else { // renderowanie przez Display List else {
// renderowanie przez Display List
if( !RenderDL( Camera ) ) if( !RenderDL( Camera ) )
return false; return false;
if( !RenderAlphaDL( Camera ) ) if( !RenderAlphaDL( Camera ) )
return false; return false;
} }
return true; return true;
} }
@@ -4893,6 +4954,7 @@ bool TGround::RenderDL(vector3 pPosition)
if (CameraDirection.x * direction.x + CameraDirection.z * direction.z < 0.55) if (CameraDirection.x * direction.x + CameraDirection.z * direction.z < 0.55)
continue; // pomijanie sektorów poza kątem patrzenia 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] Rects[(i + c) / iNumSubRects][(j + r) / iNumSubRects]
.RenderDL(); // kwadrat kilometrowy nie zawsze, bo szkoda FPS .RenderDL(); // kwadrat kilometrowy nie zawsze, bo szkoda FPS
if ((tmp = FastGetSubRect(i + c, j + r)) != NULL) if ((tmp = FastGetSubRect(i + c, j + r)) != NULL)
@@ -4908,7 +4970,7 @@ bool TGround::RenderDL(vector3 pPosition)
bool TGround::RenderAlphaDL(vector3 pPosition) bool TGround::RenderAlphaDL(vector3 pPosition)
{ // renderowanie scenerii z Display List - faza przezroczystych { // renderowanie scenerii z Display List - faza przezroczystych
glEnable(GL_BLEND); 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; TGroundNode *node;
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
TSubRect *tmp; TSubRect *tmp;

View File

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

View File

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

View File

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

View File

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

View File

@@ -193,7 +193,7 @@ double TBrakeCyl::P()
static double const cD = 1; static double const cD = 1;
static double const pD = VD - cD; 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) // Added div/0 trap for vehicles with incomplete definitions (cars etc)
// P:=VtoC; // P:=VtoC;
if (VtoC < VS) if (VtoC < VS)

View File

@@ -138,9 +138,9 @@ static int const i_bcpno = 6;
class TReservoir { class TReservoir {
protected: protected:
double Cap = 1.0; double Cap{ 1.0 };
double Vol = 0.0; double Vol{ 0.0 };
double dVol = 0.0; double dVol{ 0.0 };
public: public:
void CreateCap(double Capacity); void CreateCap(double Capacity);
@@ -509,6 +509,8 @@ class TDriverHandle {
virtual double GetSound(int i); virtual double GetSound(int i);
virtual double GetPos(int i); virtual double GetPos(int i);
virtual double GetEP(double pos); virtual double GetEP(double pos);
inline TDriverHandle() { ::SecureZeroMemory( Sounds, sizeof( Sounds ) ); }
}; };
class TFV4a : public TDriverHandle { class TFV4a : public TDriverHandle {

View File

@@ -33,7 +33,7 @@ using namespace Mtable;
double TSubModel::fSquareDist = 0; double TSubModel::fSquareDist = 0;
size_t TSubModel::iInstance; // numer renderowanego egzemplarza obiektu 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 int TSubModel::iAlpha = 0x30300030; // maska do testowania flag tekstur wymiennych
TModel3d *TSubModel::pRoot; // Ra: tymczasowo wskaźnik na model widoczny z submodelu TModel3d *TSubModel::pRoot; // Ra: tymczasowo wskaźnik na model widoczny z submodelu
std::string *TSubModel::pasText; std::string *TSubModel::pasText;
@@ -48,7 +48,7 @@ std::string *TSubModel::pasText;
TSubModel::TSubModel() TSubModel::TSubModel()
{ {
ZeroMemory(this, sizeof(TSubModel)); // istotne przy zapisywaniu wersji binarnej ::SecureZeroMemory(this, sizeof(TSubModel)); // istotne przy zapisywaniu wersji binarnej
FirstInit(); FirstInit();
}; };
@@ -1054,6 +1054,7 @@ void TSubModel::RaAnimation(glm::mat4 &m, TAnimType a)
void TSubModel::RenderDL() void TSubModel::RenderDL()
{ // główna procedura renderowania przez DL { // główna procedura renderowania przez DL
return;
if( ( iVisible ) if( ( iVisible )
&& ( fSquareDist >= (fSquareMinDist / Global::fDistanceFactor) ) && ( fSquareDist >= (fSquareMinDist / Global::fDistanceFactor) )
&& ( fSquareDist <= (fSquareMaxDist * Global::fDistanceFactor) ) ) && ( fSquareDist <= (fSquareMaxDist * Global::fDistanceFactor) ) )
@@ -1153,6 +1154,7 @@ void TSubModel::RenderDL()
void TSubModel::RenderAlphaDL() void TSubModel::RenderAlphaDL()
{ // renderowanie przezroczystych przez DL { // renderowanie przezroczystych przez DL
return;
if( ( iVisible ) if( ( iVisible )
&& ( fSquareDist >= (fSquareMinDist / Global::fDistanceFactor) ) && ( fSquareDist >= (fSquareMinDist / Global::fDistanceFactor) )
&& ( fSquareDist <= (fSquareMaxDist * Global::fDistanceFactor) ) ) && ( fSquareDist <= (fSquareMaxDist * Global::fDistanceFactor) ) )
@@ -2099,39 +2101,7 @@ void TModel3d::BreakHierarhy()
Error("Not implemented yet :("); Error("Not implemented yet :(");
}; };
/* #ifdef EU07_USE_OLD_RENDERCODE
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();
};
*/
void TModel3d::Render(double fSquareDistance, texture_manager::size_type *ReplacableSkinId, int iAlpha) void TModel3d::Render(double fSquareDistance, texture_manager::size_type *ReplacableSkinId, int iAlpha)
{ {
iAlpha ^= 0x0F0F000F; // odwrócenie flag tekstur, aby wyłapać nieprzezroczyste 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(); Root->RenderAlphaDL();
} }
}; };
#endif
/* void TModel3d::RaRender(double fSquareDistance, texture_manager::size_type const *ReplacableSkinId, int iAlpha)
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)
{ // renderowanie specjalne, np. kabiny { // renderowanie specjalne, np. kabiny
iAlpha ^= 0x0F0F000F; // odwrócenie flag tekstur, aby wyłapać nieprzezroczyste iAlpha ^= 0x0F0F000F; // odwrócenie flag tekstur, aby wyłapać nieprzezroczyste
if (iAlpha & iFlags & 0x1F1F001F) // czy w ogóle jest co robić w tym cyklu? 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 { // renderowanie specjalne, np. kabiny
if (iAlpha & iFlags & 0x2F2F002F) // czy w ogóle jest co robić w tym cyklu? 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 // 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) void TModel3d::Render(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId, int iAlpha)
{ // nieprzezroczyste, Display List { // nieprzezroczyste, Display List
glPushMatrix(); glPushMatrix();
@@ -2289,7 +2205,8 @@ void TModel3d::RenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager:
Root->RenderAlphaDL(); Root->RenderAlphaDL();
glPopMatrix(); 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 { // nieprzezroczyste, VBO
glPushMatrix(); glPushMatrix();
glTranslated(vPosition->x, vPosition->y, vPosition->z); glTranslated(vPosition->x, vPosition->y, vPosition->z);
@@ -2316,7 +2233,7 @@ void TModel3d::RaRender(vector3 *vPosition, vector3 *vAngle, texture_manager::si
} }
glPopMatrix(); 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) int iAlpha)
{ // przezroczyste, VBO { // przezroczyste, VBO
glPushMatrix(); glPushMatrix();
@@ -2345,6 +2262,7 @@ void TModel3d::RaRenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manage
glPopMatrix(); glPopMatrix();
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// 2012-02 funkcje do tworzenia terenu z E3D // 2012-02 funkcje do tworzenia terenu z E3D
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@@ -132,6 +132,9 @@ class TModel3d;
class TSubModel class TSubModel
{ // klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów { // klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów
//m7todo: zrobić normalną serializację //m7todo: zrobić normalną serializację
friend class opengl_renderer;
private: private:
int iNext; int iNext;
int iChild; int iChild;
@@ -222,7 +225,7 @@ private:
public: public:
static size_t iInstance; // identyfikator egzemplarza, który aktualnie renderuje model 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 int iAlpha; // maska bitowa dla danego przebiegu
static double fSquareDist; static double fSquareDist;
static TModel3d *pRoot; static TModel3d *pRoot;
@@ -279,7 +282,7 @@ public:
void DisplayLists(); void DisplayLists();
void BinInit(TSubModel *s, float4x4 *m, float8 *v, void BinInit(TSubModel *s, float4x4 *m, float8 *v,
std::vector<std::string> *t, std::vector<std::string> *n, bool dynamic); 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; ReplacableSkinId = r;
iAlpha = a; iAlpha = a;
@@ -322,6 +325,8 @@ public:
class TModel3d : public CMesh class TModel3d : public CMesh
{ {
friend class opengl_renderer;
private: private:
// TMaterial *Materials; // TMaterial *Materials;
// int MaterialsCount; //Ra: nie używane // int MaterialsCount; //Ra: nie używane
@@ -355,32 +360,21 @@ public:
void SaveToBinFile(char const *FileName); void SaveToBinFile(char const *FileName);
void BreakHierarhy(); void BreakHierarhy();
// renderowanie specjalne // renderowanie specjalne
#ifdef EU07_USE_OLD_RENDERCODE
void Render(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030); void Render(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
void RenderAlpha(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL, void RenderAlpha(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
int iAlpha = 0x30300030); #endif
void RaRender(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030); void RaRender(double fSquareDistance, texture_manager::size_type const *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
void RaRenderAlpha(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL, void RaRenderAlpha(double fSquareDistance, texture_manager::size_type const *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
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);
// trzy kąty obrotu // trzy kąty obrotu
void Render(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL, #ifdef EU07_USE_OLD_RENDERCODE
int iAlpha = 0x30300030); 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, void RenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
int iAlpha = 0x30300030); #endif
void RaRender(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL, void RaRender(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type const *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
int iAlpha = 0x30300030); void RaRenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type const *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
void RaRenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL,
int iAlpha = 0x30300030);
// inline int GetSubModelsCount() { return (SubModelsCount); }; // inline int GetSubModelsCount() { return (SubModelsCount); };
int Flags() int Flags() const
{ {
return iFlags; 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 // data state will be set by called loader, so we're all done here
if( data_state == resource_state::good ) { if( data_state == resource_state::good ) {
has_alpha = (
data_components == GL_RGBA ?
true :
false );
size = data.size() / 1024;
return; return;
} }
@@ -473,6 +480,16 @@ opengl_texture::load_TGA() {
return; 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 // fill remaining data info
data_mapcount = 1; data_mapcount = 1;
data_format = GL_BGRA; data_format = GL_BGRA;
@@ -485,14 +502,32 @@ opengl_texture::load_TGA() {
return; 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() { opengl_texture::create() {
if( data_state != resource_state::good ) { if( data_state != resource_state::good ) {
// don't bother until we have useful texture data // don't bother until we have useful texture data
return; return data_state;
} }
// 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 ) {
::glGenTextures( 1, &id ); ::glGenTextures( 1, &id );
::glBindTexture( GL_TEXTURE_2D, id ); ::glBindTexture( GL_TEXTURE_2D, id );
@@ -553,14 +588,15 @@ opengl_texture::create() {
} }
} }
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.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::none;
*/
data_state = resource_state::good;
is_ready = true;
}
return data_state;
} }
void 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 void
texture_manager::Init() { texture_manager::Init() {
} }
@@ -733,7 +794,9 @@ texture_manager::GetTextureId( std::string Filename, std::string const &Dir, int
if( true == Loadnow ) { if( true == Loadnow ) {
Texture( textureindex ).load(); Texture( textureindex ).load();
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
Texture( textureindex ).create(); Texture( textureindex ).create();
#endif
} }
return textureindex; 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 // TODO: do binding in texture object, add support for other types
if( Id != 0 ) { if( Id != 0 ) {
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
auto const &texture = Texture( Id ); ::glBindTexture( GL_TEXTURE_2D, Id );
if( true == texture.is_ready ) { m_activetexture = 0;
::glBindTexture( GL_TEXTURE_2D, texture.id ); #else
if( Texture( Id ).bind() == resource_state::good ) {
m_activetexture = Id; m_activetexture = Id;
return;
} }
else {
// TODO: bind a special 'error' texture on failure
} }
#endif
}
else {
::glBindTexture( GL_TEXTURE_2D, 0 ); ::glBindTexture( GL_TEXTURE_2D, 0 );
m_activetexture = 0; m_activetexture = 0;
}
// all done
return; 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. // checks whether specified texture is in the texture bank. returns texture id, or npos.
texture_manager::size_type texture_manager::size_type
texture_manager::find_in_databank( std::string const &Texturename ) { 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 // no results either way, report failure
return ""; 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 // methods
void load(); void load();
void create(); resource_state bind();
resource_state create();
// members // members
GLuint id{ (GLuint)-1 }; // associated GL resource GLuint id{ (GLuint)-1 }; // associated GL resource
bool has_alpha{ false }; // indicates the texture has alpha channel bool has_alpha{ false }; // indicates the texture has alpha channel
bool is_ready{ false }; // indicates the texture was processed and is ready for use 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 traits; // requested texture attributes: wrapping modes etc
std::string name; // name of the texture source file std::string name; // name of the texture source file
std::size_t size{ 0 }; // size of the texture data, in kb
private: private:
// methods // methods
@@ -44,6 +46,7 @@ private:
void load_TEX(); void load_TEX();
void load_TGA(); void load_TGA();
void set_filtering(); void set_filtering();
void downsize( GLuint const Format );
// members // members
std::vector<char> data; // texture data std::vector<char> data; // texture data
@@ -71,11 +74,19 @@ public:
texture_manager(); texture_manager();
~texture_manager() { Free(); } ~texture_manager() { Free(); }
size_type GetTextureId( std::string Filename, std::string const &Dir, int const Filter = -1, bool const Loadnow = true ); size_type
void Bind( size_type const Id ); GetTextureId( std::string Filename, std::string const &Dir, int const Filter = -1, bool const Loadnow = true );
opengl_texture &Texture( size_type const Id ) { return m_textures.at( Id ); } void
void Init(); Bind( size_type const Id );
void Free(); opengl_texture &
Texture( size_type const Id ) { return m_textures[ Id ]; }
void
Init();
void
Free();
// debug performance string
std::string
Info() const;
private: private:
typedef std::unordered_map<std::string, size_type> index_map; typedef std::unordered_map<std::string, size_type> index_map;
@@ -103,3 +114,60 @@ private:
index_map m_texturemappings; index_map m_texturemappings;
size_type m_activetexture{ 0 }; // last i.e. currently bound texture 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; 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 #endif
}; };
@@ -2610,6 +2624,17 @@ void TTrack::EnvironmentReset()
glLightfv(GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, Global::specularDayLight); 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 #endif
}; };
@@ -2625,7 +2650,11 @@ void TTrack::RenderDyn()
#else #else
for( auto dynamic : Dynamics ) { for( auto dynamic : Dynamics ) {
// sam sprawdza, czy VBO; zmienia kontekst VBO! // sam sprawdza, czy VBO; zmienia kontekst VBO!
#ifdef EU07_USE_OLD_RENDERCODE
dynamic->Render(); dynamic->Render();
#else
GfxRenderer.Render( dynamic );
#endif
} }
#endif #endif
}; };
@@ -2642,7 +2671,11 @@ void TTrack::RenderDynAlpha()
#else #else
for( auto dynamic : Dynamics ) { for( auto dynamic : Dynamics ) {
// sam sprawdza, czy VBO; zmienia kontekst VBO! // sam sprawdza, czy VBO; zmienia kontekst VBO!
#ifdef EU07_USE_OLD_RENDERCODE
dynamic->RenderAlpha(); dynamic->RenderAlpha();
#else
GfxRenderer.Render_Alpha( dynamic );
#endif
} }
#endif #endif
}; };

284
Train.cpp
View File

@@ -295,35 +295,58 @@ PyObject *TTrain::GetTrainState() {
return NULL; return NULL;
} }
PyDict_SetItemString( dict, "direction", PyGetInt( DynamicObject->MoverParameters->ActiveDir ) ); auto const &mover = DynamicObject->MoverParameters;
PyDict_SetItemString( dict, "cab", PyGetInt( DynamicObject->MoverParameters->ActiveCab ) );
PyDict_SetItemString( dict, "slipping_wheels", PyDict_SetItemString( dict, "cab", PyGetInt( mover->ActiveCab ) );
PyGetBool( DynamicObject->MoverParameters->SlippingWheels ) ); // basic systems state data
PyDict_SetItemString( dict, "converter", PyDict_SetItemString( dict, "battery", PyGetBool( mvControlled->Battery ) );
PyGetBool( DynamicObject->MoverParameters->ConverterFlag ) ); PyDict_SetItemString( dict, "linebreaker", PyGetBool( mvControlled->Mains ) );
PyDict_SetItemString( dict, "main_ctrl_actual_pos", PyDict_SetItemString( dict, "converter", PyGetBool( mover->ConverterFlag ) );
PyGetInt( DynamicObject->MoverParameters->MainCtrlActualPos ) ); PyDict_SetItemString( dict, "converter_overload", PyGetBool( mover->ConvOvldFlag ) );
PyDict_SetItemString( dict, "scnd_ctrl_actual_pos", PyDict_SetItemString( dict, "compress", PyGetBool( mover->CompressorFlag ) );
PyGetInt( DynamicObject->MoverParameters->ScndCtrlActualPos ) ); // reverser
PyDict_SetItemString( dict, "fuse", PyGetBool( DynamicObject->MoverParameters->FuseFlag ) ); PyDict_SetItemString( dict, "direction", PyGetInt( mover->ActiveDir ) );
PyDict_SetItemString( dict, "converter_overload", // throttle
PyGetBool( DynamicObject->MoverParameters->ConvOvldFlag ) ); PyDict_SetItemString( dict, "mainctrl_pos", PyGetInt( mover->MainCtrlPos ) );
PyDict_SetItemString( dict, "voltage", PyGetFloat( DynamicObject->MoverParameters->Voltage ) ); PyDict_SetItemString( dict, "main_ctrl_actual_pos", PyGetInt( mover->MainCtrlActualPos ) );
PyDict_SetItemString( dict, "velocity", PyGetFloat( DynamicObject->MoverParameters->Vel ) ); PyDict_SetItemString( dict, "scndctrl_pos", PyGetInt( mover->ScndCtrlPos ) );
PyDict_SetItemString( dict, "im", PyGetFloat( DynamicObject->MoverParameters->Im ) ); PyDict_SetItemString( dict, "scnd_ctrl_actual_pos", PyGetInt( mover->ScndCtrlActualPos ) );
PyDict_SetItemString( dict, "compress", // brakes
PyGetBool( DynamicObject->MoverParameters->CompressorFlag ) ); PyDict_SetItemString( dict, "manual_brake", PyGetBool( mvOccupied->ManualBrakePos > 0 ) );
PyDict_SetItemString( dict, "hours", PyGetInt( GlobalTime->hh ) ); bool const bEP = ( mvControlled->LocHandle->GetCP()>0.2 ) || ( fEIMParams[ 0 ][ 2 ]>0.01 );
PyDict_SetItemString( dict, "minutes", PyGetInt( GlobalTime->mm ) ); PyDict_SetItemString( dict, "dir_brake", PyGetBool( bEP ) );
PyDict_SetItemString( dict, "seconds", PyGetInt( GlobalTime->mr ) ); bool bPN;
PyDict_SetItemString( dict, "velocity_desired", PyGetFloat( DynamicObject->Mechanik->VelDesired ) ); 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* 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* TXTC[ 10 ] = { "fr", "frt", "frb", "pr", "prt", "prb", "im", "vm", "ihv", "uhv" };
char* TXTP[ 3 ] = { "bc", "bp", "sp" }; 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 ] ) ); 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 i = 0; i < 8; ++i ) {
for( int j = 0; j<10; j++ ) 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( "_" ) + 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( "_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 ] ) ); PyDict_SetItemString( dict, ( std::string( "eimp_c" ) + std::to_string( i + 1 ) + std::string( "_cv" ) ).c_str(), PyGetFloatS( fCntVol[ i ] ) );
@@ -337,24 +360,16 @@ PyObject *TTrain::GetTrainState() {
PyDict_SetItemString( dict, ( std::string( "eimp_c" ) + std::to_string( i + 1 ) + std::string( "_heat" ) ).c_str(), PyGetBool( bHeat[ i ] ) ); 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 i = 0; i < 20; ++i ) {
for( int j = 0; j<3; j++ ) 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(), PyDict_SetItemString( dict, ( std::string( "eimp_pn" ) + std::to_string( i + 1 ) + std::string( "_" ) + std::string( TXTP[ j ] ) ).c_str(),
PyGetFloatS( fPress[ i ][ j ] ) ); PyGetFloatS( fPress[ i ][ j ] ) );
} }
bool bEP, bPN; // multi-unit state data
bEP = ( mvControlled->LocHandle->GetCP()>0.2 ) || ( fEIMParams[ 0 ][ 2 ]>0.01 ); PyDict_SetItemString( dict, "car_no", PyGetInt( iCarNo ) );
PyDict_SetItemString( dict, "dir_brake", PyGetBool( bEP ) ); PyDict_SetItemString( dict, "power_no", PyGetInt( iPowerNo ) );
if( ( typeid( *mvControlled->Hamulec ) == typeid( TLSt ) ) PyDict_SetItemString( dict, "unit_no", PyGetInt( iUnitNo ) );
|| ( typeid( *mvControlled->Hamulec ) == typeid( TEStED ) ) ) {
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_" ) + 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_r_" ) + std::to_string( i + 1 ) ).c_str(), PyGetFloatS( bDoors[ i ][ 1 ] ) );
@@ -364,23 +379,21 @@ PyObject *TTrain::GetTrainState() {
cCode[ i ] ).c_str() ) ); 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, ( std::string( "car_name" ) + std::to_string( i + 1 ) ).c_str(), PyGetString( asCarName[ i ].c_str() ) );
} }
PyDict_SetItemString( dict, "car_no", PyGetInt( iCarNo ) ); // ai state data
PyDict_SetItemString( dict, "power_no", PyGetInt( iPowerNo ) ); auto const &driver = DynamicObject->Mechanik;
PyDict_SetItemString( dict, "unit_no", PyGetInt( iUnitNo ) );
PyDict_SetItemString( dict, "universal3", PyGetBool( LampkaUniversal3_st ) ); PyDict_SetItemString( dict, "velocity_desired", PyGetFloat( driver->VelDesired ) );
PyDict_SetItemString( dict, "ca", PyGetBool( TestFlag( mvOccupied->SecuritySystem.Status, s_aware ) ) ); PyDict_SetItemString( dict, "velroad", PyGetFloat( driver->VelRoad ) );
PyDict_SetItemString( dict, "shp", PyGetBool( TestFlag( mvOccupied->SecuritySystem.Status, s_active ) ) ); PyDict_SetItemString( dict, "vellimitlast", PyGetFloat( driver->VelLimitLast ) );
PyDict_SetItemString( dict, "manual_brake", PyGetBool( mvOccupied->ManualBrakePos > 0 ) ); PyDict_SetItemString( dict, "velsignallast", PyGetFloat( driver->VelSignalLast ) );
PyDict_SetItemString( dict, "pantpress", PyGetFloat( mvControlled->PantPress ) ); PyDict_SetItemString( dict, "velsignalnext", PyGetFloat( driver->VelSignalNext ) );
PyDict_SetItemString( dict, "trainnumber", PyGetString( DynamicObject->Mechanik->TrainName().c_str() ) ); PyDict_SetItemString( dict, "velnext", PyGetFloat( driver->VelNext ) );
PyDict_SetItemString( dict, "velnext", PyGetFloat( DynamicObject->Mechanik->VelNext ) ); PyDict_SetItemString( dict, "actualproximitydist", PyGetFloat( driver->ActualProximityDist ) );
PyDict_SetItemString( dict, "actualproximitydist", PyGetFloat( DynamicObject->Mechanik->ActualProximityDist ) ); PyDict_SetItemString( dict, "trainnumber", PyGetString( driver->TrainName().c_str() ) );
PyDict_SetItemString( dict, "velsignallast", PyGetFloat( DynamicObject->Mechanik->VelSignalLast ) ); // world state data
PyDict_SetItemString( dict, "vellimitlast", PyGetFloat( DynamicObject->Mechanik->VelLimitLast ) ); PyDict_SetItemString( dict, "hours", PyGetInt( GlobalTime->hh ) );
PyDict_SetItemString( dict, "velroad", PyGetFloat( DynamicObject->Mechanik->VelRoad ) ); PyDict_SetItemString( dict, "minutes", PyGetInt( GlobalTime->mm ) );
PyDict_SetItemString( dict, "velsignalnext", PyGetFloat( DynamicObject->Mechanik->VelSignalNext ) ); PyDict_SetItemString( dict, "seconds", PyGetInt( GlobalTime->mr ) );
PyDict_SetItemString( dict, "battery", PyGetBool( mvControlled->Battery ) );
PyDict_SetItemString( dict, "tractionforce", PyGetFloat( DynamicObject->MoverParameters->Ft ) );
return dict; 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) if (mvControlled->TrainType == dt_EZT)
{ {
@@ -1792,21 +1805,18 @@ if
{ // tryb freefly { // tryb freefly
int CouplNr = -1; // normalnie żaden ze sprzęgów int CouplNr = -1; // normalnie żaden ze sprzęgów
TDynamicObject *tmp; TDynamicObject *tmp;
tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), 1, 1500, tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), 1, 1500, CouplNr);
CouplNr); if (tmp == nullptr)
if (tmp == NULL) tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), -1, 1500, CouplNr);
tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), -1, if( ( CouplNr != -1 )
1500, CouplNr); && ( tmp != nullptr )
if (tmp && (CouplNr != -1)) && ( tmp->MoverParameters->Couplers[ CouplNr ].Connected != nullptr ) )
{ {
if (tmp->MoverParameters->Couplers[CouplNr].CouplingFlag == if (tmp->MoverParameters->Couplers[CouplNr].CouplingFlag == 0) // najpierw hak
0) // najpierw hak
{ {
if ((tmp->MoverParameters->Couplers[CouplNr] if ((tmp->MoverParameters->Couplers[CouplNr].Connected->Couplers[CouplNr].AllowedFlag
.Connected->Couplers[CouplNr] & tmp->MoverParameters->Couplers[CouplNr].AllowedFlag
.AllowedFlag & & ctrain_coupler) == ctrain_coupler)
tmp->MoverParameters->Couplers[CouplNr].AllowedFlag &
ctrain_coupler) == ctrain_coupler)
if (tmp->MoverParameters->Attach( if (tmp->MoverParameters->Attach(
CouplNr, 2, CouplNr, 2,
tmp->MoverParameters->Couplers[CouplNr].Connected, tmp->MoverParameters->Couplers[CouplNr].Connected,
@@ -1815,46 +1825,37 @@ if
// tmp->MoverParameters->Couplers[CouplNr].Render=true; // tmp->MoverParameters->Couplers[CouplNr].Render=true;
// //podłączony sprzęg będzie widoczny // //podłączony sprzęg będzie widoczny
if (DynamicObject->Mechanik) // na wszelki wypadek if (DynamicObject->Mechanik) // na wszelki wypadek
DynamicObject->Mechanik->CheckVehicles( DynamicObject->Mechanik->CheckVehicles(Connect); // aktualizacja flag kierunku w składzie
Connect); // aktualizacja flag kierunku w składzie
dsbCouplerAttach->SetVolume(DSBVOLUME_MAX); dsbCouplerAttach->SetVolume(DSBVOLUME_MAX);
dsbCouplerAttach->Play(0, 0, 0); dsbCouplerAttach->Play(0, 0, 0);
} }
else else
WriteLog("Mechanical coupling failed."); WriteLog("Mechanical coupling failed.");
} }
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_pneumatic)) // pneumatyka
ctrain_pneumatic)) // pneumatyka
{ {
if ((tmp->MoverParameters->Couplers[CouplNr] if ((tmp->MoverParameters->Couplers[CouplNr].Connected->Couplers[CouplNr].AllowedFlag
.Connected->Couplers[CouplNr] & tmp->MoverParameters->Couplers[CouplNr].AllowedFlag
.AllowedFlag & & ctrain_pneumatic) == ctrain_pneumatic)
tmp->MoverParameters->Couplers[CouplNr].AllowedFlag &
ctrain_pneumatic) == ctrain_pneumatic)
if (tmp->MoverParameters->Attach( if (tmp->MoverParameters->Attach(
CouplNr, 2, CouplNr, 2,
tmp->MoverParameters->Couplers[CouplNr].Connected, tmp->MoverParameters->Couplers[CouplNr].Connected,
tmp->MoverParameters->Couplers[CouplNr].CouplingFlag + (tmp->MoverParameters->Couplers[CouplNr].CouplingFlag | ctrain_pneumatic)))
ctrain_pneumatic))
{ {
rsHiss.Play(1, DSBPLAY_LOOPING, true, tmp->GetPosition()); rsHiss.Play(1, DSBPLAY_LOOPING, true, tmp->GetPosition());
DynamicObject->SetPneumatic(CouplNr != 0, true); // Ra: to mi się nie podoba !!!! DynamicObject->SetPneumatic(CouplNr != 0, true); // Ra: to mi się nie podoba !!!!
tmp->SetPneumatic(CouplNr != 0, true); tmp->SetPneumatic(CouplNr != 0, true);
} }
} }
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_scndpneumatic)) // zasilajacy
ctrain_scndpneumatic)) // zasilajacy
{ {
if ((tmp->MoverParameters->Couplers[CouplNr] if ((tmp->MoverParameters->Couplers[CouplNr].Connected->Couplers[CouplNr].AllowedFlag
.Connected->Couplers[CouplNr] & tmp->MoverParameters->Couplers[CouplNr].AllowedFlag
.AllowedFlag & & ctrain_scndpneumatic) == ctrain_scndpneumatic)
tmp->MoverParameters->Couplers[CouplNr].AllowedFlag &
ctrain_scndpneumatic) == ctrain_scndpneumatic)
if (tmp->MoverParameters->Attach( if (tmp->MoverParameters->Attach(
CouplNr, 2, CouplNr, 2,
tmp->MoverParameters->Couplers[CouplNr].Connected, tmp->MoverParameters->Couplers[CouplNr].Connected,
tmp->MoverParameters->Couplers[CouplNr].CouplingFlag + (tmp->MoverParameters->Couplers[CouplNr].CouplingFlag | ctrain_scndpneumatic)))
ctrain_scndpneumatic))
{ {
// rsHiss.Play(1,DSBPLAY_LOOPING,true,tmp->GetPosition()); // rsHiss.Play(1,DSBPLAY_LOOPING,true,tmp->GetPosition());
dsbCouplerDetach->SetVolume(DSBVOLUME_MAX); dsbCouplerDetach->SetVolume(DSBVOLUME_MAX);
@@ -1863,8 +1864,7 @@ if
tmp->SetPneumatic(CouplNr != 0, false); tmp->SetPneumatic(CouplNr != 0, false);
} }
} }
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_controll)) // ukrotnionko
ctrain_controll)) // ukrotnionko
{ {
if ((tmp->MoverParameters->Couplers[CouplNr] if ((tmp->MoverParameters->Couplers[CouplNr]
.Connected->Couplers[CouplNr] .Connected->Couplers[CouplNr]
@@ -1874,15 +1874,13 @@ if
if (tmp->MoverParameters->Attach( if (tmp->MoverParameters->Attach(
CouplNr, 2, CouplNr, 2,
tmp->MoverParameters->Couplers[CouplNr].Connected, tmp->MoverParameters->Couplers[CouplNr].Connected,
tmp->MoverParameters->Couplers[CouplNr].CouplingFlag + (tmp->MoverParameters->Couplers[CouplNr].CouplingFlag | ctrain_controll)))
ctrain_controll))
{ {
dsbCouplerAttach->SetVolume(DSBVOLUME_MAX); dsbCouplerAttach->SetVolume(DSBVOLUME_MAX);
dsbCouplerAttach->Play(0, 0, 0); dsbCouplerAttach->Play(0, 0, 0);
} }
} }
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_passenger)) // mostek
ctrain_passenger)) // mostek
{ {
if ((tmp->MoverParameters->Couplers[CouplNr] if ((tmp->MoverParameters->Couplers[CouplNr]
.Connected->Couplers[CouplNr] .Connected->Couplers[CouplNr]
@@ -1892,8 +1890,7 @@ if
if (tmp->MoverParameters->Attach( if (tmp->MoverParameters->Attach(
CouplNr, 2, CouplNr, 2,
tmp->MoverParameters->Couplers[CouplNr].Connected, tmp->MoverParameters->Couplers[CouplNr].Connected,
tmp->MoverParameters->Couplers[CouplNr].CouplingFlag + (tmp->MoverParameters->Couplers[CouplNr].CouplingFlag | ctrain_passenger)))
ctrain_passenger))
{ {
// rsHiss.Play(1,DSBPLAY_LOOPING,true,tmp->GetPosition()); // rsHiss.Play(1,DSBPLAY_LOOPING,true,tmp->GetPosition());
dsbCouplerDetach->SetVolume(DSBVOLUME_MAX); dsbCouplerDetach->SetVolume(DSBVOLUME_MAX);
@@ -1912,8 +1909,7 @@ if
// odlegle wagony // odlegle wagony
if (iCabn > 0) if (iCabn > 0)
{ {
if (!FreeFlyModeFlag) // tryb 'kabinowy' (pozwala również rozłączyć if (!FreeFlyModeFlag) // tryb 'kabinowy' (pozwala również rozłączyć sprzęgi zablokowane)
// sprzęgi zablokowane)
{ {
if (DynamicObject->DettachStatus(iCabn - 1) < 0) // jeśli jest co odczepić if (DynamicObject->DettachStatus(iCabn - 1) < 0) // jeśli jest co odczepić
if (DynamicObject->Dettach(iCabn - 1)) // iCab==1:przód,iCab==2:tył if (DynamicObject->Dettach(iCabn - 1)) // iCab==1:przód,iCab==2:tył
@@ -1926,15 +1922,12 @@ if
{ // tryb freefly { // tryb freefly
int CouplNr = -1; int CouplNr = -1;
TDynamicObject *tmp; TDynamicObject *tmp;
tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), 1, 1500, tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), 1, 1500, CouplNr);
CouplNr);
if (tmp == NULL) if (tmp == NULL)
tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), -1, tmp = DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), -1, 1500, CouplNr);
1500, CouplNr);
if (tmp && (CouplNr != -1)) if (tmp && (CouplNr != -1))
{ {
if ((tmp->MoverParameters->Couplers[CouplNr].CouplingFlag & ctrain_depot) == if ((tmp->MoverParameters->Couplers[CouplNr].CouplingFlag & ctrain_depot) == 0) // jeżeli sprzęg niezablokowany
0) // jeżeli sprzęg niezablokowany
if (tmp->DettachStatus(CouplNr) < 0) // jeśli jest co odczepić i się da if (tmp->DettachStatus(CouplNr) < 0) // jeśli jest co odczepić i się da
if (!tmp->Dettach(CouplNr)) if (!tmp->Dettach(CouplNr))
{ // dźwięk odczepiania { // 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 // liniowych
{ {
if ((mvControlled->TrainType != dt_EZT) && (mvControlled->TrainType != dt_EP05) && if ((mvControlled->TrainType != dt_EZT) && (mvControlled->TrainType != dt_EP05) &&
@@ -2481,6 +2474,29 @@ if
++iRadioChannel; // 0=wyłączony ++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) void TTrain::OnKeyUp(int cKey)
@@ -2490,7 +2506,7 @@ void TTrain::OnKeyUp(int cKey)
} }
else 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 { // zwolnienie klawisza daje powrót przycisku do zwykłego stanu
if ((mvControlled->TrainType != dt_EZT) && (mvControlled->TrainType != dt_EP05) && if ((mvControlled->TrainType != dt_EZT) && (mvControlled->TrainType != dt_EP05) &&
(mvControlled->TrainType != dt_ET40)) (mvControlled->TrainType != dt_ET40))
@@ -2686,10 +2702,9 @@ bool TTrain::Update( double const Deltatime )
iSekunda=floor(GlobalTime->mr); iSekunda=floor(GlobalTime->mr);
} }
*/ */
// Ra 2014-09: napięcia i prądy muszą być ustalone najpierw, bo wysyłane są // Ra 2014-09: napięcia i prądy muszą być ustalone najpierw, bo wysyłane są ewentualnie na PoKeys
// ewentualnie na if ((mvControlled->EngineType != DieselElectric)
// PoKeys && (mvControlled->EngineType != ElectricInductionMotor)) // Ra 2014-09: czy taki rozdzia? ma sens?
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? fHVoltage = mvControlled->RunningTraction.TractionVoltage; // Winger czy to nie jest zle?
// *mvControlled->Mains); // *mvControlled->Mains);
else else
@@ -3901,41 +3916,6 @@ bool TTrain::Update( double const Deltatime )
ggLeftEndLightButton.PutValue(0); 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 // hunter-230112
// REFLEKTOR LEWY // REFLEKTOR LEWY
@@ -4073,6 +4053,11 @@ bool TTrain::Update( double const Deltatime )
ggLightsButton.PutValue(mvOccupied->LightsPos - 1); ggLightsButton.PutValue(mvOccupied->LightsPos - 1);
ggLightsButton.Update(); ggLightsButton.Update();
} }
if( ggDimHeadlightsButton.SubModel ) {
ggDimHeadlightsButton.PutValue( DynamicObject->DimHeadlights ? 1.0 : 0.0 );
ggDimHeadlightsButton.Update();
}
//--------- //---------
// Winger 010304 - pantografy // Winger 010304 - pantografy
@@ -5879,6 +5864,7 @@ void TTrain::clear_cab_controls()
ggLeftLightButton.Clear(); ggLeftLightButton.Clear();
ggRightLightButton.Clear(); ggRightLightButton.Clear();
ggUpperLightButton.Clear(); ggUpperLightButton.Clear();
ggDimHeadlightsButton.Clear();
ggLeftEndLightButton.Clear(); ggLeftEndLightButton.Clear();
ggRightEndLightButton.Clear(); ggRightEndLightButton.Clear();
ggLightsButton.Clear(); ggLightsButton.Clear();
@@ -6283,6 +6269,10 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
// swiatlo // swiatlo
ggRightLightButton.Load(Parser, DynamicObject->mdKabina); ggRightLightButton.Load(Parser, DynamicObject->mdKabina);
} }
else if( Label == "dimheadlights_sw:" ) {
// swiatlo
ggDimHeadlightsButton.Load( Parser, DynamicObject->mdKabina );
}
else if( Label == "leftend_sw:" ) else if( Label == "leftend_sw:" )
{ {
// swiatlo // swiatlo

View File

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

1952
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 "stars.h"
#include "skydome.h" #include "skydome.h"
#include "mczapkie/mover.h" #include "mczapkie/mover.h"
#include "glfw/glfw3.h" #include "renderer.h"
// wrapper for environment elements -- sky, sun, stars, clouds etc // wrapper for environment elements -- sky, sun, stars, clouds etc
class world_environment { class world_environment {
@@ -27,6 +27,7 @@ public:
void init(); void init();
void update(); void update();
void render(); void render();
void time( int const Hour = -1, int const Minute = -1, int const Second = -1 );
private: private:
CSkyDome m_skydome; CSkyDome m_skydome;
@@ -37,6 +38,9 @@ private:
class TWorld 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 InOutKey( bool const Near = true );
void FollowView(bool wycisz = true); void FollowView(bool wycisz = true);
void DistantView( bool const Near = false ); void DistantView( bool const Near = false );
@@ -53,6 +57,8 @@ class TWorld
void OnCommandGet(DaneRozkaz *pRozkaz); void OnCommandGet(DaneRozkaz *pRozkaz);
bool Update(); bool Update();
void TrainDelete(TDynamicObject *d = NULL); void TrainDelete(TDynamicObject *d = NULL);
// switches between static and dynamic daylight calculation
void ToggleDaylight();
TWorld(); TWorld();
~TWorld(); ~TWorld();
// double Aspect; // double Aspect;
@@ -63,27 +69,24 @@ class TWorld
std::string OutText4; std::string OutText4;
void Update_Environment(); void Update_Environment();
void Update_Camera( const double Deltatime ); void Update_Camera( const double Deltatime );
bool Render(); void Update_UI();
void ResourceSweep();
void Render_Cab(); void Render_Cab();
void Render_UI();
TCamera Camera; TCamera Camera;
TGround Ground; TGround Ground;
world_environment Environment; world_environment Environment;
TTrain *Train; TTrain *Train;
TDynamicObject *pDynamicNearest; TDynamicObject *pDynamicNearest;
bool Paused{ true }; 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 TEvent *KeyEvents[10]; // eventy wyzwalane z klawiaury
TMoverParameters *mvControlled; // wskaźnik na człon silnikowy, do wyświetlania jego parametrów 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 fTime50Hz; // bufor czasu dla komunikacji z PoKeys
double fTimeBuffer; // bufor czasu aktualizacji dla stałego kroku fizyki double fTimeBuffer; // bufor czasu aktualizacji dla stałego kroku fizyki
double fMaxDt; //[s] krok czasowy fizyki (0.01 dla normalnych warunków) double fMaxDt; //[s] krok czasowy fizyki (0.01 dla normalnych warunków)
double m_primaryupdaterate{ 1.0 / 100.0 }; 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_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 int iPause; // wykrywanie zmian w zapauzowaniu
double VelPrev; // poprzednia prędkość double VelPrev; // poprzednia prędkość
int tprev; // poprzedni czas int tprev; // poprzedni czas
@@ -94,6 +97,8 @@ class TWorld
void ModifyTGA(std::string const &dir = ""); void ModifyTGA(std::string const &dir = "");
void CreateE3D(std::string const &dir = "", bool dyn = false); void CreateE3D(std::string const &dir = "", bool dyn = false);
void CabChange(TDynamicObject *old, TDynamicObject *now); void CabChange(TDynamicObject *old, TDynamicObject *now);
// handles vehicle change flag
void ChangeDynamic();
gl_program_light shader; //m7todo: tmp gl_program_light shader; //m7todo: tmp
}; };

View File

@@ -11,15 +11,12 @@ http://mozilla.org/MPL/2.0/.
#include "frustum.h" #include "frustum.h"
void void
cFrustum::calculate() { cFrustum::calculate( glm::mat4 &Projection, glm::mat4 &Modelview ) {
float proj[ 16 ]; float *proj = &Projection[ 0 ][ 0 ];
float modl[ 16 ]; float *modl = &Modelview[ 0 ][ 0 ];
float clip[ 16 ]; float clip[ 16 ];
glGetFloatv( GL_PROJECTION_MATRIX, proj );
glGetFloatv( GL_MODELVIEW_MATRIX, modl );
// multiply the matrices to retrieve clipping planes // 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[ 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 ]; 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: // methods:
// update the frustum to match current view orientation // update the frustum to match current view orientation
void void
calculate(); calculate(glm::mat4 &Projection, glm::mat4 &Modelview);
// returns true if specified point is inside of the frustum // returns true if specified point is inside of the frustum
inline inline
bool bool

View File

@@ -46,12 +46,12 @@ light_array::update() {
// update light parameters to match current data of the owner // update light parameters to match current data of the owner
if( light.index == 0 ) { if( light.index == 0 ) {
// front light set // 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(); light.direction = light.owner->VectorFront();
} }
else { else {
// rear light set // 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 = light.owner->VectorFront();
light.direction.x = -light.direction.x; light.direction.x = -light.direction.x;
light.direction.z = -light.direction.z; light.direction.z = -light.direction.z;
@@ -68,7 +68,7 @@ light_array::update() {
if( light.count > 0 ) { if( light.count > 0 ) {
// TODO: intensity can be affected further by dim switch or other factors // 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 + 1.0f ) );
// light.intensity = std::max( 0.0f, std::log( (float)light.count + 3.0f ) ); light.intensity *= ( light.owner->DimHeadlights ? 0.6f : 1.0f );
} }
else { else {
light.intensity = 0.0f; 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 ); 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 ) { void cParser::addCommentStyle( std::string const &Commentstart, std::string const &Commentend ) {
mComments.insert( commentmap::value_type(Commentstart, 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 ;"); bool getTokens(unsigned int Count = 1, bool ToLower = true, const char *Break = "\n\r\t ;");
// returns percentage of file processed so far // returns percentage of file processed so far
int getProgress() const; 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 // add custom definition of text which should be ignored when retrieving tokens
void addCommentStyle( std::string const &Commentstart, std::string const &Commentend ); void addCommentStyle( std::string const &Commentstart, std::string const &Commentend );
@@ -91,6 +94,7 @@ class cParser //: public std::stringstream
// std::string trtest; // std::string trtest;
bool findQuotes( std::string &String ); bool findQuotes( std::string &String );
bool trimComments( std::string &String ); bool trimComments( std::string &String );
std::size_t count();
// members: // members:
bool LoadTraction; // load traction? bool LoadTraction; // load traction?
std::istream *mStream; // relevant kind of buffer is attached on creation. 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 This Source Code Form is subject to the
terms of the Mozilla Public License, v. terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not 2.0. If a copy of the MPL was not
@@ -8,16 +8,499 @@ http://mozilla.org/MPL/2.0/.
*/ */
#include "stdafx.h" #include "stdafx.h"
#include "renderer.h" #include "renderer.h"
#include "globals.h" #include "globals.h"
#include "World.h" #include "World.h"
#include "dynobj.h"
#include "uilayer.h"
#include "logs.h"
opengl_renderer GfxRenderer; opengl_renderer GfxRenderer;
extern TWorld World; extern TWorld World;
void // returns true if specified object is within camera frustum, false otherwise
opengl_renderer::Init() { 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 void
@@ -66,4 +549,35 @@ opengl_renderer::Disable_Lights() {
World.shader.set_light_count(0); 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 This Source Code Form is subject to the
terms of the Mozilla Public License, v. terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not 2.0. If a copy of the MPL was not
@@ -9,10 +9,13 @@ http://mozilla.org/MPL/2.0/.
#pragma once #pragma once
#include "GL/glew.h" #include <GL/glew.h>
#include "texture.h" #include "texture.h"
#include "lightarray.h" #include "lightarray.h"
#include "dumb3d.h" #include "dumb3d.h"
#include "frustum.h"
#include "ground.h"
#include "shader.h"
// encapsulates basic rendering setup. // encapsulates basic rendering setup.
// for modern opengl this translates to a specific collection of glsl shaders, // 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 // bare-bones render controller, in lack of anything better yet
class opengl_renderer { class opengl_renderer {
@@ -35,14 +56,40 @@ public:
// types // types
// methods // 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 void
Init(); Update( double const Deltatime);
void void
Update_Lights( light_array const &Lights ); Update_Lights( light_array const &Lights );
void void
Disable_Lights(); 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 texture_manager::size_type
GetTextureId( std::string Filename, std::string const &Dir, int const Filter = -1, bool const Loadnow = true ) { GetTextureId( std::string Filename, std::string const &Dir, int const Filter = -1, bool const Loadnow = true ) {
@@ -71,9 +118,18 @@ private:
color color
}; };
// methods
bool Init_caps();
// members // members
rendermode renderpass{ rendermode::color }; rendermode renderpass{ rendermode::color };
texture_manager m_textures; 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; extern opengl_renderer GfxRenderer;

View File

@@ -46,8 +46,13 @@ void TSky::Render( float3 const &Tint )
} }
else else
{ // renderowanie z Display List { // renderowanie z Display List
#ifdef EU07_USE_OLD_RENDERCODE
mdCloud->Render(100, 0); mdCloud->Render(100, 0);
mdCloud->RenderAlpha(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 #ifdef EU07_USE_OLD_LIGHTING_MODEL
glPopMatrix(); 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 ::glRotatef( -std::fmod( Global::fTimeAngleDeg, 360.0f ), 0.0f, 1.0f, 0.0f ); // obrót dobowy osi OX
::glPointSize( 2.0f ); ::glPointSize( 2.0f );
#ifdef EU07_USE_OLD_RENDERCODE
m_stars.Render( 1.0 ); m_stars.Render( 1.0 );
#else
GfxRenderer.Render( &m_stars, nullptr, 1.0 );
#endif
::glPointSize( 3.0f ); ::glPointSize( 3.0f );
::glPopMatrix(); ::glPopMatrix();

View File

@@ -60,10 +60,16 @@
#include <condition_variable> #include <condition_variable>
#include <typeinfo> #include <typeinfo>
#ifdef EU07_BUILD_STATIC
#define GLEW_STATIC
#else
#ifdef _WINDOWS
#define GLFW_DLL
#endif // _windows
#endif // build_static
#include "GL/glew.h" #include "GL/glew.h"
#ifdef _WINDOWS #ifdef _WINDOWS
#include "GL/wglew.h" #include "GL/wglew.h"
#define GLFW_DLL
#endif #endif
#define GLFW_INCLUDE_GLU #define GLFW_INCLUDE_GLU
//m7todo: jest tu bo nie chcia³o mi siê wpychaæ do wszystkich plików //m7todo: jest tu bo nie chcia³o mi siê wpychaæ do wszystkich plików
@@ -71,3 +77,7 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.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 "sun.h"
#include "globals.h" #include "globals.h"
#include "mtable.h" #include "mtable.h"
#include "usefull.h"
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// cSun -- class responsible for dynamic calculation of position and intensity of the Sun, // 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 ; 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 ) { void cSun::setTemperature( float const Temperature ) {
m_observer.temp = Temperature; m_observer.temp = Temperature;
@@ -112,6 +121,10 @@ void cSun::move() {
SYSTEMTIME localtime; // time for the calculation SYSTEMTIME localtime; // time for the calculation
time( &localtime ); 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 double ut = localtime.wHour
+ localtime.wMinute / 60.0 // too low resolution, noticeable skips + localtime.wMinute / 60.0 // too low resolution, noticeable skips
+ localtime.wSecond / 3600.0; // good enough in normal circumstances + localtime.wSecond / 3600.0; // good enough in normal circumstances

5
sun.h
View File

@@ -27,6 +27,8 @@ public:
float getAngle(); float getAngle();
// returns current intensity of the sun // returns current intensity of the sun
float getIntensity(); 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 // sets current geographic location
void setLocation( float const Longitude, float const Latitude ); void setLocation( float const Longitude, float const Latitude );
// sets ambient temperature in degrees C. // sets ambient temperature in degrees C.
@@ -87,6 +89,9 @@ protected:
double latitude; // latitude, degrees north (south negative) double latitude; // latitude, degrees north (south negative)
double longitude; // longitude, degrees east (west negative) double longitude; // longitude, degrees east (west negative)
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 utime; // universal (Greenwich) standard time
double timezone; // time zone, east (west negative). USA: Mountain = -7, Central = -6, etc. double timezone; // time zone, east (west negative). USA: Mountain = -7, Central = -6, etc.
double gmst; // Greenwich mean sidereal time, hours double gmst; // Greenwich mean sidereal time, hours

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;