mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-19 04:19:19 +02:00
merge
This commit is contained in:
@@ -57,6 +57,7 @@ set(SOURCES
|
||||
"sky.cpp"
|
||||
"sun.cpp"
|
||||
"stars.cpp"
|
||||
"lightarray.cpp"
|
||||
"skydome.cpp"
|
||||
"Sound.cpp"
|
||||
"Spring.cpp"
|
||||
|
||||
@@ -3758,12 +3758,14 @@ void TDynamicObject::Render()
|
||||
// double ObjDist= SquareMagnitude(Global::pCameraPosition-pos);
|
||||
if (this == Global::pUserDynamic)
|
||||
{ // specjalne ustawienie, aby nie trzęsło
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
if (Global::bSmudge)
|
||||
{ // jak jest widoczna smuga, to pojazd renderować po
|
||||
// wyrenderowaniu smugi
|
||||
glPopMatrix(); // a to trzeba zebrać przed wyjściem
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// if (Global::pWorld->) //tu trzeba by ustawić animacje na modelu
|
||||
// zewnętrznym
|
||||
glLoadIdentity(); // zacząć od macierzy jedynkowej
|
||||
|
||||
6
DynObj.h
6
DynObj.h
@@ -420,7 +420,7 @@ public: // modele składowe pojazdu
|
||||
void Render();
|
||||
void RenderAlpha();
|
||||
void RenderSounds();
|
||||
inline vector3 GetPosition()
|
||||
inline vector3 GetPosition() const
|
||||
{
|
||||
return vPosition;
|
||||
};
|
||||
@@ -436,7 +436,7 @@ public: // modele składowe pojazdu
|
||||
{
|
||||
return iAxleFirst ? Axle1.pPosition : Axle0.pPosition;
|
||||
};
|
||||
inline vector3 VectorFront()
|
||||
inline vector3 VectorFront() const
|
||||
{
|
||||
return vFront;
|
||||
};
|
||||
@@ -456,7 +456,7 @@ public: // modele składowe pojazdu
|
||||
{
|
||||
return MoverParameters->Vel;
|
||||
};
|
||||
inline double GetLength()
|
||||
inline double GetLength() const
|
||||
{
|
||||
return MoverParameters->Dim.L;
|
||||
};
|
||||
|
||||
@@ -79,6 +79,11 @@ inline float DotProduct( float3 const &v1, float3 const &v2 ) {
|
||||
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
|
||||
}
|
||||
|
||||
inline float3 Interpolate( float3 const &First, float3 const &Second, float const Factor ) {
|
||||
|
||||
return ( First * ( 1.0f - Factor ) ) + ( Second * Factor );
|
||||
}
|
||||
|
||||
class float4
|
||||
{ // kwaternion obrotu
|
||||
public:
|
||||
|
||||
10
Globals.cpp
10
Globals.cpp
@@ -104,6 +104,7 @@ GLfloat Global::diffuseLight[] = {0.85f, 0.85f, 0.80f, 1.0f};
|
||||
GLfloat Global::specularLight[] = {0.95f, 0.94f, 0.90f, 1.0f};
|
||||
#else
|
||||
opengl_light Global::DayLight;
|
||||
int Global::DynamicLightCount{ 3 };
|
||||
#endif
|
||||
GLfloat Global::whiteLight[] = {1.00f, 1.00f, 1.00f, 1.0f};
|
||||
GLfloat Global::noLight[] = {0.00f, 0.00f, 0.00f, 1.0f};
|
||||
@@ -575,7 +576,14 @@ void Global::ConfigParse(cParser &Parser)
|
||||
std::tm *localtime = std::localtime(&timenow);
|
||||
Global::fMoveLight = localtime->tm_yday + 1; // numer bieżącego dnia w roku
|
||||
}
|
||||
// TODO: calculate lights single time here for static setup. or get rid of static setup
|
||||
}
|
||||
else if( token == "dynamiclights" ) {
|
||||
// number of dynamic lights in the scene
|
||||
Parser.getTokens( 1, false );
|
||||
Parser >> Global::DynamicLightCount;
|
||||
// clamp the light number
|
||||
Global::DynamicLightCount = std::min( 7, Global::DynamicLightCount ); // max 8 lights per opengl specs, and one used for sun
|
||||
Global::DynamicLightCount = std::max( 1, Global::DynamicLightCount ); // at least one light for controlled vehicle
|
||||
}
|
||||
else if (token == "smoothtraction")
|
||||
{
|
||||
|
||||
@@ -232,7 +232,9 @@ class Global
|
||||
static GLfloat diffuseLight[];
|
||||
static GLfloat specularLight[];
|
||||
#else
|
||||
// TODO: put these things in the renderer
|
||||
static opengl_light DayLight;
|
||||
static int DynamicLightCount;
|
||||
#endif
|
||||
static GLfloat whiteLight[];
|
||||
static GLfloat noLight[];
|
||||
|
||||
101
Ground.cpp
101
Ground.cpp
@@ -1834,29 +1834,20 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
||||
case TP_DYNAMIC:
|
||||
tmp->DynamicObject = new TDynamicObject();
|
||||
// tmp->DynamicObject->Load(Parser);
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str1 = token; // katalog
|
||||
// McZapkie: doszedl parametr ze zmienialna skora
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
Skin = token; // tekstura wymienna
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str3 = token; // McZapkie-131102: model w MMD
|
||||
parser->getTokens(3);
|
||||
*parser
|
||||
>> str1 // katalog
|
||||
>> Skin // tekstura wymienna
|
||||
>> str3; // McZapkie-131102: model w MMD
|
||||
if (bTrainSet)
|
||||
{ // jeśli pojazd jest umieszczony w składzie
|
||||
str = asTrainSetTrack;
|
||||
parser->getTokens();
|
||||
*parser >> tf1; // Ra: -1 oznacza odwrotne wstawienie, normalnie w składzie 0
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
DriverType = token; // McZapkie:010303 - w przyszlosci rozne
|
||||
// konfiguracje mechanik/pomocnik itp
|
||||
parser->getTokens(3);
|
||||
*parser
|
||||
>> tf1 // Ra: -1 oznacza odwrotne wstawienie, normalnie w składzie 0
|
||||
>> DriverType // McZapkie:010303 - w przyszlosci rozne konfiguracje mechanik/pomocnik itp
|
||||
>> str4;
|
||||
tf3 = fTrainSetVel; // prędkość
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str4 = token;
|
||||
int2 = str4.find("."); // yB: wykorzystuje tutaj zmienna, ktora potem bedzie ladunkiem
|
||||
if (int2 != string::npos) // yB: jesli znalazl kropke, to ja przetwarza jako parametry
|
||||
{
|
||||
@@ -1885,17 +1876,12 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
||||
fTrainSetDist = 0; // zerowanie dodatkowego przesunięcia
|
||||
asTrainName = ""; // puste oznacza jazdę pojedynczego bez rozkładu, "none" jest dla
|
||||
// składu (trainset)
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str = token; // track
|
||||
parser->getTokens();
|
||||
*parser >> tf1; // Ra: -1 oznacza odwrotne wstawienie
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
DriverType = token; // McZapkie:010303: obsada
|
||||
parser->getTokens();
|
||||
*parser >>
|
||||
tf3; // prędkość, niektórzy wpisują tu "3" jako sprzęg, żeby nie było tabliczki
|
||||
parser->getTokens(4);
|
||||
*parser
|
||||
>> str // track
|
||||
>> tf1 // Ra: -1 oznacza odwrotne wstawienie
|
||||
>> DriverType // McZapkie:010303: obsada
|
||||
>> tf3; // prędkość, niektórzy wpisują tu "3" jako sprzęg, żeby nie było tabliczki
|
||||
iTrainSetWehicleNumber = 0;
|
||||
TempConnectionType[iTrainSetWehicleNumber] = 3; // likwidacja tabliczki na końcu?
|
||||
}
|
||||
@@ -1904,8 +1890,7 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
||||
if (int2 > 0)
|
||||
{ // jeżeli ładunku jest więcej niż 0, to rozpoznajemy jego typ
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str2 = token; // LoadType
|
||||
*parser >> str2; // LoadType
|
||||
if (str2 == "enddynamic") // idiotoodporność: ładunek bez podanego typu
|
||||
{
|
||||
str2 = "";
|
||||
@@ -1979,6 +1964,16 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
||||
}
|
||||
if (token.compare("enddynamic") != 0)
|
||||
Error("enddynamic statement missing");
|
||||
/*
|
||||
if( tmp->DynamicObject->MoverParameters->LightPowerSource.SourceType != TPowerSource::NotDefined ) {
|
||||
// if the vehicle has defined light source, it can (potentially) emit light, so add it to the light array
|
||||
*/
|
||||
if( tmp->DynamicObject->MoverParameters->SecuritySystem.SystemType != 0 ) {
|
||||
// we check for presence of security system, as a way to determine whether the vehicle is a controllable engine
|
||||
// NOTE: this isn't 100% precise, e.g. middle EZT module comes with security system, while it has no lights
|
||||
m_lights.insert( tmp->DynamicObject );
|
||||
}
|
||||
|
||||
break;
|
||||
case TP_MODEL:
|
||||
if (rmin < 0)
|
||||
@@ -4544,6 +4539,25 @@ bool TGround::Update(double dt, int iter)
|
||||
return true;
|
||||
};
|
||||
|
||||
// updates scene lights array
|
||||
void
|
||||
TGround::Update_Lights() {
|
||||
|
||||
m_lights.update();
|
||||
// arrange the light array from closest to farthest from current position of the camera
|
||||
auto const camera = Global::pCameraPosition;
|
||||
std::sort(
|
||||
m_lights.data.begin(),
|
||||
m_lights.data.end(),
|
||||
[&]( light_array::light_record const &Left, light_array::light_record const &Right ) {
|
||||
// move lights which are off at the end...
|
||||
if( Left.intensity == 0.0f ) { return false; }
|
||||
if( Right.intensity == 0.0f ) { return true; }
|
||||
// ...otherwise prefer closer and/or brigher light sources
|
||||
return ((camera - Left.position).LengthSquared() * (1.0f - Left.intensity)) < ((camera - Right.position).LengthSquared() * (1.0f - Right.intensity));
|
||||
} );
|
||||
}
|
||||
|
||||
// Winger 170204 - szukanie trakcji nad pantografami
|
||||
bool TGround::GetTraction(TDynamicObject *model)
|
||||
{ // aktualizacja drutu zasilającego dla każdego pantografu, żeby odczytać napięcie
|
||||
@@ -4794,6 +4808,27 @@ bool TGround::GetTraction(TDynamicObject *model)
|
||||
return true;
|
||||
};
|
||||
|
||||
bool
|
||||
TGround::Render( Math3D::vector3 const &Camera ) {
|
||||
|
||||
GfxRenderer.Update_Lights( m_lights );
|
||||
|
||||
if( Global::bUseVBO ) { // renderowanie przez VBO
|
||||
if( !RenderVBO( Camera ) )
|
||||
return false;
|
||||
if( !RenderAlphaVBO( Camera ) )
|
||||
return false;
|
||||
}
|
||||
else { // renderowanie przez Display List
|
||||
if( !RenderDL( Camera ) )
|
||||
return false;
|
||||
if( !RenderAlphaDL( Camera ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TGround::RenderDL(vector3 pPosition)
|
||||
{ // renderowanie scenerii z Display List - faza nieprzezroczystych
|
||||
glDisable(GL_BLEND);
|
||||
@@ -5330,6 +5365,8 @@ void TGround::DynamicRemove(TDynamicObject *dyn)
|
||||
node = (*n); // zapamiętanie węzła, aby go usunąć
|
||||
(*n) = node->nNext; // pominięcie na liście
|
||||
Global::TrainDelete(d);
|
||||
// remove potential entries in the light array
|
||||
m_lights.remove( d );
|
||||
d = d->Next(); // przejście do kolejnego pojazdu, póki jeszcze jest
|
||||
delete node; // usuwanie fizyczne z pamięci
|
||||
}
|
||||
|
||||
8
Ground.h
8
Ground.h
@@ -16,7 +16,9 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "ResourceManager.h"
|
||||
#include "Texture.h"
|
||||
#include "dumb3d.h"
|
||||
#include "Float3d.h"
|
||||
#include "Names.h"
|
||||
#include "lightarray.h"
|
||||
|
||||
using namespace Math3D;
|
||||
|
||||
@@ -303,11 +305,11 @@ class TGround
|
||||
TNames *sTracks = nullptr; // posortowane nazwy torów i eventów
|
||||
#else
|
||||
typedef std::unordered_map<std::string, TEvent *> event_map;
|
||||
// typedef std::unordered_map<std::string, TGroundNode *> groundnode_map;
|
||||
event_map m_eventmap;
|
||||
// groundnode_map m_memcellmap, m_modelmap, m_trackmap;
|
||||
TNames<TGroundNode *> m_trackmap;
|
||||
#endif
|
||||
light_array m_lights; // collection of dynamic light sources present in the scene
|
||||
|
||||
private: // metody prywatne
|
||||
bool EventConditon(TEvent *e);
|
||||
|
||||
@@ -350,8 +352,10 @@ class TGround
|
||||
void MoveGroundNode(vector3 pPosition);
|
||||
void UpdatePhys(double dt, int iter); // aktualizacja fizyki stałym krokiem
|
||||
bool Update(double dt, int iter); // aktualizacja przesunięć zgodna z FPS
|
||||
void Update_Lights(); // updates scene lights array
|
||||
bool AddToQuery(TEvent *Event, TDynamicObject *Node);
|
||||
bool GetTraction(TDynamicObject *model);
|
||||
bool Render( Math3D::vector3 const &Camera );
|
||||
bool RenderDL(vector3 pPosition);
|
||||
bool RenderAlphaDL(vector3 pPosition);
|
||||
bool RenderVBO(vector3 pPosition);
|
||||
|
||||
75
Model3d.cpp
75
Model3d.cpp
@@ -207,43 +207,44 @@ inline void readMatrix(cParser &parser, float4x4 &matrix)
|
||||
|
||||
int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
|
||||
{ // Ra: VBO tworzone na poziomie modelu, a nie submodeli
|
||||
iNumVerts = 0;
|
||||
iVboPtr = Pos; // pozycja w VBO
|
||||
// TMaterialColorf Ambient,Diffuse,Specular;
|
||||
// GLuint TextureID;
|
||||
// char *extName;
|
||||
if (!parser.expectToken("type:"))
|
||||
Error("Model type parse failure!");
|
||||
{
|
||||
std::string type = parser.getToken<std::string>();
|
||||
if (type == "mesh")
|
||||
eType = GL_TRIANGLES; // submodel - trójkaty
|
||||
else if (type == "point")
|
||||
eType = GL_POINTS; // co to niby jest?
|
||||
else if (type == "freespotlight")
|
||||
eType = TP_FREESPOTLIGHT; //światełko
|
||||
else if (type == "text")
|
||||
eType = TP_TEXT; // wyświetlacz tekstowy (generator napisów)
|
||||
else if (type == "stars")
|
||||
eType = TP_STARS; // wiele punktów świetlnych
|
||||
};
|
||||
parser.ignoreToken();
|
||||
std::string token;
|
||||
// parser.getToken(token1); //ze zmianą na małe!
|
||||
parser.getTokens(1, false); // nazwa submodelu bez zmieny na małe
|
||||
parser >> token;
|
||||
NameSet(token.c_str());
|
||||
if (dynamic)
|
||||
{ // dla pojazdu, blokujemy załączone submodele, które mogą być
|
||||
// nieobsługiwane
|
||||
if (token.find("_on") + 3 == token.length()) // jeśli nazwa kończy się na "_on"
|
||||
iVisible = 0; // to domyślnie wyłączyć, żeby się nie nakładało z obiektem "_off"
|
||||
}
|
||||
else // dla pozostałych modeli blokujemy zapalone światła, które mogą być
|
||||
// nieobsługiwane
|
||||
if (token.compare(0, 8, "Light_On") == 0) // jeśli nazwa zaczyna się od "Light_On"
|
||||
iVisible = 0; // to domyślnie wyłączyć, żeby się nie nakładało z obiektem
|
||||
// "Light_Off"
|
||||
iNumVerts = 0;
|
||||
iVboPtr = Pos; // pozycja w VBO
|
||||
// TMaterialColorf Ambient,Diffuse,Specular;
|
||||
// GLuint TextureID;
|
||||
// char *extName;
|
||||
if (!parser.expectToken("type:"))
|
||||
Error("Model type parse failure!");
|
||||
{
|
||||
std::string type = parser.getToken<std::string>();
|
||||
if (type == "mesh")
|
||||
eType = GL_TRIANGLES; // submodel - trójkaty
|
||||
else if (type == "point")
|
||||
eType = GL_POINTS; // co to niby jest?
|
||||
else if (type == "freespotlight")
|
||||
eType = TP_FREESPOTLIGHT; //światełko
|
||||
else if (type == "text")
|
||||
eType = TP_TEXT; // wyświetlacz tekstowy (generator napisów)
|
||||
else if (type == "stars")
|
||||
eType = TP_STARS; // wiele punktów świetlnych
|
||||
};
|
||||
parser.ignoreToken();
|
||||
std::string token;
|
||||
// parser.getToken(token1); //ze zmianą na małe!
|
||||
parser.getTokens(1, false); // nazwa submodelu bez zmieny na małe
|
||||
parser >> token;
|
||||
NameSet(token.c_str());
|
||||
if (dynamic)
|
||||
{ // dla pojazdu, blokujemy załączone submodele, które mogą być
|
||||
// nieobsługiwane
|
||||
if ( (token.size() >= 3)
|
||||
&& (token.find("_on") + 3 == token.length())) // jeśli nazwa kończy się na "_on"
|
||||
iVisible = 0; // to domyślnie wyłączyć, żeby się nie nakładało z obiektem "_off"
|
||||
}
|
||||
else // dla pozostałych modeli blokujemy zapalone światła, które mogą być
|
||||
// nieobsługiwane
|
||||
if (token.compare(0, 8, "Light_On") == 0) // jeśli nazwa zaczyna się od "Light_On"
|
||||
iVisible = 0; // to domyślnie wyłączyć, żeby się nie nakładało z obiektem
|
||||
// "Light_Off"
|
||||
|
||||
if (parser.expectToken("anim:")) // Ra: ta informacja by się przydała!
|
||||
{ // rodzaj animacji
|
||||
|
||||
95
Segment.cpp
95
Segment.cpp
@@ -21,6 +21,11 @@ http://mozilla.org/MPL/2.0/.
|
||||
// 101206 Ra: trapezoidalne drogi
|
||||
// 110806 Ra: odwrócone mapowanie wzdłuż - Point1 == 1.0
|
||||
|
||||
float Interpolate( float const First, float const Second, float const Factor ) {
|
||||
|
||||
return ( First * ( 1.0f - Factor ) ) + ( Second * Factor );
|
||||
}
|
||||
|
||||
std::string Where(vector3 p)
|
||||
{ // zamiana współrzędnych na tekst, używana w błędach
|
||||
return std::to_string(p.x) + " " + std::to_string(p.y) + " " + std::to_string(p.z);
|
||||
@@ -116,7 +121,11 @@ bool TSegment::Init(vector3 &NewPoint1, vector3 NewCPointOut, vector3 NewCPointI
|
||||
fStoop = atan2((Point2.y - Point1.y),
|
||||
fLength); // pochylenie toru prostego, żeby nie liczyć wielokrotnie
|
||||
SafeDeleteArray(fTsBuffer);
|
||||
/*
|
||||
if ((bCurve) && (fStep > 0))
|
||||
*/
|
||||
// we're enforcing sub-division of even straight track, to have dense enough mesh for the spotlight to work with
|
||||
if( fStep > 0 )
|
||||
{ // Ra: prosty dostanie podział, jak ma różną przechyłkę na końcach
|
||||
double s = 0;
|
||||
int i = 0;
|
||||
@@ -454,6 +463,7 @@ void TSegment::RenderLoft(const vector6 *ShapePoints, int iNumShapePoints, doubl
|
||||
}
|
||||
}
|
||||
else
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
{ // gdy prosty, nie modyfikujemy wektora kierunkowego i poprzecznego
|
||||
pos1 = FastGetPoint((fStep * iSkip) / fLength);
|
||||
pos2 = FastGetPoint_1();
|
||||
@@ -498,6 +508,91 @@ void TSegment::RenderLoft(const vector6 *ShapePoints, int iNumShapePoints, doubl
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
#else
|
||||
{
|
||||
Math3D::vector3 const pos0 = FastGetPoint( ( fStep * iSkip ) / fLength );
|
||||
Math3D::vector3 const pos1 = FastGetPoint_1();
|
||||
dir = GetDirection();
|
||||
Math3D::vector3 const parallel = Normalize( vector3( -dir.z, 0.0, dir.x ) ); // wektor poprzeczny
|
||||
|
||||
Math3D::vector3 startnormal0, startnormal1, endnormal0, endnormal1;
|
||||
Math3D::vector3 startvertex0, startvertex1, endvertex0, endvertex1;
|
||||
float startuv0, startuv1, enduv0, enduv1;
|
||||
|
||||
for( j = 0; j < iNumShapePoints - 1; ++j ) {
|
||||
|
||||
startnormal0 = ShapePoints[ j ].n.x * parallel;
|
||||
startnormal0.y += ShapePoints[ j ].n.y;
|
||||
startvertex0 = parallel * ShapePoints[ j ].x + pos0;
|
||||
startvertex0.y += ShapePoints[ j ].y;
|
||||
startuv0 = ShapePoints[ j ].z;
|
||||
startnormal1 = ShapePoints[ j + 1 ].n.x * parallel;
|
||||
startnormal1.y += ShapePoints[ j + 1 ].n.y;
|
||||
startvertex1 = parallel * ShapePoints[ j + 1 ].x + pos0;
|
||||
startvertex1.y += ShapePoints[ j + 1 ].y;
|
||||
startuv1 = ShapePoints[ j + 1 ].z;
|
||||
|
||||
if( trapez == false ) {
|
||||
// single profile throughout
|
||||
endnormal0 = startnormal0;
|
||||
endvertex0 = startvertex0 + ( pos1 - pos0 );
|
||||
enduv0 = startuv0;
|
||||
endnormal1 = startnormal1;
|
||||
endvertex1 = startvertex1 + ( pos1 - pos0 );
|
||||
enduv1 = startuv1;
|
||||
}
|
||||
else {
|
||||
// end profile is different
|
||||
endnormal0 = ShapePoints[ j + iNumShapePoints ].n.x * parallel;
|
||||
endnormal0.y += ShapePoints[ j + iNumShapePoints ].n.y;
|
||||
endvertex0 = parallel * ShapePoints[ j + iNumShapePoints ].x + pos1; // odsunięcie
|
||||
endvertex0.y += ShapePoints[ j + iNumShapePoints ].y; // wysokość
|
||||
enduv0 = ShapePoints[ j + iNumShapePoints ].z;
|
||||
endnormal1 = ShapePoints[ j + iNumShapePoints + 1 ].n.x * parallel;
|
||||
endnormal1.y += ShapePoints[ j + iNumShapePoints + 1 ].n.y;
|
||||
endvertex1 = parallel * ShapePoints[ j + iNumShapePoints + 1 ].x + pos1; // odsunięcie
|
||||
endvertex1.y += ShapePoints[ j + iNumShapePoints + 1 ].y; // wysokość
|
||||
enduv1 = ShapePoints[ j + iNumShapePoints + 1 ].z;
|
||||
}
|
||||
// now build strips, lerping from start to endpoint
|
||||
step = 10.0; // arbitrary segment size for straights
|
||||
float s = 0.0,
|
||||
t = 0.0,
|
||||
uv = 0.0;
|
||||
glBegin( GL_TRIANGLE_STRIP );
|
||||
while( s < fLength ) {
|
||||
|
||||
t = s / fLength;
|
||||
uv = s / fTextureLength;
|
||||
|
||||
auto const normal1lerp = Interpolate( startnormal1, endnormal1, t );
|
||||
glNormal3dv( &normal1lerp.x );
|
||||
auto const uv1lerp = Interpolate( startuv1, enduv1, t );
|
||||
glTexCoord2f( uv1lerp, uv );
|
||||
auto const vertex1lerp = Interpolate( startvertex1, endvertex1, t );
|
||||
glVertex3dv( &vertex1lerp.x );
|
||||
|
||||
auto const normal0lerp = Interpolate( startnormal0, endnormal0, t );
|
||||
glNormal3dv( &normal0lerp.x );
|
||||
auto const uv0lerp = Interpolate( startuv0, enduv0, t );
|
||||
glTexCoord2f( uv0lerp, uv );
|
||||
auto const vertex0lerp = Interpolate( startvertex0, endvertex0, t );
|
||||
glVertex3dv( &vertex0lerp.x );
|
||||
|
||||
s += step;
|
||||
}
|
||||
// add ending vertex pair if needed
|
||||
glNormal3dv( &endnormal1.x );
|
||||
glTexCoord2f( enduv1, fLength / fTextureLength );
|
||||
glVertex3dv( &endvertex1.x );
|
||||
glNormal3dv( &endnormal0.x );
|
||||
glTexCoord2f( enduv0, fLength / fTextureLength );
|
||||
glVertex3dv( &endvertex0.x );
|
||||
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
void TSegment::RenderSwitchRail(const vector6 *ShapePoints1, const vector6 *ShapePoints2,
|
||||
|
||||
340
World.cpp
340
World.cpp
@@ -251,89 +251,34 @@ bool TWorld::Init(GLFWwindow *w)
|
||||
WriteLog("Max texture size: " + std::to_string(Global::iMaxTextureSize));
|
||||
}
|
||||
/*-----------------------Render Initialization----------------------*/
|
||||
if (Global::fOpenGL >= 1.2) // poniższe nie działa w 1.1
|
||||
glTexEnvf(TEXTURE_FILTER_CONTROL_EXT, TEXTURE_LOD_BIAS_EXT, -1);
|
||||
GLfloat FogColor[] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear screen and depth buffer
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
// WriteLog("glClearColor (FogColor[0], FogColor[1], FogColor[2], 0.0); ");
|
||||
// glClearColor (1.0, 0.0, 0.0, 0.0); // Background Color
|
||||
// glClearColor (FogColor[0], FogColor[1], FogColor[2], 0.0);
|
||||
// Background // Color
|
||||
glClearColor(Global::Background[0], Global::Background[1], Global::Background[2], 1.0); // Background Color
|
||||
|
||||
WriteLog("glFogfv(GL_FOG_COLOR, FogColor);");
|
||||
glFogfv(GL_FOG_COLOR, FogColor); // Set Fog Color
|
||||
glClearDepth( 1.0f ); // ZBuffer Value
|
||||
glClearColor( 51.0f / 255.0f, 106.0f / 255.0f, 85.0f / 255.0f, 1.0f ); // Background Color
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // Clear screen and depth buffer
|
||||
|
||||
WriteLog("glClearDepth(1.0f); ");
|
||||
glClearDepth(1.0f); // ZBuffer Value
|
||||
|
||||
// glEnable(GL_NORMALIZE);
|
||||
// glEnable(GL_RESCALE_NORMAL);
|
||||
|
||||
// glEnable(GL_CULL_FACE);
|
||||
WriteLog("glEnable(GL_TEXTURE_2D);");
|
||||
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
|
||||
WriteLog("glShadeModel(GL_SMOOTH);");
|
||||
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
|
||||
WriteLog("glEnable(GL_DEPTH_TEST);");
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
// McZapkie:261102-uruchomienie polprzezroczystosci (na razie linie) pod kierunkiem Marcina
|
||||
// if (Global::bRenderAlpha) //Ra: wywalam tę flagę
|
||||
{
|
||||
WriteLog("glEnable(GL_BLEND);");
|
||||
glEnable(GL_BLEND);
|
||||
WriteLog("glEnable(GL_ALPHA_TEST);");
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
WriteLog("glAlphaFunc(GL_GREATER,0.04);");
|
||||
glAlphaFunc(GL_GREATER, 0.04f);
|
||||
WriteLog("glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);");
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
WriteLog("glDepthFunc(GL_LEQUAL);");
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
}
|
||||
/*
|
||||
else
|
||||
{
|
||||
WriteLog("glEnable(GL_ALPHA_TEST);");
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
WriteLog("glAlphaFunc(GL_GREATER,0.5);");
|
||||
glAlphaFunc(GL_GREATER,0.5);
|
||||
WriteLog("glDepthFunc(GL_LEQUAL);");
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
WriteLog("glDisable(GL_BLEND);");
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
*/
|
||||
/* zakomentowanie to co bylo kiedys mieszane
|
||||
WriteLog("glEnable(GL_ALPHA_TEST);");
|
||||
glEnable(GL_ALPHA_TEST);//glGetIntegerv()
|
||||
WriteLog("glAlphaFunc(GL_GREATER,0.5);");
|
||||
// glAlphaFunc(GL_LESS,0.5);
|
||||
glAlphaFunc(GL_GREATER,0.5);
|
||||
// glBlendFunc(GL_SRC_ALPHA,GL_ONE);
|
||||
WriteLog("glDepthFunc(GL_LEQUAL);");
|
||||
glDepthFunc(GL_LEQUAL);//EQUAL);
|
||||
// The Type Of Depth Testing To Do
|
||||
// glEnable(GL_BLEND);
|
||||
// glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
*/
|
||||
|
||||
WriteLog("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);");
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
|
||||
|
||||
WriteLog("glPolygonMode(GL_FRONT, GL_FILL);");
|
||||
glPolygonMode(GL_FRONT, GL_FILL);
|
||||
WriteLog("glFrontFace(GL_CCW);");
|
||||
glFrontFace(GL_CCW); // Counter clock-wise polygons face out
|
||||
WriteLog("glEnable(GL_CULL_FACE); ");
|
||||
glEnable(GL_CULL_FACE); // Cull back-facing triangles
|
||||
WriteLog("glLineWidth(1.0f);");
|
||||
glLineWidth(1.0f);
|
||||
// glLineWidth(2.0f);
|
||||
WriteLog("glPointSize(3.0f);");
|
||||
glPointSize(3.0f);
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
// ----------- LIGHTING SETUP -----------
|
||||
@@ -365,35 +310,18 @@ bool TWorld::Init(GLFWwindow *w)
|
||||
glEnable(GL_LIGHT0);
|
||||
#endif
|
||||
// glColor() ma zmieniać kolor wybrany w glColorMaterial()
|
||||
WriteLog("glEnable(GL_COLOR_MATERIAL);");
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
|
||||
WriteLog("glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);");
|
||||
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
|
||||
glColor4fv(Global::whiteLight);
|
||||
|
||||
// WriteLog("glMaterialfv( GL_FRONT, GL_AMBIENT, whiteLight );");
|
||||
// glMaterialfv( GL_FRONT, GL_AMBIENT, Global::whiteLight );
|
||||
|
||||
WriteLog("glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, whiteLight );");
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, Global::whiteLight);
|
||||
|
||||
/*
|
||||
WriteLog("glMaterialfv( GL_FRONT, GL_SPECULAR, noLight );");
|
||||
glMaterialfv( GL_FRONT, GL_SPECULAR, Global::noLight );
|
||||
*/
|
||||
|
||||
WriteLog("glEnable(GL_LIGHTING);");
|
||||
glEnable(GL_LIGHTING);
|
||||
|
||||
WriteLog("glFogi(GL_FOG_MODE, GL_LINEAR);");
|
||||
glFogi(GL_FOG_MODE, GL_LINEAR); // Fog Mode
|
||||
WriteLog("glFogfv(GL_FOG_COLOR, FogColor);");
|
||||
GLfloat FogColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
glFogfv(GL_FOG_COLOR, FogColor); // Set Fog Color
|
||||
WriteLog("glFogf(GL_FOG_START, 1000.0f);");
|
||||
glFogf(GL_FOG_START, 10.0f); // Fog Start Depth
|
||||
WriteLog("glFogf(GL_FOG_END, 2000.0f);");
|
||||
glFogf(GL_FOG_END, 200.0f); // Fog End Depth
|
||||
WriteLog("glEnable(GL_FOG);");
|
||||
glEnable(GL_FOG); // Enables GL_FOG
|
||||
|
||||
// Ra: ustawienia testowe
|
||||
@@ -456,7 +384,7 @@ bool TWorld::Init(GLFWwindow *w)
|
||||
|
||||
glLoadIdentity();
|
||||
// glColor4f(0.3f,0.0f,0.0f,0.0f);
|
||||
glTranslatef(0.0f, 0.0f, -0.50f);
|
||||
// glTranslatef(0.0f, 0.0f, -0.50f);
|
||||
// glRasterPos2f(-0.25f, -0.10f);
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
glColor3f( 3.0f, 3.0f, 3.0f );
|
||||
@@ -467,23 +395,25 @@ bool TWorld::Init(GLFWwindow *w)
|
||||
auto logo = GfxRenderer.GetTextureId( "logo", szTexturePath, 6 );
|
||||
GfxRenderer.Bind(logo); // Select our texture
|
||||
|
||||
float const widthratio = ( 4.0f / 3.0f ) / ( (float)Global::iWindowWidth / Global::iWindowHeight );
|
||||
|
||||
glBegin(GL_QUADS); // Drawing using triangles
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex3f(-1.0f, -1.0f, 0.0f); // bottom left of the texture and quad
|
||||
glVertex2f( -widthratio, -1.0f ); // bottom left of the texture and quad
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glVertex3f(1.0f, -1.0f, 0.0f); // bottom right of the texture and quad
|
||||
glVertex2f(widthratio, -1.0f); // bottom right of the texture and quad
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex3f(1.0f, 1.0f, 0.0f); // top right of the texture and quad
|
||||
glVertex2f(widthratio, 1.0f); // top right of the texture and quad
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glVertex3f(-1.0f, 1.0f, 0.0f); // top left of the texture and quad
|
||||
glVertex2f( -widthratio, 1.0f ); // top left of the texture and quad
|
||||
glEnd();
|
||||
//~logo; Ra: to jest bez sensu zapis
|
||||
glColor3f(0.0f, 0.0f, 1.0f);
|
||||
if (Global::detonatoryOK)
|
||||
{
|
||||
glRasterPos2f(-0.85f, -0.25f);
|
||||
glRasterPos2f(-0.85f * widthratio, -0.25f);
|
||||
glPrint("Uruchamianie / Initializing...");
|
||||
glRasterPos2f(-0.85f, -0.30f);
|
||||
glRasterPos2f(-0.85f * widthratio, -0.30f);
|
||||
glPrint("Dzwiek / Sound...");
|
||||
}
|
||||
glfwSwapBuffers(window);
|
||||
@@ -496,7 +426,7 @@ bool TWorld::Init(GLFWwindow *w)
|
||||
WriteLog("Sound Init OK");
|
||||
if (Global::detonatoryOK)
|
||||
{
|
||||
glRasterPos2f(-0.25f, -0.30f);
|
||||
glRasterPos2f(-0.25f * widthratio, -0.30f);
|
||||
glPrint("OK.");
|
||||
}
|
||||
|
||||
@@ -506,7 +436,7 @@ bool TWorld::Init(GLFWwindow *w)
|
||||
WriteLog("Textures init");
|
||||
if (Global::detonatoryOK)
|
||||
{
|
||||
glRasterPos2f(-0.85f, -0.35f);
|
||||
glRasterPos2f(-0.85f * widthratio, -0.35f);
|
||||
glPrint("Tekstury / Textures...");
|
||||
}
|
||||
glfwSwapBuffers(window);
|
||||
@@ -514,7 +444,7 @@ bool TWorld::Init(GLFWwindow *w)
|
||||
WriteLog("Textures init OK");
|
||||
if (Global::detonatoryOK)
|
||||
{
|
||||
glRasterPos2f(-0.25f, -0.35f);
|
||||
glRasterPos2f( -0.25f * widthratio, -0.35f );
|
||||
glPrint("OK.");
|
||||
}
|
||||
glfwSwapBuffers(window);
|
||||
@@ -522,7 +452,7 @@ bool TWorld::Init(GLFWwindow *w)
|
||||
WriteLog("Models init");
|
||||
if (Global::detonatoryOK)
|
||||
{
|
||||
glRasterPos2f(-0.85f, -0.40f);
|
||||
glRasterPos2f( -0.85f * widthratio, -0.40f );
|
||||
glPrint("Modele / Models...");
|
||||
}
|
||||
glfwSwapBuffers(window);
|
||||
@@ -532,7 +462,7 @@ bool TWorld::Init(GLFWwindow *w)
|
||||
WriteLog("Models init OK");
|
||||
if (Global::detonatoryOK)
|
||||
{
|
||||
glRasterPos2f(-0.25f, -0.40f);
|
||||
glRasterPos2f( -0.25f * widthratio, -0.40f );
|
||||
glPrint("OK.");
|
||||
}
|
||||
glfwSwapBuffers(window);
|
||||
@@ -540,7 +470,7 @@ bool TWorld::Init(GLFWwindow *w)
|
||||
WriteLog("Ground init");
|
||||
if (Global::detonatoryOK)
|
||||
{
|
||||
glRasterPos2f(-0.85f, -0.45f);
|
||||
glRasterPos2f( -0.85f * widthratio, -0.45f );
|
||||
glPrint("Sceneria / Scenery (please wait)...");
|
||||
}
|
||||
glfwSwapBuffers(window);
|
||||
@@ -568,7 +498,7 @@ bool TWorld::Init(GLFWwindow *w)
|
||||
WriteLog("Ground init OK");
|
||||
if (Global::detonatoryOK)
|
||||
{
|
||||
glRasterPos2f(-0.25f, -0.45f);
|
||||
glRasterPos2f( -0.25f * widthratio, -0.45f );
|
||||
glPrint("OK.");
|
||||
}
|
||||
glfwSwapBuffers(window);
|
||||
@@ -585,7 +515,7 @@ bool TWorld::Init(GLFWwindow *w)
|
||||
char buff[255] = "Player train init: ";
|
||||
if (Global::detonatoryOK)
|
||||
{
|
||||
glRasterPos2f(-0.85f, -0.50f);
|
||||
glRasterPos2f( -0.85f * widthratio, -0.50f );
|
||||
glPrint("Przygotowanie kabiny do sterowania...");
|
||||
}
|
||||
glfwSwapBuffers(window);
|
||||
@@ -606,7 +536,7 @@ bool TWorld::Init(GLFWwindow *w)
|
||||
WriteLog("Player train init OK");
|
||||
if (Global::detonatoryOK)
|
||||
{
|
||||
glRasterPos2f(-0.25f, -0.50f);
|
||||
glRasterPos2f( -0.25f * widthratio, -0.50f );
|
||||
glPrint("OK.");
|
||||
}
|
||||
FollowView();
|
||||
@@ -618,7 +548,7 @@ bool TWorld::Init(GLFWwindow *w)
|
||||
FreeFlyModeFlag = true; // Ra: automatycznie włączone latanie
|
||||
if (Global::detonatoryOK)
|
||||
{
|
||||
glRasterPos2f(-0.85f, -0.50f);
|
||||
glRasterPos2f( -0.85f * widthratio, -0.50f );
|
||||
glPrint("Blad inicjalizacji sterowanego pojazdu!");
|
||||
}
|
||||
glfwSwapBuffers(window);
|
||||
@@ -634,7 +564,7 @@ bool TWorld::Init(GLFWwindow *w)
|
||||
Error("Player train not exist!");
|
||||
if (Global::detonatoryOK)
|
||||
{
|
||||
glRasterPos2f(-0.85f, -0.55f);
|
||||
glRasterPos2f( -0.85f * widthratio, -0.55f );
|
||||
glPrint("Wybrany pojazd nie istnieje w scenerii!");
|
||||
}
|
||||
}
|
||||
@@ -731,49 +661,102 @@ void TWorld::OnKeyDown(int cKey)
|
||||
}
|
||||
else if (cKey >= GLFW_KEY_F1 && cKey <= GLFW_KEY_F12)
|
||||
{
|
||||
switch (cKey)
|
||||
{
|
||||
case GLFW_KEY_F1: // czas i relacja
|
||||
case GLFW_KEY_F3:
|
||||
case GLFW_KEY_F5: // przesiadka do innego pojazdu
|
||||
case GLFW_KEY_F8: // FPS
|
||||
case GLFW_KEY_F9: // wersja, typ wyświetlania, błędy OpenGL
|
||||
case GLFW_KEY_F10:
|
||||
if (Global::iTextMode == cKey)
|
||||
Global::iTextMode =
|
||||
(Global::iPause && (cKey != GLFW_KEY_F1) ? GLFW_KEY_F1 :
|
||||
0); // wyłączenie napisów, chyba że pauza
|
||||
else
|
||||
Global::iTextMode = cKey;
|
||||
break;
|
||||
case GLFW_KEY_F2: // parametry pojazdu
|
||||
if (Global::iTextMode == cKey) // jeśli kolejne naciśnięcie
|
||||
++Global::iScreenMode[cKey - GLFW_KEY_F1]; // kolejny ekran
|
||||
else
|
||||
{ // pierwsze naciśnięcie daje pierwszy (tzn. zerowy) ekran
|
||||
Global::iTextMode = cKey;
|
||||
Global::iScreenMode[cKey - GLFW_KEY_F1] = 0;
|
||||
switch (cKey) {
|
||||
|
||||
case GLFW_KEY_F1: {
|
||||
if( DebugModeFlag ) {
|
||||
// additional time speedup keys in debug mode
|
||||
if(Global::ctrlState) {
|
||||
// ctrl-f3
|
||||
GlobalTime->UpdateMTableTime( 20.0 * 60.0 );
|
||||
}
|
||||
else if(Global::shiftState) {
|
||||
// shift-f3
|
||||
GlobalTime->UpdateMTableTime( 5.0 * 60.0 );
|
||||
}
|
||||
}
|
||||
if( (Global::ctrlState)
|
||||
&& (Global::shiftState) ) {
|
||||
// czas i relacja
|
||||
if( Global::iTextMode == cKey ) {
|
||||
// wyłączenie napisów, chyba że pauza
|
||||
Global::iTextMode =
|
||||
( Global::iPause && ( cKey != GLFW_KEY_F1 ) ?
|
||||
GLFW_KEY_F1 :
|
||||
0 );
|
||||
}
|
||||
else
|
||||
Global::iTextMode = cKey;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GLFW_KEY_F12:
|
||||
if (Global::ctrlState && Global::shiftState)
|
||||
DebugModeFlag = !DebugModeFlag; // taka opcjonalna funkcja, może się czasem przydać
|
||||
else
|
||||
case GLFW_KEY_F2: {
|
||||
// parametry pojazdu
|
||||
if( Global::iTextMode == cKey ) {
|
||||
// jeśli kolejne naciśnięcie
|
||||
++Global::iScreenMode[ cKey - GLFW_KEY_F1 ]; // kolejny ekran
|
||||
}
|
||||
else {
|
||||
// pierwsze naciśnięcie daje pierwszy (tzn. zerowy) ekran
|
||||
Global::iTextMode = cKey;
|
||||
Global::iScreenMode[ cKey - GLFW_KEY_F1 ] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GLFW_KEY_F3: {
|
||||
Global::iTextMode = cKey;
|
||||
break;
|
||||
case GLFW_KEY_F4:
|
||||
InOutKey();
|
||||
break;
|
||||
case GLFW_KEY_F6:
|
||||
if (DebugModeFlag)
|
||||
{ // przyspieszenie symulacji do testowania scenerii... uwaga na FPS!
|
||||
// Global::iViewMode=GLFW_KEY_F6;
|
||||
if (Global::ctrlState)
|
||||
Global::fTimeSpeed = (Global::shiftState ? 10.0 : 5.0);
|
||||
break;
|
||||
}
|
||||
case GLFW_KEY_F4: {
|
||||
InOutKey();
|
||||
break;
|
||||
}
|
||||
case GLFW_KEY_F5: {
|
||||
// przesiadka do innego pojazdu
|
||||
Global::iTextMode = cKey;
|
||||
break;
|
||||
}
|
||||
case GLFW_KEY_F6: {
|
||||
Global::iTextMode = cKey;
|
||||
// przyspieszenie symulacji do testowania scenerii... uwaga na FPS!
|
||||
if( DebugModeFlag ) {
|
||||
|
||||
if( Global::ctrlState ) { Global::fTimeSpeed = (Global::shiftState ? 60.0 : 20.0 ); }
|
||||
else { Global::fTimeSpeed = ( Global::shiftState ? 5.0 : 1.0 ); }
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GLFW_KEY_F8: {
|
||||
Global::iTextMode = cKey;
|
||||
// FPS
|
||||
break;
|
||||
}
|
||||
case GLFW_KEY_F9: {
|
||||
Global::iTextMode = cKey;
|
||||
// wersja, typ wyświetlania, błędy OpenGL
|
||||
break;
|
||||
}
|
||||
case GLFW_KEY_F10: {
|
||||
if( Global::iTextMode == cKey ) {
|
||||
Global::iTextMode =
|
||||
( Global::iPause && ( cKey != GLFW_KEY_F1 ) ?
|
||||
GLFW_KEY_F1 :
|
||||
0 ); // wyłączenie napisów, chyba że pauza
|
||||
}
|
||||
else {
|
||||
Global::iTextMode = cKey;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GLFW_KEY_F12: {
|
||||
// coś tam jeszcze
|
||||
if( Global::ctrlState
|
||||
&& Global::shiftState )
|
||||
DebugModeFlag = !DebugModeFlag; // taka opcjonalna funkcja, może się czasem przydać
|
||||
else
|
||||
Global::fTimeSpeed = (Global::shiftState ? 2.0 : 1.0);
|
||||
Global::iTextMode = cKey;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// if (cKey!=GLFW_KEY_F4)
|
||||
return; // nie są przekazywane do pojazdu wcale
|
||||
@@ -1112,7 +1095,8 @@ bool TWorld::Update()
|
||||
iCheckFPS = 0.25 * Timer::GetFPS(); // tak za 0.25 sekundy sprawdzić ponownie (jeszcze przycina?)
|
||||
}
|
||||
Timer::UpdateTimers(Global::iPause != 0);
|
||||
if (!Global::iPause)
|
||||
if( (Global::iPause == false)
|
||||
|| (m_init == false) )
|
||||
{ // jak pauza, to nie ma po co tego przeliczać
|
||||
GlobalTime->UpdateMTableTime(Timer::GetDeltaTime()); // McZapkie-300302: czas rozkladowy
|
||||
// Ra 2014-07: przeliczenie kąta czasu (do animacji zależnych od czasu)
|
||||
@@ -1196,6 +1180,8 @@ bool TWorld::Update()
|
||||
|
||||
Ground.CheckQuery();
|
||||
|
||||
Ground.Update_Lights();
|
||||
|
||||
if( Train != nullptr ) {
|
||||
TSubModel::iInstance = reinterpret_cast<size_t>( Train->Dynamic() );
|
||||
Train->Update( dt );
|
||||
@@ -1207,13 +1193,17 @@ bool TWorld::Update()
|
||||
// przy 0.25 smuga gaśnie o 6:37 w Quarku, a mogłaby już 5:40
|
||||
// Ra 2014-12: przy 0.15 się skarżyli, że nie widać smug => zmieniłem na 0.25
|
||||
// changed light activation threshold to 0.5, paired with strength reduction in daylight
|
||||
if (Train) // jeśli nie usunięty
|
||||
if( Train ) {
|
||||
// jeśli nie usunięty
|
||||
Global::bSmudge =
|
||||
( FreeFlyModeFlag ?
|
||||
false :
|
||||
( Train->Dynamic()->fShade <= 0.0 ?
|
||||
(Global::fLuminance <= 0.5) :
|
||||
(Train->Dynamic()->fShade * Global::fLuminance <= 0.5) ) );
|
||||
( Global::fLuminance <= 0.5 ) :
|
||||
( Train->Dynamic()->fShade * Global::fLuminance <= 0.5 ) ) );
|
||||
}
|
||||
|
||||
m_init = true;
|
||||
|
||||
if (!Render())
|
||||
return false;
|
||||
@@ -1484,31 +1474,11 @@ bool TWorld::Render()
|
||||
Environment.render();
|
||||
}
|
||||
|
||||
if (Global::bUseVBO)
|
||||
{ // renderowanie przez VBO
|
||||
if (!Ground.RenderVBO(Camera.Pos))
|
||||
return false;
|
||||
if (!Ground.RenderAlphaVBO(Camera.Pos))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{ // renderowanie przez Display List
|
||||
if (!Ground.RenderDL(Camera.Pos))
|
||||
return false;
|
||||
if (!Ground.RenderAlphaDL(Camera.Pos))
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
TSubModel::iInstance = (int)(Train ? Train->Dynamic() : 0); //żeby nie robić cudzych animacji
|
||||
// if (Camera.Type==tp_Follow)
|
||||
if (Train)
|
||||
Train->Update();
|
||||
*/
|
||||
if( false == Ground.Render( Camera.Pos ) ) { return false; }
|
||||
|
||||
Render_Cab();
|
||||
Render_UI();
|
||||
|
||||
// glFlush();
|
||||
// Global::bReCompile=false; //Ra: już zrobiona rekompilacja
|
||||
ResourceManager::Sweep( Timer::GetSimulationTime() );
|
||||
|
||||
return true;
|
||||
@@ -1533,6 +1503,7 @@ TWorld::Render_Cab() {
|
||||
// ABu: Rendering kabiny jako ostatniej, zeby bylo widac przez szyby, tylko w widoku ze srodka
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
// ABu: Rendering kabiny jako ostatniej, zeby bylo widac przez szyby, tylko w widoku ze srodka
|
||||
if( ( Train->Dynamic()->mdKabina != Train->Dynamic()->mdModel ) &&
|
||||
@@ -1546,10 +1517,11 @@ TWorld::Render_Cab() {
|
||||
glLoadIdentity(); // zacząć od macierzy jedynkowej
|
||||
Camera.SetCabMatrix( pos ); // widok z kamery po przesunięciu
|
||||
glMultMatrixd( dynamic->mMatrix.getArray() ); // ta macierz nie ma przesunięcia
|
||||
|
||||
/*
|
||||
//*yB: moje smuuugi 1
|
||||
if( Global::bSmudge ) { // Ra: uwzględniłem zacienienie pojazdu przy zapalaniu smug
|
||||
// 1. warunek na smugę wyznaczyc wcześniej
|
||||
|
||||
// 1. warunek na smugę wyznaczyc wcześniej
|
||||
// 2. jeśli smuga włączona, nie renderować pojazdu użytkownika w DynObj
|
||||
// 3. jeśli smuga właczona, wyrenderować pojazd użytkownia po dodaniu smugi do sceny
|
||||
auto const &frontlights = Train->Controlled()->iLights[ 0 ];
|
||||
@@ -1622,24 +1594,25 @@ TWorld::Render_Cab() {
|
||||
//float ddl = (0.15*Global::diffuseDayLight[0]+0.295*Global::diffuseDayLight[1]+0.055*Global::diffuseDayLight[2]); //0.24:0
|
||||
glBegin( GL_QUADS );
|
||||
float fSmudge = dynamic->MoverParameters->DimHalf.y + 7; // gdzie zaczynać smugę
|
||||
if( frontlightstrength > 0.f ) { // wystarczy jeden zapalony z przodu
|
||||
|
||||
if( frontlightstrength > 0.f ) {
|
||||
// wystarczy jeden zapalony z przodu
|
||||
for( int i = 15; i <= 35; i++ ) {
|
||||
float z = i * i * i * 0.01f;//25/4;
|
||||
//float C = (36 - i*0.5)*0.005*(1.5 - sqrt(ddl));
|
||||
float C = ( 36 - i*0.5 )*0.005*sqrt( ( 1 / sqrt( Global::fLuminance + 0.015 ) ) - 1 ) * frontlightstrength;
|
||||
glColor4f( C, C, C, 1.0f );// *frontlightstrength );
|
||||
glTexCoord2f( 0, 0 ); glVertex3f( -10 / 2 - 2 * i / 4, 6.0 + 0.3*z, 13 + 1.7*z / 3 );
|
||||
glTexCoord2f( 1, 0 ); glVertex3f( 10 / 2 + 2 * i / 4, 6.0 + 0.3*z, 13 + 1.7*z / 3 );
|
||||
glTexCoord2f( 1, 1 ); glVertex3f( 10 / 2 + 2 * i / 4, -5.0 - 0.5*z, 13 + 1.7*z / 3 );
|
||||
glTexCoord2f( 0, 0 ); glVertex3f( -10 / 2 - 2 * i / 4, 6.0 + 0.3*z, 13 + 1.7*z / 3 );
|
||||
glTexCoord2f( 1, 0 ); glVertex3f( 10 / 2 + 2 * i / 4, 6.0 + 0.3*z, 13 + 1.7*z / 3 );
|
||||
glTexCoord2f( 1, 1 ); glVertex3f( 10 / 2 + 2 * i / 4, -5.0 - 0.5*z, 13 + 1.7*z / 3 );
|
||||
glTexCoord2f( 0, 1 ); glVertex3f( -10 / 2 - 2 * i / 4, -5.0 - 0.5*z, 13 + 1.7*z / 3 );
|
||||
}
|
||||
}
|
||||
if( rearlightstrength > 0.f ) { // wystarczy jeden zapalony z tyłu
|
||||
if( rearlightstrength > 0.f ) {
|
||||
// wystarczy jeden zapalony z tyłu
|
||||
for( int i = 15; i <= 35; i++ ) {
|
||||
float z = i * i * i * 0.01f;//25/4;
|
||||
float C = ( 36 - i*0.5 )*0.005*sqrt( ( 1 / sqrt( Global::fLuminance + 0.015 ) ) - 1 ) * rearlightstrength;
|
||||
glColor4f( C, C, C, 0.35f );// *rearlightstrength );
|
||||
glColor4f( C, C, C, 1.0f );// *rearlightstrength );
|
||||
glTexCoord2f( 0, 0 ); glVertex3f( 10 / 2 + 2 * i / 4, 6.0 + 0.3*z, -13 - 1.7*z / 3 );
|
||||
glTexCoord2f( 1, 0 ); glVertex3f( -10 / 2 - 2 * i / 4, 6.0 + 0.3*z, -13 - 1.7*z / 3 );
|
||||
glTexCoord2f( 1, 1 ); glVertex3f( -10 / 2 - 2 * i / 4, -5.0 - 0.5*z, -13 - 1.7*z / 3 );
|
||||
@@ -1656,14 +1629,17 @@ TWorld::Render_Cab() {
|
||||
glEnable( GL_FOG );
|
||||
}
|
||||
}
|
||||
|
||||
glEnable( GL_LIGHTING ); // po renderowaniu smugi jest to wyłączone
|
||||
// Ra: pojazd użytkownika należało by renderować po smudze, aby go nie rozświetlała
|
||||
|
||||
Global::bSmudge = false; // aby model użytkownika się teraz wyrenderował
|
||||
dynamic->Render();
|
||||
dynamic->RenderAlpha(); // przezroczyste fragmenty pojazdów na torach
|
||||
} // yB: moje smuuugi 1 - koniec*/
|
||||
|
||||
} // yB: moje smuuugi 1 - koniec
|
||||
else
|
||||
glEnable( GL_LIGHTING ); // po renderowaniu drutów może być to wyłączone
|
||||
*/ glEnable( GL_LIGHTING ); // po renderowaniu drutów może być to wyłączone. TODO: have the wires render take care of its own shit
|
||||
|
||||
if( dynamic->mdKabina ) // bo mogła zniknąć przy przechodzeniu do innego pojazdu
|
||||
{
|
||||
@@ -1794,9 +1770,9 @@ TWorld::Render_UI() {
|
||||
glLoadIdentity();
|
||||
|
||||
if( DebugModeFlag && !Global::iTextMode ) {
|
||||
OutText1 = " FPS: ";
|
||||
OutText1 = "FPS: ";
|
||||
OutText1 += to_string( Timer::GetFPS(), 2 );
|
||||
OutText1 += Global::iSlowMotion ? "s" : "n";
|
||||
OutText1 += Global::iSlowMotion ? "(s)" : "(n)";
|
||||
|
||||
OutText1 += ( Timer::GetDeltaTime() >= 0.2 ) ? "!" : " ";
|
||||
// if (GetDeltaTime()>=0.2) //Ra: to za bardzo miota tekstem!
|
||||
@@ -1811,7 +1787,7 @@ TWorld::Render_UI() {
|
||||
|
||||
if( Global::iTextMode == GLFW_KEY_F8 ) {
|
||||
Global::iViewMode = GLFW_KEY_F8;
|
||||
OutText1 = " FPS: ";
|
||||
OutText1 = "FPS: ";
|
||||
OutText1 += to_string( Timer::GetFPS(), 2 );
|
||||
//OutText1 += sprintf();
|
||||
if( Global::iSlowMotion )
|
||||
@@ -2248,7 +2224,7 @@ TWorld::Render_UI() {
|
||||
OutText1 +=
|
||||
" " +
|
||||
std::string( "S SEE NEN NWW SW" )
|
||||
.substr( 1 + 2 * floor( fmod( 8 + ( Camera.Yaw + 0.5 * M_PI_4 ) / M_PI_4, 8 ) ), 2 );
|
||||
.substr( 0 + 2 * floor( fmod( 8 + ( Camera.Yaw + 0.5 * M_PI_4 ) / M_PI_4, 8 ) ), 2 );
|
||||
// current luminance level
|
||||
OutText2 = "Light level: " + to_string( Global::fLuminance, 3 );
|
||||
}
|
||||
@@ -2963,16 +2939,14 @@ world_environment::update() {
|
||||
auto const position = m_sun.getPosition();
|
||||
// ...update the global data to match new sun state...
|
||||
Global::SunAngle = m_sun.getAngle();
|
||||
Global::DayLight.position[ 0 ] = position.x;
|
||||
Global::DayLight.position[ 1 ] = position.y;
|
||||
Global::DayLight.position[ 2 ] = position.z;
|
||||
Global::DayLight.set_position( position );
|
||||
Global::DayLight.direction = -1.0 * m_sun.getDirection();
|
||||
// ...update skydome to match the current sun position as well...
|
||||
m_skydome.Update( position );
|
||||
// ...retrieve current sky colour and brightness...
|
||||
auto const skydomecolour = m_skydome.GetAverageColor();
|
||||
auto const skydomehsv = RGBtoHSV( skydomecolour );
|
||||
auto const intensity = std::min( 0.05f + m_sun.getIntensity() + skydomehsv.z, 1.25f );
|
||||
auto const intensity = std::min( 1.15f * (0.05f + m_sun.getIntensity() + skydomehsv.z), 1.25f );
|
||||
// ...update light colours and intensity.
|
||||
// NOTE: intensity combines intensity of the sun and the light reflected by the sky dome
|
||||
// it'd be more technically correct to have just the intensity of the sun here,
|
||||
@@ -3009,7 +2983,7 @@ world_environment::render() {
|
||||
|
||||
m_skydome.Render();
|
||||
m_stars.render();
|
||||
// m_clouds.Render();
|
||||
m_clouds.Render( m_skydome.GetAverageColor() * 2.5f );
|
||||
|
||||
if( DebugModeFlag == true ) {
|
||||
// mark sun position for easier debugging
|
||||
|
||||
1
World.h
1
World.h
@@ -82,6 +82,7 @@ class TWorld
|
||||
double VelPrev; // poprzednia prędkość
|
||||
int tprev; // poprzedni czas
|
||||
double Acc; // przyspieszenie styczne
|
||||
bool m_init{ false }; // indicates whether initial update of the world was performed
|
||||
public:
|
||||
void ModifyTGA(std::string const &dir = "");
|
||||
void CreateE3D(std::string const &dir = "", bool dyn = false);
|
||||
|
||||
15
dumb3d.h
15
dumb3d.h
@@ -83,7 +83,8 @@ class vector3
|
||||
|
||||
void inline Normalize();
|
||||
void inline SafeNormalize();
|
||||
double inline Length();
|
||||
double inline Length() const;
|
||||
double inline LengthSquared() const;
|
||||
void inline Zero()
|
||||
{
|
||||
x = y = z = 0.0;
|
||||
@@ -415,6 +416,11 @@ inline vector3 CrossProduct(const vector3 &v1, const vector3 &v2)
|
||||
return vector3(v1.y * v2.z - v1.z * v2.y, v2.x * v1.z - v2.z * v1.x, v1.x * v2.y - v1.y * v2.x);
|
||||
}
|
||||
|
||||
inline vector3 Interpolate( vector3 const &First, vector3 const &Second, float const Factor ) {
|
||||
|
||||
return ( First * ( 1.0f - Factor ) ) + ( Second * Factor );
|
||||
}
|
||||
|
||||
inline vector3 operator*(const matrix4x4 &m, const vector3 &v)
|
||||
{
|
||||
return vector3(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + m[3][0],
|
||||
@@ -430,11 +436,16 @@ void inline vector3::Normalize()
|
||||
z *= il;
|
||||
}
|
||||
|
||||
double inline vector3::Length()
|
||||
double inline vector3::Length() const
|
||||
{
|
||||
return SQRT_FUNCTION(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
double inline vector3::LengthSquared() const {
|
||||
|
||||
return ( x * x + y * y + z * z );
|
||||
}
|
||||
|
||||
inline bool operator==(const matrix4x4 &m1, const matrix4x4 &m2)
|
||||
{
|
||||
for (int x = 0; x < 4; ++x)
|
||||
|
||||
75
lightarray.cpp
Normal file
75
lightarray.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
/*
|
||||
MaSzyna EU07 locomotive simulator
|
||||
Copyright (C) 2001-2004 Marcin Wozniak and others
|
||||
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "lightarray.h"
|
||||
#include "dynobj.h"
|
||||
|
||||
void
|
||||
light_array::insert( TDynamicObject const *Owner ) {
|
||||
|
||||
// we're only storing lights for locos, which have two sets of lights, front and rear
|
||||
// for a more generic role this function would have to be tweaked to add vehicle type-specific light combinations
|
||||
data.emplace_back( Owner, 0 );
|
||||
data.emplace_back( Owner, 1 );
|
||||
}
|
||||
|
||||
void
|
||||
light_array::remove( TDynamicObject const *Owner ) {
|
||||
|
||||
data.erase(
|
||||
std::remove_if(
|
||||
data.begin(),
|
||||
data.end(),
|
||||
[=]( light_record const &light ){ return light.owner == Owner; } ),
|
||||
data.end() );
|
||||
}
|
||||
|
||||
// updates records in the collection
|
||||
void
|
||||
light_array::update() {
|
||||
|
||||
for( auto &light : data ) {
|
||||
// update light parameters to match current data of the owner
|
||||
if( light.index == 0 ) {
|
||||
// front light set
|
||||
light.position = light.owner->GetPosition() + ( light.owner->VectorFront() * light.owner->GetLength() * 0.45 );
|
||||
light.direction = light.owner->VectorFront();
|
||||
}
|
||||
else {
|
||||
// rear light set
|
||||
light.position = light.owner->GetPosition() - ( light.owner->VectorFront() * light.owner->GetLength() * 0.45 );
|
||||
light.direction = light.owner->VectorFront();
|
||||
light.direction.x = -light.direction.x;
|
||||
light.direction.z = -light.direction.z;
|
||||
}
|
||||
// determine intensity of this light set
|
||||
if( true == light.owner->MoverParameters->Battery ) {
|
||||
// with battery on, the intensity depends on the state of activated switches
|
||||
auto const &lightbits = light.owner->iLights[ light.index ];
|
||||
light.count = 0 +
|
||||
( ( lightbits & 1 ) ? 1 : 0 ) +
|
||||
( ( lightbits & 4 ) ? 1 : 0 ) +
|
||||
( ( lightbits & 16 ) ? 1 : 0 );
|
||||
|
||||
light.intensity = 0.15f * light.count; // TODO: intensity can be affected further by dim switch or other factors
|
||||
}
|
||||
else {
|
||||
// with battery off the lights are off
|
||||
light.intensity = 0.0f;
|
||||
light.count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
45
lightarray.h
Normal file
45
lightarray.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "dumb3d.h"
|
||||
#include "float3d.h"
|
||||
#include "dynobj.h"
|
||||
|
||||
// collection of virtual light sources present in the scene
|
||||
// used by the renderer to determine most suitable placement for actual light sources during render
|
||||
struct light_array {
|
||||
|
||||
public:
|
||||
// types
|
||||
struct light_record {
|
||||
|
||||
light_record( TDynamicObject const *Owner, int const Lightindex) :
|
||||
owner(Owner), index(Lightindex)
|
||||
{};
|
||||
|
||||
TDynamicObject const *owner; // the object in world which 'carries' the light
|
||||
int index{ -1 }; // 0: front lights, 1: rear lights
|
||||
Math3D::vector3 position; // position of the light in 3d scene
|
||||
Math3D::vector3 direction; // direction of the light in 3d scene
|
||||
float3 color{ 255.0f / 255.0f, 241.0f / 255.0f, 224.0f / 255.0f }; // color of the light, default is halogen light
|
||||
float intensity{ 0.0f }; // (combined) intensity of the light(s)
|
||||
int count{ 0 }; // number (or pattern) of active light(s)
|
||||
};
|
||||
|
||||
// methods
|
||||
// adds records for lights of specified owner to the collection
|
||||
void
|
||||
insert( TDynamicObject const *Owner );
|
||||
// removes records for lights of specified owner from the collection
|
||||
void
|
||||
remove( TDynamicObject const *Owner );
|
||||
// updates records in the collection
|
||||
void
|
||||
update();
|
||||
|
||||
// types
|
||||
typedef std::vector<light_record> lightrecord_array;
|
||||
|
||||
// members
|
||||
lightrecord_array data;
|
||||
};
|
||||
78
renderer.cpp
78
renderer.cpp
@@ -9,7 +9,85 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "renderer.h"
|
||||
#include "globals.h"
|
||||
|
||||
opengl_renderer GfxRenderer;
|
||||
|
||||
void
|
||||
opengl_renderer::Init() {
|
||||
|
||||
// create dynamic light pool
|
||||
for( int idx = 0; idx < Global::DynamicLightCount; ++idx ) {
|
||||
|
||||
opengl_light light;
|
||||
light.id = GL_LIGHT1 + idx;
|
||||
|
||||
light.position[ 3 ] = 1.0f;
|
||||
::glLightf( light.id, GL_SPOT_CUTOFF, 20.0f );
|
||||
::glLightf( light.id, GL_SPOT_EXPONENT, 10.0f );
|
||||
::glLightf( light.id, GL_CONSTANT_ATTENUATION, 0.0f );
|
||||
::glLightf( light.id, GL_LINEAR_ATTENUATION, 0.035f );
|
||||
|
||||
m_lights.emplace_back( light );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
opengl_renderer::Update_Lights( light_array const &Lights ) {
|
||||
|
||||
size_t const count = std::min( m_lights.size(), Lights.data.size() );
|
||||
if( count == 0 ) { return; }
|
||||
|
||||
auto renderlight = m_lights.begin();
|
||||
|
||||
for( auto const &scenelight : Lights.data ) {
|
||||
|
||||
if( renderlight == m_lights.end() ) {
|
||||
// we ran out of lights to assign
|
||||
break;
|
||||
}
|
||||
if( scenelight.intensity == 0.0f ) {
|
||||
// all lights past this one are bound to be off
|
||||
break;
|
||||
}
|
||||
if( ( Global::pCameraPosition - scenelight.position ).Length() > 1000.0f ) {
|
||||
// we don't care about lights past arbitrary limit of 1 km.
|
||||
// but there could still be weaker lights which are closer, so keep looking
|
||||
continue;
|
||||
}
|
||||
// if the light passed tests so far, it's good enough
|
||||
renderlight->set_position( scenelight.position );
|
||||
renderlight->direction = scenelight.direction;
|
||||
|
||||
renderlight->diffuse[ 0 ] = scenelight.color.x;
|
||||
renderlight->diffuse[ 1 ] = scenelight.color.y;
|
||||
renderlight->diffuse[ 2 ] = scenelight.color.z;
|
||||
renderlight->ambient[ 0 ] = scenelight.color.x * scenelight.intensity;
|
||||
renderlight->ambient[ 1 ] = scenelight.color.y * scenelight.intensity;
|
||||
renderlight->ambient[ 2 ] = scenelight.color.z * scenelight.intensity;
|
||||
|
||||
::glLightf( renderlight->id, GL_LINEAR_ATTENUATION, 0.3f / std::pow( scenelight.count, 2 ) );
|
||||
::glEnable( renderlight->id );
|
||||
|
||||
renderlight->apply_intensity();
|
||||
renderlight->apply_angle();
|
||||
|
||||
++renderlight;
|
||||
}
|
||||
|
||||
while( renderlight != m_lights.end() ) {
|
||||
// if we went through all scene lights and there's still opengl lights remaining, kill these
|
||||
::glDisable( renderlight->id );
|
||||
++renderlight;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
opengl_renderer::Disable_Lights() {
|
||||
|
||||
for( int idx = 0; idx < m_lights.size() + 1; ++idx ) {
|
||||
|
||||
::glDisable( GL_LIGHT0 + idx );
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
40
renderer.h
40
renderer.h
@@ -11,6 +11,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include "GL/glew.h"
|
||||
#include "texture.h"
|
||||
#include "lightarray.h"
|
||||
#include "dumb3d.h"
|
||||
|
||||
struct opengl_light {
|
||||
@@ -23,10 +24,10 @@ struct opengl_light {
|
||||
GLfloat specular[ 4 ];
|
||||
|
||||
opengl_light() {
|
||||
position[ 0 ] = position[ 1 ] = position[ 2 ] = 0.0f; position[ 3 ] = 1.0f;
|
||||
ambient[ 0 ] = ambient[ 1 ] = ambient[ 2 ] = ambient[ 3 ] = 1.0f;
|
||||
diffuse[ 0 ] = diffuse[ 1 ] = diffuse[ 2 ] = diffuse[ 3 ] = 1.0f;
|
||||
specular[ 0 ] = specular[ 1 ] = specular[ 2 ] = specular[ 3 ] = 1.0f;
|
||||
position[ 0 ] = position[ 1 ] = position[ 2 ] = 0.0f; position[ 3 ] = 1.0f; // 0,0,0,1
|
||||
ambient[ 0 ] = ambient[ 1 ] = ambient[ 2 ] = 0.0f; ambient[ 3 ] = 1.0f; // 0,0,0,1
|
||||
diffuse[ 0 ] = diffuse[ 1 ] = diffuse[ 2 ] = diffuse[ 3 ] = 1.0f; // 1,1,1,1
|
||||
specular[ 0 ] = specular[ 1 ] = specular[ 2 ] = specular[ 3 ] = 1.0f; // 1,1,1,1
|
||||
}
|
||||
|
||||
inline
|
||||
@@ -45,6 +46,13 @@ struct opengl_light {
|
||||
glLightfv( id, GL_SPOT_DIRECTION, directionarray );
|
||||
}
|
||||
}
|
||||
inline
|
||||
void set_position( Math3D::vector3 const &Position ) {
|
||||
|
||||
position[ 0 ] = Position.x;
|
||||
position[ 1 ] = Position.y;
|
||||
position[ 2 ] = Position.z;
|
||||
}
|
||||
};
|
||||
|
||||
// encapsulates basic rendering setup.
|
||||
@@ -65,32 +73,50 @@ struct opengl_material {
|
||||
class opengl_renderer {
|
||||
|
||||
public:
|
||||
GLenum static const sunlight{ GL_LIGHT0 };
|
||||
// GLenum static const ambientlight{ GL_LIGHT1 };
|
||||
// types
|
||||
|
||||
// methods
|
||||
void
|
||||
Init();
|
||||
|
||||
void
|
||||
Update_Lights( light_array const &Lights );
|
||||
|
||||
void
|
||||
Disable_Lights();
|
||||
|
||||
texture_manager::size_type
|
||||
GetTextureId( std::string Filename, std::string const &Dir, int const Filter = -1, bool const Loadnow = true ) {
|
||||
|
||||
return m_textures.GetTextureId( Filename, Dir, Filter, Loadnow );
|
||||
}
|
||||
|
||||
void
|
||||
Bind( texture_manager::size_type const Id ) {
|
||||
// temporary until we separate the renderer
|
||||
m_textures.Bind( Id );
|
||||
}
|
||||
|
||||
opengl_texture &
|
||||
Texture( texture_manager::size_type const Id ) {
|
||||
|
||||
return m_textures.Texture( Id );
|
||||
}
|
||||
|
||||
// members
|
||||
GLenum static const sunlight{ GL_LIGHT0 };
|
||||
|
||||
private:
|
||||
// types
|
||||
enum class rendermode {
|
||||
color
|
||||
};
|
||||
|
||||
typedef std::vector<opengl_light> opengllight_array;
|
||||
|
||||
// members
|
||||
rendermode renderpass{ rendermode::color };
|
||||
|
||||
opengllight_array m_lights;
|
||||
texture_manager m_textures;
|
||||
};
|
||||
|
||||
|
||||
20
sky.cpp
20
sky.cpp
@@ -22,21 +22,22 @@ TSky::TSky(){};
|
||||
|
||||
void TSky::Init()
|
||||
{
|
||||
WriteLog(Global::asSky.c_str());
|
||||
WriteLog("init");
|
||||
WriteLog( "Clouds init" );
|
||||
if ((Global::asSky != "1") && (Global::asSky != "0"))
|
||||
// {
|
||||
mdCloud = TModelsManager::GetModel(Global::asSky.c_str());
|
||||
// }
|
||||
mdCloud = TModelsManager::GetModel( Global::asSky );
|
||||
};
|
||||
|
||||
void TSky::Render()
|
||||
void TSky::Render( float3 const &Tint )
|
||||
{
|
||||
if (mdCloud)
|
||||
{ // jeśli jest model nieba
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
// TODO: re-implement this
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
|
||||
#else
|
||||
::glEnable( GL_LIGHTING );
|
||||
GfxRenderer.Disable_Lights();
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &Tint.x );
|
||||
#endif
|
||||
if (Global::bUseVBO)
|
||||
{ // renderowanie z VBO
|
||||
@@ -48,10 +49,15 @@ void TSky::Render()
|
||||
mdCloud->Render(100, 0);
|
||||
mdCloud->RenderAlpha(100, 0);
|
||||
}
|
||||
glPopMatrix();
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
glPopMatrix();
|
||||
// TODO: re-implement this
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, Global::lightPos);
|
||||
#else
|
||||
GLfloat noambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, noambient );
|
||||
::glEnable( GL_LIGHT0 ); // other lights will be enabled during lights update
|
||||
::glDisable( GL_LIGHTING );
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
3
sky.h
3
sky.h
@@ -11,6 +11,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#pragma once
|
||||
|
||||
#include "Model3d.h"
|
||||
#include "Float3d.h"
|
||||
|
||||
class TSky
|
||||
{
|
||||
@@ -21,7 +22,7 @@ class TSky
|
||||
TSky();
|
||||
~TSky();
|
||||
void Init();
|
||||
void Render();
|
||||
void Render( float3 const &Tint = float3(1.0f, 1.0f, 1.0f) );
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
34
skydome.cpp
34
skydome.cpp
@@ -61,9 +61,9 @@ CSkyDome::CSkyDome (int const Tesselation) :
|
||||
m_tesselation( Tesselation ) {
|
||||
|
||||
// SetSunPosition( Math3D::vector3(75.0f, 0.0f, 0.0f) );
|
||||
SetTurbidity( 3.5f );
|
||||
SetExposure( true, 16.0f );
|
||||
SetOvercastFactor( 0.08f );
|
||||
SetTurbidity( 3.0f );
|
||||
SetExposure( true, 20.0f );
|
||||
SetOvercastFactor( 0.05f );
|
||||
SetGammaCorrection( 2.2f );
|
||||
Generate();
|
||||
}
|
||||
@@ -75,7 +75,8 @@ CSkyDome::~CSkyDome() {
|
||||
|
||||
void CSkyDome::Generate() {
|
||||
// radius of dome
|
||||
float const radius = 1.0f; // 100.0f;
|
||||
float const radius = 1.0f;
|
||||
float const offset = 0.1f * radius; // horizontal offset, a cheap way to prevent a gap between ground and horizon
|
||||
|
||||
// create geometry chunk
|
||||
int const latitudes = m_tesselation / 2;
|
||||
@@ -98,11 +99,11 @@ void CSkyDome::Generate() {
|
||||
float x = std::cos( longitude );
|
||||
float y = std::sin( longitude );
|
||||
|
||||
m_vertices.emplace_back( float3( x * zr0, y * zr0 - 0.1f, z0 ) * radius );
|
||||
m_vertices.emplace_back( float3( x * zr0, y * zr0 - offset, z0 ) * radius );
|
||||
// m_normals.emplace_back( float3( -x * zr0, -y * zr0, -z0 ) );
|
||||
m_colours.emplace_back( float3( 0.75f, 0.75f, 0.75f ) );
|
||||
|
||||
m_vertices.emplace_back( float3( x * zr1, y * zr1 - 0.1f, z1 ) * radius );
|
||||
m_vertices.emplace_back( float3( x * zr1, y * zr1 - offset, z1 ) * radius );
|
||||
// m_normals.emplace_back( float3( -x * zr1, -y * zr1, -z1 ) );
|
||||
m_colours.emplace_back( float3( 0.75f, 0.75f, 0.75f ) );
|
||||
}
|
||||
@@ -156,7 +157,7 @@ bool CSkyDome::SetSunPosition( Math3D::vector3 const &Direction ) {
|
||||
|
||||
m_sundirection = sundirection;
|
||||
m_thetasun = std::acosf( m_sundirection.y );
|
||||
m_phisun = std::atan2( m_sundirection.z , m_sundirection.x );
|
||||
m_phisun = std::atan2( m_sundirection.z, m_sundirection.x );
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -249,7 +250,7 @@ void CSkyDome::RebuildColors() {
|
||||
|
||||
// trough all vertices
|
||||
float3 vertex;
|
||||
float3 color, colorconverter;
|
||||
float3 color, colorconverter, shiftedcolor;
|
||||
|
||||
for ( unsigned int i = 0; i < m_vertices.size(); ++i ) {
|
||||
// grab it
|
||||
@@ -295,9 +296,24 @@ void CSkyDome::RebuildColors() {
|
||||
// exp scale
|
||||
colorconverter.z = 1.0f - exp( -m_expfactor * colorconverter.z );
|
||||
}
|
||||
|
||||
// override the hue, based on sun height above the horizon. crude way to deal with model shortcomings
|
||||
// correction begins when the sun is higher than 10 degrees above the horizon, and fully in effect at 10+15 degrees
|
||||
auto const degreesabovehorizon = 90.0f - m_thetasun * ( 180.0f / M_PI );
|
||||
auto const sunbasedphase = clamp( (1.0f / 15.0f) * ( degreesabovehorizon - 10.0f ), 0.0f, 1.0f );
|
||||
// correction is applied in linear manner from the bottom, becomes fully in effect for vertices with y = 0.50
|
||||
auto const heightbasedphase = clamp( vertex.y * 2.0f, 0.0f, 1.0f );
|
||||
// this height-based factor is reduced the farther the sky is up in the sky
|
||||
float const shiftfactor = clamp( interpolate(heightbasedphase, sunbasedphase, sunbasedphase), 0.0f, 1.0f );
|
||||
// h = 210 makes for 'typical' sky tone
|
||||
shiftedcolor = float3( 210.0f, colorconverter.y, colorconverter.z );
|
||||
shiftedcolor = HSVtoRGB( shiftedcolor );
|
||||
|
||||
color = HSVtoRGB(colorconverter);
|
||||
|
||||
color = Interpolate( color, shiftedcolor, shiftfactor );
|
||||
/*
|
||||
// gamma control
|
||||
// gamma control
|
||||
color.x = std::pow( color.x, m_gammacorrection );
|
||||
color.x = std::pow( color.y, m_gammacorrection );
|
||||
color.x = std::pow( color.z, m_gammacorrection );
|
||||
|
||||
@@ -42,7 +42,7 @@ private:
|
||||
// data
|
||||
int const m_tesselation;
|
||||
std::vector<float3> m_vertices;
|
||||
std::vector<float3> m_normals;
|
||||
// std::vector<float3> m_normals;
|
||||
std::vector<float3> m_colours;
|
||||
|
||||
static float m_distributionluminance[ 5 ][ 2 ];
|
||||
|
||||
8
sun.cpp
8
sun.cpp
@@ -32,8 +32,8 @@ cSun::update() {
|
||||
|
||||
move();
|
||||
Math3D::vector3 position( 0.0f, 0.0f, -2000.0f );
|
||||
position.RotateX( (float)( m_body.elevref * ( M_PI / 180.0 ) ) );
|
||||
position.RotateY( (float)( ( 90.0 - m_body.hrang ) * ( M_PI / 180.0 ) ) );
|
||||
position.RotateX( (float)( m_body.elevref * ( M_PI / 180.0 ) ) );
|
||||
position.RotateY( (float)( -m_body.hrang * ( M_PI / 180.0 ) ) );
|
||||
|
||||
m_position = position;
|
||||
}
|
||||
@@ -69,8 +69,8 @@ Math3D::vector3
|
||||
cSun::getDirection() {
|
||||
|
||||
Math3D::vector3 position( 0.f, 0.f, -1.f );
|
||||
position.RotateX( (float)(m_body.elevref * (M_PI/180.0)) );
|
||||
position.RotateY( (float)((90.0 - m_body.hrang) * (M_PI/180.0)) );
|
||||
position.RotateX( (float)( m_body.elevref * (M_PI/180.0)) );
|
||||
position.RotateY( (float)( -m_body.hrang * (M_PI/180.0)) );
|
||||
position.Normalize();
|
||||
return position;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user