From 013a6f055960b1d0bf7cd08ffaf9a879556d1c73 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Wed, 15 Feb 2017 22:57:48 +0100 Subject: [PATCH 01/40] light wrapper object --- DynObj.cpp | 69 +++------- Globals.cpp | 4 + Globals.h | 53 +++++++ Ground.cpp | 112 ++++++++++----- Track.cpp | 6 + Traction.cpp | 24 +++- World.cpp | 95 +++++++++++-- World.h | 2 + maszyna.vcxproj | 2 + maszyna.vcxproj.filters | 6 + sky.cpp | 21 ++- sun.cpp | 298 ++++++++++++++++++++++++++++++++++++++++ sun.h | 99 +++++++++++++ 13 files changed, 682 insertions(+), 109 deletions(-) create mode 100644 sun.cpp create mode 100644 sun.h diff --git a/DynObj.cpp b/DynObj.cpp index 9dba3343..0442e7a7 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -3771,6 +3771,8 @@ void TDynamicObject::Render() 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}; @@ -3787,6 +3789,7 @@ void TDynamicObject::Render() glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight); glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight); } +#endif if (Global::bUseVBO) { // wersja VBO if (mdLowPolyInt) @@ -3819,6 +3822,8 @@ void TDynamicObject::Render() // ma byc wyswietlana // ABu: tylko w trybie FreeFly, zwykly tryb w world.cpp // Ra: świetła są ustawione dla zewnętrza danego pojazdu +#ifdef EU07_USE_OLD_LIGHTING_MODEL + // TODO: re-mplement this // oswietlenie kabiny GLfloat ambientCabLight[4] = {0.5f, 0.5f, 0.5f, 1.0f}; GLfloat diffuseCabLight[4] = {0.5f, 0.5f, 0.5f, 1.0f}; @@ -3854,20 +3859,25 @@ void TDynamicObject::Render() glLightfv(GL_LIGHT0, GL_AMBIENT, ambientCabLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseCabLight); glLightfv(GL_LIGHT0, GL_SPECULAR, specularCabLight); +#endif if (Global::bUseVBO) mdKabina->RaRender(ObjSqrDist, 0); else mdKabina->Render(ObjSqrDist, 0); +#ifdef EU07_USE_OLD_LIGHTING_MODEL glLightfv(GL_LIGHT0, GL_AMBIENT, Global::ambientDayLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight); glLightfv(GL_LIGHT0, GL_SPECULAR, Global::specularDayLight); +#endif } - if (fShade != 0.0) // tylko jeśli było zmieniane +#ifdef EU07_USE_OLD_LIGHTING_MODEL + 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 @@ -4265,6 +4275,8 @@ void TDynamicObject::RenderAlpha() 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}; @@ -4281,6 +4293,7 @@ void TDynamicObject::RenderAlpha() glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight); glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight); } +#endif if (Global::bUseVBO) { // wersja VBO if (mdLowPolyInt) @@ -4303,63 +4316,15 @@ void TDynamicObject::RenderAlpha() // if (mdPrzedsionek) //Ra: przedsionków tu wcześniej nie było - włączyć? // mdPrzedsionek->RenderAlpha(ObjSqrDist,ReplacableSkinID,iAlpha); } - /* skoro false to można wyciąc - //ABu: Tylko w trybie freefly - if (false)//((mdKabina!=mdModel) && bDisplayCab && FreeFlyModeFlag) - { - //oswietlenie kabiny - GLfloat ambientCabLight[4]= { 0.5f, 0.5f, 0.5f, 1.0f }; - GLfloat diffuseCabLight[4]= { 0.5f, 0.5f, 0.5f, 1.0f }; - GLfloat specularCabLight[4]= { 0.5f, 0.5f, 0.5f, 1.0f }; - for (int li=0; li<3; li++) - { - ambientCabLight[li]= Global::ambientDayLight[li]*0.9; - diffuseCabLight[li]= Global::diffuseDayLight[li]*0.5; - specularCabLight[li]= Global::specularDayLight[li]*0.5; - } - switch (MyTrack->eEnvironment) - { - case e_canyon: - { - for (int li=0; li<3; li++) - { - diffuseCabLight[li]*= 0.6; - specularCabLight[li]*= 0.8; - } - } - break; - case e_tunnel: - { - for (int li=0; li<3; li++) - { - ambientCabLight[li]*= 0.3; - diffuseCabLight[li]*= 0.1; - specularCabLight[li]*= 0.2; - } - } - break; - } - // dorobic swiatlo od drugiej strony szyby - - glLightfv(GL_LIGHT0,GL_AMBIENT,ambientCabLight); - glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseCabLight); - glLightfv(GL_LIGHT0,GL_SPECULAR,specularCabLight); - - mdKabina->RenderAlpha(ObjSqrDist,0); - //smierdzi - // mdModel->RenderAlpha(SquareMagnitude(Global::pCameraPosition-pos),0); - - glLightfv(GL_LIGHT0,GL_AMBIENT,Global::ambientDayLight); - glLightfv(GL_LIGHT0,GL_DIFFUSE,Global::diffuseDayLight); - glLightfv(GL_LIGHT0,GL_SPECULAR,Global::specularDayLight); - } - */ +#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 diff --git a/Globals.cpp b/Globals.cpp index 348fa827..fcd165a6 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -90,12 +90,16 @@ double Global::fFogEnd = 2000; float Global::Background[3] = {0.2, 0.4, 0.33}; GLfloat Global::AtmoColor[] = {0.423f, 0.702f, 1.0f}; GLfloat Global::FogColor[] = {0.6f, 0.7f, 0.8f}; +#ifdef EU07_USE_OLD_LIGHTING_MODEL GLfloat Global::ambientDayLight[] = {0.40f, 0.40f, 0.45f, 1.0f}; // robocze GLfloat Global::diffuseDayLight[] = {0.55f, 0.54f, 0.50f, 1.0f}; GLfloat Global::specularDayLight[] = {0.95f, 0.94f, 0.90f, 1.0f}; GLfloat Global::ambientLight[] = {0.80f, 0.80f, 0.85f, 1.0f}; // stałe 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; +#endif GLfloat Global::whiteLight[] = {1.00f, 1.00f, 1.00f, 1.0f}; GLfloat Global::noLight[] = {0.00f, 0.00f, 0.00f, 1.0f}; GLfloat Global::darkLight[] = {0.03f, 0.03f, 0.03f, 1.0f}; //śladowe diff --git a/Globals.h b/Globals.h index 2793ed30..e20c581a 100644 --- a/Globals.h +++ b/Globals.h @@ -120,6 +120,53 @@ class cParser; // nowy (powolny!) parser class TEvent; class TTextSound; +// bare-bones render controller, in lack of anything better yet +struct opengl_renderer { + + GLenum static const sunlight{ GL_LIGHT0 }; + GLenum static const ambientlight{ GL_LIGHT1 }; + + enum class rendermode { + color + }; + + rendermode renderpass{ rendermode::color }; +}; + +struct opengl_light { + + GLuint id{ -1 }; + Math3D::vector3 direction; + GLfloat position[ 4 ]; // 4th parameter specifies directional(0) or omni-directional(1) light source + GLfloat ambient[ 4 ]; + GLfloat diffuse[ 4 ]; + 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; + } + + inline + void apply_intensity() { + + glLightfv( id, GL_AMBIENT, ambient ); + glLightfv( id, GL_DIFFUSE, diffuse ); + glLightfv( id, GL_SPECULAR, specular ); + } + inline + void apply_angle() { + + glLightfv( id, GL_POSITION, position ); + if( position[ 3 ] == 1.0f ) { + GLfloat directionarray[] = { direction.x, direction.y, direction.z }; + glLightfv( id, GL_SPOT_DIRECTION, directionarray ); + } + } +}; + class TTranscript { // klasa obsługująca linijkę napisu do dźwięku public: @@ -220,12 +267,18 @@ class Global static GLfloat AtmoColor[]; static GLfloat FogColor[]; // static bool bTimeChange; +#ifdef EU07_USE_OLD_LIGHTING_MODEL + static opengl_light AmbientLight; + static GLfloat ambientDayLight[]; static GLfloat diffuseDayLight[]; static GLfloat specularDayLight[]; static GLfloat ambientLight[]; static GLfloat diffuseLight[]; static GLfloat specularLight[]; +#else + static opengl_light DayLight; +#endif static GLfloat whiteLight[]; static GLfloat noLight[]; static GLfloat darkLight[]; diff --git a/Ground.cpp b/Ground.cpp index b1d55d3c..5afdccca 100644 --- a/Ground.cpp +++ b/Ground.cpp @@ -327,9 +327,15 @@ void TGroundNode::RenderVBO() if (linealpha > 255) linealpha = 255; float r, g, b; - r = floor(Diffuse[0] * Global::ambientDayLight[0]); // w zaleznosci od koloru swiatla - g = floor(Diffuse[1] * Global::ambientDayLight[1]); - b = floor(Diffuse[2] * Global::ambientDayLight[2]); +#ifdef EU07_USE_OLD_LIGHTING_MODEL + r = floor( Diffuse[ 0 ] * Global::ambientDayLight[ 0 ] ); // w zaleznosci od koloru swiatla + g = floor( Diffuse[ 1 ] * Global::ambientDayLight[ 1 ] ); + b = floor( Diffuse[ 2 ] * Global::ambientDayLight[ 2 ] ); +#else + r = floor( Diffuse[ 0 ] * Global::DayLight.ambient[ 0 ] ); // w zaleznosci od koloru swiatla + g = floor( Diffuse[ 1 ] * Global::DayLight.ambient[ 1 ] ); + b = floor( Diffuse[ 2 ] * Global::DayLight.ambient[ 2 ] ); +#endif glColor4ub(r, g, b, linealpha); // przezroczystosc dalekiej linii // glDisable(GL_LIGHTING); //nie powinny świecić glDrawArrays(iType, iVboPtr, iNumPts); // rysowanie linii @@ -388,9 +394,15 @@ void TGroundNode::RenderAlphaVBO() float linealpha = 255000 * fLineThickness / (mgn + 1.0); if (linealpha > 255) linealpha = 255; - r = Diffuse[0] * Global::ambientDayLight[0]; // w zaleznosci od koloru swiatla - g = Diffuse[1] * Global::ambientDayLight[1]; - b = Diffuse[2] * Global::ambientDayLight[2]; +#ifdef EU07_USE_OLD_LIGHTING_MODEL + r = Diffuse[ 0 ] * Global::ambientDayLight[ 0 ]; // w zaleznosci od koloru swiatla + g = Diffuse[ 1 ] * Global::ambientDayLight[ 1 ]; + b = Diffuse[ 2 ] * Global::ambientDayLight[ 2 ]; +#else + r = Diffuse[ 0 ] * Global::DayLight.ambient[ 0 ]; // w zaleznosci od koloru swiatla + g = Diffuse[ 1 ] * Global::DayLight.ambient[ 1 ]; + b = Diffuse[ 2 ] * Global::DayLight.ambient[ 2 ]; +#endif glColor4ub(r, g, b, linealpha); // przezroczystosc dalekiej linii // glDisable(GL_LIGHTING); //nie powinny świecić glDrawArrays(iType, iVboPtr, iNumPts); // rysowanie linii @@ -583,9 +595,15 @@ void TGroundNode::RenderDL() // if (iNumPts) { // wszelkie linie są rysowane na samym końcu float r, g, b; - r = Diffuse[0] * Global::ambientDayLight[0]; // w zaleznosci od koloru swiatla - g = Diffuse[1] * Global::ambientDayLight[1]; - b = Diffuse[2] * Global::ambientDayLight[2]; +#ifdef EU07_USE_OLD_LIGHTING_MODEL + r = Diffuse[ 0 ] * Global::ambientDayLight[ 0 ]; // w zaleznosci od koloru swiatla + g = Diffuse[ 1 ] * Global::ambientDayLight[ 1 ]; + b = Diffuse[ 2 ] * Global::ambientDayLight[ 2 ]; +#else + r = Diffuse[ 0 ] * Global::DayLight.ambient[ 0 ]; // w zaleznosci od koloru swiatla + g = Diffuse[ 1 ] * Global::DayLight.ambient[ 1 ]; + b = Diffuse[ 2 ] * Global::DayLight.ambient[ 2 ]; +#endif glColor4ub(r, g, b, 1.0); glCallList(DisplayListID); // glColor4fv(Diffuse); //przywrócenie koloru @@ -659,9 +677,15 @@ void TGroundNode::RenderAlphaDL() float linealpha = 255000 * fLineThickness / (mgn + 1.0); if (linealpha > 255) linealpha = 255; - r = Diffuse[0] * Global::ambientDayLight[0]; // w zaleznosci od koloru swiatla - g = Diffuse[1] * Global::ambientDayLight[1]; - b = Diffuse[2] * Global::ambientDayLight[2]; +#ifdef EU07_USE_OLD_LIGHTING_MODEL + r = Diffuse[ 0 ] * Global::ambientDayLight[ 0 ]; // w zaleznosci od koloru swiatla + g = Diffuse[ 1 ] * Global::ambientDayLight[ 1 ]; + b = Diffuse[ 2 ] * Global::ambientDayLight[ 2 ]; +#else + r = Diffuse[ 0 ] * Global::DayLight.ambient[ 0 ]; // w zaleznosci od koloru swiatla + g = Diffuse[ 1 ] * Global::DayLight.ambient[ 1 ]; + b = Diffuse[ 2 ] * Global::DayLight.ambient[ 2 ]; +#endif glColor4ub(r, g, b, linealpha); // przezroczystosc dalekiej linii glCallList(DisplayListID); } @@ -2454,15 +2478,20 @@ void TGround::FirstInit() 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 @@ -2472,6 +2501,7 @@ void TGround::FirstInit() 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 @@ -2837,6 +2867,7 @@ bool TGround::Init(std::string asFile, HDC hDC) else if (str == "light") { // Ra: ustawianie światła przeniesione do FirstInit WriteLog("Scenery light definition"); +#ifdef EU07_USE_OLD_LIGHTING_MODEL vector3 lp; parser.getTokens(); parser >> lp.x; @@ -2848,27 +2879,44 @@ bool TGround::Init(std::string asFile, HDC hDC) Global::lightPos[0] = lp.x; // daylight position Global::lightPos[1] = lp.y; Global::lightPos[2] = lp.z; - parser.getTokens(); - parser >> Global::ambientDayLight[0]; // kolor wszechobceny - parser.getTokens(); - parser >> Global::ambientDayLight[1]; - parser.getTokens(); - parser >> Global::ambientDayLight[2]; - - parser.getTokens(); - parser >> Global::diffuseDayLight[0]; // kolor padający - parser.getTokens(); - parser >> Global::diffuseDayLight[1]; - parser.getTokens(); - parser >> Global::diffuseDayLight[2]; - - parser.getTokens(); - parser >> Global::specularDayLight[0]; // kolor odbity - parser.getTokens(); - parser >> Global::specularDayLight[1]; - parser.getTokens(); - parser >> Global::specularDayLight[2]; +#else + parser.getTokens(3, false); + parser + >> Global::DayLight.direction.x + >> Global::DayLight.direction.y + >> Global::DayLight.direction.z;; + Global::DayLight.direction.Normalize(); +#endif + parser.getTokens(9, false); +#ifdef EU07_USE_OLD_LIGHTING_MODEL + parser + >> Global::ambientDayLight[ 0 ] + >> Global::ambientDayLight[ 1 ] + >> Global::ambientDayLight[ 2 ] + >> Global::diffuseDayLight[ 0 ] + >> Global::diffuseDayLight[ 1 ] + >> Global::diffuseDayLight[ 2 ] + >> Global::specularDayLight[ 0 ] + >> Global::specularDayLight[ 1 ] + >> Global::specularDayLight[ 2 ]; +#else +/* + parser + // kolor wszechobceny + >> Global::DayLight.ambient[0] + >> Global::DayLight.ambient[1] + >> Global::DayLight.ambient[2] + // kolor padający + >> Global::DayLight.diffuse[0] + >> Global::DayLight.diffuse[1] + >> Global::DayLight.diffuse[2] + // kolor odbity + >> Global::DayLight.specular[0] + >> Global::DayLight.specular[1] + >> Global::DayLight.specular[2]; +*/ +#endif do { parser.getTokens(); diff --git a/Track.cpp b/Track.cpp index d36b4016..10eab7a7 100644 --- a/Track.cpp +++ b/Track.cpp @@ -2583,6 +2583,8 @@ void TTrack::RaRenderVBO(int iPtr) void TTrack::EnvironmentSet() { // ustawienie zmienionego światła glColor3f(1.0f, 1.0f, 1.0f); // Ra: potrzebne to? +#ifdef EU07_USE_OLD_LIGHTING_MODEL + // TODO: re-implement this if (eEnvironment) { // McZapkie-310702: zmiana oswietlenia w tunelu, wykopie GLfloat ambientLight[4] = {0.5f, 0.5f, 0.5f, 1.0f}; @@ -2614,10 +2616,13 @@ void TTrack::EnvironmentSet() break; } } +#endif }; void TTrack::EnvironmentReset() { // przywrócenie domyślnego światła +#ifdef EU07_USE_OLD_LIGHTING_MODEL + // TODO: re-implement this switch (eEnvironment) { // przywrócenie globalnych ustawień światła, o ile było zmienione case e_canyon: // wykop @@ -2626,6 +2631,7 @@ void TTrack::EnvironmentReset() glLightfv(GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight); glLightfv(GL_LIGHT0, GL_SPECULAR, Global::specularDayLight); } +#endif }; void TTrack::RenderDyn() diff --git a/Traction.cpp b/Traction.cpp index c9a2bdf2..e5a17614 100644 --- a/Traction.cpp +++ b/Traction.cpp @@ -323,9 +323,15 @@ void TTraction::RenderDL(float mgn) // McZapkie: mgn to odleglosc od obserwatora g *= 0.6; b *= 0.6; } - r *= Global::ambientDayLight[0]; // w zaleźności od koloru swiatła - g *= Global::ambientDayLight[1]; - b *= Global::ambientDayLight[2]; +#ifdef EU07_USE_OLD_LIGHTING_MODEL + r *= Global::ambientDayLight[ 0 ]; // w zaleźności od koloru swiatła + g *= Global::ambientDayLight[ 1 ]; + b *= Global::ambientDayLight[ 2 ]; +#else + r *= Global::DayLight.ambient[ 0 ]; // w zaleźności od koloru swiatła + g *= Global::DayLight.ambient[ 1 ]; + b *= Global::DayLight.ambient[2]; +#endif if (linealpha > 1.0) linealpha = 1.0; // trzeba ograniczyć do <=1 glColor4f(r, g, b, linealpha); @@ -527,9 +533,15 @@ void TTraction::RenderVBO(float mgn, int iPtr) b = 0.0; break; //żółte z podłączonym zasilaniem z obu stron } - r = r * Global::ambientDayLight[0]; // w zaleznosci od koloru swiatla - g = g * Global::ambientDayLight[1]; - b = b * Global::ambientDayLight[2]; +#ifdef EU07_USE_OLD_LIGHTING_MODEL + r *= Global::ambientDayLight[ 0 ]; // w zaleźności od koloru swiatła + g *= Global::ambientDayLight[ 1 ]; + b *= Global::ambientDayLight[ 2 ]; +#else + r *= Global::DayLight.ambient[ 0 ]; // w zaleźności od koloru swiatła + g *= Global::DayLight.ambient[ 1 ]; + b *= Global::DayLight.ambient[ 2 ]; +#endif if (linealpha > 1.0) linealpha = 1.0; // trzeba ograniczyć do <=1 glColor4f(r, g, b, linealpha); diff --git a/World.cpp b/World.cpp index c0188625..ed342300 100644 --- a/World.cpp +++ b/World.cpp @@ -347,7 +347,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) // glLineWidth(2.0f); WriteLog("glPointSize(2.0f);"); glPointSize(2.0f); - +#ifdef EU07_USE_OLD_LIGHTING_MODEL // ----------- LIGHTING SETUP ----------- // Light values and coordinates @@ -359,7 +359,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) Global::lightPos[3] = 0.0f; // Ra: światła by sensowniej było ustawiać po wczytaniu scenerii - + // TODO: re-implement this // Ra: szczątkowe światło rozproszone - żeby było cokolwiek widać w ciemności WriteLog("glLightModelfv(GL_LIGHT_MODEL_AMBIENT,darkLight);"); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, Global::darkLight); @@ -375,7 +375,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) glLightfv(GL_LIGHT0, GL_POSITION, Global::lightPos); WriteLog("glEnable(GL_LIGHT0);"); glEnable(GL_LIGHT0); - +#endif // glColor() ma zmieniać kolor wybrany w glColorMaterial() WriteLog("glEnable(GL_COLOR_MATERIAL);"); glEnable(GL_COLOR_MATERIAL); @@ -470,13 +470,22 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) SetForegroundWindow(hWnd); WriteLog("Sound Init"); + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + glDisable( GL_DEPTH_TEST ); // Disables depth testing +#ifndef EU07_USE_OLD_LIGHTING_MODEL + glEnable( GL_LIGHTING ); + glEnable( GL_LIGHT0 ); +#endif + glLoadIdentity(); // glColor4f(0.3f,0.0f,0.0f,0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glTranslatef(0.0f, 0.0f, -0.50f); // glRasterPos2f(-0.25f, -0.10f); - glDisable(GL_DEPTH_TEST); // Disables depth testing - glColor3f(3.0f, 3.0f, 3.0f); +#ifdef EU07_USE_OLD_LIGHTING_MODEL + glColor3f( 3.0f, 3.0f, 3.0f ); +#else + glColor3f( 1.0f, 1.0f, 1.0f ); +#endif auto logo = TextureManager.GetTextureId( "logo", szTexturePath, 6 ); TextureManager.Bind(logo); // Select our texture @@ -492,7 +501,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) glVertex3f(-0.28f, 0.22f, 0.0f); // top left of the texture and quad glEnd(); //~logo; Ra: to jest bez sensu zapis - glColor3f(0.0f, 0.0f, 100.0f); + glColor3f(0.0f, 0.0f, 1.0f); if (Global::detonatoryOK) { glRasterPos2f(-0.25f, -0.09f); @@ -502,7 +511,6 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) } SwapBuffers(hDC); // Swap Buffers (Double Buffering) - glEnable(GL_LIGHTING); /*-----------------------Sound Initialization-----------------------*/ TSoundsManager::Init(hWnd); // TSoundsManager::LoadSounds( "" ); @@ -562,8 +570,26 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) } SwapBuffers(hDC); // Swap Buffers (Double Buffering) +#ifndef EU07_USE_OLD_LIGHTING_MODEL + // setup lighting +// GLfloat ambient[] = { 0.65f, 0.65f, 0.65f, 0.5f }; + GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient ); + + Global::DayLight.id = opengl_renderer::sunlight; + // directional light + // TODO, TBD: test omni-directional variant + Global::DayLight.position[ 3 ] = 1.0f; + ::glLightf( opengl_renderer::sunlight, GL_SPOT_CUTOFF, 90.0 ); + // rgb value for 5780 kelvin + Global::DayLight.diffuse[ 0 ] = 255.0 / 255.0; + Global::DayLight.diffuse[ 1 ] = 242.0 / 255.0; + Global::DayLight.diffuse[ 2 ] = 231.0 / 255.0; +#endif + Ground.Init(Global::SceneryFile, hDC); // Global::tSinceStart= 0; + Sun.init(); Clouds.Init(); WriteLog("Ground init OK"); if (Global::detonatoryOK) @@ -1401,6 +1427,7 @@ void TWorld::Update_Lights() { return; } +#ifdef EU07_USE_OLD_LIGHTING_MODEL // double a=Global::fTimeAngleDeg/180.0*M_PI-M_PI; //kąt godzinny w radianach double a = fmod( Global::fTimeAngleDeg, 360.0 ) / 180.0 * M_PI - M_PI; // kąt godzinny w radianach @@ -1478,7 +1505,32 @@ void TWorld::Update_Lights() { +0.150 * ( Global::diffuseDayLight[ 0 ] + Global::ambientDayLight[ 0 ] ) // R + 0.295 * ( Global::diffuseDayLight[ 1 ] + Global::ambientDayLight[ 1 ] ) // G + 0.055 * ( Global::diffuseDayLight[ 2 ] + Global::ambientDayLight[ 2 ] ); // B - +#else + Sun.update(); + auto const position = Sun.getPosition(); + Global::DayLight.position[0] = position.x; + Global::DayLight.position[1] = position.y; + Global::DayLight.position[2] = position.z; + auto const direction = -1.0 * Sun.getDirection(); + Global::DayLight.direction = direction; + auto const intensity = std::min( 2.0f * Sun.getIntensity(), 1.0f ); + + Global::DayLight.diffuse[ 0 ] = 255.0 / 255.0 * intensity; + Global::DayLight.diffuse[ 1 ] = 242.0 / 255.0 * intensity; + Global::DayLight.diffuse[ 2 ] = 231.0 / 255.0 * intensity; +// Global::DayLight.diffuse[ 3 ] = 1.0f;// std::min( 0.15f + intensity, 1.0f ); + Global::DayLight.ambient[ 0 ] = 205.0 / 255.0 * intensity * 0.75f; + Global::DayLight.ambient[ 1 ] = 217.0 / 255.0 * intensity * 0.75f; + Global::DayLight.ambient[ 2 ] = 231.0 / 255.0 * intensity * 0.75f; +// Global::DayLight.ambient[ 3 ] = 1.0f; + /* + // Global::DayLight.ambient[ 3 ] = intensity; + GLfloat ambient[] = { 0.1f + 0.5f * intensity, 0.1f + 0.5f * intensity, 0.1f + 0.5f * intensity, 0.5f }; + ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient ); +*/ + Global::fLuminance = intensity; +#endif + vector3 sky = vector3( Global::AtmoColor[ 0 ], Global::AtmoColor[ 1 ], Global::AtmoColor[ 2 ] ); if( Global::fLuminance < 0.25 ) { // przyspieszenie zachodu/wschodu sky *= 4.0 * Global::fLuminance; // nocny kolor nieba @@ -1503,14 +1555,20 @@ bool TWorld::Render() glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix glLoadIdentity(); Camera.SetMatrix(); // ustawienie macierzy kamery względem początku scenerii - glLightfv(GL_LIGHT0, GL_POSITION, Global::lightPos); - if (!Global::bWireFrame) - { // bez nieba w trybie rysowania linii - glDisable(GL_FOG); + if( !Global::bWireFrame ) { // bez nieba w trybie rysowania linii + glDisable( GL_FOG ); Clouds.Render(); - glEnable(GL_FOG); + glEnable( GL_FOG ); } + +#ifdef EU07_USE_OLD_LIGHTING_MODEL + glLightfv(GL_LIGHT0, GL_POSITION, Global::lightPos); +#else + Sun.render( Camera.Pos ); + Global::DayLight.apply_angle(); + Global::DayLight.apply_intensity(); +#endif if (Global::bUseVBO) { // renderowanie przez VBO if (!Ground.RenderVBO(Camera.Pos)) @@ -1693,7 +1751,10 @@ TWorld::Render_Cab() { glEnable( GL_LIGHTING ); // po renderowaniu drutów może być to wyłączone if( dynamic->mdKabina ) // bo mogła zniknąć przy przechodzeniu do innego pojazdu - { // oswietlenie kabiny + { +#ifdef EU07_USE_OLD_LIGHTING_MODEL + // TODO: re-implement this + // oswietlenie kabiny GLfloat ambientCabLight[ 4 ] = { 0.5f, 0.5f, 0.5f, 1.0f }; GLfloat diffuseCabLight[ 4 ] = { 0.5f, 0.5f, 0.5f, 1.0f }; GLfloat specularCabLight[ 4 ] = { 0.5f, 0.5f, 0.5f, 1.0f }; @@ -1773,6 +1834,7 @@ TWorld::Render_Cab() { glLightfv( GL_LIGHT0, GL_AMBIENT, ambientCabLight ); glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseCabLight ); glLightfv( GL_LIGHT0, GL_SPECULAR, specularCabLight ); +#endif if( Global::bUseVBO ) { // renderowanie z użyciem VBO dynamic->mdKabina->RaRender( 0.0, dynamic->ReplacableSkinID, dynamic->iAlpha ); dynamic->mdKabina->RaRenderAlpha( 0.0, dynamic->ReplacableSkinID, dynamic->iAlpha ); @@ -1781,10 +1843,13 @@ TWorld::Render_Cab() { dynamic->mdKabina->Render( 0.0, dynamic->ReplacableSkinID, dynamic->iAlpha ); dynamic->mdKabina->RenderAlpha( 0.0, dynamic->ReplacableSkinID, dynamic->iAlpha ); } +#ifdef EU07_USE_OLD_LIGHTING_MODEL + // TODO: re-implement this // przywrócenie standardowych, bo zawsze są zmieniane glLightfv( GL_LIGHT0, GL_AMBIENT, Global::ambientDayLight ); glLightfv( GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight ); glLightfv( GL_LIGHT0, GL_SPECULAR, Global::specularDayLight ); +#endif } glPopMatrix(); } diff --git a/World.h b/World.h index f710a515..61742e6b 100644 --- a/World.h +++ b/World.h @@ -13,6 +13,7 @@ http://mozilla.org/MPL/2.0/. #include "Camera.h" #include "Ground.h" #include "sky.h" +#include "sun.h" #include "mczapkie/mover.h" class TWorld @@ -53,6 +54,7 @@ class TWorld GLuint base; // numer DL dla znaków w napisach texture_manager::size_type light; // numer tekstury dla smugi TSky Clouds; + cSun Sun; TEvent *KeyEvents[10]; // eventy wyzwalane z klawiaury TMoverParameters *mvControlled; // wskaźnik na człon silnikowy, do wyświetlania jego parametrów int iCheckFPS; // kiedy znów sprawdzić FPS, żeby wyłączać optymalizacji od razu do zera diff --git a/maszyna.vcxproj b/maszyna.vcxproj index 2797b436..e15e29cf 100644 --- a/maszyna.vcxproj +++ b/maszyna.vcxproj @@ -128,6 +128,7 @@ Create Create + @@ -186,6 +187,7 @@ + diff --git a/maszyna.vcxproj.filters b/maszyna.vcxproj.filters index fed256d5..994b2526 100644 --- a/maszyna.vcxproj.filters +++ b/maszyna.vcxproj.filters @@ -189,6 +189,9 @@ Source Files + + Source Files + @@ -365,6 +368,9 @@ Header Files\console + + Header Files + diff --git a/sky.cpp b/sky.cpp index fd622f47..0febec09 100644 --- a/sky.cpp +++ b/sky.cpp @@ -32,13 +32,22 @@ void TSky::Init() void TSky::Render() { +#ifndef EU07_USE_OLD_LIGHTING_MODEL + return; +#endif if (mdCloud) { // jeśli jest model nieba + glDisable(GL_DEPTH_TEST); + glDepthMask( GL_FALSE ); glPushMatrix(); - // glDisable(GL_DEPTH_TEST); glTranslatef(Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z); +#ifdef EU07_USE_OLD_LIGHTING_MODEL + // TODO: re-implement this glLightfv(GL_LIGHT0, GL_POSITION, lightPos); +#else + glDisable( GL_LIGHTING ); +#endif if (Global::bUseVBO) { // renderowanie z VBO mdCloud->RaRender(100, 0); @@ -49,11 +58,15 @@ void TSky::Render() mdCloud->Render(100, 0); mdCloud->RenderAlpha(100, 0); } - // glEnable(GL_DEPTH_TEST); - glClear(GL_DEPTH_BUFFER_BIT); - // glEnable(GL_LIGHTING); glPopMatrix(); +#ifdef EU07_USE_OLD_LIGHTING_MODEL + // TODO: re-implement this glLightfv(GL_LIGHT0, GL_POSITION, Global::lightPos); +#else + glEnable( GL_LIGHTING ); +#endif + glDepthMask( GL_TRUE ); + glEnable( GL_DEPTH_TEST ); } }; diff --git a/sun.cpp b/sun.cpp new file mode 100644 index 00000000..4d21f62d --- /dev/null +++ b/sun.cpp @@ -0,0 +1,298 @@ + +#include "stdafx.h" +#include "sun.h" +#include "globals.h" +#include "mtable.h" + +////////////////////////////////////////////////////////////////////////////////////////// +// cSun -- class responsible for dynamic calculation of position and intensity of the Sun, + +cSun::cSun() { + + setLocation( 19.00f, 52.00f ); // default location roughly in centre of Poland + m_observer.press = 1013.0; // surface pressure, millibars + m_observer.temp = 15.0; // ambient dry-bulb temperature, degrees C + + TIME_ZONE_INFORMATION timezoneinfo; // TODO: timezone dependant on geographic location + ::GetTimeZoneInformation( &timezoneinfo ); + m_observer.timezone = -timezoneinfo.Bias / 60.0f; +} + +cSun::~cSun() { gluDeleteQuadric( sunsphere ); } + +void +cSun::init() { + + sunsphere = gluNewQuadric(); + gluQuadricNormals( sunsphere, GLU_SMOOTH ); +} + +void +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 ) ) ); + + m_position = position; +} + +void +cSun::render( Math3D::vector3 const &Origin ) { + +/* + glLightfv(GL_LIGHT0, GL_POSITION, position.getVector() ); // sun + + GLfloat LightPosition[]= { 10.0f, 50.0f, -5.0f, 1.0f }; // ambient + glLightfv(GL_LIGHT1, GL_POSITION, LightPosition ); +*/ + glDisable(GL_LIGHTING); + glDisable(GL_FOG); + glColor4f( 255.0f/255.0f, 242.0f/255.0f, 231.0f/255.0f, 1.f ); + // debug line to locate the sun easier + Math3D::vector3 position = m_position + Origin; + glBegin( GL_LINES ); + glVertex3f( position.x, position.y, position.z ); + glVertex3f( position.x, 0.0f, position.z ); + glEnd(); + glPushMatrix(); + glTranslatef( position.x, position.y, position.z ); + // radius is a result of scaling true distance down to 2km -- it's scaled by equal ratio + gluSphere( sunsphere, (float)(m_body.distance * 9.359157), 12, 12 ); + glPopMatrix(); + glEnable(GL_FOG); + glEnable(GL_LIGHTING); +} + +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.Normalize(); + return position; +} + +float +cSun::getAngle() { + + return (float)m_body.elevref; +} + +float cSun::getIntensity() { + + irradiance(); + return (float)( m_body.etr/ 1399.0 ); // arbitrary scaling factor taken from etrn value +} + +void cSun::setLocation( float const Longitude, float const Latitude ) { + + // convert fraction from geographical base of 6o minutes + m_observer.longitude = (int)Longitude + (Longitude - (int)(Longitude)) * 100.0 / 60.0; + m_observer.latitude = (int)Latitude + (Latitude - (int)(Latitude)) * 100.0 / 60.0 ; +} + +void cSun::setTemperature( float const Temperature ) { + + m_observer.temp = Temperature; +} + +void cSun::setPressure( float const Pressure ) { + + m_observer.press = Pressure; +} + +void cSun::move() { + + static double degrad = 57.295779513; // converts from radians to degrees + static double raddeg = 0.0174532925; // converts from degrees to radians + + SYSTEMTIME localtime; // time for the calculation + time( &localtime ); + + double ut = localtime.wHour + + localtime.wMinute / 60.0 // too low resolution, noticeable skips + + localtime.wSecond / 3600.0; // good enough in normal circumstances +/* + + localtime.wMilliseconds / 3600000.0; // for really smooth movement +*/ + double daynumber = 367 * localtime.wYear + - 7 * ( localtime.wYear + ( localtime.wMonth + 9 ) /12 ) / 4 + + 275 * localtime.wMonth / 9 + + localtime.wDay + - 730530 + + (ut / 24.0); + + // Universal Coordinated (Greenwich standard) time + m_observer.utime = ut * 3600.0; + m_observer.utime = m_observer.utime / 3600.0 - m_observer.timezone; + + // mean longitude + m_body.mnlong = 280.460 + 0.9856474 * daynumber; + m_body.mnlong -= 360.0 * (int) ( m_body.mnlong / 360.0 ); // clamp the range to 0-360 + if( m_body.mnlong < 0.0 ) m_body.mnlong += 360.0; + + // mean anomaly + m_body.mnanom = 357.528 + 0.9856003 * daynumber; + m_body.mnanom -= 360.0 * (int) ( m_body.mnanom / 360.0 ); // clamp the range to 0-360 + if( m_body.mnanom < 0.0 ) m_body.mnanom += 360.0; + + // ecliptic longitude + m_body.eclong = m_body.mnlong + + 1.915 * sin( m_body.mnanom * raddeg ) + + 0.020 * sin ( 2.0 * m_body.mnanom * raddeg ); + m_body.eclong -= 360.0 * (int)( m_body.eclong / 360.0 ); + if( m_body.eclong < 0.0 ) m_body.eclong += 360.0; // clamp the range to 0-360 + + // obliquity of the ecliptic + m_body.ecobli = 23.439 - 4.0e-07 * daynumber; + + // declination + m_body.declin = degrad * asin( sin (m_body.ecobli * raddeg) * sin (m_body.eclong * raddeg) ); + + // right ascension + double top = cos ( raddeg * m_body.ecobli ) * sin ( raddeg * m_body.eclong ); + double bottom = cos ( raddeg * m_body.eclong ); + + m_body.rascen = degrad * atan2( top, bottom ); + if( m_body.rascen < 0.0 ) m_body.rascen += 360.0; // (make it a positive angle) + + // Greenwich mean sidereal time + m_observer.gmst = 6.697375 + 0.0657098242 * daynumber + m_observer.utime; + + m_observer.gmst -= 24.0 * (int)( m_observer.gmst / 24.0 ); + if( m_observer.gmst < 0.0 ) m_observer.gmst += 24.0; + + // local mean sidereal time + m_observer.lmst = m_observer.gmst * 15.0 + m_observer.longitude; + + m_observer.lmst -= 360.0 * (int)( m_observer.lmst / 360.0 ); + if( m_observer.lmst < 0.0 ) m_observer.lmst += 360.0; + + // hour angle + m_body.hrang = m_observer.lmst - m_body.rascen; + + if( m_body.hrang < -180.0 ) m_body.hrang += 360.0; // (force it between -180 and 180 degrees) + else if( m_body.hrang > 180.0 ) m_body.hrang -= 360.0; + + double cz; // cosine of the solar zenith angle + + double tdatcd = cos( raddeg * m_body.declin ); + double tdatch = cos( raddeg * m_body.hrang ); + double tdatcl = cos( raddeg * m_observer.latitude ); + double tdatsd = sin( raddeg * m_body.declin ); + double tdatsl = sin( raddeg * m_observer.latitude ); + + cz = tdatsd * tdatsl + tdatcd * tdatcl * tdatch; + + // (watch out for the roundoff errors) + if( fabs (cz) > 1.0 ) { cz >= 0.0 ? cz = 1.0 : cz = -1.0; } + + m_body.zenetr = acos( cz ) * degrad; + m_body.elevetr = 90.0 - m_body.zenetr; + refract(); + + // additional calculations for proper object sizing. + // orbit eccentricity + double e = 0.016709 - 1.151e-9 * daynumber; + // eccentric anomaly + double E = m_body.mnanom + e * degrad * sin(m_body.mnanom) * ( 1.0 + e * cos(m_body.mnanom) ); + double xv = cos(E) - e; + double yv = sqrt(1.0 - e*e) * sin(E); + m_body.distance = sqrt( xv*xv + yv*yv ); +} + +void cSun::refract() { + + static double raddeg = 0.0174532925; // converts from degrees to radians + + double prestemp; // temporary pressure/temperature correction + double refcor; // temporary refraction correction + double tanelev; // tangent of the solar elevation angle + + // if the sun is near zenith, the algorithm bombs; refraction near 0. + if( m_body.elevetr > 85.0 ) + refcor = 0.0; + else { + + tanelev = tan( raddeg * m_body.elevetr ); + if( m_body.elevetr >= 5.0 ) + refcor = 58.1 / tanelev + - 0.07 / pow( tanelev, 3 ) + + 0.000086 / pow( tanelev, 5 ); + else if( m_body.elevetr >= -0.575 ) + refcor = 1735.0 + + m_body.elevetr * ( -518.2 + m_body.elevetr * + ( 103.4 + m_body.elevetr * ( -12.79 + m_body.elevetr * 0.711 ) ) ); + else + refcor = -20.774 / tanelev; + + prestemp = ( m_observer.press * 283.0 ) / ( 1013.0 * ( 273.0 + m_observer.temp ) ); + refcor *= prestemp / 3600.0; + } + + // refracted solar elevation angle + m_body.elevref = m_body.elevetr + refcor; + + // refracted solar zenith angle + m_body.zenref = 90.0 - m_body.elevref; +} + +void cSun::irradiance() { + + static double degrad = 57.295779513; // converts from radians to degrees + static double raddeg = 0.0174532925; // converts from degrees to radians + + SYSTEMTIME localtime; // time for the calculation + time( &localtime ); + + m_body.dayang = ( yearday( localtime.wDay, localtime.wMonth, localtime.wYear ) - 1 ) * 360.0 / 365.0; + double sd = sin( raddeg * m_body.dayang ); // sine of the day angle + double cd = cos( raddeg * m_body.dayang ); // cosine of the day angle or delination + m_body.erv = 1.000110 + 0.034221*cd + 0.001280*sd; + double d2 = 2.0 * m_body.dayang; + double c2 = cos( raddeg * d2 ); + double s2 = sin( raddeg * d2 ); + m_body.erv += 0.000719*c2 + 0.000077*s2; + + double solcon = 1367.0; // Solar constant, 1367 W/sq m + + m_body.coszen = cos( raddeg * m_body.zenref ); + if( m_body.coszen > 0.0 ) { + m_body.etrn = solcon * m_body.erv; + m_body.etr = m_body.etrn * m_body.coszen; + } + else { + m_body.etrn = 0.0; + m_body.etr = 0.0; + } +} + +int cSun::yearday( int Day, const int Month, const int Year ) { + + char daytab[ 2 ][ 13 ] = { + { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } + }; + int i, leap; + + leap = ( Year%4 == 0 ) && ( Year%100 != 0 ) || ( Year%400 == 0 ); + for( i = 1; i < Month; ++i ) + Day += daytab[ leap ][ i ]; + + return Day; +} + +// obtains current time for calculations +void +cSun::time( SYSTEMTIME *Time ) { + + ::GetLocalTime( Time ); + // NOTE: we're currently using local time to determine day/month/year + // TODO: enter scenario-defined day/month/year instead. + Time->wHour = GlobalTime->hh; + Time->wMinute = GlobalTime->mm; + Time->wSecond = std::floor( GlobalTime->mr ); +} diff --git a/sun.h b/sun.h new file mode 100644 index 00000000..8863795e --- /dev/null +++ b/sun.h @@ -0,0 +1,99 @@ +#pragma once + +#include "windows.h" +#include "opengl/glew.h" +#include "opengl/wglew.h" +#include "dumb3d.h" + + +////////////////////////////////////////////////////////////////////////////////////////// +// cSun -- class responsible for dynamic calculation of position and intensity of the Sun, +// given current weather, time and geographic location. + +class cSun { + +public: +// types: + +// methods: + void init(); + void update(); + void render( Math3D::vector3 const &Origin ); + // returns location of the sun in the 3d scene + Math3D::vector3 getPosition() { return m_position; } + // returns vector pointing at the sun + Math3D::vector3 getDirection(); + // returns current elevation above horizon + float getAngle(); + // returns current intensity of the sun + float getIntensity(); + // sets current geographic location + void setLocation( float const Longitude, float const Latitude ); + // sets ambient temperature in degrees C. + void setTemperature( float const Temperature ); + // sets surface pressure in milibars + void setPressure( float const Pressure ); + +// constructors: + cSun(); + +// deconstructor: + ~cSun(); + +// members: + +protected: +// types: + +// methods: + // calculates sun position on the sky given specified time and location + void move(); + // calculates position adjustment due to refraction + void refract(); + // calculates light intensity at current moment + void irradiance(); + // calculates day of year from given date + int yearday( int Day, int const Month, int const Year ); + // obtains current time for calculations + void time( SYSTEMTIME *Time ); + +// members: + GLUquadricObj *sunsphere; // temporary handler for sun positioning test + + struct celestialbody { // main planet parameters + + double dayang; // day angle (daynum*360/year-length) degrees + double mnlong; // mean longitude, degrees + double mnanom; // mean anomaly, degrees + double eclong; // ecliptic longitude, degrees. + double ecobli; // obliquity of ecliptic. + double declin; // declination--zenith angle of solar noon at equator, degrees NORTH. + double rascen; // right ascension, degrees + double hrang; // hour angle--hour of sun from solar noon, degrees WEST + double zenetr; // solar zenith angle, no atmospheric correction (= ETR) + double zenref; // solar zenith angle, deg. from zenith, refracted + double coszen; // cosine of refraction corrected solar zenith angle + double elevetr; // solar elevation, no atmospheric correction (= ETR) + double elevref; // solar elevation angle, deg. from horizon, refracted. + double distance; // distance from earth in AUs + double erv; // earth radius vector (multiplied to solar constant) + double etr; // extraterrestrial (top-of-atmosphere) W/sq m global horizontal solar irradiance + double etrn; // extraterrestrial (top-of-atmosphere) W/sq m direct normal solar irradiance + }; + + struct observer { // weather, time and position data in observer's location + + double latitude; // latitude, degrees north (south negative) + double longitude; // longitude, degrees east (west negative) + double utime; // universal (Greenwich) standard time + double timezone; // time zone, east (west negative). USA: Mountain = -7, Central = -6, etc. + double gmst; // Greenwich mean sidereal time, hours + double lmst; // local mean sidereal time, degrees + double temp; // ambient dry-bulb temperature, degrees C, used for refraction correction + double press; // surface pressure, millibars, used for refraction correction and ampress + }; + + celestialbody m_body; + observer m_observer; + Math3D::vector3 m_position; +}; From b93d673edea7d378aa1fcc858c77ed7785d3d5a6 Mon Sep 17 00:00:00 2001 From: maciek001 Date: Fri, 17 Feb 2017 23:04:16 +0100 Subject: [PATCH 02/40] kosmetyka --- Console/MWD.cpp | 56 ++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/Console/MWD.cpp b/Console/MWD.cpp index 2c8c891b..0bcddb9c 100644 --- a/Console/MWD.cpp +++ b/Console/MWD.cpp @@ -231,43 +231,43 @@ void TMWDComm::CheckData() // sprawdzanie wejść cyfrowych i odpowiednie sterow /* Rozpiska portów! Port0: 0 NC odblok. przek. sprężarki i wentyl. oporów - 1 M wyłącznik wył. szybkiego - 2 Shift+M impuls załączający wył. szybki - 3 N odblok. przekaźników nadmiarowych + 1 M wyłącznik wył. szybkiego + 2 Shift+M impuls załączający wył. szybki + 3 N odblok. przekaźników nadmiarowych i różnicowego obwodu głównego - 4 NC rezerwa - 5 Ctrl+N odblok. przek. nadmiarowych + 4 NC rezerwa + 5 Ctrl+N odblok. przek. nadmiarowych przetwornicy, ogrzewania pociągu i różnicowych obw. pomocniczych - 6 L wył. styczników liniowych - 7 SPACE kasowanie czuwaka + 6 L wył. styczników liniowych + 7 SPACE kasowanie czuwaka Port1: 0 NC - 1 (Shift) X przetwornica - 2 (Shift) C sprężarka - 3 S piasecznice - 4 (Shift) H ogrzewanie składu - 5 przel. hamowania Shift+B + 1 (Shift) X przetwornica + 2 (Shift) C sprężarka + 3 S piasecznice + 4 (Shift) H ogrzewanie składu + 5 przel. hamowania Shift+B pspbpwy Ctrl+B pospieszny B towarowy - 6 przel. hamowania - 7 (Shift) F rozruch w/n + 6 przel. hamowania + 7 (Shift) F rozruch w/n Port2: 0 (Shift) P pantograf przedni - 1 (Shift) O pantograf tylni - 2 ENTER przyhamowanie przy poślizgu - 3 () przyciemnienie świateł - 4 () przyciemnienie świateł - 5 NUM6 odluźniacz - 6 a syrena lok W - 7 A syrena lok N + 1 (Shift) O pantograf tylni + 2 ENTER przyhamowanie przy poślizgu + 3 () przyciemnienie świateł + 4 () przyciemnienie świateł + 5 NUM6 odluźniacz + 6 a syrena lok W + 7 A syrena lok N Port3: 0 Shift+J bateria - 1 - 2 - 3 - 4 - 5 - 6 - 7 + 1 + 2 + 3 + 4 + 5 + 6 + 7 */ /* po przełączeniu bistabilnego najpierw wciskamy klawisz i przy następnym From 4ae03170f39accdebc93ae0b09c2fa8d6be034e6 Mon Sep 17 00:00:00 2001 From: maciek001 Date: Sat, 18 Feb 2017 16:11:46 +0100 Subject: [PATCH 03/40] =?UTF-8?q?usun=C4=85=C5=82em=20"inline"=20przy=20Ge?= =?UTF-8?q?tMWEState=20-=20powodowa=C5=82=20b=C5=82=C4=85d=20linkera=20prz?= =?UTF-8?q?y=20budowaniu=20RELASE'a?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Console/MWD.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Console/MWD.cpp b/Console/MWD.cpp index 0bcddb9c..67e08f46 100644 --- a/Console/MWD.cpp +++ b/Console/MWD.cpp @@ -152,7 +152,7 @@ bool TMWDComm::Close() // zamykanie portu COM return TRUE; } -inline bool TMWDComm::GetMWDState() // sprawdzanie otwarcia portu COM +bool TMWDComm::GetMWDState() // sprawdzanie otwarcia portu COM { if (hComm > 0) return 1; From a1942ce77130bfb9ac6114caf10fc76e0c72e157 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sat, 18 Feb 2017 18:15:39 +0100 Subject: [PATCH 04/40] support for config-specified day of the year --- Globals.cpp | 13 +------------ Texture.cpp | 5 +++++ World.cpp | 6 +++--- parser.cpp | 1 + sun.cpp | 22 +++++++++++++++++++++- sun.h | 2 ++ 6 files changed, 33 insertions(+), 16 deletions(-) diff --git a/Globals.cpp b/Globals.cpp index fcd165a6..837eb88b 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -552,18 +552,7 @@ void Global::ConfigParse(cParser &Parser) std::tm *localtime = std::localtime(&timenow); Global::fMoveLight = localtime->tm_yday + 1; // numer bieżącego dnia w roku } - if (fMoveLight > 0.f) // tu jest nadal zwiększone o 1 - { // obliczenie deklinacji wg: - // http://naturalfrequency.com/Tregenza_Sharples/Daylight_Algorithms/algorithm_1_11.htm - // Spencer J W Fourier series representation of the position of the sun Search 2 (5) - // 172 (1971) - Global::fMoveLight = - M_PI / 182.5 * (Global::fMoveLight - 1.0); // numer dnia w postaci kąta - fSunDeclination = - 0.006918 - 0.3999120 * std::cos(fMoveLight) + 0.0702570 * std::sin(fMoveLight) - - 0.0067580 * std::cos(2 * fMoveLight) + 0.0009070 * std::sin(2 * fMoveLight) - - 0.0026970 * std::cos(3 * fMoveLight) + 0.0014800 * std::sin(3 * fMoveLight); - } + // TODO: calculate lights single time here for static setup. or get rid of static setup } else if (token == "smoothtraction") { diff --git a/Texture.cpp b/Texture.cpp index fb9a4dd0..71c94f9e 100644 --- a/Texture.cpp +++ b/Texture.cpp @@ -505,6 +505,11 @@ opengl_texture::set_filtering() { ::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); ::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); + if( GLEW_EXT_texture_filter_anisotropic ) { + // anisotropic filtering + ::glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f ); + } + bool sharpen{ false }; for( auto const &trait : traits ) { diff --git a/World.cpp b/World.cpp index ed342300..c8670ffb 100644 --- a/World.cpp +++ b/World.cpp @@ -1513,14 +1513,14 @@ void TWorld::Update_Lights() { Global::DayLight.position[2] = position.z; auto const direction = -1.0 * Sun.getDirection(); Global::DayLight.direction = direction; - auto const intensity = std::min( 2.0f * Sun.getIntensity(), 1.0f ); + auto const intensity = std::min( 2.0f * Sun.getIntensity(), 1.25f ); Global::DayLight.diffuse[ 0 ] = 255.0 / 255.0 * intensity; Global::DayLight.diffuse[ 1 ] = 242.0 / 255.0 * intensity; Global::DayLight.diffuse[ 2 ] = 231.0 / 255.0 * intensity; // Global::DayLight.diffuse[ 3 ] = 1.0f;// std::min( 0.15f + intensity, 1.0f ); - Global::DayLight.ambient[ 0 ] = 205.0 / 255.0 * intensity * 0.75f; - Global::DayLight.ambient[ 1 ] = 217.0 / 255.0 * intensity * 0.75f; + Global::DayLight.ambient[ 0 ] = 155.0 / 255.0 * intensity * 0.75f; + Global::DayLight.ambient[ 1 ] = 192.0 / 255.0 * intensity * 0.75f; Global::DayLight.ambient[ 2 ] = 231.0 / 255.0 * intensity * 0.75f; // Global::DayLight.ambient[ 3 ] = 1.0f; /* diff --git a/parser.cpp b/parser.cpp index 46cd8701..9276a063 100644 --- a/parser.cpp +++ b/parser.cpp @@ -67,6 +67,7 @@ cParser::~cParser() // methods bool cParser::getTokens(int Count, bool ToLower, const char *Break) { + tokens.clear(); // emulates old parser behaviour. TODO, TBD: allow manual reset? /* if (LoadTraction==true) trtest="niemaproblema"; //wczytywać diff --git a/sun.cpp b/sun.cpp index 4d21f62d..e571a0a7 100644 --- a/sun.cpp +++ b/sun.cpp @@ -285,13 +285,33 @@ int cSun::yearday( int Day, const int Month, const int Year ) { return Day; } +void cSun::daymonth( WORD &Day, WORD &Month, WORD const Year, WORD const Yearday ) { + + WORD daytab[ 2 ][ 13 ] = { + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } + }; + + int leap = ( Year % 4 == 0 ) && ( Year % 100 != 0 ) || ( Year % 400 == 0 ); + WORD idx = 1; + while( (idx < 13) && ( Yearday <= daytab[ leap ][ idx ] )) { + + ++idx; + } + Month = idx + 1; + Day = Yearday - daytab[ leap ][ idx ]; +} + // obtains current time for calculations void cSun::time( SYSTEMTIME *Time ) { ::GetLocalTime( Time ); // NOTE: we're currently using local time to determine day/month/year - // TODO: enter scenario-defined day/month/year instead. + if( Global::fMoveLight > 0.0 ) { + // TODO: enter scenario-defined day/month/year instead. + daymonth( Time->wDay, Time->wMonth, Time->wYear, static_cast(Global::fMoveLight) ); + } Time->wHour = GlobalTime->hh; Time->wMinute = GlobalTime->mm; Time->wSecond = std::floor( GlobalTime->mr ); diff --git a/sun.h b/sun.h index 8863795e..74349599 100644 --- a/sun.h +++ b/sun.h @@ -54,6 +54,8 @@ protected: void irradiance(); // calculates day of year from given date int yearday( int Day, int const Month, int const Year ); + // calculates day and month from given day of year + void daymonth( WORD &Day, WORD &Month, WORD const Year, WORD const Yearday ); // obtains current time for calculations void time( SYSTEMTIME *Time ); From 7e0aeb1bfa5e1018b9f76ad929950292481fecf6 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sat, 18 Feb 2017 18:53:02 +0100 Subject: [PATCH 05/40] anisotropic filtering support --- Globals.cpp | 8 +++++++- Globals.h | 1 + Texture.cpp | 5 +++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Globals.cpp b/Globals.cpp index 14f3968f..c5e613fc 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -130,6 +130,7 @@ bool Global::bAdjustScreenFreq = true; bool Global::bEnableTraction = true; bool Global::bLoadTraction = true; bool Global::bLiveTraction = true; +float Global::AnisotropicFiltering = 8.0f; // requested level of anisotropic filtering. TODO: move it to renderer object int Global::iDefaultFiltering = 9; // domyślne rozmywanie tekstur TGA bez alfa int Global::iBallastFiltering = 9; // domyślne rozmywanie tekstur podsypki int Global::iRailProFiltering = 5; // domyślne rozmywanie tekstur szyn @@ -465,7 +466,12 @@ void Global::ConfigParse(cParser &Parser) Parser.getTokens(1, false); Parser >> Global::iDynamicFiltering; } - else if (token == "usevbo") + else if( token == "anisotropicfiltering" ) { + + Parser.getTokens( 1, false ); + Parser >> Global::AnisotropicFiltering; + } + else if( token == "usevbo" ) { Parser.getTokens(); diff --git a/Globals.h b/Globals.h index c2b2b708..d63af985 100644 --- a/Globals.h +++ b/Globals.h @@ -237,6 +237,7 @@ class Global static std::string asSky; static bool bnewAirCouplers; // Ra: nowe zmienne globalne + static float AnisotropicFiltering; // requested level of anisotropic filtering. TODO: move it to renderer object static int iDefaultFiltering; // domyślne rozmywanie tekstur TGA static int iBallastFiltering; // domyślne rozmywanie tekstury podsypki static int iRailProFiltering; // domyślne rozmywanie tekstury szyn diff --git a/Texture.cpp b/Texture.cpp index fb9a4dd0..b2f15340 100644 --- a/Texture.cpp +++ b/Texture.cpp @@ -505,6 +505,11 @@ opengl_texture::set_filtering() { ::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); ::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); + if( GLEW_EXT_texture_filter_anisotropic ) { + // anisotropic filtering + ::glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, Global::AnisotropicFiltering ); + } + bool sharpen{ false }; for( auto const &trait : traits ) { From 59ac66c6f8e2ba4fc3b69d7a3d8245259c1cfa9c Mon Sep 17 00:00:00 2001 From: maciek001 Date: Sun, 19 Feb 2017 01:51:30 +0100 Subject: [PATCH 06/40] dodane logowanie przebiegu pracy (RUN) --- Console/MWD.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Console/MWD.cpp b/Console/MWD.cpp index 67e08f46..e6a93008 100644 --- a/Console/MWD.cpp +++ b/Console/MWD.cpp @@ -133,9 +133,11 @@ bool TMWDComm::Open() // otwieranie portu COM bool TMWDComm::Close() // zamykanie portu COM { - Global::bMWDmasterEnable = false; // główne włączenie portu! - Global::bMWDInputEnable = false; // włącz wejścia - Global::bMWDBreakEnable = false; // włącz wejścia analogowe + Global::bMWDmasterEnable = false; // wyłącz SerialPort + Global::bMWDInputEnable = false; // wyłącz wejścia + Global::bMWDBreakEnable = false; // wyłącz wejścia analogowe + Global::bMWDdebugEnable = false; // wyłącz debugowanie + Global::iMWDDebugMode = 0; // wyłącz debugMode! WriteLog("COM Port is closing..."); int i = 0; @@ -164,7 +166,7 @@ bool TMWDComm::ReadData() // odbieranie danych + odczyta danych analogowych i za { DWORD bytes_read; ReadFile(hComm, &ReadDataBuff[0], BYTETOREAD, &bytes_read, NULL); - + if (Global::bMWDdebugEnable && Global::iMWDDebugMode == 128) WriteLog("Data receive. Checking data..."); if (Global::bMWDBreakEnable) { uiAnalog[0] = (ReadDataBuff[9] << 8) + ReadDataBuff[8]; @@ -204,8 +206,11 @@ bool TMWDComm::Run() // wywoływanie obsługi MWD + generacja większego opóźn if (!(MWDTime % Global::iMWDdivider)) { MWDTime = 0; + if (Global::bMWDdebugEnable && Global::iMWDDebugMode == 128) WriteLog("Sending data..."); SendData(); + if (Global::bMWDdebugEnable && Global::iMWDDebugMode == 128) WriteLog(" complet!\nReceiving data..."); ReadData(); + if (Global::bMWDdebugEnable && Global::iMWDDebugMode == 128) WriteLog(" complet!"); return 1; } } From 8cace6f4da35a75e6bd1e65cc98a87e9fa8d4d52 Mon Sep 17 00:00:00 2001 From: maciek001 Date: Sun, 19 Feb 2017 01:54:22 +0100 Subject: [PATCH 07/40] dodane logi --- Console/MWD.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Console/MWD.cpp b/Console/MWD.cpp index 67e08f46..8aca11a0 100644 --- a/Console/MWD.cpp +++ b/Console/MWD.cpp @@ -204,8 +204,11 @@ bool TMWDComm::Run() // wywoływanie obsługi MWD + generacja większego opóźn if (!(MWDTime % Global::iMWDdivider)) { MWDTime = 0; + if (Global::bMWDdebugEnable && Global::iMWDDebugMode == 128) WriteLog("Sending data..."); SendData(); + if (Global::bMWDdebugEnable && Global::iMWDDebugMode == 128) WriteLog(" complet!\nReceiving data..."); ReadData(); + if (Global::bMWDdebugEnable && Global::iMWDDebugMode == 128) WriteLog(" complet!"); return 1; } } From d9860dbdb2a518f1ea1c2e75bda615f331665c1a Mon Sep 17 00:00:00 2001 From: maciek001 Date: Sun, 19 Feb 2017 02:12:07 +0100 Subject: [PATCH 08/40] =?UTF-8?q?przerobione=20hamulce:=20teraz=20AnalogCa?= =?UTF-8?q?librateGet()zwraca=20warto=C5=9B=C4=87=20od=200=20do=201=20i=20?= =?UTF-8?q?dopiero=20w=20Train=20przeliczana=20jest=20warto=C5=9B=C4=87=20?= =?UTF-8?q?na=20po=C5=82o=C5=BCenie=20hamulca.=20Osobno=20hamulec=20FV4a?= =?UTF-8?q?=20i=20osobno=20FVel6.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Console.cpp | 11 +---------- Train.cpp | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Console.cpp b/Console.cpp index d38bb4e9..0000c790 100644 --- a/Console.cpp +++ b/Console.cpp @@ -474,16 +474,7 @@ float Console::AnalogCalibrateGet(int x) if (Global::bMWDmasterEnable && Global::bMWDBreakEnable) { float b = (float)MWDComm->uiAnalog[x]; - b = (b - Global::fMWDAnalogInCalib[x][0]) / (Global::fMWDAnalogInCalib[x][1] - Global::fMWDAnalogInCalib[x][0]); - switch (x) - { - case 0: if (Global::bMWDdebugEnable && Global::iMWDDebugMode & 4) WriteLog("Pozycja kranu = " + to_string(b * 8 - 2)); - return (b * 8 - 2); - break; - case 1: return (b * 10); - break; - default: return 0; - } + return (b - Global::fMWDAnalogInCalib[x][0]) / (Global::fMWDAnalogInCalib[x][1] - Global::fMWDAnalogInCalib[x][0]); } return -1.0; // odcięcie }; diff --git a/Train.cpp b/Train.cpp index e557dcbe..a4b0488d 100644 --- a/Train.cpp +++ b/Train.cpp @@ -3762,11 +3762,20 @@ bool TTrain::Update( double const Deltatime ) false) // nie blokujemy AI { // Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba // Firleju: dlatego kasujemy i zastepujemy funkcją w Console - if (((mvOccupied->BrakeHandle == FV4a) || - (mvOccupied->BrakeHandle == FVel6))) // może można usunąć ograniczenie do FV4a i FVel6? + if (mvOccupied->BrakeHandle == FV4a) + { + double b = Console::AnalogCalibrateGet(0); + b = b * 8 - 2; + b = Global::CutValueToRange(-2.0, b, mvOccupied->BrakeCtrlPosNo); // przycięcie zmiennej do granic + + ggBrakeCtrl.UpdateValue(b); // przesów bez zaokrąglenia + mvOccupied->BrakeLevelSet(b); + } + if (mvOccupied->BrakeHandle == FVel6) // może można usunąć ograniczenie do FV4a i FVel6? { double b = Console::AnalogCalibrateGet(0); - b = Global::CutValueToRange(-2.0, b, mvOccupied->BrakeCtrlPosNo); // przycięcie zmiennej do granic + b = b * 7 - 1; + b = Global::CutValueToRange(-1.0, b, mvOccupied->BrakeCtrlPosNo); // przycięcie zmiennej do granic ggBrakeCtrl.UpdateValue(b); // przesów bez zaokrąglenia mvOccupied->BrakeLevelSet(b); @@ -3789,6 +3798,7 @@ bool TTrain::Update( double const Deltatime ) if ((mvOccupied->BrakeLocHandle == FD1)) { double b = Console::AnalogCalibrateGet(1); + b *= 10; b = Global::CutValueToRange(0.0, b, LocalBrakePosNo); // przycięcie zmiennej do granic ggLocalBrake.UpdateValue(b); // przesów bez zaokrąglenia mvOccupied->LocalBrakePos = From e3811fe9953093e9506b431f0793dd001695459b Mon Sep 17 00:00:00 2001 From: maciek001 Date: Sun, 19 Feb 2017 02:20:23 +0100 Subject: [PATCH 09/40] dodano loga pozycji kranu hamula zespolonego --- Train.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Train.cpp b/Train.cpp index a4b0488d..78a512d7 100644 --- a/Train.cpp +++ b/Train.cpp @@ -3767,7 +3767,7 @@ bool TTrain::Update( double const Deltatime ) double b = Console::AnalogCalibrateGet(0); b = b * 8 - 2; b = Global::CutValueToRange(-2.0, b, mvOccupied->BrakeCtrlPosNo); // przycięcie zmiennej do granic - + if (Global::bMWDdebugEnable && Global::iMWDDebugMode & 4) WriteLog("Pozycja kranu = " + to_string(b)); ggBrakeCtrl.UpdateValue(b); // przesów bez zaokrąglenia mvOccupied->BrakeLevelSet(b); } @@ -3776,7 +3776,7 @@ bool TTrain::Update( double const Deltatime ) double b = Console::AnalogCalibrateGet(0); b = b * 7 - 1; b = Global::CutValueToRange(-1.0, b, mvOccupied->BrakeCtrlPosNo); // przycięcie zmiennej do granic - + if (Global::bMWDdebugEnable && Global::iMWDDebugMode & 4) WriteLog("Pozycja kranu = " + to_string(b)); ggBrakeCtrl.UpdateValue(b); // przesów bez zaokrąglenia mvOccupied->BrakeLevelSet(b); } From da4755c3cc53550a5333abef85a5853b56a90b88 Mon Sep 17 00:00:00 2001 From: maciek001 Date: Sun, 19 Feb 2017 02:37:40 +0100 Subject: [PATCH 10/40] =?UTF-8?q?pr=C4=99dko=C5=9B=C4=87=200=20gdy=20pauza?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Console.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Console.cpp b/Console.cpp index 0000c790..93263ed4 100644 --- a/Console.cpp +++ b/Console.cpp @@ -421,7 +421,8 @@ void Console::ValueSet(int x, double y) MWDComm->WriteDataBuff[20] = (unsigned int)(iliczba >> 8); MWDComm->WriteDataBuff[19] = (unsigned char)iliczba; break; - case 7: MWDComm->WriteDataBuff[0] = (unsigned char)floor(y); // prędkość + case 7: if (Global::iPause) MWDComm->WriteDataBuff[0] = 0; //skoro pauza to hasler stoi i nie nabija kilometrów + else MWDComm->WriteDataBuff[0] = (unsigned char)floor(y); // prędkość dla np haslera break; } } From 658a05a976cff77ce8993bc95f65ba7ca0fa14ff Mon Sep 17 00:00:00 2001 From: maciek001 Date: Sun, 19 Feb 2017 12:49:30 +0100 Subject: [PATCH 11/40] =?UTF-8?q?wy=C5=82=C4=85czanie=20debugowania=20przy?= =?UTF-8?q?=20wy=C5=82=C4=85czaniu=20komunikacji?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Console/MWD.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Console/MWD.cpp b/Console/MWD.cpp index 8aca11a0..020af603 100644 --- a/Console/MWD.cpp +++ b/Console/MWD.cpp @@ -133,9 +133,11 @@ bool TMWDComm::Open() // otwieranie portu COM bool TMWDComm::Close() // zamykanie portu COM { - Global::bMWDmasterEnable = false; // główne włączenie portu! - Global::bMWDInputEnable = false; // włącz wejścia - Global::bMWDBreakEnable = false; // włącz wejścia analogowe + Global::bMWDmasterEnable = false; // główne włączenie portu! + Global::bMWDInputEnable = false; // włącz wejścia + Global::bMWDBreakEnable = false; // włącz wejścia analogowe + Global::bMWDdebugEnable = false; // wyłącz debugowanie + Global::iMWDDebugMode = 0; // wyłącz debugMode! WriteLog("COM Port is closing..."); int i = 0; From 01dff9b85c1951a61b8d4559a6f177a1581a4b6d Mon Sep 17 00:00:00 2001 From: maciek001 Date: Sun, 19 Feb 2017 13:41:11 +0100 Subject: [PATCH 12/40] =?UTF-8?q?dodane=20uzale=C5=BCnienia=20do=20cofania?= =?UTF-8?q?=20famulca=20FVel6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Train.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Train.cpp b/Train.cpp index 78a512d7..ff800230 100644 --- a/Train.cpp +++ b/Train.cpp @@ -3791,7 +3791,7 @@ bool TTrain::Update( double const Deltatime ) if (ggLocalBrake.SubModel) { if (DynamicObject->Mechanik ? - (DynamicObject->Mechanik->AIControllFlag ? false : (Global::iFeedbackMode == 4 || Global::bMWDmasterEnable)) : + (DynamicObject->Mechanik->AIControllFlag ? false : (Global::iFeedbackMode == 4 || (Global::bMWDmasterEnable && Global::bMWDBreakEnable))) : false) // nie blokujemy AI { // Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba // Firleju: dlatego kasujemy i zastepujemy funkcją w Console @@ -4691,7 +4691,7 @@ bool TTrain::Update( double const Deltatime ) if ((!Console::Pressed(Global::Keys[k_DecBrakeLevel])) && (!Console::Pressed(Global::Keys[k_WaveBrake])) && (mvOccupied->BrakeCtrlPos == -1) && (mvOccupied->BrakeHandle == FVel6) && (DynamicObject->Controller != AIdriver) && - (Global::iFeedbackMode != 4)) + (Global::iFeedbackMode != 4 || !(Global::bMWDmasterEnable && Global::bMWDBreakEnable))) { // mvOccupied->BrakeCtrlPos=(mvOccupied->BrakeCtrlPos)+1; // mvOccupied->IncBrakeLevel(); From e06c6b79434793af1c39ad6dc586085a509250e3 Mon Sep 17 00:00:00 2001 From: maciek001 Date: Sun, 19 Feb 2017 13:41:50 +0100 Subject: [PATCH 13/40] =?UTF-8?q?dodane=20info=20na=20ko=C5=84cu=20o=20wpi?= =?UTF-8?q?sach=20do=20ini?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Console/MWD.h | 50 ++++++++++++++++++-------------------------------- 1 file changed, 18 insertions(+), 32 deletions(-) diff --git a/Console/MWD.h b/Console/MWD.h index ad35ee87..ef2ec632 100644 --- a/Console/MWD.h +++ b/Console/MWD.h @@ -70,43 +70,29 @@ public: #endif /* - INFO - zmiany dokonane w innych plikach niezbędne do prawidłowego działania: +INFO - wpisy do eu07.ini: - Console.cpp: - Console::AnalogCalibrateGet - obsługa kranów hamulców - Console::Update - wywoływanie obsługi MWD - Console::ValueSet - obsługa manometrów, mierników WN (PWM-y) - Console::BitsUpdate - ustawiania lampek - Console::Off - zamykanie portu COM - Console::On - otwieranie portu COM - Console::~Console - usuwanie MWD (jest też w Console OFF) +mwdmasterenable yes // włącz MWD (master MWD Enable) +mwddebugenable yes // włącz logowanie +mwddebugmode 4 // tryb debugowania (które logi) - MWDComm * Console::MWD = NULL; - luzem, obiekt i wskaźnik(?) - dodatkowo zmieniłem int na long int dla BitSet i BitClear oraz iBits +mwdcomportname COM3 // nazwa portu +mwdbaudrate 500000 // prędkość transmisji - Train.cpp: - if (Global::iFeedbackMode == 5) - pobieranie prędkości, manometrów i mierników WN - if (ggBrakeCtrl.SubModel) - możliwość sterowania hamulcem zespolonym - if (ggLocalBrake.SubModel) - możliwość sterowania hamulcem lokomotywy +mwdinputenable yes // włącz wejścia (przyciski, przełączniki) +mwdbreakenable yes // włącz hamulce (wejścia analogowe) - Globals.h: - dodano zmienne dla MWD - Globals.cpp: - dodano inicjalizaję zmiennych i odczyt z ini ustawień +mwdmainbreakconfig 0 1023 // konfiguracja kranu zespolonego -> min, max (położenie kranu - odczyt z ADC) +mwdlocbreakconfig 0 1023 // konfiguracja kranu maszynisty -> min, max (położenie kranu - odczyt z ADC) +mwdanalogin2config 0 1023 +mwdanalogin2config 0 1023 - Wpisy do pliku eu07.ini +mwdmaintankpress 0.9 1023 // max ciśnienie w zbiorniku głownym i rozdzielczość +mwdmainpipepress 0.7 1023 // max ciśnienie w przewodzie głównym i rozdzielczość +mwdbreakpress 0.5 1023 // max ciśnienie w cylindrach hamulcowych i rozdzielczość - //maciek001 MWD - comportname COM3 // wybór portu COM - mwdbaudrate 500000 +mwdhivoltmeter 4000 1023 // max napięcie na woltomierzu WN +mwdhiampmeter 800 1023 // max prąd amperomierza WN - mwdbreakenable yes // czy załączyć sterowanie hamulcami? blokuje klawiature - mwdbreak 1 255 0 255 // hamulec zespolony - mwdbreak 2 255 0 255 // hamulec lokomotywy - - mwdzbiornikglowny 0.82 255 - mwdprzewodglowny 0.7 255 - mwdcylinderhamulcowy 0.43 255 - mwdwoltomierzwn 4000 255 - mwdamperomierzwn 800 255 +mwddivider 5 // dzielnik - czym większy tym rzadziej czyta diwajs */ From 8ae135375e675772c1ac4a9694eab522490098d0 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sun, 19 Feb 2017 16:24:10 +0100 Subject: [PATCH 14/40] feature: camera zoom --- DynObj.cpp | 4 ++-- EU07.cpp | 6 +++-- Gauge.cpp | 18 ++++++++------- Globals.cpp | 3 +++ Globals.h | 3 +++ Ground.cpp | 4 ++-- World.cpp | 63 +++++++++++++++++++++++++++++++++++++---------------- 7 files changed, 68 insertions(+), 33 deletions(-) diff --git a/DynObj.cpp b/DynObj.cpp index 0bdfc85b..ed0de3ae 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -3710,7 +3710,7 @@ void TDynamicObject::Render() // zmienne renderme = false; // przeklejka - double ObjSqrDist = SquareMagnitude(Global::pCameraPosition - vPosition); + 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 @@ -3737,7 +3737,7 @@ void TDynamicObject::Render() { TSubModel::iInstance = (int)this; //żeby nie robić cudzych animacji // AnsiString asLoadName=""; - double ObjSqrDist = SquareMagnitude(Global::pCameraPosition - vPosition); + double ObjSqrDist = SquareMagnitude(Global::pCameraPosition - vPosition) / Global::ZoomFactor; ABuLittleUpdate(ObjSqrDist); // ustawianie zmiennych submodeli dla wspólnego modelu // Cone(vCoulpler[0],modelRot.z,0); diff --git a/EU07.cpp b/EU07.cpp index 3a071cd3..b02ef876 100644 --- a/EU07.cpp +++ b/EU07.cpp @@ -85,17 +85,19 @@ int InitGL(GLvoid) // All Setup For OpenGL Goes Here GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // resize and initialize the GL Window { - WindowWidth = width; - WindowHeight = height; + Global::ScreenWidth = WindowWidth = width; + Global::ScreenHeight = WindowHeight = height; if (height == 0) // prevent a divide by zero by height = 1; // making height equal one glViewport(0, 0, width, height); // Reset The Current Viewport +/* glMatrixMode(GL_PROJECTION); // select the Projection Matrix glLoadIdentity(); // reset the Projection Matrix // calculate the aspect ratio of the window gluPerspective(45.0f, (GLdouble)width / (GLdouble)height, 0.2f, 2500.0f); glMatrixMode(GL_MODELVIEW); // select the Modelview Matrix glLoadIdentity(); // reset the Modelview Matrix +*/ } //--------------------------------------------------------------------------- diff --git a/Gauge.cpp b/Gauge.cpp index 04091419..b9870eab 100644 --- a/Gauge.cpp +++ b/Gauge.cpp @@ -175,14 +175,16 @@ void TGauge::Update() */ std::string n( "000000000" + std::to_string( static_cast( std::floor( fValue ) ) ) ); if( n.length() > 10 ) { n.erase( 0, n.length() - 10 ); } // also dumb but should work for now do - { // pętla po submodelach potomnych i obracanie ich o kąt zależy od - // cyfry w (fValue) - if (sm->pName) - { // musi mieć niepustą nazwę - if (sm->pName[0] >= '0') - if (sm->pName[0] <= '9') - sm->SetRotate(float3(0, 1, 0), - -36.0 * (n['0' + 10 - sm->pName[0]] - '0')); + { // pętla po submodelach potomnych i obracanie ich o kąt zależy od cyfry w (fValue) + if( sm->pName ) { + // musi mieć niepustą nazwę + if( ( sm->pName[ 0 ] >= '0' ) + && ( sm->pName[ 0 ] <= '9' ) ) { + + sm->SetRotate( + float3( 0, 1, 0 ), + -36.0 * ( n[ '0' + 9 - sm->pName[ 0 ] ] - '0' ) ); + } } sm = sm->NextGet(); } while (sm); diff --git a/Globals.cpp b/Globals.cpp index c5e613fc..3e0c0f9b 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -49,6 +49,9 @@ 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 int Global::iReCompile = 0; // zwiększany, gdy trzeba odświeżyć siatki HWND Global::hWnd = NULL; // uchwyt okna +int Global::ScreenWidth = 1; +int Global::ScreenHeight = 1; +float Global::ZoomFactor = 1.0f; int Global::iCameraLast = -1; std::string Global::asRelease = "16.0.1172.482"; std::string Global::asVersion = diff --git a/Globals.h b/Globals.h index d63af985..c4970efe 100644 --- a/Globals.h +++ b/Globals.h @@ -253,6 +253,9 @@ class Global static double fLuminance; // jasność światła do automatycznego zapalania static int iMultiplayer; // blokada działania niektórych eventów na rzecz kominikacji static HWND hWnd; // uchwyt okna + static int ScreenWidth; // current window dimensions. TODO: move it to renderer + static int ScreenHeight; + static float ZoomFactor; // determines current camera zoom level. TODO: move it to the renderer static int iCameraLast; static std::string asRelease; // numer static std::string asVersion; // z opisem diff --git a/Ground.cpp b/Ground.cpp index b1d55d3c..bfd4a344 100644 --- a/Ground.cpp +++ b/Ground.cpp @@ -555,7 +555,7 @@ void TGroundNode::RenderDL() return smTerrain->RenderDL(); } // if (pTriGroup) if (pTriGroup!=this) return; //wyświetla go inny obiekt - double mgn = SquareMagnitude(pCenter - Global::pCameraPosition); + double mgn = SquareMagnitude(pCenter - Global::pCameraPosition) / Global::ZoomFactor; if ((mgn > fSquareRadius) || (mgn < fSquareMinRadius)) // McZapkie-070602: nie rysuj odleglych // obiektow ale sprawdzaj wyzwalacz // zdarzen @@ -615,7 +615,7 @@ void TGroundNode::RenderAlphaDL() // i jezeli tak to odpowiedni GL_GREATER w przeciwnym wypadku standardowy 0.04 // if (pTriGroup) if (pTriGroup!=this) return; //wyświetla go inny obiekt - double mgn = SquareMagnitude(pCenter - Global::pCameraPosition); + double mgn = SquareMagnitude(pCenter - Global::pCameraPosition) / Global::ZoomFactor; float r, g, b; if (mgn < fSquareMinRadius) return; diff --git a/World.cpp b/World.cpp index df7d559b..5e47971c 100644 --- a/World.cpp +++ b/World.cpp @@ -485,21 +485,21 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) glBegin(GL_QUADS); // Drawing using triangles glTexCoord2f(0.0f, 0.0f); - glVertex3f(-0.28f, -0.22f, 0.0f); // bottom left of the texture and quad + glVertex3f(-1.0f, -1.0f, 0.0f); // bottom left of the texture and quad glTexCoord2f(1.0f, 0.0f); - glVertex3f(0.28f, -0.22f, 0.0f); // bottom right of the texture and quad + glVertex3f(1.0f, -1.0f, 0.0f); // bottom right of the texture and quad glTexCoord2f(1.0f, 1.0f); - glVertex3f(0.28f, 0.22f, 0.0f); // top right of the texture and quad + glVertex3f(1.0f, 1.0f, 0.0f); // top right of the texture and quad glTexCoord2f(0.0f, 1.0f); - glVertex3f(-0.28f, 0.22f, 0.0f); // top left of the texture and quad + glVertex3f(-1.0f, 1.0f, 0.0f); // top left of the texture and quad glEnd(); //~logo; Ra: to jest bez sensu zapis glColor3f(0.0f, 0.0f, 100.0f); if (Global::detonatoryOK) { - glRasterPos2f(-0.25f, -0.09f); + glRasterPos2f(-0.85f, -0.25f); glPrint("Uruchamianie / Initializing..."); - glRasterPos2f(-0.25f, -0.10f); + glRasterPos2f(-0.85f, -0.30f); glPrint("Dzwiek / Sound..."); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -512,7 +512,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) WriteLog("Sound Init OK"); if (Global::detonatoryOK) { - glRasterPos2f(-0.25f, -0.11f); + glRasterPos2f(-0.25f, -0.30f); glPrint("OK."); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -523,7 +523,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) WriteLog("Textures init"); if (Global::detonatoryOK) { - glRasterPos2f(-0.25f, -0.12f); + glRasterPos2f(-0.85f, -0.35f); glPrint("Tekstury / Textures..."); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -533,7 +533,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) WriteLog("Textures init OK"); if (Global::detonatoryOK) { - glRasterPos2f(-0.25f, -0.13f); + glRasterPos2f(-0.25f, -0.35f); glPrint("OK."); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -541,7 +541,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) WriteLog("Models init"); if (Global::detonatoryOK) { - glRasterPos2f(-0.25f, -0.14f); + glRasterPos2f(-0.85f, -0.40f); glPrint("Modele / Models..."); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -551,7 +551,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) WriteLog("Models init OK"); if (Global::detonatoryOK) { - glRasterPos2f(-0.25f, -0.15f); + glRasterPos2f(-0.25f, -0.40f); glPrint("OK."); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -559,7 +559,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) WriteLog("Ground init"); if (Global::detonatoryOK) { - glRasterPos2f(-0.25f, -0.16f); + glRasterPos2f(-0.85f, -0.45f); glPrint("Sceneria / Scenery (please wait)..."); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -570,7 +570,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) WriteLog("Ground init OK"); if (Global::detonatoryOK) { - glRasterPos2f(-0.25f, -0.17f); + glRasterPos2f(-0.25f, -0.45f); glPrint("OK."); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -587,7 +587,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) char buff[255] = "Player train init: "; if (Global::detonatoryOK) { - glRasterPos2f(-0.25f, -0.18f); + glRasterPos2f(-0.85f, -0.50f); glPrint("Przygotowanie kabiny do sterowania..."); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -608,7 +608,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) WriteLog("Player train init OK"); if (Global::detonatoryOK) { - glRasterPos2f(-0.25f, -0.19f); + glRasterPos2f(-0.25f, -0.50f); glPrint("OK."); } FollowView(); @@ -620,7 +620,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) FreeFlyModeFlag = true; // Ra: automatycznie włączone latanie if (Global::detonatoryOK) { - glRasterPos2f(-0.25f, -0.20f); + glRasterPos2f(-0.85f, -0.50f); glPrint("Blad inicjalizacji sterowanego pojazdu!"); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -636,7 +636,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) Error("Player train not exist!"); if (Global::detonatoryOK) { - glRasterPos2f(-0.25f, -0.20f); + glRasterPos2f(-0.85f, -0.55f); glPrint("Wybrany pojazd nie istnieje w scenerii!"); } } @@ -984,7 +984,7 @@ void TWorld::OnKeyUp(int cKey) void TWorld::OnMouseMove(double x, double y) { // McZapkie:060503-definicja obracania myszy - Camera.OnCursorMove(x * Global::fMouseXScale, -y * Global::fMouseYScale); + Camera.OnCursorMove(x * Global::fMouseXScale / Global::ZoomFactor, -y * Global::fMouseYScale / Global::ZoomFactor); } void TWorld::InOutKey() @@ -1299,8 +1299,19 @@ TWorld::Update_Camera( double const Deltatime ) { if( FreeFlyModeFlag ) Camera.RaLook(); // jednorazowe przestawienie kamery } - else if( Console::Pressed( VK_RBUTTON ) ) //||Console::Pressed(VK_F4)) + else if( Console::Pressed( VK_RBUTTON ) ) { //||Console::Pressed(VK_F4)) FollowView( false ); // bez wyciszania dźwięków + } + else if( true == Console::Pressed( VK_MBUTTON ) ) { + // middle mouse button controls zoom. + Global::ZoomFactor = std::min( 4.5f, Global::ZoomFactor + 15.0f * static_cast(Deltatime) ); + } + else if( false == Console::Pressed( VK_MBUTTON ) ) { + // reset zoom level if the button is no longer held down. + // NOTE: yes, this is terrible way to go about it. it'll do for now. + Global::ZoomFactor = std::max( 1.0f, Global::ZoomFactor - 15.0f * static_cast( Deltatime ) ); + } + /* else if( Global::iTextMode == -1 ) { // tu mozna dodac dopisywanie do logu przebiegu lokomotywy WriteLog( "Number of textures used: " + std::to_string( Global::iTextures ) ); @@ -1502,6 +1513,12 @@ bool TWorld::Render() // glColor3b(255, 0, 255); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDepthFunc( GL_LEQUAL ); + + glMatrixMode( GL_PROJECTION ); // select the Projection Matrix + glLoadIdentity(); // reset the Projection Matrix + // calculate the aspect ratio of the window + gluPerspective( 45.0f / Global::ZoomFactor, (GLdouble)Global::ScreenWidth / (GLdouble)Global::ScreenHeight, 0.1f * Global::ZoomFactor, 2500.0f * Global::ZoomFactor ); + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix glLoadIdentity(); Camera.SetMatrix(); // ustawienie macierzy kamery względem początku scenerii @@ -1794,6 +1811,14 @@ TWorld::Render_Cab() { void TWorld::Render_UI() { + // set the UI mode projection. TODO: rework it all into somethinig more elegant... eventually + glMatrixMode( GL_PROJECTION ); // select the Projection Matrix + glLoadIdentity(); // reset the Projection Matrix + // calculate the aspect ratio of the window + gluPerspective( 45.0f, (GLdouble)Global::ScreenWidth / (GLdouble)Global::ScreenHeight, 0.2f, 2500.0f ); + glMatrixMode( GL_MODELVIEW ); // Select The Modelview Matrix + glLoadIdentity(); + if( DebugModeFlag && !Global::iTextMode ) { OutText1 = " FPS: "; OutText1 += to_string( Timer::GetFPS(), 2 ); From 1c8bfe067e45454c8594c2b0000b19703d942652 Mon Sep 17 00:00:00 2001 From: maciek001 Date: Mon, 20 Feb 2017 13:21:14 +0100 Subject: [PATCH 15/40] =?UTF-8?q?Poprawka=20kranu=20FVel6=20-=20ju=C5=BC?= =?UTF-8?q?=20nie=20cofa=20na=20analogowym?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Train.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Train.cpp b/Train.cpp index ff800230..f4dfdc18 100644 --- a/Train.cpp +++ b/Train.cpp @@ -4691,7 +4691,7 @@ bool TTrain::Update( double const Deltatime ) if ((!Console::Pressed(Global::Keys[k_DecBrakeLevel])) && (!Console::Pressed(Global::Keys[k_WaveBrake])) && (mvOccupied->BrakeCtrlPos == -1) && (mvOccupied->BrakeHandle == FVel6) && (DynamicObject->Controller != AIdriver) && - (Global::iFeedbackMode != 4 || !(Global::bMWDmasterEnable && Global::bMWDBreakEnable))) + Global::iFeedbackMode != 4 && (!(Global::bMWDmasterEnable && Global::bMWDBreakEnable))) { // mvOccupied->BrakeCtrlPos=(mvOccupied->BrakeCtrlPos)+1; // mvOccupied->IncBrakeLevel(); From 76fd3487a6d4c774e037426af23439e26b7c006b Mon Sep 17 00:00:00 2001 From: maciek001 Date: Mon, 20 Feb 2017 13:22:26 +0100 Subject: [PATCH 16/40] Poprawa FVel6 - cofanie z -1 --- Train.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Train.cpp b/Train.cpp index e557dcbe..faea72d9 100644 --- a/Train.cpp +++ b/Train.cpp @@ -4681,7 +4681,7 @@ bool TTrain::Update( double const Deltatime ) if ((!Console::Pressed(Global::Keys[k_DecBrakeLevel])) && (!Console::Pressed(Global::Keys[k_WaveBrake])) && (mvOccupied->BrakeCtrlPos == -1) && (mvOccupied->BrakeHandle == FVel6) && (DynamicObject->Controller != AIdriver) && - (Global::iFeedbackMode != 4)) + (Global::iFeedbackMode != 4) && (!(Global::bMWDmasterEnable && Global::bMWDBreakEnable))) { // mvOccupied->BrakeCtrlPos=(mvOccupied->BrakeCtrlPos)+1; // mvOccupied->IncBrakeLevel(); From b383b536da163339bb30cae54ccbdb41ebe128ec Mon Sep 17 00:00:00 2001 From: maciek001 Date: Mon, 20 Feb 2017 13:23:08 +0100 Subject: [PATCH 17/40] =?UTF-8?q?kosmetyka=20wcze=C5=9Bniejszego?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Train.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Train.cpp b/Train.cpp index f4dfdc18..035a5524 100644 --- a/Train.cpp +++ b/Train.cpp @@ -4691,7 +4691,7 @@ bool TTrain::Update( double const Deltatime ) if ((!Console::Pressed(Global::Keys[k_DecBrakeLevel])) && (!Console::Pressed(Global::Keys[k_WaveBrake])) && (mvOccupied->BrakeCtrlPos == -1) && (mvOccupied->BrakeHandle == FVel6) && (DynamicObject->Controller != AIdriver) && - Global::iFeedbackMode != 4 && (!(Global::bMWDmasterEnable && Global::bMWDBreakEnable))) + (Global::iFeedbackMode != 4) && (!(Global::bMWDmasterEnable && Global::bMWDBreakEnable))) { // mvOccupied->BrakeCtrlPos=(mvOccupied->BrakeCtrlPos)+1; // mvOccupied->IncBrakeLevel(); From 8baefd69b00bcedac208e19c804332c7d33cc4f0 Mon Sep 17 00:00:00 2001 From: maciek001 Date: Mon, 20 Feb 2017 13:29:00 +0100 Subject: [PATCH 18/40] kosmetyka przy kranie --- maszyna.sln | 7 ++----- maszyna.vcxproj | 19 ++++++++++--------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/maszyna.sln b/maszyna.sln index 1c19b757..24fa39aa 100644 --- a/maszyna.sln +++ b/maszyna.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.40629.0 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "maszyna", "maszyna.vcxproj", "{8E0232E5-1C67-442F-9E04-45ED2DDFC960}" EndProject @@ -19,7 +19,4 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(Performance) = preSolution - HasPerformanceSessions = true - EndGlobalSection EndGlobal diff --git a/maszyna.vcxproj b/maszyna.vcxproj index 2797b436..50c6e3cd 100644 --- a/maszyna.vcxproj +++ b/maszyna.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -13,17 +13,18 @@ {8E0232E5-1C67-442F-9E04-45ED2DDFC960} Win32Proj + 8.1 Application true - v120_xp + v140_xp Application false - v120_xp + v140_xp @@ -36,14 +37,14 @@ - eu07++ - $(SolutionDir)tmp\$(PlatformShortName)-$(Configuration)\$(ProjectName)\ - $(SolutionDir)bin\ + mhEU07-201702debug + E:\Gry\EU07\eu07 exe\tmj-cpp-hamulec + E:\Gry\EU07\eu07 exe\tmj-cpp - eu07++ + mhEU07-201702relase $(SolutionDir)tmp\$(PlatformShortName)-$(Configuration)\$(ProjectName)\ - $(SolutionDir)bin\ + E:\Gry\EU07\eu07 exe\tmj-cpp-hamulec false @@ -55,7 +56,7 @@ Use true false - true + false MachineX86 From 1ea207b60fabc14959a03c3531dad6eaa53dfe16 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Mon, 20 Feb 2017 16:17:04 +0100 Subject: [PATCH 19/40] field of view setting, t3d loader fix --- Globals.cpp | 9 +++++++++ Globals.h | 1 + Model3d.cpp | 3 +++ World.cpp | 2 +- 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Globals.cpp b/Globals.cpp index 3e0c0f9b..e841346a 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -52,6 +52,7 @@ HWND Global::hWnd = NULL; // uchwyt okna int Global::ScreenWidth = 1; int Global::ScreenHeight = 1; float Global::ZoomFactor = 1.0f; +float Global::FieldOfView = 45.0f; int Global::iCameraLast = -1; std::string Global::asRelease = "16.0.1172.482"; std::string Global::asVersion = @@ -261,6 +262,14 @@ void Global::ConfigParse(cParser &Parser) Parser.getTokens(); Parser >> Global::asHumanCtrlVehicle; } + else if( token == "fieldofview" ) { + + Parser.getTokens( 1, false ); + Parser >> Global::FieldOfView; + // guard against incorrect values + Global::FieldOfView = std::min( 75.0f, Global::FieldOfView ); + Global::FieldOfView = std::max( 15.0f, Global::FieldOfView ); + } else if (token == "width") { diff --git a/Globals.h b/Globals.h index c4970efe..ff7fef81 100644 --- a/Globals.h +++ b/Globals.h @@ -256,6 +256,7 @@ class Global static int ScreenWidth; // current window dimensions. TODO: move it to renderer static int ScreenHeight; static float ZoomFactor; // determines current camera zoom level. TODO: move it to the renderer + static float FieldOfView; // vertical field of view for the camera. TODO: move it to the renderer static int iCameraLast; static std::string asRelease; // numer static std::string asVersion; // z opisem diff --git a/Model3d.cpp b/Model3d.cpp index fec5b563..22b956b5 100644 --- a/Model3d.cpp +++ b/Model3d.cpp @@ -219,6 +219,9 @@ template inline void readColor(cParser &parser, ColorT *color) double discard; parser.getTokens(4, false); parser >> discard >> color[0] >> color[1] >> color[2]; + color[ 0 ] /= 255.0; + color[ 1 ] /= 255.0; + color[ 2 ] /= 255.0; }; inline void readColor(cParser &parser, int &color) diff --git a/World.cpp b/World.cpp index 5e47971c..ee9eb1bd 100644 --- a/World.cpp +++ b/World.cpp @@ -1517,7 +1517,7 @@ bool TWorld::Render() glMatrixMode( GL_PROJECTION ); // select the Projection Matrix glLoadIdentity(); // reset the Projection Matrix // calculate the aspect ratio of the window - gluPerspective( 45.0f / Global::ZoomFactor, (GLdouble)Global::ScreenWidth / (GLdouble)Global::ScreenHeight, 0.1f * Global::ZoomFactor, 2500.0f * Global::ZoomFactor ); + gluPerspective( Global::FieldOfView / Global::ZoomFactor, (GLdouble)Global::ScreenWidth / (GLdouble)Global::ScreenHeight, 0.1f * Global::ZoomFactor, 2500.0f * Global::ZoomFactor ); glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix glLoadIdentity(); From 74cd2585eb646019f24dacd6af1145d94d13740f Mon Sep 17 00:00:00 2001 From: maciek001 Date: Mon, 20 Feb 2017 16:32:43 +0100 Subject: [PATCH 20/40] - --- Console/MWD.h | 4 ++-- maszyna.sln | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Console/MWD.h b/Console/MWD.h index ad35ee87..773e3ad6 100644 --- a/Console/MWD.h +++ b/Console/MWD.h @@ -61,8 +61,8 @@ public: unsigned int uiAnalog[4]; // trzymanie danych z wejść analogowych - BYTE ReadDataBuff[BYTETOREAD]; //17]; // bufory danych - BYTE WriteDataBuff[BYTETOWRITE]; //31]; + BYTE ReadDataBuff[BYTETOREAD+2]; //17]; // bufory danych + BYTE WriteDataBuff[BYTETOWRITE+2]; //31]; TMWDComm(); // konstruktor ~TMWDComm(); // destruktor diff --git a/maszyna.sln b/maszyna.sln index 1c19b757..24fa39aa 100644 --- a/maszyna.sln +++ b/maszyna.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.40629.0 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "maszyna", "maszyna.vcxproj", "{8E0232E5-1C67-442F-9E04-45ED2DDFC960}" EndProject @@ -19,7 +19,4 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(Performance) = preSolution - HasPerformanceSessions = true - EndGlobalSection EndGlobal From 64bb5048e5a4bb4bf30081aac69849fbfcc1a9fa Mon Sep 17 00:00:00 2001 From: maciek001 Date: Mon, 20 Feb 2017 17:08:56 +0100 Subject: [PATCH 21/40] =?UTF-8?q?AnalogCalibrateGet=20dla=20PoKeys=20zwrac?= =?UTF-8?q?a=20=20warto=C5=9B=C4=87=20od=200=20do=201=20bez=20konieczno?= =?UTF-8?q?=C5=9Bci=20zmiany=20wpis=C3=B3w=20kalibracyjnych=20do=20eu07.in?= =?UTF-8?q?i?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Console.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Console.cpp b/Console.cpp index 93263ed4..bf8950bb 100644 --- a/Console.cpp +++ b/Console.cpp @@ -463,14 +463,23 @@ float Console::AnalogCalibrateGet(int x) if (iMode == 4 && PoKeys55[0]) { float b = PoKeys55[0]->fAnalog[x]; - return (((((Global::fCalibrateIn[x][5] * b) + Global::fCalibrateIn[x][4]) * b + + /*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]; + Global::fCalibrateIn[x][0];*/ + b = (((((Global::fCalibrateIn[x][5] * b) + Global::fCalibrateIn[x][4]) * b + + Global::fCalibrateIn[x][3]) * + b + + Global::fCalibrateIn[x][2]) * + b + + Global::fCalibrateIn[x][1]) * + b + + Global::fCalibrateIn[x][0]; + return (b + 2) / 8; } if (Global::bMWDmasterEnable && Global::bMWDBreakEnable) { From 540c6ad28e6cd81fd0f67f9ea0c912b46927f135 Mon Sep 17 00:00:00 2001 From: maciek001 Date: Mon, 20 Feb 2017 17:53:36 +0100 Subject: [PATCH 22/40] =?UTF-8?q?dodane=20kana=C5=82y=20pwm=20i=20pr=C4=99?= =?UTF-8?q?dko=C5=9B=C4=87=20ale=20nie=20testowane!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Console.cpp | 10 +++++++++- Console/MWD.cpp | 8 +++----- Train.cpp | 16 ++++++++++++++-- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/Console.cpp b/Console.cpp index bf8950bb..0480cd93 100644 --- a/Console.cpp +++ b/Console.cpp @@ -396,33 +396,41 @@ void Console::ValueSet(int x, double y) case 0: iliczba = (unsigned int)floor((y / (Global::fMWDzg[0] * 10) * Global::fMWDzg[1]) + 0.5); // zbiornik g??wny MWDComm->WriteDataBuff[12] = (unsigned char)(iliczba >> 8); MWDComm->WriteDataBuff[11] = (unsigned char)iliczba; + if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Main tank presure " + to_string(MWDComm->WriteDataBuff[12]) + " " + to_string(MWDComm->WriteDataBuff[11])); break; case 1: iliczba = (unsigned int)floor((y / (Global::fMWDpg[0] * 10) * Global::fMWDpg[1]) + 0.5); // przew?d g??wny MWDComm->WriteDataBuff[10] = (unsigned char)(iliczba >> 8); MWDComm->WriteDataBuff[9] = (unsigned char)iliczba; + if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Main pipe presure " + to_string(MWDComm->WriteDataBuff[10]) + " " + to_string(MWDComm->WriteDataBuff[9])); break; case 2: iliczba = (unsigned int)floor((y / (Global::fMWDph[0] * 10) * Global::fMWDph[1]) + 0.5); // cylinder hamulcowy MWDComm->WriteDataBuff[8] = (unsigned char)(iliczba >> 8); MWDComm->WriteDataBuff[7] = (unsigned char)iliczba; + if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Break presure " + to_string(MWDComm->WriteDataBuff[8]) + " " + to_string(MWDComm->WriteDataBuff[7])); break; case 3: iliczba = (unsigned int)floor((y / Global::fMWDvolt[0] * Global::fMWDvolt[1]) + 0.5); // woltomierz WN MWDComm->WriteDataBuff[14] = (unsigned char)(iliczba >> 8); MWDComm->WriteDataBuff[13] = (unsigned char)iliczba; + if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Volt meter " + to_string(MWDComm->WriteDataBuff[14]) + " " + to_string(MWDComm->WriteDataBuff[13])); break; case 4: iliczba = (unsigned int)floor((y / Global::fMWDamp[0] * Global::fMWDamp[1]) + 0.5); // amp WN 1 MWDComm->WriteDataBuff[16] = (unsigned char)(iliczba >> 8); MWDComm->WriteDataBuff[15] = (unsigned char)iliczba; + if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Apm meter1 " + to_string(MWDComm->WriteDataBuff[16]) + " " + to_string(MWDComm->WriteDataBuff[15])); break; case 5: iliczba = (unsigned int)floor((y / Global::fMWDamp[0] * Global::fMWDamp[1]) + 0.5); // amp WN 2 MWDComm->WriteDataBuff[18] = (unsigned char)(iliczba >> 8); MWDComm->WriteDataBuff[17] = (unsigned char)iliczba; + if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Apm meter2 " + to_string(MWDComm->WriteDataBuff[18]) + " " + to_string(MWDComm->WriteDataBuff[17])); break; case 6: iliczba = (unsigned int)floor((y / Global::fMWDamp[0] * Global::fMWDamp[1]) + 0.5); // amp WN 3 MWDComm->WriteDataBuff[20] = (unsigned int)(iliczba >> 8); MWDComm->WriteDataBuff[19] = (unsigned char)iliczba; + if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Apm meter3 " + to_string(MWDComm->WriteDataBuff[20]) + " " + to_string(MWDComm->WriteDataBuff[19])); break; - case 7: if (Global::iPause) MWDComm->WriteDataBuff[0] = 0; //skoro pauza to hasler stoi i nie nabija kilometrów + case 7: if (Global::iPause) MWDComm->WriteDataBuff[0] = 0; //skoro pauza to hasler stoi i nie nabija kilometrów CHYBA NIE DZIAŁA! else MWDComm->WriteDataBuff[0] = (unsigned char)floor(y); // prędkość dla np haslera + if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Speed: " + to_string(MWDComm->WriteDataBuff[0])); break; } } diff --git a/Console/MWD.cpp b/Console/MWD.cpp index e6a93008..19564b8f 100644 --- a/Console/MWD.cpp +++ b/Console/MWD.cpp @@ -133,11 +133,9 @@ bool TMWDComm::Open() // otwieranie portu COM bool TMWDComm::Close() // zamykanie portu COM { - Global::bMWDmasterEnable = false; // wyłącz SerialPort - Global::bMWDInputEnable = false; // wyłącz wejścia - Global::bMWDBreakEnable = false; // wyłącz wejścia analogowe - Global::bMWDdebugEnable = false; // wyłącz debugowanie - Global::iMWDDebugMode = 0; // wyłącz debugMode! + Global::bMWDmasterEnable = false; // główne włączenie portu! + Global::bMWDInputEnable = false; // włącz wejścia + Global::bMWDBreakEnable = false; // włącz wejścia analogowe WriteLog("COM Port is closing..."); int i = 0; diff --git a/Train.cpp b/Train.cpp index 035a5524..6436cc2f 100644 --- a/Train.cpp +++ b/Train.cpp @@ -2842,6 +2842,18 @@ bool TTrain::Update( double const Deltatime ) /// napędu } + if (Global::bMWDmasterEnable) // pobieranie danych dla pulpitu przez port szeregowy (COM) + { + Console::ValueSet(0, mvOccupied->Compressor); // zbiornik główny + Console::ValueSet(1, mvOccupied->PipePress); // przewód główny + Console::ValueSet(2, mvOccupied->BrakePress); // cylinder hamulcowy + Console::ValueSet(3, fHVoltage); // woltomierz wysokiego napięcia + Console::ValueSet(4, fHCurrent[3]); // drugi amperomierz 3 + Console::ValueSet(4, fHCurrent[2]); // drugi amperomierz 2 + Console::ValueSet(5, fHCurrent[(mvControlled->TrainType & dt_EZT) ? 0 : 1]); // pierwszy amperomierz; dla EZT prąd całkowity + Console::ValueSet(6, fTachoVelocity); + } + // hunter-080812: wyrzucanie szybkiego na elektrykach gdy nie ma napiecia // przy dowolnym ustawieniu kierunkowego // Ra: to już jest w T_MoverParameters::TractionForce(), ale zależy od @@ -3763,8 +3775,8 @@ bool TTrain::Update( double const Deltatime ) { // Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba // Firleju: dlatego kasujemy i zastepujemy funkcją w Console if (mvOccupied->BrakeHandle == FV4a) - { - double b = Console::AnalogCalibrateGet(0); + { + double b = Console::AnalogCalibrateGet(0); b = b * 8 - 2; b = Global::CutValueToRange(-2.0, b, mvOccupied->BrakeCtrlPosNo); // przycięcie zmiennej do granic if (Global::bMWDdebugEnable && Global::iMWDDebugMode & 4) WriteLog("Pozycja kranu = " + to_string(b)); From 420428ce9bcbb76373e254e35f477e11206888c9 Mon Sep 17 00:00:00 2001 From: maciek001 Date: Mon, 20 Feb 2017 17:55:56 +0100 Subject: [PATCH 23/40] poprawki 2 --- Console.cpp | 6 +++--- Train.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Console.cpp b/Console.cpp index 0480cd93..9b44b661 100644 --- a/Console.cpp +++ b/Console.cpp @@ -396,17 +396,17 @@ void Console::ValueSet(int x, double y) case 0: iliczba = (unsigned int)floor((y / (Global::fMWDzg[0] * 10) * Global::fMWDzg[1]) + 0.5); // zbiornik g??wny MWDComm->WriteDataBuff[12] = (unsigned char)(iliczba >> 8); MWDComm->WriteDataBuff[11] = (unsigned char)iliczba; - if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Main tank presure " + to_string(MWDComm->WriteDataBuff[12]) + " " + to_string(MWDComm->WriteDataBuff[11])); + if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Main tank press " + to_string(MWDComm->WriteDataBuff[12]) + " " + to_string(MWDComm->WriteDataBuff[11])); break; case 1: iliczba = (unsigned int)floor((y / (Global::fMWDpg[0] * 10) * Global::fMWDpg[1]) + 0.5); // przew?d g??wny MWDComm->WriteDataBuff[10] = (unsigned char)(iliczba >> 8); MWDComm->WriteDataBuff[9] = (unsigned char)iliczba; - if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Main pipe presure " + to_string(MWDComm->WriteDataBuff[10]) + " " + to_string(MWDComm->WriteDataBuff[9])); + if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Main pipe press " + to_string(MWDComm->WriteDataBuff[10]) + " " + to_string(MWDComm->WriteDataBuff[9])); break; case 2: iliczba = (unsigned int)floor((y / (Global::fMWDph[0] * 10) * Global::fMWDph[1]) + 0.5); // cylinder hamulcowy MWDComm->WriteDataBuff[8] = (unsigned char)(iliczba >> 8); MWDComm->WriteDataBuff[7] = (unsigned char)iliczba; - if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Break presure " + to_string(MWDComm->WriteDataBuff[8]) + " " + to_string(MWDComm->WriteDataBuff[7])); + if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Break press " + to_string(MWDComm->WriteDataBuff[8]) + " " + to_string(MWDComm->WriteDataBuff[7])); break; case 3: iliczba = (unsigned int)floor((y / Global::fMWDvolt[0] * Global::fMWDvolt[1]) + 0.5); // woltomierz WN MWDComm->WriteDataBuff[14] = (unsigned char)(iliczba >> 8); diff --git a/Train.cpp b/Train.cpp index 6436cc2f..d32ec22e 100644 --- a/Train.cpp +++ b/Train.cpp @@ -2848,10 +2848,10 @@ bool TTrain::Update( double const Deltatime ) Console::ValueSet(1, mvOccupied->PipePress); // przewód główny Console::ValueSet(2, mvOccupied->BrakePress); // cylinder hamulcowy Console::ValueSet(3, fHVoltage); // woltomierz wysokiego napięcia - Console::ValueSet(4, fHCurrent[3]); // drugi amperomierz 3 - Console::ValueSet(4, fHCurrent[2]); // drugi amperomierz 2 - Console::ValueSet(5, fHCurrent[(mvControlled->TrainType & dt_EZT) ? 0 : 1]); // pierwszy amperomierz; dla EZT prąd całkowity - Console::ValueSet(6, fTachoVelocity); + Console::ValueSet(6, fHCurrent[3]); // drugi amperomierz 3 + Console::ValueSet(5, fHCurrent[2]); // drugi amperomierz 2 + Console::ValueSet(4, fHCurrent[(mvControlled->TrainType & dt_EZT) ? 0 : 1]); // pierwszy amperomierz; dla EZT prąd całkowity + Console::ValueSet(7, fTachoVelocity); } // hunter-080812: wyrzucanie szybkiego na elektrykach gdy nie ma napiecia From 1e4cdda367d199e9fe72a00d8ff782eaa64a3b37 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Tue, 21 Feb 2017 17:12:52 +0100 Subject: [PATCH 24/40] basic renderer types. texture manager moved to renderer --- AnimModel.cpp | 6 +-- DynObj.cpp | 34 +++++++------- Globals.h | 48 +------------------- Ground.cpp | 14 +++--- Model3d.cpp | 36 +++++++-------- PyInt.cpp | 3 +- Segment.cpp | 2 +- Texture.cpp | 11 ++--- Texture.h | 2 - Track.cpp | 50 ++++++++++----------- Traction.cpp | 6 +-- World.cpp | 16 +++---- maszyna.vcxproj | 2 + maszyna.vcxproj.filters | 6 +++ renderer.cpp | 15 +++++++ renderer.h | 99 +++++++++++++++++++++++++++++++++++++++++ 16 files changed, 210 insertions(+), 140 deletions(-) create mode 100644 renderer.cpp create mode 100644 renderer.h diff --git a/AnimModel.cpp b/AnimModel.cpp index f19210f3..c61267de 100644 --- a/AnimModel.cpp +++ b/AnimModel.cpp @@ -22,7 +22,7 @@ http://mozilla.org/MPL/2.0/. #include "Timer.h" #include "MdlMngr.h" // McZapkie: -#include "Texture.h" +#include "renderer.h" //--------------------------------------------------------------------------- TAnimContainer *TAnimModel::acAnimList = NULL; @@ -449,9 +449,9 @@ bool TAnimModel::Init(std::string const &asName, std::string const &asReplacable asText = asReplacableTexture.substr(1, asReplacableTexture.length() - 1); // zapamiętanie tekstu else if (asReplacableTexture != "none") ReplacableSkinId[1] = - TextureManager.GetTextureId( asReplacableTexture, "" ); + GfxRenderer.GetTextureId( asReplacableTexture, "" ); if( ( ReplacableSkinId[ 1 ] != 0 ) - && ( TextureManager.Texture( ReplacableSkinId[ 1 ] ).has_alpha ) ) { + && ( GfxRenderer.Texture( ReplacableSkinId[ 1 ] ).has_alpha ) ) { // tekstura z kanałem alfa - nie renderować w cyklu nieprzezroczystych iTexAlpha = 0x31310031; } diff --git a/DynObj.cpp b/DynObj.cpp index 0442e7a7..1f4f5c21 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -21,7 +21,7 @@ http://mozilla.org/MPL/2.0/. #include "Usefull.h" // McZapkie-260202 #include "Globals.h" -#include "Texture.h" +#include "renderer.h" #include "AirCoupler.h" #include "TractionPower.h" @@ -4389,7 +4389,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName, Global::asCurrentTexturePath + ReplacableSkin; // skory tez z dynamic/... std::string x = TextureTest(Global::asCurrentTexturePath + "nowhere"); // na razie prymitywnie if (!x.empty()) - ReplacableSkinID[4] = TextureManager.GetTextureId( Global::asCurrentTexturePath + "nowhere", "", 9); + ReplacableSkinID[4] = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + "nowhere", "", 9); /* if ((i = ReplacableSkin.Pos("|")) > 0) // replacable dzielone { @@ -4452,21 +4452,21 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName, */ if (iMultiTex > 0) { // jeśli model ma 4 tekstury - ReplacableSkinID[1] = TextureManager.GetTextureId( + ReplacableSkinID[1] = GfxRenderer.GetTextureId( ReplacableSkin + ",1", "", Global::iDynamicFiltering); if (ReplacableSkinID[1]) { // pierwsza z zestawu znaleziona - ReplacableSkinID[2] = TextureManager.GetTextureId( + ReplacableSkinID[2] = GfxRenderer.GetTextureId( ReplacableSkin + ",2", "", Global::iDynamicFiltering); if (ReplacableSkinID[2]) { iMultiTex = 2; // już są dwie - ReplacableSkinID[3] = TextureManager.GetTextureId( + ReplacableSkinID[3] = GfxRenderer.GetTextureId( ReplacableSkin + ",3", "", Global::iDynamicFiltering); if (ReplacableSkinID[3]) { iMultiTex = 3; // a teraz nawet trzy - ReplacableSkinID[4] = TextureManager.GetTextureId( + ReplacableSkinID[4] = GfxRenderer.GetTextureId( ReplacableSkin + ",4", "", Global::iDynamicFiltering); if (ReplacableSkinID[4]) iMultiTex = 4; // jak są cztery, to blokujemy podmianę tekstury @@ -4477,14 +4477,14 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName, else { // zestaw nie zadziałał, próbujemy normanie iMultiTex = 0; - ReplacableSkinID[1] = TextureManager.GetTextureId( + ReplacableSkinID[1] = GfxRenderer.GetTextureId( ReplacableSkin, "", Global::iDynamicFiltering); } } else - ReplacableSkinID[1] = TextureManager.GetTextureId( + ReplacableSkinID[1] = GfxRenderer.GetTextureId( ReplacableSkin, "", Global::iDynamicFiltering); - if (TextureManager.Texture(ReplacableSkinID[1]).has_alpha) + if (GfxRenderer.Texture(ReplacableSkinID[1]).has_alpha) iAlpha = 0x31310031; // tekstura -1 z kanałem alfa - nie renderować w cyklu // nieprzezroczystych else @@ -4492,17 +4492,17 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName, // renderować w // cyklu przezroczystych if (ReplacableSkinID[2]) - if (TextureManager.Texture(ReplacableSkinID[2]).has_alpha) + if (GfxRenderer.Texture(ReplacableSkinID[2]).has_alpha) iAlpha |= 0x02020002; // tekstura -2 z kanałem alfa - nie renderować // w cyklu // nieprzezroczystych if (ReplacableSkinID[3]) - if (TextureManager.Texture(ReplacableSkinID[3]).has_alpha) + if (GfxRenderer.Texture(ReplacableSkinID[3]).has_alpha) iAlpha |= 0x04040004; // tekstura -3 z kanałem alfa - nie renderować // w cyklu // nieprzezroczystych if (ReplacableSkinID[4]) - if (TextureManager.Texture(ReplacableSkinID[4]).has_alpha) + if (GfxRenderer.Texture(ReplacableSkinID[4]).has_alpha) iAlpha |= 0x08080008; // tekstura -4 z kanałem alfa - nie renderować // w cyklu // nieprzezroczystych @@ -5831,13 +5831,13 @@ void TDynamicObject::DestinationSet(std::string to, std::string numer) std::string x = TextureTest(asBaseDir + numer + "@" + MoverParameters->TypeName); if (!x.empty()) { - ReplacableSkinID[4] = TextureManager.GetTextureId( x, "", 9); // rozmywania 0,1,4,5 nie nadają się + ReplacableSkinID[4] = GfxRenderer.GetTextureId( x, "", 9); // rozmywania 0,1,4,5 nie nadają się return; } x = TextureTest(asBaseDir + numer ); if (!x.empty()) { - ReplacableSkinID[4] = TextureManager.GetTextureId( x, "", 9); // rozmywania 0,1,4,5 nie nadają się + ReplacableSkinID[4] = GfxRenderer.GetTextureId( x, "", 9); // rozmywania 0,1,4,5 nie nadają się return; } if (to.empty()) @@ -5845,17 +5845,17 @@ void TDynamicObject::DestinationSet(std::string to, std::string numer) x = TextureTest(asBaseDir + to + "@" + MoverParameters->TypeName); // w pierwszej kolejności z nazwą FIZ/MMD if (!x.empty()) { - ReplacableSkinID[4] = TextureManager.GetTextureId( x, "", 9); // rozmywania 0,1,4,5 nie nadają się + ReplacableSkinID[4] = GfxRenderer.GetTextureId( x, "", 9); // rozmywania 0,1,4,5 nie nadają się return; } x = TextureTest(asBaseDir + to); // na razie prymitywnie if (!x.empty()) - ReplacableSkinID[4] = TextureManager.GetTextureId( x, "", 9); // rozmywania 0,1,4,5 nie nadają się + ReplacableSkinID[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()) - ReplacableSkinID[4] = TextureManager.GetTextureId( x, "", 9); + ReplacableSkinID[4] = GfxRenderer.GetTextureId( x, "", 9); } // Ra 2015-01: żeby zalogować błąd, trzeba by mieć pewność, że model używa // tekstury nr 4 diff --git a/Globals.h b/Globals.h index e20c581a..eb63d7b9 100644 --- a/Globals.h +++ b/Globals.h @@ -11,6 +11,7 @@ http://mozilla.org/MPL/2.0/. #include #include +#include "renderer.h" #include "opengl/glew.h" #include "dumb3d.h" @@ -120,53 +121,6 @@ class cParser; // nowy (powolny!) parser class TEvent; class TTextSound; -// bare-bones render controller, in lack of anything better yet -struct opengl_renderer { - - GLenum static const sunlight{ GL_LIGHT0 }; - GLenum static const ambientlight{ GL_LIGHT1 }; - - enum class rendermode { - color - }; - - rendermode renderpass{ rendermode::color }; -}; - -struct opengl_light { - - GLuint id{ -1 }; - Math3D::vector3 direction; - GLfloat position[ 4 ]; // 4th parameter specifies directional(0) or omni-directional(1) light source - GLfloat ambient[ 4 ]; - GLfloat diffuse[ 4 ]; - 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; - } - - inline - void apply_intensity() { - - glLightfv( id, GL_AMBIENT, ambient ); - glLightfv( id, GL_DIFFUSE, diffuse ); - glLightfv( id, GL_SPECULAR, specular ); - } - inline - void apply_angle() { - - glLightfv( id, GL_POSITION, position ); - if( position[ 3 ] == 1.0f ) { - GLfloat directionarray[] = { direction.x, direction.y, direction.z }; - glLightfv( id, GL_SPOT_DIRECTION, directionarray ); - } - } -}; - class TTranscript { // klasa obsługująca linijkę napisu do dźwięku public: diff --git a/Ground.cpp b/Ground.cpp index 5afdccca..f863ce6d 100644 --- a/Ground.cpp +++ b/Ground.cpp @@ -23,7 +23,7 @@ http://mozilla.org/MPL/2.0/. #include "Logs.h" #include "usefull.h" #include "Timer.h" -#include "Texture.h" +#include "renderer.h" #include "Event.h" #include "EvLaunch.h" #include "TractionPower.h" @@ -276,7 +276,7 @@ void TGroundNode::RaRenderVBO() { // renderowanie z domyslnego bufora VBO glColor3ub(Diffuse[0], Diffuse[1], Diffuse[2]); if (TextureID) - TextureManager.Bind(TextureID); // Ustaw aktywną teksturę + GfxRenderer.Bind(TextureID); // Ustaw aktywną teksturę glDrawArrays(iType, iVboPtr, iNumVerts); // Narysuj naraz wszystkie trójkąty } @@ -457,7 +457,7 @@ void TGroundNode::Compile(bool many) #ifdef USE_VERTEX_ARRAYS glVertexPointer(3, GL_DOUBLE, sizeof(vector3), &Points[0].x); #endif - TextureManager.Bind(0); + GfxRenderer.Bind(0); #ifdef USE_VERTEX_ARRAYS glDrawArrays(iType, 0, iNumPts); #else @@ -478,7 +478,7 @@ void TGroundNode::Compile(bool many) glTexCoordPointer(2, GL_FLOAT, sizeof(TGroundVertex), &tri->Vertices[0].tu); #endif glColor3ub(tri->Diffuse[0], tri->Diffuse[1], tri->Diffuse[2]); - TextureManager.Bind(Global::bWireFrame ? 0 : tri->TextureID); + GfxRenderer.Bind(Global::bWireFrame ? 0 : tri->TextureID); #ifdef USE_VERTEX_ARRAYS glDrawArrays(Global::bWireFrame ? GL_LINE_LOOP : tri->iType, 0, tri->iNumVerts); #else @@ -506,7 +506,7 @@ void TGroundNode::Compile(bool many) else if (iType == TP_MESH) { // grupa ze wspólną teksturą - wrzucanie do wspólnego Display List if (TextureID) - TextureManager.Bind(TextureID); // Ustaw aktywną teksturę + GfxRenderer.Bind(TextureID); // Ustaw aktywną teksturę TGroundNode *n = nNode; while (n ? n->TextureID == TextureID : false) { // wszystkie obiekty o tej samej testurze @@ -2133,8 +2133,8 @@ TGroundNode * TGround::AddGroundNode(cParser *parser) tmp->PROBLEND = false; } #endif - tmp->TextureID = TextureManager.GetTextureId( str, szTexturePath ); - tmp->iFlags = TextureManager.Texture(tmp->TextureID).has_alpha ? 0x220 : 0x210; // z usuwaniem + tmp->TextureID = GfxRenderer.GetTextureId( str, szTexturePath ); + tmp->iFlags = GfxRenderer.Texture(tmp->TextureID).has_alpha ? 0x220 : 0x210; // z usuwaniem if (((tmp->iType == GL_TRIANGLES) && (tmp->iFlags & 0x10)) ? Global::pTerrainCompact->TerrainLoaded() : false) diff --git a/Model3d.cpp b/Model3d.cpp index 4071db89..b7bde3c0 100644 --- a/Model3d.cpp +++ b/Model3d.cpp @@ -19,7 +19,7 @@ http://mozilla.org/MPL/2.0/. #include "logs.h" #include "mczapkie/mctools.h" #include "Usefull.h" -#include "Texture.h" +#include "renderer.h" #include "Timer.h" #include "mtable.h" //--------------------------------------------------------------------------- @@ -411,12 +411,12 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic) TextureNameSet(texture.c_str()); if (texture.find_first_of("/\\") == texture.npos) texture.insert(0, Global::asCurrentTexturePath.c_str()); - TextureID = TextureManager.GetTextureId( texture, szTexturePath ); + TextureID = GfxRenderer.GetTextureId( texture, szTexturePath ); // TexAlpha=TTexturesManager::GetAlpha(TextureID); // iFlags|=TexAlpha?0x20:0x10; //0x10-nieprzezroczysta, 0x20-przezroczysta if (Opacity < 1.0) // przezroczystość z tekstury brana tylko dla Opacity // 0! - iFlags |= TextureManager.Texture(TextureID).has_alpha ? + iFlags |= GfxRenderer.Texture(TextureID).has_alpha ? 0x20 : 0x10; // 0x10-nieprzezroczysta, 0x20-przezroczysta else @@ -636,7 +636,7 @@ int TSubModel::TriangleAdd(TModel3d *m, texture_manager::size_type tex, int tri) m->AddTo(this, s); } // s->asTexture=AnsiString(TTexturesManager::GetName(tex).c_str()); - s->TextureNameSet(TextureManager.Texture(tex).name.c_str()); + s->TextureNameSet(GfxRenderer.Texture(tex).name.c_str()); s->TextureID = tex; s->eType = GL_TRIANGLES; // iAnimOwner=0; //roboczy wskaźnik na wierzchołek @@ -714,7 +714,7 @@ void TSubModel::DisplayLists() { uiDisplayList = glGenLists(1); glNewList(uiDisplayList, GL_COMPILE); - TextureManager.Bind(0); + GfxRenderer.Bind(0); // if (eType==smt_FreeSpotLight) // { // if (iFarAttenDecay==0) @@ -737,7 +737,7 @@ void TSubModel::DisplayLists() { // punkty świecące dookólnie uiDisplayList = glGenLists(1); glNewList(uiDisplayList, GL_COMPILE); - TextureManager.Bind(0); // tekstury nie ma + GfxRenderer.Bind(0); // tekstury nie ma glColorMaterial(GL_FRONT, GL_EMISSION); glDisable(GL_LIGHTING); // Tolaris-030603: bo mu punkty swiecace sie blendowaly glBegin(GL_POINTS); @@ -1100,11 +1100,11 @@ void TSubModel::RenderDL() { if (TextureID < 0) // && (ReplacableSkinId!=0)) { // zmienialne skóry - TextureManager.Bind(ReplacableSkinId[-TextureID]); + GfxRenderer.Bind(ReplacableSkinId[-TextureID]); // TexAlpha=!(iAlpha&1); //zmiana tylko w przypadku wymienej tekstury } else - TextureManager.Bind(TextureID); // również 0 + GfxRenderer.Bind(TextureID); // również 0 if (Global::fLuminance < fLight) { glMaterialfv(GL_FRONT, GL_EMISSION, f4Diffuse); // zeby swiecilo na kolorowo @@ -1197,11 +1197,11 @@ void TSubModel::RenderAlphaDL() { if (TextureID < 0) // && (ReplacableSkinId!=0)) { // zmienialne skóry - TextureManager.Bind(ReplacableSkinId[-TextureID]); + GfxRenderer.Bind(ReplacableSkinId[-TextureID]); // TexAlpha=iAlpha&1; //zmiana tylko w przypadku wymienej tekstury } else - TextureManager.Bind(TextureID); // również 0 + GfxRenderer.Bind(TextureID); // również 0 if (Global::fLuminance < fLight) { glMaterialfv(GL_FRONT, GL_EMISSION, f4Diffuse); // zeby swiecilo na kolorowo @@ -1278,11 +1278,11 @@ void TSubModel::RenderVBO() { if (TextureID < 0) // && (ReplacableSkinId!=0)) { // zmienialne skóry - TextureManager.Bind(ReplacableSkinId[-TextureID]); + GfxRenderer.Bind(ReplacableSkinId[-TextureID]); // TexAlpha=!(iAlpha&1); //zmiana tylko w przypadku wymienej tekstury } else - TextureManager.Bind(TextureID); // również 0 + GfxRenderer.Bind(TextureID); // również 0 glColor3fv(f4Diffuse); // McZapkie-240702: zamiast ub // glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,f4Diffuse); //to samo, // co glColor @@ -1349,7 +1349,7 @@ void TSubModel::RenderVBO() Distdimm=1; */ - TextureManager.Bind(0); // nie teksturować + GfxRenderer.Bind(0); // nie teksturować // glColor3f(f4Diffuse[0],f4Diffuse[1],f4Diffuse[2]); // glColorMaterial(GL_FRONT,GL_EMISSION); float color[4] = {f4Diffuse[0] * Distdimm, f4Diffuse[1] * Distdimm, @@ -1378,7 +1378,7 @@ void TSubModel::RenderVBO() if (pRoot->StartColorVBO()) { // wyświetlanie kolorowych punktów zamiast // trójkątów - TextureManager.Bind(0); // tekstury nie ma + GfxRenderer.Bind(0); // tekstury nie ma glColorMaterial(GL_FRONT, GL_EMISSION); glDisable(GL_LIGHTING); // Tolaris-030603: bo mu punkty swiecace sie // blendowaly @@ -1452,11 +1452,11 @@ void TSubModel::RenderAlphaVBO() { if (TextureID < 0) // && (ReplacableSkinId!=0)) { // zmienialne skory - TextureManager.Bind(ReplacableSkinId[-TextureID]); + GfxRenderer.Bind(ReplacableSkinId[-TextureID]); // TexAlpha=iAlpha&1; //zmiana tylko w przypadku wymienej tekstury } else - TextureManager.Bind(TextureID); // również 0 + GfxRenderer.Bind(TextureID); // również 0 if (Global::fLuminance < fLight) { glMaterialfv(GL_FRONT, GL_EMISSION, f4Diffuse); // zeby swiecilo na kolorowo @@ -1624,14 +1624,14 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, float8 *v, TStringPack *t, TS std::string tex = pTexture; if (tex.find_last_of("/\\") == std::string::npos) tex.insert(0, Global::asCurrentTexturePath); - TextureID = TextureManager.GetTextureId( tex, szTexturePath ); + TextureID = GfxRenderer.GetTextureId( tex, szTexturePath ); // TexAlpha=TTexturesManager::GetAlpha(TextureID); //zmienna robocza // ustawienie cyklu przezroczyste/nieprzezroczyste zależnie od własności // stałej tekstury // iFlags=(iFlags&~0x30)|(TTexturesManager::GetAlpha(TextureID)?0x20:0x10); // //0x10-nieprzezroczysta, 0x20-przezroczysta if (Opacity < 1.0) // przezroczystość z tekstury brana tylko dla Opacity 0! - iFlags |= TextureManager.Texture(TextureID).has_alpha ? + iFlags |= GfxRenderer.Texture(TextureID).has_alpha ? 0x20 : 0x10; // 0x10-nieprzezroczysta, 0x20-przezroczysta else diff --git a/PyInt.cpp b/PyInt.cpp index b3cdb28a..43d9c975 100644 --- a/PyInt.cpp +++ b/PyInt.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "PyInt.h" +#include "renderer.h" #include "Train.h" #include "Logs.h" //#include @@ -453,7 +454,7 @@ void TPythonScreens::init(cParser &parser, TModel3d *model, std::string const &n WriteLog( "Python Screen: submodel " + subModelName + " not found - Ignoring screen" ); return; // nie ma takiego sub modelu w danej kabinie pomijamy } - int textureId = TextureManager.Texture(subModel->GetTextureId()).id; + int textureId = GfxRenderer.Texture(subModel->GetTextureId()).id; if (textureId <= 0) { WriteLog( "Python Screen: invalid texture id " + std::to_string(textureId) + " - Ignoring screen" ); diff --git a/Segment.cpp b/Segment.cpp index daaf7356..21f66a41 100644 --- a/Segment.cpp +++ b/Segment.cpp @@ -641,7 +641,7 @@ void TSegment::RenderSwitchRail(const vector6 *ShapePoints1, const vector6 *Shap void TSegment::Render() { vector3 pt; - TextureManager.Bind(0); + GfxRenderer.Bind(0); int i; if (bCurve) { diff --git a/Texture.cpp b/Texture.cpp index 71c94f9e..249bbe2e 100644 --- a/Texture.cpp +++ b/Texture.cpp @@ -14,19 +14,14 @@ http://mozilla.org/MPL/2.0/. */ #include "stdafx.h" -#include "Texture.h" +#include "texture.h" #include -#include -#include #include "opengl/glew.h" -#include "Globals.h" +#include "usefull.h" +#include "globals.h" #include "logs.h" -#include "Usefull.h" -#include "TextureDDS.h" - -texture_manager TextureManager; texture_manager::texture_manager() { diff --git a/Texture.h b/Texture.h index 168bdfe1..8e036ffc 100644 --- a/Texture.h +++ b/Texture.h @@ -97,5 +97,3 @@ private: index_map m_texturemappings; size_type m_activetexture{ 0 }; // last i.e. currently bound texture }; - -extern texture_manager TextureManager; \ No newline at end of file diff --git a/Track.cpp b/Track.cpp index 10eab7a7..e0d6f27a 100644 --- a/Track.cpp +++ b/Track.cpp @@ -17,7 +17,7 @@ http://mozilla.org/MPL/2.0/. #include "Globals.h" #include "Logs.h" #include "Usefull.h" -#include "Texture.h" +#include "renderer.h" #include "Timer.h" #include "Ground.h" #include "parser.h" @@ -508,7 +508,7 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name) parser->getTokens(); *parser >> token; str = token; // railtex - TextureID1 = (str == "none" ? 0 : TextureManager.GetTextureId( + TextureID1 = (str == "none" ? 0 : GfxRenderer.GetTextureId( str, szTexturePath, (iCategoryFlag & 1) ? Global::iRailProFiltering : Global::iBallastFiltering)); @@ -519,7 +519,7 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name) parser->getTokens(); *parser >> token; str = token; // sub || railtex - TextureID2 = (str == "none" ? 0 : TextureManager.GetTextureId( + TextureID2 = (str == "none" ? 0 : GfxRenderer.GetTextureId( str, szTexturePath, (eType == tt_Normal) ? Global::iBallastFiltering : Global::iRailProFiltering)); @@ -579,12 +579,12 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name) if (TextureID1 && fTexLength) { // dla drogi trzeba ustalić proporcje boków nawierzchni float w, h; - TextureManager.Bind(TextureID1); + GfxRenderer.Bind(TextureID1); glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); if (h != 0.0) fTexRatio1 = w / h; // proporcja boków - TextureManager.Bind(TextureID2); + GfxRenderer.Bind(TextureID2); glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); if (h != 0.0) @@ -1299,14 +1299,14 @@ void TTrack::Compile(GLuint tex) } } if (!tex) - TextureManager.Bind( TextureID2 ); + GfxRenderer.Bind( TextureID2 ); Segment->RenderLoft(bpts1, iTrapezoid ? -4 : 4, fTexLength); } if (TextureID1) if (tex ? TextureID1 == tex : true) // jeśli pasuje do grupy (tex) { // szyny if (!tex) - TextureManager.Bind( TextureID1 ); + GfxRenderer.Bind( TextureID1 ); Segment->RenderLoft(rpts1, iTrapezoid ? -nnumPts : nnumPts, fTexLength); Segment->RenderLoft(rpts2, iTrapezoid ? -nnumPts : nnumPts, fTexLength); } @@ -1345,7 +1345,7 @@ void TTrack::Compile(GLuint tex) // McZapkie-130302 - poprawione rysowanie szyn if (SwitchExtension->RightSwitch) { // zwrotnica prawa - TextureManager.Bind( TextureID1 ); + GfxRenderer.Bind( TextureID1 ); SwitchExtension->Segments[0]->RenderLoft(rpts1, nnumPts, fTexLength, 2); // prawa szyna za iglicą SwitchExtension->Segments[0]->RenderSwitchRail( @@ -1354,7 +1354,7 @@ void TTrack::Compile(GLuint tex) SwitchExtension->Segments[0]->RenderLoft( rpts2, nnumPts, fTexLength); // lewa szyna normalnie cała if (TextureID2 != TextureID1) // nie wiadomo, czy OpenGL to optymalizuje - TextureManager.Bind( TextureID2 ); + GfxRenderer.Bind( TextureID2 ); SwitchExtension->Segments[1]->RenderLoft( rpts1, nnumPts, fTexLength); // prawa szyna normalna cała SwitchExtension->Segments[1]->RenderLoft(rpts2, nnumPts, fTexLength, @@ -1365,7 +1365,7 @@ void TTrack::Compile(GLuint tex) } else { // lewa kiedyś działała lepiej niż prawa - TextureManager.Bind( TextureID1 ); + GfxRenderer.Bind( TextureID1 ); SwitchExtension->Segments[0]->RenderLoft( rpts1, nnumPts, fTexLength); // prawa szyna normalna cała SwitchExtension->Segments[0]->RenderLoft(rpts2, nnumPts, fTexLength, @@ -1374,7 +1374,7 @@ void TTrack::Compile(GLuint tex) rpts2, rpts4, nnumPts, fTexLength, 2, -SwitchExtension->fOffset2); // lewa iglica if (TextureID2 != TextureID1) // nie wiadomo, czy OpenGL to optymalizuje - TextureManager.Bind( TextureID2 ); + GfxRenderer.Bind( TextureID2 ); SwitchExtension->Segments[1]->RenderLoft(rpts1, nnumPts, fTexLength, 2); // prawa szyna za iglicą SwitchExtension->Segments[1]->RenderSwitchRail( @@ -1422,7 +1422,7 @@ void TTrack::Compile(GLuint tex) if (tex ? TextureID1 == tex : true) // jeśli pasuje do grupy (tex) { // tworzenie trójkątów nawierzchni szosy if (!tex) - TextureManager.Bind( TextureID1 ); + GfxRenderer.Bind( TextureID1 ); Segment->RenderLoft(bpts1, iTrapezoid ? -2 : 2, fTexLength); } if (TextureID2) @@ -1430,7 +1430,7 @@ void TTrack::Compile(GLuint tex) { // pobocze drogi - poziome przy przechyłce (a może krawężnik i chodnik zrobić jak // w Midtown Madness 2?) if (!tex) - TextureManager.Bind( TextureID2 ); + GfxRenderer.Bind( TextureID2 ); vector6 rpts1[6], rpts2[6]; // współrzędne przekroju i mapowania dla prawej i lewej strony if (fTexHeight1 >= 0.0) @@ -1610,7 +1610,7 @@ void TTrack::Compile(GLuint tex) // Midtown Madness 2?) if (TextureID2) if (!tex) - TextureManager.Bind( TextureID2 ); + GfxRenderer.Bind( TextureID2 ); vector6 rpts1[6], rpts2[6]; // współrzędne przekroju i mapowania dla prawej i lewej strony // Ra 2014-07: trzeba to przerobić na pętlę i pobierać profile (przynajmniej 2..4) z @@ -1755,7 +1755,7 @@ void TTrack::Compile(GLuint tex) if (tex ? TextureID1 == tex : true) // jeśli pasuje do grupy (tex) { if (!tex) - TextureManager.Bind( TextureID1 ); + GfxRenderer.Bind( TextureID1 ); glBegin(GL_TRIANGLE_FAN); // takie kółeczko będzie glNormal3f(0, 1, 0); glTexCoord2f(0.5, 0.5); //środek tekstury na środku skrzyżowania @@ -1787,7 +1787,7 @@ void TTrack::Compile(GLuint tex) if (tex ? TextureID1 == tex : true) // jeśli pasuje do grupy (tex) { if (!tex) - TextureManager.Bind( TextureID1 ); + GfxRenderer.Bind( TextureID1 ); Segment->RenderLoft(bpts1, numPts, fTexLength); } if (TextureID2) @@ -1799,7 +1799,7 @@ void TTrack::Compile(GLuint tex) vector6 rpts2[3] = {vector6(-fHTW, 0.0, 1.0), vector6(-fHTW - side, 0.0, 0.5), vector6(-rozp, -fTexHeight1, 0.0)}; // Ra: po kiego 0.1? if (!tex) - TextureManager.Bind( TextureID2 ); // brzeg rzeki + GfxRenderer.Bind( TextureID2 ); // brzeg rzeki Segment->RenderLoft(rpts1, 3, fTexLength); Segment->RenderLoft(rpts2, 3, fTexLength); } @@ -2473,7 +2473,7 @@ void TTrack::RaRenderVBO(int iPtr) if (TextureID1) if ((seg = SwitchExtension->Segments[0]->RaSegCount()) > 0) { - TextureManager.Bind( TextureID1 ); // szyny + + GfxRenderer.Bind( TextureID1 ); // szyny + for (i = 0; i < seg; ++i) glDrawArrays(GL_TRIANGLE_STRIP, iPtr + 24 * i, 24); iPtr += 24 * seg; // pominięcie lewej szyny @@ -2484,7 +2484,7 @@ void TTrack::RaRenderVBO(int iPtr) if (TextureID2) if ((seg = SwitchExtension->Segments[1]->RaSegCount()) > 0) { - TextureManager.Bind( TextureID2 ); // szyny - + GfxRenderer.Bind( TextureID2 ); // szyny - for (i = 0; i < seg; ++i) glDrawArrays(GL_TRIANGLE_STRIP, iPtr + 24 * i, 24); iPtr += 24 * seg; // pominięcie lewej szyny @@ -2498,14 +2498,14 @@ void TTrack::RaRenderVBO(int iPtr) { if (TextureID2) { - TextureManager.Bind( TextureID2 ); // podsypka + GfxRenderer.Bind( TextureID2 ); // podsypka for (i = 0; i < seg; ++i) glDrawArrays(GL_TRIANGLE_STRIP, iPtr + 8 * i, 8); iPtr += 8 * seg; // pominięcie podsypki } if (TextureID1) { - TextureManager.Bind( TextureID1 ); // szyny + GfxRenderer.Bind( TextureID1 ); // szyny for (i = 0; i < seg; ++i) glDrawArrays(GL_TRIANGLE_STRIP, iPtr + 24 * i, 24); iPtr += 24 * seg; // pominięcie lewej szyny @@ -2520,7 +2520,7 @@ void TTrack::RaRenderVBO(int iPtr) { if (TextureID1) { - TextureManager.Bind( TextureID1 ); // nawierzchnia + GfxRenderer.Bind( TextureID1 ); // nawierzchnia for (i = 0; i < seg; ++i) { glDrawArrays(GL_TRIANGLE_STRIP, iPtr, 4); @@ -2529,7 +2529,7 @@ void TTrack::RaRenderVBO(int iPtr) } if (TextureID2) { - TextureManager.Bind( TextureID2 ); // pobocze + GfxRenderer.Bind( TextureID2 ); // pobocze if (fTexHeight1 >= 0.0) { // normalna droga z poboczem for (i = 0; i < seg; ++i) @@ -2558,7 +2558,7 @@ void TTrack::RaRenderVBO(int iPtr) { if (TextureID1) { - TextureManager.Bind( TextureID1 ); // nawierzchnia + GfxRenderer.Bind( TextureID1 ); // nawierzchnia for (i = 0; i < seg; ++i) { glDrawArrays(GL_TRIANGLE_STRIP, iPtr, 4); @@ -2567,7 +2567,7 @@ void TTrack::RaRenderVBO(int iPtr) } if (TextureID2) { - TextureManager.Bind( TextureID2 ); // pobocze + GfxRenderer.Bind( TextureID2 ); // pobocze for (i = 0; i < seg; ++i) glDrawArrays(GL_TRIANGLE_STRIP, iPtr + 6 * i, 6); iPtr += 6 * seg; // pominięcie lewego pobocza diff --git a/Traction.cpp b/Traction.cpp index e5a17614..9328e3e1 100644 --- a/Traction.cpp +++ b/Traction.cpp @@ -18,7 +18,7 @@ http://mozilla.org/MPL/2.0/. #include "logs.h" #include "mctools.h" #include "TractionPower.h" -#include "Texture.h" +#include "renderer.h" //--------------------------------------------------------------------------- /* @@ -116,7 +116,7 @@ void TTraction::Optimize() uiDisplayList = glGenLists(1); glNewList(uiDisplayList, GL_COMPILE); - TextureManager.Bind(0); + GfxRenderer.Bind(0); // glColor3ub(0,0,0); McZapkie: to do render // glPushMatrix(); @@ -469,7 +469,7 @@ void TTraction::RenderVBO(float mgn, int iPtr) { // renderowanie z użyciem VBO if (Wires != 0 && !TestFlag(DamageFlag, 128)) // rysuj jesli sa druty i nie zerwana { - TextureManager.Bind(0); + GfxRenderer.Bind(0); glDisable(GL_LIGHTING); // aby nie używało wektorów normalnych do kolorowania glColor4f(0, 0, 0, 1); // jak nieznany kolor to czarne nieprzezroczyste if (!Global::bSmoothTraction) diff --git a/World.cpp b/World.cpp index c8670ffb..b2988ba0 100644 --- a/World.cpp +++ b/World.cpp @@ -21,7 +21,7 @@ http://mozilla.org/MPL/2.0/. #include "Globals.h" #include "Logs.h" #include "MdlMngr.h" -#include "Texture.h" +#include "renderer.h" #include "Timer.h" #include "mtable.h" #include "Sound.h" @@ -487,8 +487,8 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) glColor3f( 1.0f, 1.0f, 1.0f ); #endif - auto logo = TextureManager.GetTextureId( "logo", szTexturePath, 6 ); - TextureManager.Bind(logo); // Select our texture + auto logo = GfxRenderer.GetTextureId( "logo", szTexturePath, 6 ); + GfxRenderer.Bind(logo); // Select our texture glBegin(GL_QUADS); // Drawing using triangles glTexCoord2f(0.0f, 0.0f); @@ -688,9 +688,9 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); //{Texture blends with object // background} if (Global::bOldSmudge == true) - light = TextureManager.GetTextureId( "smuga.tga", szTexturePath ); + light = GfxRenderer.GetTextureId( "smuga.tga", szTexturePath ); else - light = TextureManager.GetTextureId( "smuga2.tga", szTexturePath ); + light = GfxRenderer.GetTextureId( "smuga2.tga", szTexturePath ); // Camera.Reset(); Timer::ResetTimers(); WriteLog( "Load time: " + @@ -1661,7 +1661,7 @@ TWorld::Render_Cab() { glDisable( GL_DEPTH_TEST ); glDisable( GL_LIGHTING ); glDisable( GL_FOG ); - TextureManager.Bind( light ); // Select our texture + GfxRenderer.Bind( light ); // Select our texture glBegin( GL_QUADS ); float fSmudge = dynamic->MoverParameters->DimHalf.y + 7; // gdzie zaczynać smugę @@ -1703,7 +1703,7 @@ TWorld::Render_Cab() { glDisable( GL_LIGHTING ); glDisable( GL_FOG ); //glColor4f(0.15f, 0.15f, 0.15f, 0.25f); - TextureManager.Bind( light ); // Select our texture + GfxRenderer.Bind( light ); // Select our texture //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ę @@ -2011,7 +2011,7 @@ TWorld::Render_UI() { SetWindowText( hWnd, Controlled->MoverParameters->Name.c_str() ); else SetWindowText( hWnd, Global::SceneryFile.c_str() ); // nazwa scenerii - TextureManager.Bind( 0 ); + GfxRenderer.Bind( 0 ); glColor4f( 1.0f, 0.0f, 0.0f, 1.0f ); glLoadIdentity(); glTranslatef( 0.0f, 0.0f, -0.50f ); diff --git a/maszyna.vcxproj b/maszyna.vcxproj index e15e29cf..3ea50446 100644 --- a/maszyna.vcxproj +++ b/maszyna.vcxproj @@ -119,6 +119,7 @@ + @@ -180,6 +181,7 @@ + diff --git a/maszyna.vcxproj.filters b/maszyna.vcxproj.filters index 994b2526..c0530acf 100644 --- a/maszyna.vcxproj.filters +++ b/maszyna.vcxproj.filters @@ -192,6 +192,9 @@ Source Files + + Source Files + @@ -371,6 +374,9 @@ Header Files + + Header Files + diff --git a/renderer.cpp b/renderer.cpp new file mode 100644 index 00000000..13fdb85b --- /dev/null +++ b/renderer.cpp @@ -0,0 +1,15 @@ +/* +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/. +*/ + +#include "stdafx.h" +#include "renderer.h" + +opengl_renderer GfxRenderer; + +//--------------------------------------------------------------------------- diff --git a/renderer.h b/renderer.h new file mode 100644 index 00000000..deabb54e --- /dev/null +++ b/renderer.h @@ -0,0 +1,99 @@ +/* +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/. +*/ + +#pragma once + +#include "opengl/glew.h" +#include "texture.h" +#include "dumb3d.h" + +struct opengl_light { + + GLuint id{ -1 }; + Math3D::vector3 direction; + GLfloat position[ 4 ]; // 4th parameter specifies directional(0) or omni-directional(1) light source + GLfloat ambient[ 4 ]; + GLfloat diffuse[ 4 ]; + 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; + } + + inline + void apply_intensity() { + + glLightfv( id, GL_AMBIENT, ambient ); + glLightfv( id, GL_DIFFUSE, diffuse ); + glLightfv( id, GL_SPECULAR, specular ); + } + inline + void apply_angle() { + + glLightfv( id, GL_POSITION, position ); + if( position[ 3 ] == 1.0f ) { + GLfloat directionarray[] = { direction.x, direction.y, direction.z }; + glLightfv( id, GL_SPOT_DIRECTION, directionarray ); + } + } +}; + +// encapsulates basic rendering setup. +// for modern opengl this translates to a specific collection of glsl shaders, +// for legacy opengl this is combination of blending modes, active texture units etc +struct opengl_technique { + +}; + +// a collection of parameters for the rendering setup. +// for modern opengl this translates to set of attributes for the active shaders, +// for legacy opengl this is basically just texture(s) assigned to geometry +struct opengl_material { + +}; + +// bare-bones render controller, in lack of anything better yet +class opengl_renderer { + +public: + GLenum static const sunlight{ GL_LIGHT0 }; +// GLenum static const ambientlight{ GL_LIGHT1 }; + + 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 ); + } + +private: + enum class rendermode { + color + }; + + rendermode renderpass{ rendermode::color }; + + texture_manager m_textures; +}; + +extern opengl_renderer GfxRenderer; + +//--------------------------------------------------------------------------- From 746da9a5adabec64cefc46b1ac3d264b92e6a288 Mon Sep 17 00:00:00 2001 From: maciek001 Date: Tue, 21 Feb 2017 19:26:51 +0100 Subject: [PATCH 25/40] =?UTF-8?q?znalaz=C5=82em=20napi=C4=99cie=20na=20bat?= =?UTF-8?q?erii?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Train.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Train.cpp b/Train.cpp index d32ec22e..40893cb9 100644 --- a/Train.cpp +++ b/Train.cpp @@ -2852,6 +2852,7 @@ bool TTrain::Update( double const Deltatime ) Console::ValueSet(5, fHCurrent[2]); // drugi amperomierz 2 Console::ValueSet(4, fHCurrent[(mvControlled->TrainType & dt_EZT) ? 0 : 1]); // pierwszy amperomierz; dla EZT prąd całkowity Console::ValueSet(7, fTachoVelocity); + //mvControlled->BatteryVoltage; przyda się w przyszłości } // hunter-080812: wyrzucanie szybkiego na elektrykach gdy nie ma napiecia From 249fdc0f804ed8c11ac5ff3e25f12be0a07456de Mon Sep 17 00:00:00 2001 From: maciek001 Date: Wed, 22 Feb 2017 00:12:37 +0100 Subject: [PATCH 26/40] poprawka dla hamulca dodatkowego pokeys --- Console.cpp | 53 ++++++++++++++++++++++++++++++----------------------- Train.cpp | 11 +++++++---- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/Console.cpp b/Console.cpp index 9b44b661..04291262 100644 --- a/Console.cpp +++ b/Console.cpp @@ -324,7 +324,7 @@ void Console::BitsUpdate(int mask) else MWDComm->WriteDataBuff[4] &= ~(1 << 6); if (mask & 0x0004) if (iBits & 4) MWDComm->WriteDataBuff[4] |= 1 << 1; // jazda na oporach rozruchowych else MWDComm->WriteDataBuff[4] &= ~(1 << 1); - if (mask & 0x0008) if (iBits & 8) MWDComm->WriteDataBuff[5] |= 1 << 5; // wy??cznik szybki + if (mask & 0x0008) if (iBits & 8) MWDComm->WriteDataBuff[5] |= 1 << 5; // wy??cznik szybki else MWDComm->WriteDataBuff[5] &= ~(1 << 5); if (mask & 0x0010) if (iBits & 0x10) MWDComm->WriteDataBuff[5] |= 1 << 4; // nadmiarowy silnik?w trakcyjnych else MWDComm->WriteDataBuff[5] &= ~(1 << 4); @@ -342,11 +342,11 @@ void Console::BitsUpdate(int mask) else MWDComm->WriteDataBuff[2] &= ~(1 << 2); if (mask & 0x0800) if (iBits & 0x800) MWDComm->WriteDataBuff[4] |= 1 << 0; // ogrzewanie poci?gu else MWDComm->WriteDataBuff[4] &= ~(1 << 0); - if (mask & 0x1000) if (iBits & 0x1000) MWDComm->bHamowanie = true; // hasler: ci?nienie w hamulcach HASLER rysik 2 + if (mask & 0x1000) if (iBits & 0x1000) MWDComm->bHamowanie = true; // hasler: ci?nienie w hamulcach HASLER rysik 2 else MWDComm->bHamowanie = false; - if (mask & 0x2000) if (iBits & 0x2000) MWDComm->WriteDataBuff[6] |= 1 << 4; // hasler: pr?d "na" silnikach HASLER rysik 3 + if (mask & 0x2000) if (iBits & 0x2000) MWDComm->WriteDataBuff[6] |= 1 << 4; // hasler: pr?d "na" silnikach HASLER rysik 3 else MWDComm->WriteDataBuff[6] &= ~(1 << 4); - if (mask & 0x4000) if (iBits & 0x4000) MWDComm->WriteDataBuff[6] |= 1 << 7; // brz?czyk SHP/CA + if (mask & 0x4000) if (iBits & 0x4000) MWDComm->WriteDataBuff[6] |= 1 << 7; // brz?czyk SHP/CA else MWDComm->WriteDataBuff[6] &= ~(1 << 7); //if(mask & 0x8000) if(iBits & 0x8000) MWDComm->WriteDataBuff[1] |= 1<<7; (puste) //else MWDComm->WriteDataBuff[0] &= ~(1<<7); @@ -432,6 +432,11 @@ void Console::ValueSet(int x, double y) else MWDComm->WriteDataBuff[0] = (unsigned char)floor(y); // prędkość dla np haslera if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Speed: " + to_string(MWDComm->WriteDataBuff[0])); break; + /* case 8: iliczba = (unsigned int)floor((y / Global::fMWDamp[0] * Global::fMWDamp[1]) + 0.5); // amp WN 3 + MWDComm->WriteDataBuff[20] = (unsigned int)(iliczba >> 8); + MWDComm->WriteDataBuff[19] = (unsigned char)iliczba; + if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Apm meter3 " + to_string(MWDComm->WriteDataBuff[20]) + " " + to_string(MWDComm->WriteDataBuff[19])); + break; */ // na razie nie działa więc nie odkomentować! } } }; @@ -470,25 +475,27 @@ float Console::AnalogCalibrateGet(int x) { // pobranie i kalibracja wartości analogowej, jeśli nie ma PoKeys zwraca NULL if (iMode == 4 && PoKeys55[0]) { - float b = PoKeys55[0]->fAnalog[x]; - /*return (((((Global::fCalibrateIn[x][5] * b) + Global::fCalibrateIn[x][4]) * b + - Global::fCalibrateIn[x][3]) * - b + - Global::fCalibrateIn[x][2]) * - b + - Global::fCalibrateIn[x][1]) * - b + - Global::fCalibrateIn[x][0];*/ - b = (((((Global::fCalibrateIn[x][5] * b) + Global::fCalibrateIn[x][4]) * b + - Global::fCalibrateIn[x][3]) * - b + - Global::fCalibrateIn[x][2]) * - b + - Global::fCalibrateIn[x][1]) * - b + - Global::fCalibrateIn[x][0]; - return (b + 2) / 8; - } + float b = PoKeys55[0]->fAnalog[x]; + /*return (((((Global::fCalibrateIn[x][5] * b) + Global::fCalibrateIn[x][4]) * b + + Global::fCalibrateIn[x][3]) * + b + + Global::fCalibrateIn[x][2]) * + b + + Global::fCalibrateIn[x][1]) * + b + + Global::fCalibrateIn[x][0];*/ + b = (((((Global::fCalibrateIn[x][5] * b) + Global::fCalibrateIn[x][4]) * b + + Global::fCalibrateIn[x][3]) * + b + + Global::fCalibrateIn[x][2]) * + b + + Global::fCalibrateIn[x][1]) * + b + + Global::fCalibrateIn[x][0]; + if (x == 0) return (b + 2) / 8; + if (x == 1) return b/10; + else return b; + } if (Global::bMWDmasterEnable && Global::bMWDBreakEnable) { float b = (float)MWDComm->uiAnalog[x]; diff --git a/Train.cpp b/Train.cpp index 40893cb9..19ebccc9 100644 --- a/Train.cpp +++ b/Train.cpp @@ -2842,17 +2842,18 @@ bool TTrain::Update( double const Deltatime ) /// napędu } - if (Global::bMWDmasterEnable) // pobieranie danych dla pulpitu przez port szeregowy (COM) + if (Global::bMWDmasterEnable) // pobieranie danych dla pulpitu port (COM) { Console::ValueSet(0, mvOccupied->Compressor); // zbiornik główny Console::ValueSet(1, mvOccupied->PipePress); // przewód główny Console::ValueSet(2, mvOccupied->BrakePress); // cylinder hamulcowy Console::ValueSet(3, fHVoltage); // woltomierz wysokiego napięcia - Console::ValueSet(6, fHCurrent[3]); // drugi amperomierz 3 + Console::ValueSet(4, fHCurrent[(mvControlled->TrainType & dt_EZT) ? 0 : 1]); + // pierwszy amperomierz; dla EZT prąd całkowity Console::ValueSet(5, fHCurrent[2]); // drugi amperomierz 2 - Console::ValueSet(4, fHCurrent[(mvControlled->TrainType & dt_EZT) ? 0 : 1]); // pierwszy amperomierz; dla EZT prąd całkowity + Console::ValueSet(6, fHCurrent[3]); // drugi amperomierz 3 Console::ValueSet(7, fTachoVelocity); - //mvControlled->BatteryVoltage; przyda się w przyszłości + //Console::ValueSet(8, mvControlled->BatteryVoltage); // przyda się w przyszłości } // hunter-080812: wyrzucanie szybkiego na elektrykach gdy nie ma napiecia @@ -3800,6 +3801,8 @@ bool TTrain::Update( double const Deltatime ) // ggBrakeCtrl.UpdateValue(double(mvOccupied->BrakeCtrlPos)); ggBrakeCtrl.UpdateValue(mvOccupied->fBrakeCtrlPos); ggBrakeCtrl.Update(); + + } if (ggLocalBrake.SubModel) { From 9c242d3590d9c3a2b0b79a01ff0f7f20de1c75a2 Mon Sep 17 00:00:00 2001 From: maciek001 Date: Wed, 22 Feb 2017 22:36:01 +0100 Subject: [PATCH 27/40] Drobne dodatki i poprawki --- Console.cpp | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/Console.cpp b/Console.cpp index 04291262..f6ced4d2 100644 --- a/Console.cpp +++ b/Console.cpp @@ -146,7 +146,7 @@ int Console::On() { // załączenie konsoli (np. nawiązanie komunikacji) iSwitch[0] = iSwitch[1] = iSwitch[2] = iSwitch[3] = 0; // bity 0..127 - bez [Ctrl] iSwitch[4] = iSwitch[5] = iSwitch[6] = iSwitch[7] = 0; // bity 128..255 - z [Ctrl] - switch (iMode) + switch (iMode) { case 1: // kontrolki klawiatury case 2: // kontrolki klawiatury @@ -176,6 +176,7 @@ int Console::On() { // połączenie nie wyszło, ma być NULL delete PoKeys55[0]; PoKeys55[0] = NULL; + WriteLog("PoKeys not found!"); } break; } @@ -324,29 +325,29 @@ void Console::BitsUpdate(int mask) else MWDComm->WriteDataBuff[4] &= ~(1 << 6); if (mask & 0x0004) if (iBits & 4) MWDComm->WriteDataBuff[4] |= 1 << 1; // jazda na oporach rozruchowych else MWDComm->WriteDataBuff[4] &= ~(1 << 1); - if (mask & 0x0008) if (iBits & 8) MWDComm->WriteDataBuff[5] |= 1 << 5; // wy??cznik szybki + if (mask & 0x0008) if (iBits & 8) MWDComm->WriteDataBuff[5] |= 1 << 5; // wyłącznik szybki else MWDComm->WriteDataBuff[5] &= ~(1 << 5); - if (mask & 0x0010) if (iBits & 0x10) MWDComm->WriteDataBuff[5] |= 1 << 4; // nadmiarowy silnik?w trakcyjnych + if (mask & 0x0010) if (iBits & 0x10) MWDComm->WriteDataBuff[5] |= 1 << 4; // nadmiarowy silników trakcyjnych else MWDComm->WriteDataBuff[5] &= ~(1 << 4); if (mask & 0x0020) if (iBits & 0x20) MWDComm->WriteDataBuff[4] |= 1 << 0; // styczniki liniowe else MWDComm->WriteDataBuff[5] &= ~(1 << 0); - if (mask & 0x0040) if (iBits & 0x40) MWDComm->WriteDataBuff[4] |= 1 << 2; // po?lizg + if (mask & 0x0040) if (iBits & 0x40) MWDComm->WriteDataBuff[4] |= 1 << 2; // poślizg else MWDComm->WriteDataBuff[4] &= ~(1 << 2); if (mask & 0x0080) if (iBits & 0x80) MWDComm->WriteDataBuff[5] |= 1 << 2; // (nadmiarowy) przetwornicy? ++ else MWDComm->WriteDataBuff[5] &= ~(1 << 2); - if (mask & 0x0100) if (iBits & 0x100) MWDComm->WriteDataBuff[5] |= 1 << 7; // nadmiarowy spr??arki + if (mask & 0x0100) if (iBits & 0x100) MWDComm->WriteDataBuff[5] |= 1 << 7; // nadmiarowy sprężarki else MWDComm->WriteDataBuff[5] &= ~(1 << 7); if (mask & 0x0200) if (iBits & 0x200) MWDComm->WriteDataBuff[2] |= 1 << 1; // wentylatory i opory else MWDComm->WriteDataBuff[2] &= ~(1 << 1); if (mask & 0x0400) if (iBits & 0x400) MWDComm->WriteDataBuff[2] |= 1 << 2; // wysoki rozruch else MWDComm->WriteDataBuff[2] &= ~(1 << 2); - if (mask & 0x0800) if (iBits & 0x800) MWDComm->WriteDataBuff[4] |= 1 << 0; // ogrzewanie poci?gu + if (mask & 0x0800) if (iBits & 0x800) MWDComm->WriteDataBuff[4] |= 1 << 0; // ogrzewanie pociągu else MWDComm->WriteDataBuff[4] &= ~(1 << 0); - if (mask & 0x1000) if (iBits & 0x1000) MWDComm->bHamowanie = true; // hasler: ci?nienie w hamulcach HASLER rysik 2 + if (mask & 0x1000) if (iBits & 0x1000) MWDComm->bHamowanie = true; // hasler: ciśnienie w hamulcach HASLER rysik 2 else MWDComm->bHamowanie = false; - if (mask & 0x2000) if (iBits & 0x2000) MWDComm->WriteDataBuff[6] |= 1 << 4; // hasler: pr?d "na" silnikach HASLER rysik 3 + if (mask & 0x2000) if (iBits & 0x2000) MWDComm->WriteDataBuff[6] |= 1 << 4; // hasler: prąd "na" silnikach - HASLER rysik 3 else MWDComm->WriteDataBuff[6] &= ~(1 << 4); - if (mask & 0x4000) if (iBits & 0x4000) MWDComm->WriteDataBuff[6] |= 1 << 7; // brz?czyk SHP/CA + if (mask & 0x4000) if (iBits & 0x4000) MWDComm->WriteDataBuff[6] |= 1 << 7; // brzęczyk SHP/CA else MWDComm->WriteDataBuff[6] &= ~(1 << 7); //if(mask & 0x8000) if(iBits & 0x8000) MWDComm->WriteDataBuff[1] |= 1<<7; (puste) //else MWDComm->WriteDataBuff[0] &= ~(1<<7); @@ -393,25 +394,25 @@ void Console::ValueSet(int x, double y) unsigned int iliczba; switch (x) { - case 0: iliczba = (unsigned int)floor((y / (Global::fMWDzg[0] * 10) * Global::fMWDzg[1]) + 0.5); // zbiornik g??wny + case 0: iliczba = (unsigned int)floor((y / (Global::fMWDzg[0] * 10) * Global::fMWDzg[1]) + 0.5); // zbiornik główny MWDComm->WriteDataBuff[12] = (unsigned char)(iliczba >> 8); MWDComm->WriteDataBuff[11] = (unsigned char)iliczba; if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Main tank press " + to_string(MWDComm->WriteDataBuff[12]) + " " + to_string(MWDComm->WriteDataBuff[11])); break; - case 1: iliczba = (unsigned int)floor((y / (Global::fMWDpg[0] * 10) * Global::fMWDpg[1]) + 0.5); // przew?d g??wny + case 1: iliczba = (unsigned int)floor((y / (Global::fMWDpg[0] * 10) * Global::fMWDpg[1]) + 0.5); // przewód główny MWDComm->WriteDataBuff[10] = (unsigned char)(iliczba >> 8); MWDComm->WriteDataBuff[9] = (unsigned char)iliczba; if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Main pipe press " + to_string(MWDComm->WriteDataBuff[10]) + " " + to_string(MWDComm->WriteDataBuff[9])); break; - case 2: iliczba = (unsigned int)floor((y / (Global::fMWDph[0] * 10) * Global::fMWDph[1]) + 0.5); // cylinder hamulcowy + case 2: iliczba = (unsigned int)floor((y / (Global::fMWDph[0] * 10) * Global::fMWDph[1]) + 0.5); // cylinder hamulcowy MWDComm->WriteDataBuff[8] = (unsigned char)(iliczba >> 8); MWDComm->WriteDataBuff[7] = (unsigned char)iliczba; if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Break press " + to_string(MWDComm->WriteDataBuff[8]) + " " + to_string(MWDComm->WriteDataBuff[7])); break; - case 3: iliczba = (unsigned int)floor((y / Global::fMWDvolt[0] * Global::fMWDvolt[1]) + 0.5); // woltomierz WN + case 3: iliczba = (unsigned int)floor((y / Global::fMWDvolt[0] * Global::fMWDvolt[1]) + 0.5); // woltomierz WN MWDComm->WriteDataBuff[14] = (unsigned char)(iliczba >> 8); MWDComm->WriteDataBuff[13] = (unsigned char)iliczba; - if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Volt meter " + to_string(MWDComm->WriteDataBuff[14]) + " " + to_string(MWDComm->WriteDataBuff[13])); + if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Hi Volt meter " + to_string(MWDComm->WriteDataBuff[14]) + " " + to_string(MWDComm->WriteDataBuff[13])); break; case 4: iliczba = (unsigned int)floor((y / Global::fMWDamp[0] * Global::fMWDamp[1]) + 0.5); // amp WN 1 MWDComm->WriteDataBuff[16] = (unsigned char)(iliczba >> 8); @@ -432,11 +433,11 @@ void Console::ValueSet(int x, double y) else MWDComm->WriteDataBuff[0] = (unsigned char)floor(y); // prędkość dla np haslera if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Speed: " + to_string(MWDComm->WriteDataBuff[0])); break; - /* case 8: iliczba = (unsigned int)floor((y / Global::fMWDamp[0] * Global::fMWDamp[1]) + 0.5); // amp WN 3 - MWDComm->WriteDataBuff[20] = (unsigned int)(iliczba >> 8); - MWDComm->WriteDataBuff[19] = (unsigned char)iliczba; - if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Apm meter3 " + to_string(MWDComm->WriteDataBuff[20]) + " " + to_string(MWDComm->WriteDataBuff[19])); - break; */ // na razie nie działa więc nie odkomentować! + case 8: iliczba = (unsigned int)floor((y / Global::fMWDlowVolt[0] * Global::fMWDlowVolt[1]) + 0.5); // volt NN + MWDComm->WriteDataBuff[22] = (unsigned int)(iliczba >> 8); + MWDComm->WriteDataBuff[21] = (unsigned char)iliczba; + if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Low Volt meter " + to_string(MWDComm->WriteDataBuff[22]) + " " + to_string(MWDComm->WriteDataBuff[21])); + break; // przygotowane do wdrożenia, jeszcze nie wywoływane } } }; From b6c75afd257fcc5fcaacf8b15e7ab6763ed54a53 Mon Sep 17 00:00:00 2001 From: maciek001 Date: Wed, 22 Feb 2017 22:37:22 +0100 Subject: [PATCH 28/40] =?UTF-8?q?PRZYWR=C3=93CONO=20Console::ModeSet()!!!?= =?UTF-8?q?=20Nie=20dzia=C5=82a=C5=82=20przez=20to=20PoKeys!=20Dodano=20zm?= =?UTF-8?q?ienn=C4=85=20dla=20MWD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Globals.cpp | 12 +++++++++--- Globals.h | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Globals.cpp b/Globals.cpp index 14f3968f..0677fe18 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -204,6 +204,7 @@ double Global::fMWDpg[2] = { 0.8, 1023 }; double Global::fMWDph[2] = { 0.6, 1023 }; double Global::fMWDvolt[2] = { 4000, 1023 }; double Global::fMWDamp[2] = { 800, 1023 }; +double Global::fMWDlowVolt[2] = { 150, 1023 }; int Global::iMWDdivider = 5; //--------------------------------------------------------------------------- @@ -893,6 +894,11 @@ void Global::ConfigParse(cParser &Parser) Parser >> fMWDamp[0] >> fMWDamp[1]; if (bMWDdebugEnable) WriteLog("Amp settings: " + to_string(fMWDamp[0]) + (" ") + to_string(fMWDamp[1])); } + else if (token == "mwdlowvoltmeter") { + Parser.getTokens(2, false); + Parser >> fMWDlowVolt[0] >> fMWDlowVolt[1]; + if (bMWDdebugEnable) WriteLog("Low VoltMeter settings: " + to_string(fMWDlowVolt[0]) + (" ") + to_string(fMWDlowVolt[1])); + } else if (token == "mwddivider") { Parser.getTokens(1, false); Parser >> iMWDdivider; @@ -931,9 +937,9 @@ void Global::ConfigParse(cParser &Parser) /* this won't execute anymore with the old parser removed // TBD: remove, or launch depending on passed flag? if (qp) - { // to poniżej wykonywane tylko raz, jedynie po wczytaniu eu07.ini - Console::ModeSet(iFeedbackMode, iFeedbackPort); // tryb pracy konsoli sterowniczej - iFpsRadiusMax = 0.000025 * fFpsRadiusMax * + { // to poniżej wykonywane tylko raz, jedynie po wczytaniu eu07.ini*/ + Console::ModeSet(iFeedbackMode, iFeedbackPort); // tryb pracy konsoli sterowniczej + /*iFpsRadiusMax = 0.000025 * fFpsRadiusMax * fFpsRadiusMax; // maksymalny promień renderowania 3000.0 -> 225 if (iFpsRadiusMax > 400) iFpsRadiusMax = 400; diff --git a/Globals.h b/Globals.h index c2b2b708..cb8aecfd 100644 --- a/Globals.h +++ b/Globals.h @@ -346,6 +346,7 @@ class Global static double fMWDph[2]; static double fMWDvolt[2]; static double fMWDamp[2]; + static double fMWDlowVolt[2]; static int iMWDdivider; }; //--------------------------------------------------------------------------- From 4ea06d7512dd04239060f5a7a9d43105227d2caa Mon Sep 17 00:00:00 2001 From: maciek001 Date: Wed, 22 Feb 2017 22:39:01 +0100 Subject: [PATCH 29/40] Logi po angielsku --- Train.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Train.cpp b/Train.cpp index 19ebccc9..e2bf6407 100644 --- a/Train.cpp +++ b/Train.cpp @@ -2853,7 +2853,7 @@ bool TTrain::Update( double const Deltatime ) Console::ValueSet(5, fHCurrent[2]); // drugi amperomierz 2 Console::ValueSet(6, fHCurrent[3]); // drugi amperomierz 3 Console::ValueSet(7, fTachoVelocity); - //Console::ValueSet(8, mvControlled->BatteryVoltage); // przyda się w przyszłości + //Console::ValueSet(8, mvControlled->BatteryVoltage); // jeszcze nie pora ;) } // hunter-080812: wyrzucanie szybkiego na elektrykach gdy nie ma napiecia @@ -3781,7 +3781,7 @@ bool TTrain::Update( double const Deltatime ) double b = Console::AnalogCalibrateGet(0); b = b * 8 - 2; b = Global::CutValueToRange(-2.0, b, mvOccupied->BrakeCtrlPosNo); // przycięcie zmiennej do granic - if (Global::bMWDdebugEnable && Global::iMWDDebugMode & 4) WriteLog("Pozycja kranu = " + to_string(b)); + if (Global::bMWDdebugEnable && Global::iMWDDebugMode & 4) WriteLog("FV4a break position = " + to_string(b)); ggBrakeCtrl.UpdateValue(b); // przesów bez zaokrąglenia mvOccupied->BrakeLevelSet(b); } @@ -3790,7 +3790,7 @@ bool TTrain::Update( double const Deltatime ) double b = Console::AnalogCalibrateGet(0); b = b * 7 - 1; b = Global::CutValueToRange(-1.0, b, mvOccupied->BrakeCtrlPosNo); // przycięcie zmiennej do granic - if (Global::bMWDdebugEnable && Global::iMWDDebugMode & 4) WriteLog("Pozycja kranu = " + to_string(b)); + if (Global::bMWDdebugEnable && Global::iMWDDebugMode & 4) WriteLog("FVel6 break position = " + to_string(b)); ggBrakeCtrl.UpdateValue(b); // przesów bez zaokrąglenia mvOccupied->BrakeLevelSet(b); } @@ -3817,6 +3817,7 @@ bool TTrain::Update( double const Deltatime ) b *= 10; b = Global::CutValueToRange(0.0, b, LocalBrakePosNo); // przycięcie zmiennej do granic ggLocalBrake.UpdateValue(b); // przesów bez zaokrąglenia + if (Global::bMWDdebugEnable && Global::iMWDDebugMode & 4) WriteLog("FD1 break position = " + to_string(b)); mvOccupied->LocalBrakePos = int(1.09 * b); // sposób zaokrąglania jest do ustalenia } From 36ca4bc32f7e54e6c00a293f99ad523ff7f9dd1e Mon Sep 17 00:00:00 2001 From: maciek001 Date: Wed, 22 Feb 2017 22:45:15 +0100 Subject: [PATCH 30/40] =?UTF-8?q?zmiany=20ustawie=C5=84=20projektu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- maszyna.vcxproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/maszyna.vcxproj b/maszyna.vcxproj index 50c6e3cd..2178f72c 100644 --- a/maszyna.vcxproj +++ b/maszyna.vcxproj @@ -57,6 +57,7 @@ true false false + MultiThreadedDebug MachineX86 @@ -68,7 +69,7 @@ WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - MultiThreadedDLL + MultiThreaded Level3 ProgramDatabase $(SolutionDir);$(SolutionDir)console;$(SolutionDir)mczapkie;$(SolutionDir)opengl;$(SolutionDir)python/include;%(AdditionalIncludeDirectories) From 3e68e4921bef996ca431cdb76a42961b74bc4221 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Thu, 23 Feb 2017 03:55:54 +0100 Subject: [PATCH 31/40] skydome object --- Float3d.h | 11 +- Model3d.cpp | 3 +- World.cpp | 97 ++++++++---- World.h | 2 + color.h | 118 ++++++++++++++ maszyna.vcxproj | 3 + maszyna.vcxproj.filters | 9 ++ sky.cpp | 14 -- skydome.cpp | 332 ++++++++++++++++++++++++++++++++++++++++ skydome.h | 60 ++++++++ sun.cpp | 4 +- sun.h | 2 +- 12 files changed, 601 insertions(+), 54 deletions(-) create mode 100644 color.h create mode 100644 skydome.cpp create mode 100644 skydome.h diff --git a/Float3d.h b/Float3d.h index c3ee39a7..fcb5afc3 100644 --- a/Float3d.h +++ b/Float3d.h @@ -53,7 +53,10 @@ double inline float3::Length() const { return sqrt(x * x + y * y + z * z); }; -inline float3 operator/(const float3 &v, double k) +inline float3 operator*( float3 const &v, float const k ) { + return float3( v.x * k, v.y * k, v.z * k ); +}; +inline float3 operator/( float3 const &v, float const k ) { return float3(v.x / k, v.y / k, v.z / k); }; @@ -67,10 +70,14 @@ inline float3 SafeNormalize(const float3 &v) retVal = v / l; return retVal; }; -inline float3 CrossProduct(const float3 &v1, const float3 &v2) +inline float3 CrossProduct( float3 const &v1, float3 const &v2 ) { return float3(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 float DotProduct( float3 const &v1, float3 const &v2 ) { + + return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; +} class float4 { // kwaternion obrotu diff --git a/Model3d.cpp b/Model3d.cpp index ce590cff..eb55533d 100644 --- a/Model3d.cpp +++ b/Model3d.cpp @@ -1808,7 +1808,8 @@ bool TModel3d::LoadFromFile(std::string const &FileName, bool dynamic) // wczytanie modelu z pliku std::string name = ToLower(FileName); // trim extension if needed - if (name.substr(name.rfind('.')) == ".t3d") + if( ( name.rfind( '.' ) != std::string::npos ) + && ( name.substr( name.rfind( '.' ) ) == ".t3d" ) ) { name.erase(name.rfind('.')); } diff --git a/World.cpp b/World.cpp index 5160d07c..025857b8 100644 --- a/World.cpp +++ b/World.cpp @@ -31,6 +31,7 @@ http://mozilla.org/MPL/2.0/. #include "Train.h" #include "Driver.h" #include "Console.h" +#include "color.h" #define TEXTURE_FILTER_CONTROL_EXT 0x8500 #define TEXTURE_LOD_BIAS_EXT 0x8501 @@ -1434,11 +1435,12 @@ TWorld::Update_Camera( double const Deltatime ) { void TWorld::Update_Lights() { +#ifdef EU07_USE_OLD_LIGHTING_MODEL + if( Global::fMoveLight < 0.0 ) { return; } -#ifdef EU07_USE_OLD_LIGHTING_MODEL // double a=Global::fTimeAngleDeg/180.0*M_PI-M_PI; //kąt godzinny w radianach double a = fmod( Global::fTimeAngleDeg, 360.0 ) / 180.0 * M_PI - M_PI; // kąt godzinny w radianach @@ -1516,32 +1518,7 @@ void TWorld::Update_Lights() { +0.150 * ( Global::diffuseDayLight[ 0 ] + Global::ambientDayLight[ 0 ] ) // R + 0.295 * ( Global::diffuseDayLight[ 1 ] + Global::ambientDayLight[ 1 ] ) // G + 0.055 * ( Global::diffuseDayLight[ 2 ] + Global::ambientDayLight[ 2 ] ); // B -#else - Sun.update(); - auto const position = Sun.getPosition(); - Global::DayLight.position[0] = position.x; - Global::DayLight.position[1] = position.y; - Global::DayLight.position[2] = position.z; - auto const direction = -1.0 * Sun.getDirection(); - Global::DayLight.direction = direction; - auto const intensity = std::min( 2.0f * Sun.getIntensity(), 1.25f ); - Global::DayLight.diffuse[ 0 ] = 255.0 / 255.0 * intensity; - Global::DayLight.diffuse[ 1 ] = 242.0 / 255.0 * intensity; - Global::DayLight.diffuse[ 2 ] = 231.0 / 255.0 * intensity; -// Global::DayLight.diffuse[ 3 ] = 1.0f;// std::min( 0.15f + intensity, 1.0f ); - Global::DayLight.ambient[ 0 ] = 155.0 / 255.0 * intensity * 0.75f; - Global::DayLight.ambient[ 1 ] = 192.0 / 255.0 * intensity * 0.75f; - Global::DayLight.ambient[ 2 ] = 231.0 / 255.0 * intensity * 0.75f; -// Global::DayLight.ambient[ 3 ] = 1.0f; - /* - // Global::DayLight.ambient[ 3 ] = intensity; - GLfloat ambient[] = { 0.1f + 0.5f * intensity, 0.1f + 0.5f * intensity, 0.1f + 0.5f * intensity, 0.5f }; - ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient ); -*/ - Global::fLuminance = intensity; -#endif - vector3 sky = vector3( Global::AtmoColor[ 0 ], Global::AtmoColor[ 1 ], Global::AtmoColor[ 2 ] ); if( Global::fLuminance < 0.25 ) { // przyspieszenie zachodu/wschodu sky *= 4.0 * Global::fLuminance; // nocny kolor nieba @@ -1554,7 +1531,45 @@ void TWorld::Update_Lights() { else { glFogfv( GL_FOG_COLOR, Global::FogColor ); // kolor mgły } - glClearColor( sky.x, sky.y, sky.z, 0.0 ); // kolor nieba +#else + Sun.update(); + auto const position = Sun.getPosition(); + // update skydome with current sun position + SkyDome.Update( position ); + auto const skydomecolour = SkyDome.GetAverageColor(); + auto const skydomehsv = RGBtoHSV( skydomecolour ); + // update sunlight object + Global::DayLight.position[0] = position.x; + Global::DayLight.position[1] = position.y; + Global::DayLight.position[2] = position.z; + + Global::DayLight.direction = -1.0 * Sun.getDirection(); + + auto const intensity = std::min( 0.05f + Sun.getIntensity() + skydomehsv.z, 1.25f ); + + Global::DayLight.diffuse[ 0 ] = intensity * 255.0f / 255.0f; + Global::DayLight.diffuse[ 1 ] = intensity * 242.0f / 255.0f; + Global::DayLight.diffuse[ 2 ] = intensity * 231.0f / 255.0f; +// Global::DayLight.diffuse[ 3 ] = 1.0f;// std::min( 0.15f + intensity, 1.0f ); + Global::DayLight.ambient[ 0 ] = skydomecolour.x; + Global::DayLight.ambient[ 1 ] = skydomecolour.y; + Global::DayLight.ambient[ 2 ] = skydomecolour.z; +/* + Global::DayLight.ambient[ 0 ] = 155.0 / 255.0 * intensity * 0.75f; + Global::DayLight.ambient[ 1 ] = 192.0 / 255.0 * intensity * 0.75f; + Global::DayLight.ambient[ 2 ] = 231.0 / 255.0 * intensity * 0.75f; +*/ +// Global::DayLight.ambient[ 3 ] = 1.0f; + + Global::fLuminance = intensity; + + Global::FogColor[ 0 ] = skydomecolour.x; + Global::FogColor[ 1 ] = skydomecolour.y; + Global::FogColor[ 2 ] = skydomecolour.z; + glFogfv( GL_FOG_COLOR, Global::FogColor ); // kolor mgły +#endif + + glClearColor( skydomecolour.x, skydomecolour.y, skydomecolour.z, 1.0f ); // kolor nieba } bool TWorld::Render() @@ -1574,18 +1589,32 @@ bool TWorld::Render() Camera.SetMatrix(); // ustawienie macierzy kamery względem początku scenerii if( !Global::bWireFrame ) { // bez nieba w trybie rysowania linii + + glDisable( GL_LIGHTING ); glDisable( GL_FOG ); - Clouds.Render(); - glEnable( GL_FOG ); - } + glDisable( GL_DEPTH_TEST ); + glDepthMask( GL_FALSE ); + glPushMatrix(); + glTranslatef( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z ); + + SkyDome.Render(); +// Clouds.Render(); #ifdef EU07_USE_OLD_LIGHTING_MODEL - glLightfv(GL_LIGHT0, GL_POSITION, Global::lightPos); + glLightfv( GL_LIGHT0, GL_POSITION, Global::lightPos ); #else - Sun.render( Camera.Pos ); - Global::DayLight.apply_angle(); - Global::DayLight.apply_intensity(); + Sun.render(); + Global::DayLight.apply_angle(); + Global::DayLight.apply_intensity(); #endif + + glPopMatrix(); + glDepthMask( GL_TRUE ); + glEnable( GL_DEPTH_TEST ); + glEnable( GL_FOG ); + glEnable( GL_LIGHTING ); + } + if (Global::bUseVBO) { // renderowanie przez VBO if (!Ground.RenderVBO(Camera.Pos)) diff --git a/World.h b/World.h index 61742e6b..7a409460 100644 --- a/World.h +++ b/World.h @@ -14,6 +14,7 @@ http://mozilla.org/MPL/2.0/. #include "Ground.h" #include "sky.h" #include "sun.h" +#include "skydome.h" #include "mczapkie/mover.h" class TWorld @@ -54,6 +55,7 @@ class TWorld GLuint base; // numer DL dla znaków w napisach texture_manager::size_type light; // numer tekstury dla smugi TSky Clouds; + CSkyDome SkyDome; cSun Sun; TEvent *KeyEvents[10]; // eventy wyzwalane z klawiaury TMoverParameters *mvControlled; // wskaźnik na człon silnikowy, do wyświetlania jego parametrów diff --git a/color.h b/color.h new file mode 100644 index 00000000..e3e879e8 --- /dev/null +++ b/color.h @@ -0,0 +1,118 @@ +#pragma once + +#include "float3d.h" + +inline +float3 +XYZtoRGB( float3 const &XYZ ) { + + // M^-1 for Adobe RGB from http://www.brucelindbloom.com/Eqn_RGB_XYZ_Matrix.html +// float const mi[ 3 ][ 3 ] = { 2.041369, -0.969266, 0.0134474, -0.5649464, 1.8760108, -0.1183897, -0.3446944, 0.041556, 1.0154096 }; + // m^-1 for sRGB: + float const mi[ 3 ][ 3 ] = { 3.240479, -0.969256, 0.055648, -1.53715, 1.875991, -0.204043, -0.49853, 0.041556, 1.057311 }; + + return float3{ + XYZ.x*mi[ 0 ][ 0 ] + XYZ.y*mi[ 1 ][ 0 ] + XYZ.z*mi[ 2 ][ 0 ], + XYZ.x*mi[ 0 ][ 1 ] + XYZ.y*mi[ 1 ][ 1 ] + XYZ.z*mi[ 2 ][ 1 ], + XYZ.x*mi[ 0 ][ 2 ] + XYZ.y*mi[ 1 ][ 2 ] + XYZ.z*mi[ 2 ][ 2 ] }; +} + +inline +float3 +RGBtoHSV( float3 const &RGB ) { + + float3 hsv; + + float const max = std::max( std::max( RGB.x, RGB.y ), RGB.z ); + float const min = std::min( std::min( RGB.x, RGB.y ), RGB.z ); + float const delta = max - min; + + hsv.z = max; // v + if( delta < 0.00001 ) { + hsv.y = 0; + hsv.x = 0; // undefined, maybe nan? + return hsv; + } + if( max > 0.0 ) { // NOTE: if Max is == 0, this divide would cause a crash + hsv.y = ( delta / max ); // s + } + else { + // if max is 0, then r = g = b = 0 + // s = 0, v is undefined + hsv.y = 0.0; + hsv.x = NAN; // its now undefined + return hsv; + } + if( RGB.x >= max ) // > is bogus, just keeps compilor happy + hsv.x = ( RGB.y - RGB.z ) / delta; // between yellow & magenta + else + if( RGB.y >= max ) + hsv.x = 2.0 + ( RGB.y - RGB.x ) / delta; // between cyan & yellow + else + hsv.x = 4.0 + ( RGB.x - RGB.y ) / delta; // between magenta & cyan + + hsv.x *= 60.0; // degrees + + if( hsv.x < 0.0 ) + hsv.x += 360.0; + + return hsv; +} + +inline +float3 +HSVtoRGB( float3 const &HSV ) { + + float3 rgb; + + if( HSV.y <= 0.0 ) { // < is bogus, just shuts up warnings + rgb.x = HSV.z; + rgb.y = HSV.z; + rgb.z = HSV.z; + return rgb; + } + float hh = HSV.x; + if( hh >= 360.0 ) hh = 0.0; + hh /= 60.0; + int const i = (int)hh; + float const ff = hh - i; + float const p = HSV.z * ( 1.0 - HSV.y ); + float const q = HSV.z * ( 1.0 - ( HSV.y * ff ) ); + float const t = HSV.z * ( 1.0 - ( HSV.y * ( 1.0 - ff ) ) ); + + switch( i ) { + case 0: + rgb.x = HSV.z; + rgb.y = t; + rgb.z = p; + break; + case 1: + rgb.x = q; + rgb.y = HSV.z; + rgb.z = p; + break; + case 2: + rgb.x = p; + rgb.y = HSV.z; + rgb.z = t; + break; + + case 3: + rgb.x = p; + rgb.y = q; + rgb.z = HSV.z; + break; + case 4: + rgb.x = t; + rgb.y = p; + rgb.z = HSV.z; + break; + case 5: + default: + rgb.x = HSV.z; + rgb.y = p; + rgb.z = q; + break; + } + return rgb; +} diff --git a/maszyna.vcxproj b/maszyna.vcxproj index 3ea50446..be008947 100644 --- a/maszyna.vcxproj +++ b/maszyna.vcxproj @@ -123,6 +123,7 @@ + @@ -149,6 +150,7 @@ + @@ -186,6 +188,7 @@ + diff --git a/maszyna.vcxproj.filters b/maszyna.vcxproj.filters index c0530acf..4b343051 100644 --- a/maszyna.vcxproj.filters +++ b/maszyna.vcxproj.filters @@ -195,6 +195,9 @@ Source Files + + Source Files + @@ -377,6 +380,12 @@ Header Files + + Header Files + + + Header Files + diff --git a/sky.cpp b/sky.cpp index 0febec09..710adbdb 100644 --- a/sky.cpp +++ b/sky.cpp @@ -32,21 +32,11 @@ void TSky::Init() void TSky::Render() { -#ifndef EU07_USE_OLD_LIGHTING_MODEL - return; -#endif if (mdCloud) { // jeśli jest model nieba - glDisable(GL_DEPTH_TEST); - glDepthMask( GL_FALSE ); - glPushMatrix(); - glTranslatef(Global::pCameraPosition.x, Global::pCameraPosition.y, - Global::pCameraPosition.z); #ifdef EU07_USE_OLD_LIGHTING_MODEL // TODO: re-implement this glLightfv(GL_LIGHT0, GL_POSITION, lightPos); -#else - glDisable( GL_LIGHTING ); #endif if (Global::bUseVBO) { // renderowanie z VBO @@ -62,11 +52,7 @@ void TSky::Render() #ifdef EU07_USE_OLD_LIGHTING_MODEL // TODO: re-implement this glLightfv(GL_LIGHT0, GL_POSITION, Global::lightPos); -#else - glEnable( GL_LIGHTING ); #endif - glDepthMask( GL_TRUE ); - glEnable( GL_DEPTH_TEST ); } }; diff --git a/skydome.cpp b/skydome.cpp new file mode 100644 index 00000000..c84113c5 --- /dev/null +++ b/skydome.cpp @@ -0,0 +1,332 @@ +//******************************************************************************// +// NightShine Engine // +// Sky : Gradient SkyDome Class // +//******************************************************************************// +// sky gradient based on "A practical analytic model for daylight" +// by A. J. Preetham Peter Shirley Brian Smits (University of Utah) + +#include "stdafx.h" +#include "opengl/glew.h" +#include "skydome.h" +#include "color.h" + +//******************************************************************************// + +float CSkyDome::m_distributionluminance[ 5 ][ 2 ] = { // Perez distributions + { 0.17872f , -1.46303f }, // a = darkening or brightening of the horizon + { -0.35540f , 0.42749f }, // b = luminance gradient near the horizon, + { -0.02266f , 5.32505f }, // c = relative intensity of the circumsolar region + { 0.12064f , -2.57705f }, // d = width of the circumsolar region + { -0.06696f , 0.37027f } // e = relative backscattered light + }; +float CSkyDome::m_distributionxcomp[ 5 ][ 2 ] = { + { -0.01925f , -0.25922f }, + { -0.06651f , 0.00081f }, + { -0.00041f , 0.21247f }, + { -0.06409f , -0.89887f }, + { -0.00325f , 0.04517f } + }; +float CSkyDome::m_distributionycomp[ 5 ][ 2 ] = { + { -0.01669f , -0.26078f }, + { -0.09495f , 0.00921f }, + { -0.00792f , 0.21023f }, + { -0.04405f , -1.65369f }, + { -0.01092f , 0.05291f } + }; + +float CSkyDome::m_zenithxmatrix[ 3 ][ 4 ] = { + { 0.00165f, -0.00375f, 0.00209f, 0.00000f }, + { -0.02903f, 0.06377f, -0.03202f, 0.00394f }, + { 0.11693f, -0.21196f, 0.06052f, 0.25886f } + }; +float CSkyDome::m_zenithymatrix[ 3 ][ 4 ] = { + { 0.00275f, -0.00610f, 0.00317f, 0.00000f }, + { -0.04214f, 0.08970f, -0.04153f, 0.00516f }, + { 0.15346f, -0.26756f, 0.06670f, 0.26688f } + }; + +//******************************************************************************// + +float clamp( float const Value, float const Min, float const Max ) { + + float value = Value; + if( value < Min ) { value = Min; } + if( value > Max ) { value = Max; } + return value; +} + +float interpolate( float const First, float const Second, float const Factor ) { + + return ( First * ( 1.0f - Factor ) ) + ( Second * Factor ); +} + +//******************************************************************************// + +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 ); + SetGammaCorrection( 2.2f ); + Generate(); +} + +CSkyDome::~CSkyDome() { +} + +//******************************************************************************// + +void CSkyDome::Generate() { + // radius of dome + float const radius = 1.0f; // 100.0f; + + // create geometry chunk + int const latitudes = m_tesselation / 2; + int const longitudes = m_tesselation; + + for( int i = 0; i < latitudes; ++i ) { + + float lat0 = M_PI * ( -0.5f + (float)( i ) / latitudes ); + float z0 = std::sin( lat0 ); + float zr0 = std::cos( lat0 ); + + float lat1 = M_PI * ( -0.5f + (float)( i + 1 ) / latitudes ); + float z1 = std::sin( lat1 ); + float zr1 = std::cos( lat1 ); + + // quad strip + for( int j = 0; j <= longitudes / 2; ++j ) { + + float longitude = 2.0 * M_PI * (float)( j ) / longitudes; + float x = std::cos( longitude ); + float y = std::sin( longitude ); + + m_vertices.emplace_back( float3( x * zr0, y * zr0 - 0.1f, 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_normals.emplace_back( float3( -x * zr1, -y * zr1, -z1 ) ); + m_colours.emplace_back( float3( 0.75f, 0.75f, 0.75f ) ); + } + } +} + +//******************************************************************************// + +void CSkyDome::Update( Math3D::vector3 const &Sun ) { + + if( true == SetSunPosition( Sun ) ) { + // build colors if there's a change in sun position + RebuildColors(); + } +} + +// render skydome to screen +void CSkyDome::Render() { + + int const latitudes = m_tesselation / 2; + int const longitudes = m_tesselation; + int idx = 0; + + for( int i = 0; i < latitudes; ++i ) { + + ::glBegin( GL_QUAD_STRIP ); + for( int j = 0; j <= longitudes / 2; ++j ) { + + ::glColor3f( m_colours[ idx ].x, m_colours[ idx ].y, m_colours[ idx ].z ); +// ::glNormal3f( m_normals[ idx ].x, m_normals[ idx ].y, m_normals[ idx ].z ); + ::glVertex3f( m_vertices[ idx ].x, m_vertices[ idx ].y, m_vertices[ idx ].z ); + ++idx; + ::glColor3f( m_colours[ idx ].x, m_colours[ idx ].y, m_colours[ idx ].z ); +// ::glNormal3f( m_normals[ idx ].x, m_normals[ idx ].y, m_normals[ idx ].z ); + ::glVertex3f( m_vertices[ idx ].x, m_vertices[ idx ].y, m_vertices[ idx ].z ); + ++idx; + } + glEnd(); + } +} + +//******************************************************************************// + +bool CSkyDome::SetSunPosition( Math3D::vector3 const &Direction ) { + + auto sundirection = SafeNormalize( float3( Direction.x, Direction.y, Direction.z) ); + if( sundirection == m_sundirection ) { + + return false; + } + + m_sundirection = sundirection; + m_thetasun = std::acosf( m_sundirection.y ); + m_phisun = std::atan2( m_sundirection.z , m_sundirection.x ); + + return true; +} + + +void CSkyDome::SetTurbidity( float const Turbidity ) { + + m_turbidity = clamp( Turbidity, 1.0f, 512.0f ); +} + +void CSkyDome::SetExposure( bool const Linearexposure, float const Expfactor ) { + + m_linearexpcontrol = Linearexposure; + m_expfactor = 1.0f / clamp( Expfactor, 1.0f, std::numeric_limits::infinity() ); +} + +void CSkyDome::SetGammaCorrection( float const Gamma ) { + + m_gammacorrection = 1.0f / clamp( Gamma, std::numeric_limits::epsilon(), std::numeric_limits::infinity() ); +} + +void CSkyDome::SetOvercastFactor( float const Overcast ) { + + m_overcast = clamp( Overcast, 0.0f, 1.0f ); +} + +//******************************************************************************// + +void CSkyDome::GetPerez( float *Perez, float Distribution[ 5 ][ 2 ], const float Turbidity ) { + + Perez[ 0 ] = Distribution[ 0 ][ 0 ] * Turbidity + Distribution[ 0 ][ 1 ]; + Perez[ 1 ] = Distribution[ 1 ][ 0 ] * Turbidity + Distribution[ 1 ][ 1 ]; + Perez[ 2 ] = Distribution[ 2 ][ 0 ] * Turbidity + Distribution[ 2 ][ 1 ]; + Perez[ 3 ] = Distribution[ 3 ][ 0 ] * Turbidity + Distribution[ 3 ][ 1 ]; + Perez[ 4 ] = Distribution[ 4 ][ 0 ] * Turbidity + Distribution[ 4 ][ 1 ]; +} + +float CSkyDome::GetZenith( float Zenithmatrix[ 3 ][ 4 ], const float Theta, const float Turbidity ) { + + const float theta2 = Theta*Theta; + const float theta3 = Theta*theta2; + + return ( Zenithmatrix[0][0] * theta3 + Zenithmatrix[0][1] * theta2 + Zenithmatrix[0][2] * Theta + Zenithmatrix[0][3]) * Turbidity * Turbidity + + ( Zenithmatrix[1][0] * theta3 + Zenithmatrix[1][1] * theta2 + Zenithmatrix[1][2] * Theta + Zenithmatrix[1][3]) * Turbidity + + ( Zenithmatrix[2][0] * theta3 + Zenithmatrix[2][1] * theta2 + Zenithmatrix[2][2] * Theta + Zenithmatrix[2][3]); + +} + +//******************************************************************************// + +float CSkyDome::PerezFunctionO1( float Perezcoeffs[ 5 ], const float Thetasun, const float Zenithval ) { + + const float val = ( 1.0f + Perezcoeffs[ 0 ] * std::exp( Perezcoeffs[ 1 ] ) ) * + ( 1.0f + Perezcoeffs[ 2 ] * std::exp( Perezcoeffs[ 3 ] * Thetasun ) + Perezcoeffs[ 4 ] * std::pow( std::cos( Thetasun ), 2 ) ); + + return Zenithval / val; +} + +float CSkyDome::PerezFunctionO2( float Perezcoeffs[ 5 ], const float Icostheta, const float Gamma, const float Cosgamma2, const float Zenithval ) { + // iCosTheta = 1.0f / cosf(theta) + // cosGamma2 = SQR( cosf( gamma ) ) + return Zenithval * ( 1.0f + Perezcoeffs[ 0 ] * std::exp( Perezcoeffs[ 1 ] * Icostheta ) ) * + ( 1.0f + Perezcoeffs[ 2 ] * std::exp( Perezcoeffs[ 3 ] * Gamma ) + Perezcoeffs[ 4 ] * Cosgamma2 ); +} + +//******************************************************************************// +void CSkyDome::RebuildColors() { + + // get zenith luminance + float const chi = ( (4.0f / 9.0f) - (m_turbidity / 120.0f) ) * ( M_PI - (2.0f * m_thetasun) ); + float zenithluminance = ( (4.0453f * m_turbidity) - 4.9710f ) * std::tan( chi ) - (0.2155f * m_turbidity) + 2.4192f; + + // get x / y zenith + float zenithx = GetZenith( m_zenithxmatrix, m_thetasun, m_turbidity ); + float zenithy = GetZenith( m_zenithymatrix, m_thetasun, m_turbidity ); + + // get perez function parametrs + float perezluminance[5], perezx[5], perezy[5]; + GetPerez( perezluminance, m_distributionluminance, m_turbidity ); + GetPerez( perezx, m_distributionxcomp, m_turbidity ); + GetPerez( perezy, m_distributionycomp, m_turbidity ); + + // make some precalculation + zenithx = PerezFunctionO1( perezx, m_thetasun, zenithx ); + zenithy = PerezFunctionO1( perezy, m_thetasun, zenithy ); + zenithluminance = PerezFunctionO1( perezluminance, m_thetasun, zenithluminance ); + + // start with fresh average for the new pass + float3 averagecolor{ 0.0f, 0.0f, 0.0f }; + + // trough all vertices + float3 vertex; + float3 color, colorconverter; + + for ( unsigned int i = 0; i < m_vertices.size(); ++i ) { + // grab it + vertex = SafeNormalize( m_vertices[ i ] ); + + // angle between sun and vertex + const float gamma = std::acos( DotProduct( vertex, m_sundirection ) ); + + // warning : major hack!!! .. i had to do something with values under horizon + //vertex.y = Clamp( vertex.y, 0.05f, 1.0f ); + if ( vertex.y < 0.05f ) vertex.y = 0.05f; + +// from paper: +// const float theta = arccos( vertex.y ); +// const float iCosTheta = 1.0f / cosf( theta ); +// optimized: +// iCosTheta = +// = 1.0f / cosf( arccos( vertex.y ) ); +// = 1.0f / vertex.y; + float const icostheta = 1.0f / vertex.y; + float const cosgamma2 = std::pow( std::cos( gamma ), 2 ); + + // Compute x,y values + float const x = PerezFunctionO2( perezx, icostheta, gamma, cosgamma2, zenithx ); + float const y = PerezFunctionO2( perezy, icostheta, gamma, cosgamma2, zenithy ); + + // luminance(Y) for clear & overcast sky + float const yclear = PerezFunctionO2( perezluminance, icostheta, gamma, cosgamma2, zenithluminance ); + float const yover = ( 1.0f + 2.0f * vertex.y ) / 3.0f; + + float const Y = interpolate( yclear, yover, m_overcast ); + float const X = (x / y) * Y; + float const Z = ((1.0f - x - y) / y) * Y; + + colorconverter = float3( X, Y, Z ); + color = XYZtoRGB( colorconverter ); + + colorconverter = RGBtoHSV(color); + if ( m_linearexpcontrol ) { + // linear scale + colorconverter.z *= m_expfactor; + } else { + // exp scale + colorconverter.z = 1.0f - exp( -m_expfactor * colorconverter.z ); + } + color = HSVtoRGB(colorconverter); +/* + // 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 ); +*/ + // crude correction for the times where the model breaks (late night) + // TODO: use proper night sky calculation for these times instead + if( ( color.x <= 0.0f ) + && ( color.y <= 0.0f ) ) { + // darken the sky as the sun goes deeper below the horizon + // 15:50:75 is picture-based night sky colour. it may not be accurate but looks 'right enough' + color.z = 0.75f * std::max( color.z + m_sundirection.y, 0.075f ); + color.x = 0.20f * color.z; + color.y = 0.65f * color.z; + } + + // save + m_colours[ i ] = color; + averagecolor += color; + } + + m_averagecolour = averagecolor / m_vertices.size(); + m_averagecolour.x = std::max( m_averagecolour.x, 0.0f ); + m_averagecolour.y = std::max( m_averagecolour.y, 0.0f ); + m_averagecolour.z = std::max( m_averagecolour.z, 0.0f ); +} + +//******************************************************************************// diff --git a/skydome.h b/skydome.h new file mode 100644 index 00000000..df0125e4 --- /dev/null +++ b/skydome.h @@ -0,0 +1,60 @@ +#pragma once + +#include "dumb3d.h" +#include "float3d.h" + +// sky gradient based on "A practical analytic model for daylight" +// by A. J. Preetham Peter Shirley Brian Smits (University of Utah) + +class CSkyDome { +public: + CSkyDome( int const Tesselation = 54 ); + ~CSkyDome(); + void Generate(); + void RebuildColors(); + + bool SetSunPosition( Math3D::vector3 const &Direction ); + + void SetTurbidity( const float Turbidity = 5.0f ); + void SetExposure( const bool Linearexposure, const float Expfactor ); + void SetOvercastFactor( const float Overcast = 0.0f ); + void SetGammaCorrection( const float Gamma = 2.2f ); + + // update skydome + void Update( Math3D::vector3 const &Sun ); + // render skydome to screen + void Render(); + + // retrieves average colour of the sky dome + float3 GetAverageColor() { return m_averagecolour; } + +private: + // shading parametrs + float3 m_sundirection; + float m_thetasun, m_phisun; + float m_turbidity; + bool m_linearexpcontrol; + float m_expfactor; + float m_overcast; + float m_gammacorrection; + float3 m_averagecolour; + + // data + int const m_tesselation; + std::vector m_vertices; + std::vector m_normals; + std::vector m_colours; + + static float m_distributionluminance[ 5 ][ 2 ]; + static float m_distributionxcomp[ 5 ][ 2 ]; + static float m_distributionycomp[ 5 ][ 2 ]; + + static float m_zenithxmatrix[ 3 ][ 4 ]; + static float m_zenithymatrix[ 3 ][ 4 ]; + + // coloring + void GetPerez( float *Perez, float Distribution[ 5 ][ 2 ], const float Turbidity ); + float GetZenith( float Zenithmatrix[ 3 ][ 4 ], const float Theta, const float Turbidity ); + float PerezFunctionO1( float Perezcoeffs[ 5 ], const float Thetasun, const float Zenithval ); + float PerezFunctionO2( float Perezcoeffs[ 5 ], const float Icostheta, const float Gamma, const float Cosgamma2, const float Zenithval ); +}; diff --git a/sun.cpp b/sun.cpp index e571a0a7..78fd9e4f 100644 --- a/sun.cpp +++ b/sun.cpp @@ -39,7 +39,7 @@ cSun::update() { } void -cSun::render( Math3D::vector3 const &Origin ) { +cSun::render() { /* glLightfv(GL_LIGHT0, GL_POSITION, position.getVector() ); // sun @@ -51,7 +51,7 @@ cSun::render( Math3D::vector3 const &Origin ) { glDisable(GL_FOG); glColor4f( 255.0f/255.0f, 242.0f/255.0f, 231.0f/255.0f, 1.f ); // debug line to locate the sun easier - Math3D::vector3 position = m_position + Origin; + Math3D::vector3 position = m_position; glBegin( GL_LINES ); glVertex3f( position.x, position.y, position.z ); glVertex3f( position.x, 0.0f, position.z ); diff --git a/sun.h b/sun.h index 74349599..c64543f1 100644 --- a/sun.h +++ b/sun.h @@ -18,7 +18,7 @@ public: // methods: void init(); void update(); - void render( Math3D::vector3 const &Origin ); + void render(); // returns location of the sun in the 3d scene Math3D::vector3 getPosition() { return m_position; } // returns vector pointing at the sun From e7bf06e99b1e7b37151cd4f71f9d8a28e9b8da77 Mon Sep 17 00:00:00 2001 From: maciek001 Date: Thu, 23 Feb 2017 17:42:29 +0100 Subject: [PATCH 32/40] =?UTF-8?q?poprawa=20b=C5=82=C4=99dnego=20wpisu=20pr?= =?UTF-8?q?zy=20zapalaniu=20stycznika=20liniowego?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Console.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Console.cpp b/Console.cpp index f6ced4d2..d29f6f02 100644 --- a/Console.cpp +++ b/Console.cpp @@ -329,7 +329,7 @@ void Console::BitsUpdate(int mask) else MWDComm->WriteDataBuff[5] &= ~(1 << 5); if (mask & 0x0010) if (iBits & 0x10) MWDComm->WriteDataBuff[5] |= 1 << 4; // nadmiarowy silników trakcyjnych else MWDComm->WriteDataBuff[5] &= ~(1 << 4); - if (mask & 0x0020) if (iBits & 0x20) MWDComm->WriteDataBuff[4] |= 1 << 0; // styczniki liniowe + if (mask & 0x0020) if (iBits & 0x20) MWDComm->WriteDataBuff[5] |= 1 << 0; // styczniki liniowe else MWDComm->WriteDataBuff[5] &= ~(1 << 0); if (mask & 0x0040) if (iBits & 0x40) MWDComm->WriteDataBuff[4] |= 1 << 2; // poślizg else MWDComm->WriteDataBuff[4] &= ~(1 << 2); From 1b0e151fbf2c3e1c9502e688c7746c4cb2844eb1 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Fri, 24 Feb 2017 01:22:06 +0100 Subject: [PATCH 33/40] stars object, interrior lighting level as accessible parameter for dynamic object --- DynObj.cpp | 23 +++++- DynObj.h | 17 ++-- Globals.cpp | 1 + Globals.h | 1 + Model3d.cpp | 15 ++-- Train.cpp | 34 ++++++++ World.cpp | 168 ++++++++++++++++++++++++---------------- World.h | 23 +++++- color.h | 4 +- maszyna.vcxproj | 2 + maszyna.vcxproj.filters | 6 ++ skydome.cpp | 1 + stars.cpp | 28 +++++++ stars.h | 33 ++++++++ 14 files changed, 266 insertions(+), 90 deletions(-) create mode 100644 stars.cpp create mode 100644 stars.h diff --git a/DynObj.cpp b/DynObj.cpp index 6e49fb7d..18784aeb 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -3807,9 +3807,26 @@ void TDynamicObject::Render() } else { // wersja Display Lists - if (mdLowPolyInt) - if (FreeFlyModeFlag ? true : !mdKabina || !bDisplayCab) - mdLowPolyInt->Render(ObjSqrDist, ReplacableSkinID, iAlpha); + if( mdLowPolyInt ) { + // low poly interior + if( FreeFlyModeFlag ? true : !mdKabina || !bDisplayCab ) { + // enable cab light if needed + if( InteriorLightLevel > 0.0f ) { + + // crude way to light the cabin, until we have something more complete in place + auto const cablight = InteriorLight * InteriorLightLevel; + ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x ); + } + + mdLowPolyInt->Render( ObjSqrDist, ReplacableSkinID, iAlpha ); + + if( InteriorLightLevel > 0.0f ) { + // reset the overall ambient + GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient ); + } + } + } mdModel->Render(ObjSqrDist, ReplacableSkinID, iAlpha); if (mdLoad) // renderowanie nieprzezroczystego ładunku mdLoad->Render(ObjSqrDist, ReplacableSkinID, iAlpha); diff --git a/DynObj.h b/DynObj.h index bda873a7..2c675cc0 100644 --- a/DynObj.h +++ b/DynObj.h @@ -140,11 +140,10 @@ class TAnim //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- -class TDynamicObject -{ // klasa pojazdu - private: // położenie pojazdu w świecie oraz parametry ruchu +class TDynamicObject { // klasa pojazdu +private: // położenie pojazdu w świecie oraz parametry ruchu vector3 vPosition; // Ra: pozycja pojazdu liczona zaraz po przesunięciu - vector3 vCoulpler[2]; // współrzędne sprzęgów do liczenia zderzeń czołowych + vector3 vCoulpler[ 2 ]; // współrzędne sprzęgów do liczenia zderzeń czołowych vector3 vUp, vFront, vLeft; // wektory jednostkowe ustawienia pojazdu int iDirection; // kierunek pojazdu względem czoła składu (1=zgodny,0=przeciwny) TTrackShape ts; // parametry toru przekazywane do fizyki @@ -156,10 +155,10 @@ class TDynamicObject float fAxleDist; // rozstaw wózków albo osi do liczenia proporcji zacienienia vector3 modelRot; // obrot pudła względem świata - do przeanalizowania, czy potrzebne!!! // bool bCameraNear; //blisko kamer są potrzebne dodatkowe obliczenia szczegółów - TDynamicObject * ABuFindNearestObject(TTrack *Track, TDynamicObject *MyPointer, - int &CouplNr); + TDynamicObject * ABuFindNearestObject( TTrack *Track, TDynamicObject *MyPointer, + int &CouplNr ); - public: // parametry położenia pojazdu dostępne publicznie +public: // parametry położenia pojazdu dostępne publicznie std::string asTrack; // nazwa toru początkowego; wywalić? std::string asDestination; // dokąd pojazd ma być kierowany "(stacja):(tor)" matrix4x4 mMatrix; // macierz przekształcenia do renderowania modeli @@ -175,12 +174,14 @@ class TDynamicObject 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 *mdLoad; // model zmiennego ładunku TModel3d *mdPrzedsionek; // model przedsionków dla EZT - może użyć mdLoad zamiast? TModel3d *mdKabina; // model kabiny dla użytkownika; McZapkie-030303: to z train.h TModel3d *mdLowPolyInt; // ABu 010305: wnetrze lowpoly + float3 InteriorLight{ 0.9f * 255.0f / 255.0f, 0.9f * 216.0f / 255.0f, 0.9f * 176.0f / 255.0f }; // tungsten light. TODO: allow definition of light type? + float InteriorLightLevel{ 0.0f }; // current level of interior lighting 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 diff --git a/Globals.cpp b/Globals.cpp index 8285f434..3e68f5e7 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -47,6 +47,7 @@ double Global::fOpenGL = 0.0; // wersja OpenGL - do sprawdzania obecności rozsz bool Global::bOpenGL_1_5 = false; // czy są dostępne funkcje OpenGL 1.5 */ double Global::fLuminance = 1.0; // jasność światła do automatycznego zapalania +float Global::SunAngle = 0.0f; int Global::iReCompile = 0; // zwiększany, gdy trzeba odświeżyć siatki HWND Global::hWnd = NULL; // uchwyt okna int Global::ScreenWidth = 1; diff --git a/Globals.h b/Globals.h index a9ca3c85..c46932e1 100644 --- a/Globals.h +++ b/Globals.h @@ -258,6 +258,7 @@ class Global static bool bOpenGL_1_5; // czy są dostępne funkcje OpenGL 1.5 */ static double fLuminance; // jasność światła do automatycznego zapalania + static float SunAngle; // angle of the sun relative to horizon static int iMultiplayer; // blokada działania niektórych eventów na rzecz kominikacji static HWND hWnd; // uchwyt okna static int ScreenWidth; // current window dimensions. TODO: move it to renderer diff --git a/Model3d.cpp b/Model3d.cpp index eb55533d..3ac52358 100644 --- a/Model3d.cpp +++ b/Model3d.cpp @@ -742,7 +742,7 @@ void TSubModel::DisplayLists() glNewList(uiDisplayList, GL_COMPILE); GfxRenderer.Bind(0); // tekstury nie ma glColorMaterial(GL_FRONT, GL_EMISSION); - glDisable(GL_LIGHTING); // Tolaris-030603: bo mu punkty swiecace sie blendowaly +// glDisable(GL_LIGHTING); // Tolaris-030603: bo mu punkty swiecace sie blendowaly glBegin(GL_POINTS); for (int i = 0; i < iNumVerts; i++) { @@ -751,7 +751,7 @@ void TSubModel::DisplayLists() glVertex3fv(&Vertices[i].Point.x); }; glEnd(); - glEnable(GL_LIGHTING); +// glEnable(GL_LIGHTING); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glMaterialfv(GL_FRONT, GL_EMISSION, emm2); glEndList(); @@ -816,10 +816,13 @@ void TSubModel::InitialRotate(bool doit) Vertices[i].Point.y = Vertices[i].Point.z; Vertices[i].Point.z = t; // wektory normalne również trzeba przekształcić, bo się źle oświetlają - Vertices[i].Normal.x = -Vertices[i].Normal.x; // zmiana znaku X - t = Vertices[i].Normal.y; // zamiana Y i Z - Vertices[i].Normal.y = Vertices[i].Normal.z; - Vertices[i].Normal.z = t; + if( eType != TP_STARS ) { + // gwiazdki mają kolory zamiast normalnych, to // ich wtedy nie ruszamy + Vertices[ i ].Normal.x = -Vertices[ i ].Normal.x; // zmiana znaku X + t = Vertices[ i ].Normal.y; // zamiana Y i Z + Vertices[ i ].Normal.y = Vertices[ i ].Normal.z; + Vertices[ i ].Normal.z = t; + } } if (Child) Child->InitialRotate(doit); // potomne ewentualnie obrócimy diff --git a/Train.cpp b/Train.cpp index 66599599..ce35b35c 100644 --- a/Train.cpp +++ b/Train.cpp @@ -5001,6 +5001,40 @@ bool TTrain::Update( double const Deltatime ) btHaslerBrakes.Turn(DynamicObject->MoverParameters->BrakePress > 0.4); // ciśnienie w cylindrach btHaslerCurrent.Turn(DynamicObject->MoverParameters->Im != 0.0); // prąd na silnikach + // calculate current level of interior illumination + // TODO: organize it along with rest of train update in a more sensible arrangement + switch( iCabLightFlag ) // Ra: uzeleżnic od napięcia w obwodzie sterowania + { // hunter-091012: uzaleznienie jasnosci od przetwornicy + case 0: { + //światło wewnętrzne zgaszone + DynamicObject->InteriorLightLevel = 0.0f; + break; + } + case 1: { + //światło wewnętrzne przygaszone (255 216 176) + if( mvOccupied->ConverterFlag == true ) { + // jasnosc dla zalaczonej przetwornicy + DynamicObject->InteriorLightLevel = 0.75f; + } + else { + DynamicObject->InteriorLightLevel = 0.375f; + } + break; + } + case 2: { + //światło wewnętrzne zapalone (255 216 176) + if( mvOccupied->ConverterFlag == + true ) // jasnosc dla zalaczonej przetwornicy + { + DynamicObject->InteriorLightLevel = 1.0f; + } + else { + DynamicObject->InteriorLightLevel = 0.5f; + } + break; + } + } + m_updated = true; return true; //(DynamicObject->Update(dt)); } // koniec update diff --git a/World.cpp b/World.cpp index 025857b8..e216d765 100644 --- a/World.cpp +++ b/World.cpp @@ -590,8 +590,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) Ground.Init(Global::SceneryFile, hDC); // Global::tSinceStart= 0; - Sun.init(); - Clouds.Init(); + Environment.init(); WriteLog("Ground init OK"); if (Global::detonatoryOK) { @@ -1195,7 +1194,7 @@ bool TWorld::Update() Global::fClockAngleDeg[4] = 36.0 * (GlobalTime->hh % 10); // jednostki godzin Global::fClockAngleDeg[5] = 36.0 * (GlobalTime->hh / 10); // dziesiątki godzin - Update_Lights(); + Update_Environment(); } // koniec działań niewykonywanych podczas pauzy // poprzednie jakoś tam działało double dt = Timer::GetDeltaRenderTime(); // nie uwzględnia pauzowania ani mnożenia czasu @@ -1433,7 +1432,7 @@ TWorld::Update_Camera( double const Deltatime ) { } } -void TWorld::Update_Lights() { +void TWorld::Update_Environment() { #ifdef EU07_USE_OLD_LIGHTING_MODEL @@ -1532,44 +1531,8 @@ void TWorld::Update_Lights() { glFogfv( GL_FOG_COLOR, Global::FogColor ); // kolor mgły } #else - Sun.update(); - auto const position = Sun.getPosition(); - // update skydome with current sun position - SkyDome.Update( position ); - auto const skydomecolour = SkyDome.GetAverageColor(); - auto const skydomehsv = RGBtoHSV( skydomecolour ); - // update sunlight object - Global::DayLight.position[0] = position.x; - Global::DayLight.position[1] = position.y; - Global::DayLight.position[2] = position.z; - - Global::DayLight.direction = -1.0 * Sun.getDirection(); - - auto const intensity = std::min( 0.05f + Sun.getIntensity() + skydomehsv.z, 1.25f ); - - Global::DayLight.diffuse[ 0 ] = intensity * 255.0f / 255.0f; - Global::DayLight.diffuse[ 1 ] = intensity * 242.0f / 255.0f; - Global::DayLight.diffuse[ 2 ] = intensity * 231.0f / 255.0f; -// Global::DayLight.diffuse[ 3 ] = 1.0f;// std::min( 0.15f + intensity, 1.0f ); - Global::DayLight.ambient[ 0 ] = skydomecolour.x; - Global::DayLight.ambient[ 1 ] = skydomecolour.y; - Global::DayLight.ambient[ 2 ] = skydomecolour.z; -/* - Global::DayLight.ambient[ 0 ] = 155.0 / 255.0 * intensity * 0.75f; - Global::DayLight.ambient[ 1 ] = 192.0 / 255.0 * intensity * 0.75f; - Global::DayLight.ambient[ 2 ] = 231.0 / 255.0 * intensity * 0.75f; -*/ -// Global::DayLight.ambient[ 3 ] = 1.0f; - - Global::fLuminance = intensity; - - Global::FogColor[ 0 ] = skydomecolour.x; - Global::FogColor[ 1 ] = skydomecolour.y; - Global::FogColor[ 2 ] = skydomecolour.z; - glFogfv( GL_FOG_COLOR, Global::FogColor ); // kolor mgły + Environment.update(); #endif - - glClearColor( skydomecolour.x, skydomecolour.y, skydomecolour.z, 1.0f ); // kolor nieba } bool TWorld::Render() @@ -1588,31 +1551,9 @@ bool TWorld::Render() glLoadIdentity(); Camera.SetMatrix(); // ustawienie macierzy kamery względem początku scenerii - if( !Global::bWireFrame ) { // bez nieba w trybie rysowania linii - - glDisable( GL_LIGHTING ); - glDisable( GL_FOG ); - glDisable( GL_DEPTH_TEST ); - glDepthMask( GL_FALSE ); - glPushMatrix(); - glTranslatef( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z ); - - SkyDome.Render(); -// Clouds.Render(); - -#ifdef EU07_USE_OLD_LIGHTING_MODEL - glLightfv( GL_LIGHT0, GL_POSITION, Global::lightPos ); -#else - Sun.render(); - Global::DayLight.apply_angle(); - Global::DayLight.apply_intensity(); -#endif - - glPopMatrix(); - glDepthMask( GL_TRUE ); - glEnable( GL_DEPTH_TEST ); - glEnable( GL_FOG ); - glEnable( GL_LIGHTING ); + if( !Global::bWireFrame ) { + // bez nieba w trybie rysowania linii + Environment.render(); } if (Global::bUseVBO) @@ -1759,7 +1700,7 @@ TWorld::Render_Cab() { 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, 0.35f );// *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 ); @@ -1880,6 +1821,13 @@ TWorld::Render_Cab() { glLightfv( GL_LIGHT0, GL_AMBIENT, ambientCabLight ); glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseCabLight ); glLightfv( GL_LIGHT0, GL_SPECULAR, specularCabLight ); +#else + 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 ); + } #endif if( Global::bUseVBO ) { // renderowanie z użyciem VBO dynamic->mdKabina->RaRender( 0.0, dynamic->ReplacableSkinID, dynamic->iAlpha ); @@ -1895,6 +1843,12 @@ TWorld::Render_Cab() { glLightfv( GL_LIGHT0, GL_AMBIENT, Global::ambientDayLight ); glLightfv( GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight ); glLightfv( GL_LIGHT0, GL_SPECULAR, Global::specularDayLight ); +#else + 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 ); + } #endif } glPopMatrix(); @@ -2365,6 +2319,8 @@ TWorld::Render_UI() { " " + 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 ); + // current luminance level + OutText2 = "Light level: " + to_string( Global::fLuminance, 3 ); } // OutText3= AnsiString(" Online documentation (PL, ENG, DE, soon CZ): // http://www.eu07.pl"); @@ -3060,3 +3016,81 @@ void TWorld::CabChange(TDynamicObject *old, TDynamicObject *now) Global::changeDynObj = now; // uruchomienie protezy }; //--------------------------------------------------------------------------- + +void +world_environment::init() { + + m_sun.init(); + m_stars.init(); + m_clouds.Init(); +} + +void +world_environment::update() { + + // move sun... + m_sun.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.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 ); + // ...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, + // but whether it'd _look_ better is something to be tested + Global::DayLight.diffuse[ 0 ] = intensity * 255.0f / 255.0f; + Global::DayLight.diffuse[ 1 ] = intensity * 242.0f / 255.0f; + Global::DayLight.diffuse[ 2 ] = intensity * 231.0f / 255.0f; + + Global::DayLight.ambient[ 0 ] = skydomecolour.x; + Global::DayLight.ambient[ 1 ] = skydomecolour.y; + Global::DayLight.ambient[ 2 ] = skydomecolour.z; + + Global::fLuminance = intensity; + + // update the fog. setting it to match the average colour of the sky dome is cheap + // but quite effective way to make the distant items blend with background better + Global::FogColor[ 0 ] = skydomecolour.x; + Global::FogColor[ 1 ] = skydomecolour.y; + Global::FogColor[ 2 ] = skydomecolour.z; + ::glFogfv( GL_FOG_COLOR, Global::FogColor ); // kolor mgły + + ::glClearColor( skydomecolour.x, skydomecolour.y, skydomecolour.z, 1.0f ); // kolor nieba +} + +void +world_environment::render() { + + ::glDisable( GL_LIGHTING ); + ::glDisable( GL_FOG ); + ::glDisable( GL_DEPTH_TEST ); + ::glDepthMask( GL_FALSE ); + ::glPushMatrix(); + ::glTranslatef( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z ); + + m_skydome.Render(); + m_stars.render(); +// m_clouds.Render(); + + if( DebugModeFlag == true ) { + // mark sun position for easier debugging + m_sun.render(); + } + Global::DayLight.apply_angle(); + Global::DayLight.apply_intensity(); + + ::glPopMatrix(); + ::glDepthMask( GL_TRUE ); + ::glEnable( GL_DEPTH_TEST ); + ::glEnable( GL_FOG ); + ::glEnable( GL_LIGHTING ); +} diff --git a/World.h b/World.h index 7a409460..eb5f3dde 100644 --- a/World.h +++ b/World.h @@ -14,9 +14,25 @@ http://mozilla.org/MPL/2.0/. #include "Ground.h" #include "sky.h" #include "sun.h" +#include "stars.h" #include "skydome.h" #include "mczapkie/mover.h" +// wrapper for environment elements -- sky, sun, stars, clouds etc +class world_environment { + +public: + void init(); + void update(); + void render(); + +private: + CSkyDome m_skydome; + cStars m_stars; + cSun m_sun; + TSky m_clouds; +}; + class TWorld { void InOutKey(); @@ -42,21 +58,19 @@ class TWorld std::string OutText2; std::string OutText3; std::string OutText4; - void Update_Lights(); + void Update_Environment(); void Update_Camera( const double Deltatime ); bool Render(); void Render_Cab(); void Render_UI(); TCamera Camera; TGround Ground; + world_environment Environment; TTrain *Train; TDynamicObject *pDynamicNearest; bool Paused; GLuint base; // numer DL dla znaków w napisach texture_manager::size_type light; // numer tekstury dla smugi - TSky Clouds; - CSkyDome SkyDome; - cSun Sun; TEvent *KeyEvents[10]; // eventy wyzwalane z klawiaury TMoverParameters *mvControlled; // wskaźnik na człon silnikowy, do wyświetlania jego parametrów int iCheckFPS; // kiedy znów sprawdzić FPS, żeby wyłączać optymalizacji od razu do zera @@ -72,5 +86,6 @@ class TWorld void CreateE3D(std::string const &dir = "", bool dyn = false); void CabChange(TDynamicObject *old, TDynamicObject *now); }; + //--------------------------------------------------------------------------- diff --git a/color.h b/color.h index e3e879e8..68890616 100644 --- a/color.h +++ b/color.h @@ -7,9 +7,9 @@ float3 XYZtoRGB( float3 const &XYZ ) { // M^-1 for Adobe RGB from http://www.brucelindbloom.com/Eqn_RGB_XYZ_Matrix.html -// float const mi[ 3 ][ 3 ] = { 2.041369, -0.969266, 0.0134474, -0.5649464, 1.8760108, -0.1183897, -0.3446944, 0.041556, 1.0154096 }; + float const mi[ 3 ][ 3 ] = { 2.041369, -0.969266, 0.0134474, -0.5649464, 1.8760108, -0.1183897, -0.3446944, 0.041556, 1.0154096 }; // m^-1 for sRGB: - float const mi[ 3 ][ 3 ] = { 3.240479, -0.969256, 0.055648, -1.53715, 1.875991, -0.204043, -0.49853, 0.041556, 1.057311 }; +// float const mi[ 3 ][ 3 ] = { 3.240479, -0.969256, 0.055648, -1.53715, 1.875991, -0.204043, -0.49853, 0.041556, 1.057311 }; return float3{ XYZ.x*mi[ 0 ][ 0 ] + XYZ.y*mi[ 1 ][ 0 ] + XYZ.z*mi[ 2 ][ 0 ], diff --git a/maszyna.vcxproj b/maszyna.vcxproj index be008947..3cd10c56 100644 --- a/maszyna.vcxproj +++ b/maszyna.vcxproj @@ -126,6 +126,7 @@ + Create Create @@ -191,6 +192,7 @@ + diff --git a/maszyna.vcxproj.filters b/maszyna.vcxproj.filters index 4b343051..e38ea0db 100644 --- a/maszyna.vcxproj.filters +++ b/maszyna.vcxproj.filters @@ -198,6 +198,9 @@ Source Files + + Source Files + @@ -386,6 +389,9 @@ Header Files + + Header Files + diff --git a/skydome.cpp b/skydome.cpp index c84113c5..cf9e7064 100644 --- a/skydome.cpp +++ b/skydome.cpp @@ -316,6 +316,7 @@ void CSkyDome::RebuildColors() { color.z = 0.75f * std::max( color.z + m_sundirection.y, 0.075f ); color.x = 0.20f * color.z; color.y = 0.65f * color.z; + color = color * ( 1.15f - vertex.y ); // simple gradient, darkening towards the top } // save diff --git a/stars.cpp b/stars.cpp new file mode 100644 index 00000000..451d6aa0 --- /dev/null +++ b/stars.cpp @@ -0,0 +1,28 @@ + +#include "stdafx.h" +#include "stars.h" +#include "globals.h" + +////////////////////////////////////////////////////////////////////////////////////////// +// cStars -- simple starfield model, simulating appearance of starry sky + +void +cStars::init() { + + m_stars.LoadFromFile( "models\\skydome_stars.t3d", false ); +} + +void +cStars::render() { + + ::glPushMatrix(); + + ::glRotatef( m_latitude, 1.0f, 0.0f, 0.0f ); // ustawienie osi OY na północ + ::glRotatef( -std::fmod( Global::fTimeAngleDeg, 360.0f ), 0.0f, 1.0f, 0.0f ); // obrót dobowy osi OX + + ::glPointSize( 2.0f ); + m_stars.Render( 1.0 ); + ::glPointSize( 3.0f ); + + ::glPopMatrix(); +} \ No newline at end of file diff --git a/stars.h b/stars.h new file mode 100644 index 00000000..d5eb7989 --- /dev/null +++ b/stars.h @@ -0,0 +1,33 @@ +#pragma once + +#include "Model3d.h" + + +////////////////////////////////////////////////////////////////////////////////////////// +// cStars -- simple starfield model, simulating appearance of starry sky + +class cStars { + +public: +// types: + +// methods: + void init(); + void render(); + +// constructors: + +// deconstructor: + +// members: + +private: +// types: + +// methods: + +// members: + float m_longitude{ 19.0f }; // geograpic coordinates hardcoded roughly to Poland location, for the time being + float m_latitude{ 52.0f }; + TModel3d m_stars; +}; From fc49fc5fad081111423fb5424a19e407b0bdd0a0 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Fri, 24 Feb 2017 01:27:11 +0100 Subject: [PATCH 34/40] Revert "stars object, interrior lighting level as accessible parameter for dynamic object" This reverts commit 1b0e151fbf2c3e1c9502e688c7746c4cb2844eb1. --- DynObj.cpp | 23 +----- DynObj.h | 17 ++-- Globals.cpp | 1 - Globals.h | 1 - Model3d.cpp | 15 ++-- Train.cpp | 34 -------- World.cpp | 168 ++++++++++++++++------------------------ World.h | 23 +----- color.h | 4 +- maszyna.vcxproj | 2 - maszyna.vcxproj.filters | 6 -- skydome.cpp | 1 - stars.cpp | 28 ------- stars.h | 33 -------- 14 files changed, 90 insertions(+), 266 deletions(-) delete mode 100644 stars.cpp delete mode 100644 stars.h diff --git a/DynObj.cpp b/DynObj.cpp index 18784aeb..6e49fb7d 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -3807,26 +3807,9 @@ void TDynamicObject::Render() } else { // wersja Display Lists - if( mdLowPolyInt ) { - // low poly interior - if( FreeFlyModeFlag ? true : !mdKabina || !bDisplayCab ) { - // enable cab light if needed - if( InteriorLightLevel > 0.0f ) { - - // crude way to light the cabin, until we have something more complete in place - auto const cablight = InteriorLight * InteriorLightLevel; - ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x ); - } - - mdLowPolyInt->Render( ObjSqrDist, ReplacableSkinID, iAlpha ); - - if( InteriorLightLevel > 0.0f ) { - // reset the overall ambient - GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f }; - ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient ); - } - } - } + if (mdLowPolyInt) + if (FreeFlyModeFlag ? true : !mdKabina || !bDisplayCab) + mdLowPolyInt->Render(ObjSqrDist, ReplacableSkinID, iAlpha); mdModel->Render(ObjSqrDist, ReplacableSkinID, iAlpha); if (mdLoad) // renderowanie nieprzezroczystego ładunku mdLoad->Render(ObjSqrDist, ReplacableSkinID, iAlpha); diff --git a/DynObj.h b/DynObj.h index 2c675cc0..bda873a7 100644 --- a/DynObj.h +++ b/DynObj.h @@ -140,10 +140,11 @@ class TAnim //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- -class TDynamicObject { // klasa pojazdu -private: // położenie pojazdu w świecie oraz parametry ruchu +class TDynamicObject +{ // klasa pojazdu + private: // położenie pojazdu w świecie oraz parametry ruchu vector3 vPosition; // Ra: pozycja pojazdu liczona zaraz po przesunięciu - vector3 vCoulpler[ 2 ]; // współrzędne sprzęgów do liczenia zderzeń czołowych + vector3 vCoulpler[2]; // współrzędne sprzęgów do liczenia zderzeń czołowych vector3 vUp, vFront, vLeft; // wektory jednostkowe ustawienia pojazdu int iDirection; // kierunek pojazdu względem czoła składu (1=zgodny,0=przeciwny) TTrackShape ts; // parametry toru przekazywane do fizyki @@ -155,10 +156,10 @@ private: // położenie pojazdu w świecie oraz parametry ruchu float fAxleDist; // rozstaw wózków albo osi do liczenia proporcji zacienienia vector3 modelRot; // obrot pudła względem świata - do przeanalizowania, czy potrzebne!!! // bool bCameraNear; //blisko kamer są potrzebne dodatkowe obliczenia szczegółów - TDynamicObject * ABuFindNearestObject( TTrack *Track, TDynamicObject *MyPointer, - int &CouplNr ); + TDynamicObject * ABuFindNearestObject(TTrack *Track, TDynamicObject *MyPointer, + int &CouplNr); -public: // parametry położenia pojazdu dostępne publicznie + public: // parametry położenia pojazdu dostępne publicznie std::string asTrack; // nazwa toru początkowego; wywalić? std::string asDestination; // dokąd pojazd ma być kierowany "(stacja):(tor)" matrix4x4 mMatrix; // macierz przekształcenia do renderowania modeli @@ -174,14 +175,12 @@ public: // parametry położenia pojazdu dostępne publicznie 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 *mdLoad; // model zmiennego ładunku TModel3d *mdPrzedsionek; // model przedsionków dla EZT - może użyć mdLoad zamiast? TModel3d *mdKabina; // model kabiny dla użytkownika; McZapkie-030303: to z train.h TModel3d *mdLowPolyInt; // ABu 010305: wnetrze lowpoly - float3 InteriorLight{ 0.9f * 255.0f / 255.0f, 0.9f * 216.0f / 255.0f, 0.9f * 176.0f / 255.0f }; // tungsten light. TODO: allow definition of light type? - float InteriorLightLevel{ 0.0f }; // current level of interior lighting 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 diff --git a/Globals.cpp b/Globals.cpp index 3e68f5e7..8285f434 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -47,7 +47,6 @@ double Global::fOpenGL = 0.0; // wersja OpenGL - do sprawdzania obecności rozsz bool Global::bOpenGL_1_5 = false; // czy są dostępne funkcje OpenGL 1.5 */ double Global::fLuminance = 1.0; // jasność światła do automatycznego zapalania -float Global::SunAngle = 0.0f; int Global::iReCompile = 0; // zwiększany, gdy trzeba odświeżyć siatki HWND Global::hWnd = NULL; // uchwyt okna int Global::ScreenWidth = 1; diff --git a/Globals.h b/Globals.h index c46932e1..a9ca3c85 100644 --- a/Globals.h +++ b/Globals.h @@ -258,7 +258,6 @@ class Global static bool bOpenGL_1_5; // czy są dostępne funkcje OpenGL 1.5 */ static double fLuminance; // jasność światła do automatycznego zapalania - static float SunAngle; // angle of the sun relative to horizon static int iMultiplayer; // blokada działania niektórych eventów na rzecz kominikacji static HWND hWnd; // uchwyt okna static int ScreenWidth; // current window dimensions. TODO: move it to renderer diff --git a/Model3d.cpp b/Model3d.cpp index 3ac52358..eb55533d 100644 --- a/Model3d.cpp +++ b/Model3d.cpp @@ -742,7 +742,7 @@ void TSubModel::DisplayLists() glNewList(uiDisplayList, GL_COMPILE); GfxRenderer.Bind(0); // tekstury nie ma glColorMaterial(GL_FRONT, GL_EMISSION); -// glDisable(GL_LIGHTING); // Tolaris-030603: bo mu punkty swiecace sie blendowaly + glDisable(GL_LIGHTING); // Tolaris-030603: bo mu punkty swiecace sie blendowaly glBegin(GL_POINTS); for (int i = 0; i < iNumVerts; i++) { @@ -751,7 +751,7 @@ void TSubModel::DisplayLists() glVertex3fv(&Vertices[i].Point.x); }; glEnd(); -// glEnable(GL_LIGHTING); + glEnable(GL_LIGHTING); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glMaterialfv(GL_FRONT, GL_EMISSION, emm2); glEndList(); @@ -816,13 +816,10 @@ void TSubModel::InitialRotate(bool doit) Vertices[i].Point.y = Vertices[i].Point.z; Vertices[i].Point.z = t; // wektory normalne również trzeba przekształcić, bo się źle oświetlają - if( eType != TP_STARS ) { - // gwiazdki mają kolory zamiast normalnych, to // ich wtedy nie ruszamy - Vertices[ i ].Normal.x = -Vertices[ i ].Normal.x; // zmiana znaku X - t = Vertices[ i ].Normal.y; // zamiana Y i Z - Vertices[ i ].Normal.y = Vertices[ i ].Normal.z; - Vertices[ i ].Normal.z = t; - } + Vertices[i].Normal.x = -Vertices[i].Normal.x; // zmiana znaku X + t = Vertices[i].Normal.y; // zamiana Y i Z + Vertices[i].Normal.y = Vertices[i].Normal.z; + Vertices[i].Normal.z = t; } if (Child) Child->InitialRotate(doit); // potomne ewentualnie obrócimy diff --git a/Train.cpp b/Train.cpp index ce35b35c..66599599 100644 --- a/Train.cpp +++ b/Train.cpp @@ -5001,40 +5001,6 @@ bool TTrain::Update( double const Deltatime ) btHaslerBrakes.Turn(DynamicObject->MoverParameters->BrakePress > 0.4); // ciśnienie w cylindrach btHaslerCurrent.Turn(DynamicObject->MoverParameters->Im != 0.0); // prąd na silnikach - // calculate current level of interior illumination - // TODO: organize it along with rest of train update in a more sensible arrangement - switch( iCabLightFlag ) // Ra: uzeleżnic od napięcia w obwodzie sterowania - { // hunter-091012: uzaleznienie jasnosci od przetwornicy - case 0: { - //światło wewnętrzne zgaszone - DynamicObject->InteriorLightLevel = 0.0f; - break; - } - case 1: { - //światło wewnętrzne przygaszone (255 216 176) - if( mvOccupied->ConverterFlag == true ) { - // jasnosc dla zalaczonej przetwornicy - DynamicObject->InteriorLightLevel = 0.75f; - } - else { - DynamicObject->InteriorLightLevel = 0.375f; - } - break; - } - case 2: { - //światło wewnętrzne zapalone (255 216 176) - if( mvOccupied->ConverterFlag == - true ) // jasnosc dla zalaczonej przetwornicy - { - DynamicObject->InteriorLightLevel = 1.0f; - } - else { - DynamicObject->InteriorLightLevel = 0.5f; - } - break; - } - } - m_updated = true; return true; //(DynamicObject->Update(dt)); } // koniec update diff --git a/World.cpp b/World.cpp index e216d765..025857b8 100644 --- a/World.cpp +++ b/World.cpp @@ -590,7 +590,8 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) Ground.Init(Global::SceneryFile, hDC); // Global::tSinceStart= 0; - Environment.init(); + Sun.init(); + Clouds.Init(); WriteLog("Ground init OK"); if (Global::detonatoryOK) { @@ -1194,7 +1195,7 @@ bool TWorld::Update() Global::fClockAngleDeg[4] = 36.0 * (GlobalTime->hh % 10); // jednostki godzin Global::fClockAngleDeg[5] = 36.0 * (GlobalTime->hh / 10); // dziesiątki godzin - Update_Environment(); + Update_Lights(); } // koniec działań niewykonywanych podczas pauzy // poprzednie jakoś tam działało double dt = Timer::GetDeltaRenderTime(); // nie uwzględnia pauzowania ani mnożenia czasu @@ -1432,7 +1433,7 @@ TWorld::Update_Camera( double const Deltatime ) { } } -void TWorld::Update_Environment() { +void TWorld::Update_Lights() { #ifdef EU07_USE_OLD_LIGHTING_MODEL @@ -1531,8 +1532,44 @@ void TWorld::Update_Environment() { glFogfv( GL_FOG_COLOR, Global::FogColor ); // kolor mgły } #else - Environment.update(); + Sun.update(); + auto const position = Sun.getPosition(); + // update skydome with current sun position + SkyDome.Update( position ); + auto const skydomecolour = SkyDome.GetAverageColor(); + auto const skydomehsv = RGBtoHSV( skydomecolour ); + // update sunlight object + Global::DayLight.position[0] = position.x; + Global::DayLight.position[1] = position.y; + Global::DayLight.position[2] = position.z; + + Global::DayLight.direction = -1.0 * Sun.getDirection(); + + auto const intensity = std::min( 0.05f + Sun.getIntensity() + skydomehsv.z, 1.25f ); + + Global::DayLight.diffuse[ 0 ] = intensity * 255.0f / 255.0f; + Global::DayLight.diffuse[ 1 ] = intensity * 242.0f / 255.0f; + Global::DayLight.diffuse[ 2 ] = intensity * 231.0f / 255.0f; +// Global::DayLight.diffuse[ 3 ] = 1.0f;// std::min( 0.15f + intensity, 1.0f ); + Global::DayLight.ambient[ 0 ] = skydomecolour.x; + Global::DayLight.ambient[ 1 ] = skydomecolour.y; + Global::DayLight.ambient[ 2 ] = skydomecolour.z; +/* + Global::DayLight.ambient[ 0 ] = 155.0 / 255.0 * intensity * 0.75f; + Global::DayLight.ambient[ 1 ] = 192.0 / 255.0 * intensity * 0.75f; + Global::DayLight.ambient[ 2 ] = 231.0 / 255.0 * intensity * 0.75f; +*/ +// Global::DayLight.ambient[ 3 ] = 1.0f; + + Global::fLuminance = intensity; + + Global::FogColor[ 0 ] = skydomecolour.x; + Global::FogColor[ 1 ] = skydomecolour.y; + Global::FogColor[ 2 ] = skydomecolour.z; + glFogfv( GL_FOG_COLOR, Global::FogColor ); // kolor mgły #endif + + glClearColor( skydomecolour.x, skydomecolour.y, skydomecolour.z, 1.0f ); // kolor nieba } bool TWorld::Render() @@ -1551,9 +1588,31 @@ bool TWorld::Render() glLoadIdentity(); Camera.SetMatrix(); // ustawienie macierzy kamery względem początku scenerii - if( !Global::bWireFrame ) { - // bez nieba w trybie rysowania linii - Environment.render(); + if( !Global::bWireFrame ) { // bez nieba w trybie rysowania linii + + glDisable( GL_LIGHTING ); + glDisable( GL_FOG ); + glDisable( GL_DEPTH_TEST ); + glDepthMask( GL_FALSE ); + glPushMatrix(); + glTranslatef( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z ); + + SkyDome.Render(); +// Clouds.Render(); + +#ifdef EU07_USE_OLD_LIGHTING_MODEL + glLightfv( GL_LIGHT0, GL_POSITION, Global::lightPos ); +#else + Sun.render(); + Global::DayLight.apply_angle(); + Global::DayLight.apply_intensity(); +#endif + + glPopMatrix(); + glDepthMask( GL_TRUE ); + glEnable( GL_DEPTH_TEST ); + glEnable( GL_FOG ); + glEnable( GL_LIGHTING ); } if (Global::bUseVBO) @@ -1700,7 +1759,7 @@ TWorld::Render_Cab() { 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 ); + glColor4f( C, C, C, 0.35f );// *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 ); @@ -1821,13 +1880,6 @@ TWorld::Render_Cab() { glLightfv( GL_LIGHT0, GL_AMBIENT, ambientCabLight ); glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseCabLight ); glLightfv( GL_LIGHT0, GL_SPECULAR, specularCabLight ); -#else - 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 ); - } #endif if( Global::bUseVBO ) { // renderowanie z użyciem VBO dynamic->mdKabina->RaRender( 0.0, dynamic->ReplacableSkinID, dynamic->iAlpha ); @@ -1843,12 +1895,6 @@ TWorld::Render_Cab() { glLightfv( GL_LIGHT0, GL_AMBIENT, Global::ambientDayLight ); glLightfv( GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight ); glLightfv( GL_LIGHT0, GL_SPECULAR, Global::specularDayLight ); -#else - 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 ); - } #endif } glPopMatrix(); @@ -2319,8 +2365,6 @@ TWorld::Render_UI() { " " + 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 ); - // current luminance level - OutText2 = "Light level: " + to_string( Global::fLuminance, 3 ); } // OutText3= AnsiString(" Online documentation (PL, ENG, DE, soon CZ): // http://www.eu07.pl"); @@ -3016,81 +3060,3 @@ void TWorld::CabChange(TDynamicObject *old, TDynamicObject *now) Global::changeDynObj = now; // uruchomienie protezy }; //--------------------------------------------------------------------------- - -void -world_environment::init() { - - m_sun.init(); - m_stars.init(); - m_clouds.Init(); -} - -void -world_environment::update() { - - // move sun... - m_sun.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.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 ); - // ...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, - // but whether it'd _look_ better is something to be tested - Global::DayLight.diffuse[ 0 ] = intensity * 255.0f / 255.0f; - Global::DayLight.diffuse[ 1 ] = intensity * 242.0f / 255.0f; - Global::DayLight.diffuse[ 2 ] = intensity * 231.0f / 255.0f; - - Global::DayLight.ambient[ 0 ] = skydomecolour.x; - Global::DayLight.ambient[ 1 ] = skydomecolour.y; - Global::DayLight.ambient[ 2 ] = skydomecolour.z; - - Global::fLuminance = intensity; - - // update the fog. setting it to match the average colour of the sky dome is cheap - // but quite effective way to make the distant items blend with background better - Global::FogColor[ 0 ] = skydomecolour.x; - Global::FogColor[ 1 ] = skydomecolour.y; - Global::FogColor[ 2 ] = skydomecolour.z; - ::glFogfv( GL_FOG_COLOR, Global::FogColor ); // kolor mgły - - ::glClearColor( skydomecolour.x, skydomecolour.y, skydomecolour.z, 1.0f ); // kolor nieba -} - -void -world_environment::render() { - - ::glDisable( GL_LIGHTING ); - ::glDisable( GL_FOG ); - ::glDisable( GL_DEPTH_TEST ); - ::glDepthMask( GL_FALSE ); - ::glPushMatrix(); - ::glTranslatef( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z ); - - m_skydome.Render(); - m_stars.render(); -// m_clouds.Render(); - - if( DebugModeFlag == true ) { - // mark sun position for easier debugging - m_sun.render(); - } - Global::DayLight.apply_angle(); - Global::DayLight.apply_intensity(); - - ::glPopMatrix(); - ::glDepthMask( GL_TRUE ); - ::glEnable( GL_DEPTH_TEST ); - ::glEnable( GL_FOG ); - ::glEnable( GL_LIGHTING ); -} diff --git a/World.h b/World.h index eb5f3dde..7a409460 100644 --- a/World.h +++ b/World.h @@ -14,25 +14,9 @@ http://mozilla.org/MPL/2.0/. #include "Ground.h" #include "sky.h" #include "sun.h" -#include "stars.h" #include "skydome.h" #include "mczapkie/mover.h" -// wrapper for environment elements -- sky, sun, stars, clouds etc -class world_environment { - -public: - void init(); - void update(); - void render(); - -private: - CSkyDome m_skydome; - cStars m_stars; - cSun m_sun; - TSky m_clouds; -}; - class TWorld { void InOutKey(); @@ -58,19 +42,21 @@ class TWorld std::string OutText2; std::string OutText3; std::string OutText4; - void Update_Environment(); + void Update_Lights(); void Update_Camera( const double Deltatime ); bool Render(); void Render_Cab(); void Render_UI(); TCamera Camera; TGround Ground; - world_environment Environment; TTrain *Train; TDynamicObject *pDynamicNearest; bool Paused; GLuint base; // numer DL dla znaków w napisach texture_manager::size_type light; // numer tekstury dla smugi + TSky Clouds; + CSkyDome SkyDome; + cSun Sun; TEvent *KeyEvents[10]; // eventy wyzwalane z klawiaury TMoverParameters *mvControlled; // wskaźnik na człon silnikowy, do wyświetlania jego parametrów int iCheckFPS; // kiedy znów sprawdzić FPS, żeby wyłączać optymalizacji od razu do zera @@ -86,6 +72,5 @@ class TWorld void CreateE3D(std::string const &dir = "", bool dyn = false); void CabChange(TDynamicObject *old, TDynamicObject *now); }; - //--------------------------------------------------------------------------- diff --git a/color.h b/color.h index 68890616..e3e879e8 100644 --- a/color.h +++ b/color.h @@ -7,9 +7,9 @@ float3 XYZtoRGB( float3 const &XYZ ) { // M^-1 for Adobe RGB from http://www.brucelindbloom.com/Eqn_RGB_XYZ_Matrix.html - float const mi[ 3 ][ 3 ] = { 2.041369, -0.969266, 0.0134474, -0.5649464, 1.8760108, -0.1183897, -0.3446944, 0.041556, 1.0154096 }; +// float const mi[ 3 ][ 3 ] = { 2.041369, -0.969266, 0.0134474, -0.5649464, 1.8760108, -0.1183897, -0.3446944, 0.041556, 1.0154096 }; // m^-1 for sRGB: -// float const mi[ 3 ][ 3 ] = { 3.240479, -0.969256, 0.055648, -1.53715, 1.875991, -0.204043, -0.49853, 0.041556, 1.057311 }; + float const mi[ 3 ][ 3 ] = { 3.240479, -0.969256, 0.055648, -1.53715, 1.875991, -0.204043, -0.49853, 0.041556, 1.057311 }; return float3{ XYZ.x*mi[ 0 ][ 0 ] + XYZ.y*mi[ 1 ][ 0 ] + XYZ.z*mi[ 2 ][ 0 ], diff --git a/maszyna.vcxproj b/maszyna.vcxproj index 3cd10c56..be008947 100644 --- a/maszyna.vcxproj +++ b/maszyna.vcxproj @@ -126,7 +126,6 @@ - Create Create @@ -192,7 +191,6 @@ - diff --git a/maszyna.vcxproj.filters b/maszyna.vcxproj.filters index e38ea0db..4b343051 100644 --- a/maszyna.vcxproj.filters +++ b/maszyna.vcxproj.filters @@ -198,9 +198,6 @@ Source Files - - Source Files - @@ -389,9 +386,6 @@ Header Files - - Header Files - diff --git a/skydome.cpp b/skydome.cpp index cf9e7064..c84113c5 100644 --- a/skydome.cpp +++ b/skydome.cpp @@ -316,7 +316,6 @@ void CSkyDome::RebuildColors() { color.z = 0.75f * std::max( color.z + m_sundirection.y, 0.075f ); color.x = 0.20f * color.z; color.y = 0.65f * color.z; - color = color * ( 1.15f - vertex.y ); // simple gradient, darkening towards the top } // save diff --git a/stars.cpp b/stars.cpp deleted file mode 100644 index 451d6aa0..00000000 --- a/stars.cpp +++ /dev/null @@ -1,28 +0,0 @@ - -#include "stdafx.h" -#include "stars.h" -#include "globals.h" - -////////////////////////////////////////////////////////////////////////////////////////// -// cStars -- simple starfield model, simulating appearance of starry sky - -void -cStars::init() { - - m_stars.LoadFromFile( "models\\skydome_stars.t3d", false ); -} - -void -cStars::render() { - - ::glPushMatrix(); - - ::glRotatef( m_latitude, 1.0f, 0.0f, 0.0f ); // ustawienie osi OY na północ - ::glRotatef( -std::fmod( Global::fTimeAngleDeg, 360.0f ), 0.0f, 1.0f, 0.0f ); // obrót dobowy osi OX - - ::glPointSize( 2.0f ); - m_stars.Render( 1.0 ); - ::glPointSize( 3.0f ); - - ::glPopMatrix(); -} \ No newline at end of file diff --git a/stars.h b/stars.h deleted file mode 100644 index d5eb7989..00000000 --- a/stars.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "Model3d.h" - - -////////////////////////////////////////////////////////////////////////////////////////// -// cStars -- simple starfield model, simulating appearance of starry sky - -class cStars { - -public: -// types: - -// methods: - void init(); - void render(); - -// constructors: - -// deconstructor: - -// members: - -private: -// types: - -// methods: - -// members: - float m_longitude{ 19.0f }; // geograpic coordinates hardcoded roughly to Poland location, for the time being - float m_latitude{ 52.0f }; - TModel3d m_stars; -}; From 4dcb87906fede2dd287bba8ab60eaf4c0034587e Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Fri, 24 Feb 2017 01:22:06 +0100 Subject: [PATCH 35/40] stars object, interrior lighting level as accessible parameter for dynamic object --- DynObj.cpp | 23 +++++- DynObj.h | 17 ++-- Globals.cpp | 1 + Globals.h | 1 + Model3d.cpp | 15 ++-- Train.cpp | 34 ++++++++ World.cpp | 168 ++++++++++++++++++++++++---------------- World.h | 23 +++++- color.h | 4 +- maszyna.vcxproj | 2 + maszyna.vcxproj.filters | 6 ++ skydome.cpp | 10 +-- stars.cpp | 28 +++++++ stars.h | 33 ++++++++ 14 files changed, 268 insertions(+), 97 deletions(-) create mode 100644 stars.cpp create mode 100644 stars.h diff --git a/DynObj.cpp b/DynObj.cpp index 6e49fb7d..18784aeb 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -3807,9 +3807,26 @@ void TDynamicObject::Render() } else { // wersja Display Lists - if (mdLowPolyInt) - if (FreeFlyModeFlag ? true : !mdKabina || !bDisplayCab) - mdLowPolyInt->Render(ObjSqrDist, ReplacableSkinID, iAlpha); + if( mdLowPolyInt ) { + // low poly interior + if( FreeFlyModeFlag ? true : !mdKabina || !bDisplayCab ) { + // enable cab light if needed + if( InteriorLightLevel > 0.0f ) { + + // crude way to light the cabin, until we have something more complete in place + auto const cablight = InteriorLight * InteriorLightLevel; + ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x ); + } + + mdLowPolyInt->Render( ObjSqrDist, ReplacableSkinID, iAlpha ); + + if( InteriorLightLevel > 0.0f ) { + // reset the overall ambient + GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient ); + } + } + } mdModel->Render(ObjSqrDist, ReplacableSkinID, iAlpha); if (mdLoad) // renderowanie nieprzezroczystego ładunku mdLoad->Render(ObjSqrDist, ReplacableSkinID, iAlpha); diff --git a/DynObj.h b/DynObj.h index bda873a7..2c675cc0 100644 --- a/DynObj.h +++ b/DynObj.h @@ -140,11 +140,10 @@ class TAnim //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- -class TDynamicObject -{ // klasa pojazdu - private: // położenie pojazdu w świecie oraz parametry ruchu +class TDynamicObject { // klasa pojazdu +private: // położenie pojazdu w świecie oraz parametry ruchu vector3 vPosition; // Ra: pozycja pojazdu liczona zaraz po przesunięciu - vector3 vCoulpler[2]; // współrzędne sprzęgów do liczenia zderzeń czołowych + vector3 vCoulpler[ 2 ]; // współrzędne sprzęgów do liczenia zderzeń czołowych vector3 vUp, vFront, vLeft; // wektory jednostkowe ustawienia pojazdu int iDirection; // kierunek pojazdu względem czoła składu (1=zgodny,0=przeciwny) TTrackShape ts; // parametry toru przekazywane do fizyki @@ -156,10 +155,10 @@ class TDynamicObject float fAxleDist; // rozstaw wózków albo osi do liczenia proporcji zacienienia vector3 modelRot; // obrot pudła względem świata - do przeanalizowania, czy potrzebne!!! // bool bCameraNear; //blisko kamer są potrzebne dodatkowe obliczenia szczegółów - TDynamicObject * ABuFindNearestObject(TTrack *Track, TDynamicObject *MyPointer, - int &CouplNr); + TDynamicObject * ABuFindNearestObject( TTrack *Track, TDynamicObject *MyPointer, + int &CouplNr ); - public: // parametry położenia pojazdu dostępne publicznie +public: // parametry położenia pojazdu dostępne publicznie std::string asTrack; // nazwa toru początkowego; wywalić? std::string asDestination; // dokąd pojazd ma być kierowany "(stacja):(tor)" matrix4x4 mMatrix; // macierz przekształcenia do renderowania modeli @@ -175,12 +174,14 @@ class TDynamicObject 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 *mdLoad; // model zmiennego ładunku TModel3d *mdPrzedsionek; // model przedsionków dla EZT - może użyć mdLoad zamiast? TModel3d *mdKabina; // model kabiny dla użytkownika; McZapkie-030303: to z train.h TModel3d *mdLowPolyInt; // ABu 010305: wnetrze lowpoly + float3 InteriorLight{ 0.9f * 255.0f / 255.0f, 0.9f * 216.0f / 255.0f, 0.9f * 176.0f / 255.0f }; // tungsten light. TODO: allow definition of light type? + float InteriorLightLevel{ 0.0f }; // current level of interior lighting 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 diff --git a/Globals.cpp b/Globals.cpp index 8285f434..3e68f5e7 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -47,6 +47,7 @@ double Global::fOpenGL = 0.0; // wersja OpenGL - do sprawdzania obecności rozsz bool Global::bOpenGL_1_5 = false; // czy są dostępne funkcje OpenGL 1.5 */ double Global::fLuminance = 1.0; // jasność światła do automatycznego zapalania +float Global::SunAngle = 0.0f; int Global::iReCompile = 0; // zwiększany, gdy trzeba odświeżyć siatki HWND Global::hWnd = NULL; // uchwyt okna int Global::ScreenWidth = 1; diff --git a/Globals.h b/Globals.h index a9ca3c85..c46932e1 100644 --- a/Globals.h +++ b/Globals.h @@ -258,6 +258,7 @@ class Global static bool bOpenGL_1_5; // czy są dostępne funkcje OpenGL 1.5 */ static double fLuminance; // jasność światła do automatycznego zapalania + static float SunAngle; // angle of the sun relative to horizon static int iMultiplayer; // blokada działania niektórych eventów na rzecz kominikacji static HWND hWnd; // uchwyt okna static int ScreenWidth; // current window dimensions. TODO: move it to renderer diff --git a/Model3d.cpp b/Model3d.cpp index eb55533d..3ac52358 100644 --- a/Model3d.cpp +++ b/Model3d.cpp @@ -742,7 +742,7 @@ void TSubModel::DisplayLists() glNewList(uiDisplayList, GL_COMPILE); GfxRenderer.Bind(0); // tekstury nie ma glColorMaterial(GL_FRONT, GL_EMISSION); - glDisable(GL_LIGHTING); // Tolaris-030603: bo mu punkty swiecace sie blendowaly +// glDisable(GL_LIGHTING); // Tolaris-030603: bo mu punkty swiecace sie blendowaly glBegin(GL_POINTS); for (int i = 0; i < iNumVerts; i++) { @@ -751,7 +751,7 @@ void TSubModel::DisplayLists() glVertex3fv(&Vertices[i].Point.x); }; glEnd(); - glEnable(GL_LIGHTING); +// glEnable(GL_LIGHTING); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glMaterialfv(GL_FRONT, GL_EMISSION, emm2); glEndList(); @@ -816,10 +816,13 @@ void TSubModel::InitialRotate(bool doit) Vertices[i].Point.y = Vertices[i].Point.z; Vertices[i].Point.z = t; // wektory normalne również trzeba przekształcić, bo się źle oświetlają - Vertices[i].Normal.x = -Vertices[i].Normal.x; // zmiana znaku X - t = Vertices[i].Normal.y; // zamiana Y i Z - Vertices[i].Normal.y = Vertices[i].Normal.z; - Vertices[i].Normal.z = t; + if( eType != TP_STARS ) { + // gwiazdki mają kolory zamiast normalnych, to // ich wtedy nie ruszamy + Vertices[ i ].Normal.x = -Vertices[ i ].Normal.x; // zmiana znaku X + t = Vertices[ i ].Normal.y; // zamiana Y i Z + Vertices[ i ].Normal.y = Vertices[ i ].Normal.z; + Vertices[ i ].Normal.z = t; + } } if (Child) Child->InitialRotate(doit); // potomne ewentualnie obrócimy diff --git a/Train.cpp b/Train.cpp index 66599599..ce35b35c 100644 --- a/Train.cpp +++ b/Train.cpp @@ -5001,6 +5001,40 @@ bool TTrain::Update( double const Deltatime ) btHaslerBrakes.Turn(DynamicObject->MoverParameters->BrakePress > 0.4); // ciśnienie w cylindrach btHaslerCurrent.Turn(DynamicObject->MoverParameters->Im != 0.0); // prąd na silnikach + // calculate current level of interior illumination + // TODO: organize it along with rest of train update in a more sensible arrangement + switch( iCabLightFlag ) // Ra: uzeleżnic od napięcia w obwodzie sterowania + { // hunter-091012: uzaleznienie jasnosci od przetwornicy + case 0: { + //światło wewnętrzne zgaszone + DynamicObject->InteriorLightLevel = 0.0f; + break; + } + case 1: { + //światło wewnętrzne przygaszone (255 216 176) + if( mvOccupied->ConverterFlag == true ) { + // jasnosc dla zalaczonej przetwornicy + DynamicObject->InteriorLightLevel = 0.75f; + } + else { + DynamicObject->InteriorLightLevel = 0.375f; + } + break; + } + case 2: { + //światło wewnętrzne zapalone (255 216 176) + if( mvOccupied->ConverterFlag == + true ) // jasnosc dla zalaczonej przetwornicy + { + DynamicObject->InteriorLightLevel = 1.0f; + } + else { + DynamicObject->InteriorLightLevel = 0.5f; + } + break; + } + } + m_updated = true; return true; //(DynamicObject->Update(dt)); } // koniec update diff --git a/World.cpp b/World.cpp index 025857b8..e216d765 100644 --- a/World.cpp +++ b/World.cpp @@ -590,8 +590,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) Ground.Init(Global::SceneryFile, hDC); // Global::tSinceStart= 0; - Sun.init(); - Clouds.Init(); + Environment.init(); WriteLog("Ground init OK"); if (Global::detonatoryOK) { @@ -1195,7 +1194,7 @@ bool TWorld::Update() Global::fClockAngleDeg[4] = 36.0 * (GlobalTime->hh % 10); // jednostki godzin Global::fClockAngleDeg[5] = 36.0 * (GlobalTime->hh / 10); // dziesiątki godzin - Update_Lights(); + Update_Environment(); } // koniec działań niewykonywanych podczas pauzy // poprzednie jakoś tam działało double dt = Timer::GetDeltaRenderTime(); // nie uwzględnia pauzowania ani mnożenia czasu @@ -1433,7 +1432,7 @@ TWorld::Update_Camera( double const Deltatime ) { } } -void TWorld::Update_Lights() { +void TWorld::Update_Environment() { #ifdef EU07_USE_OLD_LIGHTING_MODEL @@ -1532,44 +1531,8 @@ void TWorld::Update_Lights() { glFogfv( GL_FOG_COLOR, Global::FogColor ); // kolor mgły } #else - Sun.update(); - auto const position = Sun.getPosition(); - // update skydome with current sun position - SkyDome.Update( position ); - auto const skydomecolour = SkyDome.GetAverageColor(); - auto const skydomehsv = RGBtoHSV( skydomecolour ); - // update sunlight object - Global::DayLight.position[0] = position.x; - Global::DayLight.position[1] = position.y; - Global::DayLight.position[2] = position.z; - - Global::DayLight.direction = -1.0 * Sun.getDirection(); - - auto const intensity = std::min( 0.05f + Sun.getIntensity() + skydomehsv.z, 1.25f ); - - Global::DayLight.diffuse[ 0 ] = intensity * 255.0f / 255.0f; - Global::DayLight.diffuse[ 1 ] = intensity * 242.0f / 255.0f; - Global::DayLight.diffuse[ 2 ] = intensity * 231.0f / 255.0f; -// Global::DayLight.diffuse[ 3 ] = 1.0f;// std::min( 0.15f + intensity, 1.0f ); - Global::DayLight.ambient[ 0 ] = skydomecolour.x; - Global::DayLight.ambient[ 1 ] = skydomecolour.y; - Global::DayLight.ambient[ 2 ] = skydomecolour.z; -/* - Global::DayLight.ambient[ 0 ] = 155.0 / 255.0 * intensity * 0.75f; - Global::DayLight.ambient[ 1 ] = 192.0 / 255.0 * intensity * 0.75f; - Global::DayLight.ambient[ 2 ] = 231.0 / 255.0 * intensity * 0.75f; -*/ -// Global::DayLight.ambient[ 3 ] = 1.0f; - - Global::fLuminance = intensity; - - Global::FogColor[ 0 ] = skydomecolour.x; - Global::FogColor[ 1 ] = skydomecolour.y; - Global::FogColor[ 2 ] = skydomecolour.z; - glFogfv( GL_FOG_COLOR, Global::FogColor ); // kolor mgły + Environment.update(); #endif - - glClearColor( skydomecolour.x, skydomecolour.y, skydomecolour.z, 1.0f ); // kolor nieba } bool TWorld::Render() @@ -1588,31 +1551,9 @@ bool TWorld::Render() glLoadIdentity(); Camera.SetMatrix(); // ustawienie macierzy kamery względem początku scenerii - if( !Global::bWireFrame ) { // bez nieba w trybie rysowania linii - - glDisable( GL_LIGHTING ); - glDisable( GL_FOG ); - glDisable( GL_DEPTH_TEST ); - glDepthMask( GL_FALSE ); - glPushMatrix(); - glTranslatef( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z ); - - SkyDome.Render(); -// Clouds.Render(); - -#ifdef EU07_USE_OLD_LIGHTING_MODEL - glLightfv( GL_LIGHT0, GL_POSITION, Global::lightPos ); -#else - Sun.render(); - Global::DayLight.apply_angle(); - Global::DayLight.apply_intensity(); -#endif - - glPopMatrix(); - glDepthMask( GL_TRUE ); - glEnable( GL_DEPTH_TEST ); - glEnable( GL_FOG ); - glEnable( GL_LIGHTING ); + if( !Global::bWireFrame ) { + // bez nieba w trybie rysowania linii + Environment.render(); } if (Global::bUseVBO) @@ -1759,7 +1700,7 @@ TWorld::Render_Cab() { 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, 0.35f );// *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 ); @@ -1880,6 +1821,13 @@ TWorld::Render_Cab() { glLightfv( GL_LIGHT0, GL_AMBIENT, ambientCabLight ); glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseCabLight ); glLightfv( GL_LIGHT0, GL_SPECULAR, specularCabLight ); +#else + 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 ); + } #endif if( Global::bUseVBO ) { // renderowanie z użyciem VBO dynamic->mdKabina->RaRender( 0.0, dynamic->ReplacableSkinID, dynamic->iAlpha ); @@ -1895,6 +1843,12 @@ TWorld::Render_Cab() { glLightfv( GL_LIGHT0, GL_AMBIENT, Global::ambientDayLight ); glLightfv( GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight ); glLightfv( GL_LIGHT0, GL_SPECULAR, Global::specularDayLight ); +#else + 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 ); + } #endif } glPopMatrix(); @@ -2365,6 +2319,8 @@ TWorld::Render_UI() { " " + 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 ); + // current luminance level + OutText2 = "Light level: " + to_string( Global::fLuminance, 3 ); } // OutText3= AnsiString(" Online documentation (PL, ENG, DE, soon CZ): // http://www.eu07.pl"); @@ -3060,3 +3016,81 @@ void TWorld::CabChange(TDynamicObject *old, TDynamicObject *now) Global::changeDynObj = now; // uruchomienie protezy }; //--------------------------------------------------------------------------- + +void +world_environment::init() { + + m_sun.init(); + m_stars.init(); + m_clouds.Init(); +} + +void +world_environment::update() { + + // move sun... + m_sun.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.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 ); + // ...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, + // but whether it'd _look_ better is something to be tested + Global::DayLight.diffuse[ 0 ] = intensity * 255.0f / 255.0f; + Global::DayLight.diffuse[ 1 ] = intensity * 242.0f / 255.0f; + Global::DayLight.diffuse[ 2 ] = intensity * 231.0f / 255.0f; + + Global::DayLight.ambient[ 0 ] = skydomecolour.x; + Global::DayLight.ambient[ 1 ] = skydomecolour.y; + Global::DayLight.ambient[ 2 ] = skydomecolour.z; + + Global::fLuminance = intensity; + + // update the fog. setting it to match the average colour of the sky dome is cheap + // but quite effective way to make the distant items blend with background better + Global::FogColor[ 0 ] = skydomecolour.x; + Global::FogColor[ 1 ] = skydomecolour.y; + Global::FogColor[ 2 ] = skydomecolour.z; + ::glFogfv( GL_FOG_COLOR, Global::FogColor ); // kolor mgły + + ::glClearColor( skydomecolour.x, skydomecolour.y, skydomecolour.z, 1.0f ); // kolor nieba +} + +void +world_environment::render() { + + ::glDisable( GL_LIGHTING ); + ::glDisable( GL_FOG ); + ::glDisable( GL_DEPTH_TEST ); + ::glDepthMask( GL_FALSE ); + ::glPushMatrix(); + ::glTranslatef( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z ); + + m_skydome.Render(); + m_stars.render(); +// m_clouds.Render(); + + if( DebugModeFlag == true ) { + // mark sun position for easier debugging + m_sun.render(); + } + Global::DayLight.apply_angle(); + Global::DayLight.apply_intensity(); + + ::glPopMatrix(); + ::glDepthMask( GL_TRUE ); + ::glEnable( GL_DEPTH_TEST ); + ::glEnable( GL_FOG ); + ::glEnable( GL_LIGHTING ); +} diff --git a/World.h b/World.h index 7a409460..eb5f3dde 100644 --- a/World.h +++ b/World.h @@ -14,9 +14,25 @@ http://mozilla.org/MPL/2.0/. #include "Ground.h" #include "sky.h" #include "sun.h" +#include "stars.h" #include "skydome.h" #include "mczapkie/mover.h" +// wrapper for environment elements -- sky, sun, stars, clouds etc +class world_environment { + +public: + void init(); + void update(); + void render(); + +private: + CSkyDome m_skydome; + cStars m_stars; + cSun m_sun; + TSky m_clouds; +}; + class TWorld { void InOutKey(); @@ -42,21 +58,19 @@ class TWorld std::string OutText2; std::string OutText3; std::string OutText4; - void Update_Lights(); + void Update_Environment(); void Update_Camera( const double Deltatime ); bool Render(); void Render_Cab(); void Render_UI(); TCamera Camera; TGround Ground; + world_environment Environment; TTrain *Train; TDynamicObject *pDynamicNearest; bool Paused; GLuint base; // numer DL dla znaków w napisach texture_manager::size_type light; // numer tekstury dla smugi - TSky Clouds; - CSkyDome SkyDome; - cSun Sun; TEvent *KeyEvents[10]; // eventy wyzwalane z klawiaury TMoverParameters *mvControlled; // wskaźnik na człon silnikowy, do wyświetlania jego parametrów int iCheckFPS; // kiedy znów sprawdzić FPS, żeby wyłączać optymalizacji od razu do zera @@ -72,5 +86,6 @@ class TWorld void CreateE3D(std::string const &dir = "", bool dyn = false); void CabChange(TDynamicObject *old, TDynamicObject *now); }; + //--------------------------------------------------------------------------- diff --git a/color.h b/color.h index e3e879e8..68890616 100644 --- a/color.h +++ b/color.h @@ -7,9 +7,9 @@ float3 XYZtoRGB( float3 const &XYZ ) { // M^-1 for Adobe RGB from http://www.brucelindbloom.com/Eqn_RGB_XYZ_Matrix.html -// float const mi[ 3 ][ 3 ] = { 2.041369, -0.969266, 0.0134474, -0.5649464, 1.8760108, -0.1183897, -0.3446944, 0.041556, 1.0154096 }; + float const mi[ 3 ][ 3 ] = { 2.041369, -0.969266, 0.0134474, -0.5649464, 1.8760108, -0.1183897, -0.3446944, 0.041556, 1.0154096 }; // m^-1 for sRGB: - float const mi[ 3 ][ 3 ] = { 3.240479, -0.969256, 0.055648, -1.53715, 1.875991, -0.204043, -0.49853, 0.041556, 1.057311 }; +// float const mi[ 3 ][ 3 ] = { 3.240479, -0.969256, 0.055648, -1.53715, 1.875991, -0.204043, -0.49853, 0.041556, 1.057311 }; return float3{ XYZ.x*mi[ 0 ][ 0 ] + XYZ.y*mi[ 1 ][ 0 ] + XYZ.z*mi[ 2 ][ 0 ], diff --git a/maszyna.vcxproj b/maszyna.vcxproj index be008947..3cd10c56 100644 --- a/maszyna.vcxproj +++ b/maszyna.vcxproj @@ -126,6 +126,7 @@ + Create Create @@ -191,6 +192,7 @@ + diff --git a/maszyna.vcxproj.filters b/maszyna.vcxproj.filters index 4b343051..e38ea0db 100644 --- a/maszyna.vcxproj.filters +++ b/maszyna.vcxproj.filters @@ -198,6 +198,9 @@ Source Files + + Source Files + @@ -386,6 +389,9 @@ Header Files + + Header Files + diff --git a/skydome.cpp b/skydome.cpp index c84113c5..34c0d96f 100644 --- a/skydome.cpp +++ b/skydome.cpp @@ -1,16 +1,11 @@ -//******************************************************************************// -// NightShine Engine // -// Sky : Gradient SkyDome Class // -//******************************************************************************// -// sky gradient based on "A practical analytic model for daylight" -// by A. J. Preetham Peter Shirley Brian Smits (University of Utah) #include "stdafx.h" #include "opengl/glew.h" #include "skydome.h" #include "color.h" -//******************************************************************************// +// sky gradient based on "A practical analytic model for daylight" +// by A. J. Preetham Peter Shirley Brian Smits (University of Utah) float CSkyDome::m_distributionluminance[ 5 ][ 2 ] = { // Perez distributions { 0.17872f , -1.46303f }, // a = darkening or brightening of the horizon @@ -316,6 +311,7 @@ void CSkyDome::RebuildColors() { color.z = 0.75f * std::max( color.z + m_sundirection.y, 0.075f ); color.x = 0.20f * color.z; color.y = 0.65f * color.z; + color = color * ( 1.15f - vertex.y ); // simple gradient, darkening towards the top } // save diff --git a/stars.cpp b/stars.cpp new file mode 100644 index 00000000..451d6aa0 --- /dev/null +++ b/stars.cpp @@ -0,0 +1,28 @@ + +#include "stdafx.h" +#include "stars.h" +#include "globals.h" + +////////////////////////////////////////////////////////////////////////////////////////// +// cStars -- simple starfield model, simulating appearance of starry sky + +void +cStars::init() { + + m_stars.LoadFromFile( "models\\skydome_stars.t3d", false ); +} + +void +cStars::render() { + + ::glPushMatrix(); + + ::glRotatef( m_latitude, 1.0f, 0.0f, 0.0f ); // ustawienie osi OY na północ + ::glRotatef( -std::fmod( Global::fTimeAngleDeg, 360.0f ), 0.0f, 1.0f, 0.0f ); // obrót dobowy osi OX + + ::glPointSize( 2.0f ); + m_stars.Render( 1.0 ); + ::glPointSize( 3.0f ); + + ::glPopMatrix(); +} \ No newline at end of file diff --git a/stars.h b/stars.h new file mode 100644 index 00000000..d5eb7989 --- /dev/null +++ b/stars.h @@ -0,0 +1,33 @@ +#pragma once + +#include "Model3d.h" + + +////////////////////////////////////////////////////////////////////////////////////////// +// cStars -- simple starfield model, simulating appearance of starry sky + +class cStars { + +public: +// types: + +// methods: + void init(); + void render(); + +// constructors: + +// deconstructor: + +// members: + +private: +// types: + +// methods: + +// members: + float m_longitude{ 19.0f }; // geograpic coordinates hardcoded roughly to Poland location, for the time being + float m_latitude{ 52.0f }; + TModel3d m_stars; +}; From 493340e6027118c08af8ec440ac21d08d934b4cf Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sat, 25 Feb 2017 21:02:27 +0100 Subject: [PATCH 36/40] working vehicle spotlights --- EU07.cpp | 6 + Globals.cpp | 2 + Globals.h | 4 + Model3d.cpp | 3 +- Segment.cpp | 95 +++++++++++++ World.cpp | 399 +++++++++++++++++++++++++++++----------------------- World.h | 1 + dumb3d.h | 5 + renderer.h | 12 +- sky.cpp | 2 +- sun.cpp | 8 +- 11 files changed, 353 insertions(+), 184 deletions(-) diff --git a/EU07.cpp b/EU07.cpp index b02ef876..4265784f 100644 --- a/EU07.cpp +++ b/EU07.cpp @@ -511,6 +511,12 @@ LRESULT CALLBACK WndProc(HWND hWnd, // handle for this window if (DebugModeFlag) { // siatki wyświetlane tyko w trybie testowym Global::bWireFrame = !Global::bWireFrame; + if( true == Global::bWireFrame ) { + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + } + else { + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } ++Global::iReCompile; // odświeżyć siatki // Ra: jeszcze usunąć siatki ze skompilowanych obiektów! } diff --git a/Globals.cpp b/Globals.cpp index 3e68f5e7..996b6936 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -104,6 +104,8 @@ 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; +opengl_light Global::VehicleLight; +opengl_light Global::VehicleLightRear; #endif GLfloat Global::whiteLight[] = {1.00f, 1.00f, 1.00f, 1.0f}; GLfloat Global::noLight[] = {0.00f, 0.00f, 0.00f, 1.0f}; diff --git a/Globals.h b/Globals.h index c46932e1..f2b1650b 100644 --- a/Globals.h +++ b/Globals.h @@ -231,7 +231,11 @@ class Global static GLfloat diffuseLight[]; static GLfloat specularLight[]; #else + // TODO: put these things in the renderer static opengl_light DayLight; + // TODO: possibly create a pool of few lights which can be attached to nearby vehicles + static opengl_light VehicleLight; + static opengl_light VehicleLightRear; #endif static GLfloat whiteLight[]; static GLfloat noLight[]; diff --git a/Model3d.cpp b/Model3d.cpp index 3ac52358..994862b5 100644 --- a/Model3d.cpp +++ b/Model3d.cpp @@ -278,7 +278,8 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic) 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" + 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ć diff --git a/Segment.cpp b/Segment.cpp index 21f66a41..9ed6dbfe 100644 --- a/Segment.cpp +++ b/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, diff --git a/World.cpp b/World.cpp index e216d765..9839e026 100644 --- a/World.cpp +++ b/World.cpp @@ -264,89 +264,34 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) 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.04); - 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 ----------- @@ -378,39 +323,18 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) 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 - // glFogf(GL_FOG_DENSITY, 0.594f); // How Dense Will The - //Fog - // Be - // glHint(GL_FOG_HINT, GL_NICEST); // Fog Hint Value - 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 @@ -480,7 +404,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) 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 ); @@ -491,23 +415,25 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) 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..."); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -519,7 +445,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) WriteLog("Sound Init OK"); if (Global::detonatoryOK) { - glRasterPos2f(-0.25f, -0.30f); + glRasterPos2f(-0.25f * widthratio, -0.30f); glPrint("OK."); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -530,7 +456,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) WriteLog("Textures init"); if (Global::detonatoryOK) { - glRasterPos2f(-0.85f, -0.35f); + glRasterPos2f(-0.85f * widthratio, -0.35f); glPrint("Tekstury / Textures..."); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -540,7 +466,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) WriteLog("Textures init OK"); if (Global::detonatoryOK) { - glRasterPos2f(-0.25f, -0.35f); + glRasterPos2f( -0.25f * widthratio, -0.35f ); glPrint("OK."); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -548,7 +474,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) WriteLog("Models init"); if (Global::detonatoryOK) { - glRasterPos2f(-0.85f, -0.40f); + glRasterPos2f( -0.85f * widthratio, -0.40f ); glPrint("Modele / Models..."); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -558,7 +484,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) WriteLog("Models init OK"); if (Global::detonatoryOK) { - glRasterPos2f(-0.25f, -0.40f); + glRasterPos2f( -0.25f * widthratio, -0.40f ); glPrint("OK."); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -566,7 +492,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) WriteLog("Ground init"); if (Global::detonatoryOK) { - glRasterPos2f(-0.85f, -0.45f); + glRasterPos2f( -0.85f * widthratio, -0.45f ); glPrint("Sceneria / Scenery (please wait)..."); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -586,6 +512,25 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) Global::DayLight.diffuse[ 0 ] = 255.0 / 255.0; Global::DayLight.diffuse[ 1 ] = 242.0 / 255.0; Global::DayLight.diffuse[ 2 ] = 231.0 / 255.0; + + Global::VehicleLight.id = opengl_renderer::vehiclelight; + // directional light + Global::VehicleLight.position[ 3 ] = 1.0f; + ::glLightf( opengl_renderer::vehiclelight, GL_SPOT_CUTOFF, 20.0f ); + ::glLightf( opengl_renderer::vehiclelight, GL_SPOT_EXPONENT, 10.0f ); + ::glLightf( opengl_renderer::vehiclelight, GL_CONSTANT_ATTENUATION, 0.0f ); + ::glLightf( opengl_renderer::vehiclelight, GL_LINEAR_ATTENUATION, 0.035f ); + // halogen light. TODO: allow light type definition + Global::VehicleLight.diffuse[ 0 ] = 255.0 / 255.0; + Global::VehicleLight.diffuse[ 1 ] = 241.0 / 255.0; + Global::VehicleLight.diffuse[ 2 ] = 224.0 / 255.0; + // rear light + Global::VehicleLightRear = Global::VehicleLight; + Global::VehicleLightRear.id = opengl_renderer::vehiclelightrear; + ::glLightf( opengl_renderer::vehiclelightrear, GL_SPOT_CUTOFF, 20.0f ); + ::glLightf( opengl_renderer::vehiclelightrear, GL_SPOT_EXPONENT, 10.0f ); + ::glLightf( opengl_renderer::vehiclelightrear, GL_CONSTANT_ATTENUATION, 0.0f ); + ::glLightf( opengl_renderer::vehiclelightrear, GL_LINEAR_ATTENUATION, 0.035f ); #endif Ground.Init(Global::SceneryFile, hDC); @@ -594,7 +539,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) WriteLog("Ground init OK"); if (Global::detonatoryOK) { - glRasterPos2f(-0.25f, -0.45f); + glRasterPos2f( -0.25f * widthratio, -0.45f ); glPrint("OK."); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -611,7 +556,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) 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..."); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -632,7 +577,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) WriteLog("Player train init OK"); if (Global::detonatoryOK) { - glRasterPos2f(-0.25f, -0.50f); + glRasterPos2f( -0.25f * widthratio, -0.50f ); glPrint("OK."); } FollowView(); @@ -644,7 +589,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) 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!"); } SwapBuffers(hDC); // Swap Buffers (Double Buffering) @@ -660,7 +605,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) 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!"); } } @@ -790,59 +735,97 @@ void TWorld::OnKeyDown(int cKey) } else if ((cKey >= VK_F1) ? (cKey <= VK_F12) : false) { - switch (cKey) - { - case VK_F1: // czas i relacja - case VK_F3: - case VK_F5: // przesiadka do innego pojazdu - case VK_F8: // FPS - case VK_F9: // wersja, typ wyświetlania, błędy OpenGL - case VK_F10: - if (Global::iTextMode == cKey) - Global::iTextMode = - (Global::iPause && (cKey != VK_F1) ? VK_F1 : - 0); // wyłączenie napisów, chyba że pauza - else - Global::iTextMode = cKey; - break; - case VK_F2: // parametry pojazdu - if (Global::iTextMode == cKey) // jeśli kolejne naciśnięcie - ++Global::iScreenMode[cKey - VK_F1]; // kolejny ekran - else - { // pierwsze naciśnięcie daje pierwszy (tzn. zerowy) ekran - Global::iTextMode = cKey; - Global::iScreenMode[cKey - VK_F1] = 0; - } - break; - case VK_F12: // coś tam jeszcze - if (Console::Pressed(VK_CONTROL) && Console::Pressed(VK_SHIFT)) - DebugModeFlag = !DebugModeFlag; // taka opcjonalna funkcja, może się czasem przydać - /* //Ra 2F1P: teraz włączanie i wyłączanie klawiszami cyfrowymi po użyciu [F12] - else if (Console::Pressed(VK_SHIFT)) - {//odpalenie logu w razie "W" - if ((Global::iWriteLogEnabled&2)==0) //nie było okienka - {//otwarcie okna - AllocConsole(); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN); - } - Global::iWriteLogEnabled|=3; - } */ - else - Global::iTextMode = cKey; - break; - case VK_F4: - InOutKey(); - break; - case VK_F6: - if (DebugModeFlag) - { // przyspieszenie symulacji do testowania scenerii... uwaga na FPS! - // Global::iViewMode=VK_F6; - if (Console::Pressed(VK_CONTROL)) - Global::fTimeSpeed = (Console::Pressed(VK_SHIFT) ? 10.0 : 5.0); + switch (cKey) { + + case VK_F1: { + // czas i relacja + if( Global::iTextMode == cKey ) + Global::iTextMode = + ( Global::iPause && ( cKey != VK_F1 ) ? + VK_F1 : + 0 ); // wyłączenie napisów, chyba że pauza else - Global::fTimeSpeed = (Console::Pressed(VK_SHIFT) ? 2.0 : 1.0); + Global::iTextMode = cKey; + // advance world clock in debug mode + if( DebugModeFlag ) { + if( Console::Pressed( VK_CONTROL ) ) { + // ctrl-f3 + GlobalTime->UpdateMTableTime( 20.0 * 60.0 ); + } + else if( Console::Pressed( VK_SHIFT ) ) { + // shift-f3 + GlobalTime->UpdateMTableTime( 5.0 * 60.0 ); + } + } + break; + } + case VK_F2: { + // parametry pojazdu + if( Global::iTextMode == cKey ) { + // jeśli kolejne naciśnięcie + ++Global::iScreenMode[ cKey - VK_F1 ]; // kolejny ekran + } + else { + // pierwsze naciśnięcie daje pierwszy (tzn. zerowy) ekran + Global::iTextMode = cKey; + Global::iScreenMode[ cKey - VK_F1 ] = 0; + } + break; + } + case VK_F3: { + Global::iTextMode = cKey; + break; + } + case VK_F4: { + InOutKey(); + break; + } + case VK_F5: { + // przesiadka do innego pojazdu + Global::iTextMode = cKey; + break; + } + case VK_F6: { + Global::iTextMode = cKey; + // przyspieszenie symulacji do testowania scenerii... uwaga na FPS! + if( DebugModeFlag ) { + + if( Console::Pressed( VK_CONTROL ) ) { Global::fTimeSpeed = ( Console::Pressed( VK_SHIFT ) ? 60.0 : 20.0 ); } + else { Global::fTimeSpeed = ( Console::Pressed( VK_SHIFT ) ? 5.0 : 1.0 ); } + } + break; + } + case VK_F8: { + Global::iTextMode = cKey; + // FPS + break; + } + case VK_F9: { + Global::iTextMode = cKey; + // wersja, typ wyświetlania, błędy OpenGL + break; + } + case VK_F10: { + if( Global::iTextMode == cKey ) { + Global::iTextMode = + ( Global::iPause && ( cKey != VK_F1 ) ? + VK_F1 : + 0 ); // wyłączenie napisów, chyba że pauza + } + else { + Global::iTextMode = cKey; + } + break; + } + case VK_F12: { + // coś tam jeszcze + if( Console::Pressed( VK_CONTROL ) + && Console::Pressed( VK_SHIFT ) ) + DebugModeFlag = !DebugModeFlag; // taka opcjonalna funkcja, może się czasem przydać + else + Global::iTextMode = cKey; + break; } - break; } // if (cKey!=VK_F4) return; // nie są przekazywane do pojazdu wcale @@ -1181,7 +1164,8 @@ bool TWorld::Update() iCheckFPS = 0.25 * Timer::GetFPS(); // tak za 0.25 sekundy sprawdzić ponownie (jeszcze przycina?) } Timer::UpdateTimers(Global::iPause); - 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) @@ -1278,13 +1262,24 @@ 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 ) ) ); + + // match the vehicle light position with new position of the vehicle + Global::VehicleLight.set_position( Train->Dynamic()->GetPosition() + ( Train->Dynamic()->VectorFront() * Train->Dynamic()->GetLength() * 0.45 ) ); + Global::VehicleLight.direction = Train->Dynamic()->VectorFront(); + Global::VehicleLightRear.set_position( Train->Dynamic()->GetPosition() - ( Train->Dynamic()->VectorFront() * Train->Dynamic()->GetLength() * 0.45 ) ); + Global::VehicleLightRear.direction = Train->Dynamic()->VectorFront(); + Global::VehicleLightRear.direction.RotateY( M_PI ); + } + + m_init = true; if (!Render()) return false; @@ -1556,6 +1551,51 @@ bool TWorld::Render() Environment.render(); } + // enable vehicle light, if it's present and on + if( nullptr != Train ) { + + auto const &frontlights = Train->Controlled()->iLights[ 0 ]; + int const frontlightcount = 0 + + ( ( frontlights & 1 ) ? 1 : 0 ) + + ( ( frontlights & 4 ) ? 1 : 0 ) + + ( ( frontlights & 16 ) ? 1 : 0 ); + + if( frontlightcount > 0 ) { + // halogen light. TODO: allow light type definition + Global::VehicleLight.ambient[ 0 ] = 0.15f * 255.0 * frontlightcount / 255.0; + Global::VehicleLight.ambient[ 1 ] = 0.15f * 241.0 * frontlightcount / 255.0; + Global::VehicleLight.ambient[ 2 ] = 0.15f * 224.0 * frontlightcount / 255.0; + + ::glLightf( opengl_renderer::vehiclelight, GL_LINEAR_ATTENUATION, 0.3f / pow(frontlightcount, 2) ); + glEnable( GfxRenderer.vehiclelight ); + Global::VehicleLight.apply_intensity(); + Global::VehicleLight.apply_angle(); + } + else { + glDisable( GfxRenderer.vehiclelight ); + } + auto const &rearlights = Train->Controlled()->iLights[ 1 ]; + int const rearlightcount = 0 + + ( ( rearlights & 1 ) ? 1 : 0 ) + + ( ( rearlights & 4 ) ? 1 : 0 ) + + ( ( rearlights & 16 ) ? 1 : 0 ); + + if( rearlightcount > 0 ) { + // halogen light. TODO: allow light type definition + Global::VehicleLightRear.ambient[ 0 ] = 0.15f * 255.0 * rearlightcount / 255.0; + Global::VehicleLightRear.ambient[ 1 ] = 0.15f * 241.0 * rearlightcount / 255.0; + Global::VehicleLightRear.ambient[ 2 ] = 0.15f * 224.0 * rearlightcount / 255.0; + + ::glLightf( opengl_renderer::vehiclelightrear, GL_LINEAR_ATTENUATION, 0.3f / pow( rearlightcount, 2 ) ); + glEnable( GfxRenderer.vehiclelightrear ); + Global::VehicleLightRear.apply_intensity(); + Global::VehicleLightRear.apply_angle(); + } + else { + glDisable( GfxRenderer.vehiclelightrear ); + } + } + if (Global::bUseVBO) { // renderowanie przez VBO if (!Ground.RenderVBO(Camera.Pos)) @@ -1618,10 +1658,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 ]; @@ -1694,24 +1735,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 ); @@ -1728,15 +1770,18 @@ 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 { #ifdef EU07_USE_OLD_LIGHTING_MODEL @@ -1822,6 +1867,10 @@ TWorld::Render_Cab() { glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseCabLight ); glLightfv( GL_LIGHT0, GL_SPECULAR, specularCabLight ); #else + // cab shouldn't get affected by the vehicle light, so we disable it here + ::glDisable( GfxRenderer.vehiclelight ); + ::glDisable( GfxRenderer.vehiclelightrear ); + if( dynamic->InteriorLightLevel > 0.0f ) { // crude way to light the cabin, until we have something more complete in place @@ -1866,9 +1915,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! @@ -1883,7 +1932,7 @@ TWorld::Render_UI() { if( Global::iTextMode == VK_F8 ) { Global::iViewMode = VK_F8; - OutText1 = " FPS: "; + OutText1 = "FPS: "; OutText1 += to_string( Timer::GetFPS(), 2 ); //OutText1 += sprintf(); if( Global::iSlowMotion ) @@ -2318,7 +2367,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 ); } @@ -3033,9 +3082,7 @@ 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 ); diff --git a/World.h b/World.h index eb5f3dde..cfdff5b5 100644 --- a/World.h +++ b/World.h @@ -81,6 +81,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); diff --git a/dumb3d.h b/dumb3d.h index 0ed4f67f..0d93b8e3 100644 --- a/dumb3d.h +++ b/dumb3d.h @@ -415,6 +415,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], diff --git a/renderer.h b/renderer.h index deabb54e..69e39ca7 100644 --- a/renderer.h +++ b/renderer.h @@ -24,7 +24,7 @@ struct opengl_light { opengl_light() { position[ 0 ] = position[ 1 ] = position[ 2 ] = 0.0f; position[ 3 ] = 1.0f; - ambient[ 0 ] = ambient[ 1 ] = ambient[ 2 ] = ambient[ 3 ] = 1.0f; + ambient[ 0 ] = ambient[ 1 ] = ambient[ 2 ] = 0.0f; ambient[ 3 ] = 1.0f; diffuse[ 0 ] = diffuse[ 1 ] = diffuse[ 2 ] = diffuse[ 3 ] = 1.0f; specular[ 0 ] = specular[ 1 ] = specular[ 2 ] = specular[ 3 ] = 1.0f; } @@ -45,6 +45,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. @@ -66,7 +73,8 @@ class opengl_renderer { public: GLenum static const sunlight{ GL_LIGHT0 }; -// GLenum static const ambientlight{ GL_LIGHT1 }; + GLenum static const vehiclelight{ GL_LIGHT1 }; + GLenum static const vehiclelightrear{ GL_LIGHT2 }; texture_manager::size_type GetTextureId( std::string Filename, std::string const &Dir, int const Filter = -1, bool const Loadnow = true ) { diff --git a/sky.cpp b/sky.cpp index 710adbdb..c6766f44 100644 --- a/sky.cpp +++ b/sky.cpp @@ -48,8 +48,8 @@ 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); #endif diff --git a/sun.cpp b/sun.cpp index 78fd9e4f..b21ef312 100644 --- a/sun.cpp +++ b/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; } From bd588b87b398e89b5b04fc73edf4cdcb190aa40e Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sun, 26 Feb 2017 00:20:18 +0100 Subject: [PATCH 37/40] tint ability for the clouds object --- World.cpp | 25 +++++++++++++++---------- sky.cpp | 18 ++++++++++++------ sky.h | 3 ++- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/World.cpp b/World.cpp index 9839e026..35e79974 100644 --- a/World.cpp +++ b/World.cpp @@ -738,16 +738,8 @@ void TWorld::OnKeyDown(int cKey) switch (cKey) { case VK_F1: { - // czas i relacja - if( Global::iTextMode == cKey ) - Global::iTextMode = - ( Global::iPause && ( cKey != VK_F1 ) ? - VK_F1 : - 0 ); // wyłączenie napisów, chyba że pauza - else - Global::iTextMode = cKey; - // advance world clock in debug mode if( DebugModeFlag ) { + // additional time speedup keys in debug mode if( Console::Pressed( VK_CONTROL ) ) { // ctrl-f3 GlobalTime->UpdateMTableTime( 20.0 * 60.0 ); @@ -757,6 +749,19 @@ void TWorld::OnKeyDown(int cKey) GlobalTime->UpdateMTableTime( 5.0 * 60.0 ); } } + if( ( false == Console::Pressed( VK_CONTROL ) ) + && ( false == Console::Pressed( VK_SHIFT ) ) ) { + // czas i relacja + if( Global::iTextMode == cKey ) { + // wyłączenie napisów, chyba że pauza + Global::iTextMode = + ( Global::iPause && ( cKey != VK_F1 ) ? + VK_F1 : + 0 ); + } + else + Global::iTextMode = cKey; + } break; } case VK_F2: { @@ -3126,7 +3131,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 diff --git a/sky.cpp b/sky.cpp index c6766f44..78932cf7 100644 --- a/sky.cpp +++ b/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 ); + ::glDisable( GL_LIGHT0 ); + ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &Tint.x ); #endif if (Global::bUseVBO) { // renderowanie z VBO @@ -52,6 +53,11 @@ void TSky::Render() 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 ); + ::glDisable( GL_LIGHTING ); #endif } }; diff --git a/sky.h b/sky.h index 709c2887..1117957a 100644 --- a/sky.h +++ b/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) ); }; //--------------------------------------------------------------------------- From 0752024d4724f87ae86eafd68af9f075ad2bc05e Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sun, 26 Feb 2017 16:44:42 +0100 Subject: [PATCH 38/40] manual tweaks/overrides in skydome colour model --- Float3d.h | 5 +++++ World.cpp | 8 +++++--- skydome.cpp | 34 +++++++++++++++++++++++++--------- skydome.h | 2 +- 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/Float3d.h b/Float3d.h index fcb5afc3..e9504e94 100644 --- a/Float3d.h +++ b/Float3d.h @@ -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: diff --git a/World.cpp b/World.cpp index 35e79974..940ee222 100644 --- a/World.cpp +++ b/World.cpp @@ -1565,7 +1565,8 @@ bool TWorld::Render() ( ( frontlights & 4 ) ? 1 : 0 ) + ( ( frontlights & 16 ) ? 1 : 0 ); - if( frontlightcount > 0 ) { + if( ( true == Train->Controlled()->Battery ) + && ( frontlightcount > 0 ) ) { // halogen light. TODO: allow light type definition Global::VehicleLight.ambient[ 0 ] = 0.15f * 255.0 * frontlightcount / 255.0; Global::VehicleLight.ambient[ 1 ] = 0.15f * 241.0 * frontlightcount / 255.0; @@ -1585,7 +1586,8 @@ bool TWorld::Render() ( ( rearlights & 4 ) ? 1 : 0 ) + ( ( rearlights & 16 ) ? 1 : 0 ); - if( rearlightcount > 0 ) { + if( ( true == Train->Controlled()->Battery ) + && ( rearlightcount > 0 ) ) { // halogen light. TODO: allow light type definition Global::VehicleLightRear.ambient[ 0 ] = 0.15f * 255.0 * rearlightcount / 255.0; Global::VehicleLightRear.ambient[ 1 ] = 0.15f * 241.0 * rearlightcount / 255.0; @@ -3094,7 +3096,7 @@ world_environment::update() { // ...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, diff --git a/skydome.cpp b/skydome.cpp index 34c0d96f..e57bd043 100644 --- a/skydome.cpp +++ b/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 ); diff --git a/skydome.h b/skydome.h index df0125e4..0fcfb329 100644 --- a/skydome.h +++ b/skydome.h @@ -42,7 +42,7 @@ private: // data int const m_tesselation; std::vector m_vertices; - std::vector m_normals; +// std::vector m_normals; std::vector m_colours; static float m_distributionluminance[ 5 ][ 2 ]; From 80b8da6749c2e333acbb71d220e5fdc5010b65be Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Mon, 27 Feb 2017 02:58:38 +0100 Subject: [PATCH 39/40] dynamically assigned render lights --- DynObj.cpp | 2 + DynObj.h | 6 +-- EU07.cpp | 3 ++ Globals.cpp | 12 +++-- Globals.h | 4 +- Ground.cpp | 101 ++++++++++++++++++++++++------------ Ground.h | 8 ++- World.cpp | 110 +++------------------------------------- dumb3d.h | 10 +++- lightarray.cpp | 75 +++++++++++++++++++++++++++ lightarray.h | 45 ++++++++++++++++ maszyna.vcxproj | 4 +- maszyna.vcxproj.filters | 6 +++ renderer.cpp | 78 ++++++++++++++++++++++++++++ renderer.h | 34 ++++++++++--- sky.cpp | 4 +- 16 files changed, 344 insertions(+), 158 deletions(-) create mode 100644 lightarray.cpp create mode 100644 lightarray.h diff --git a/DynObj.cpp b/DynObj.cpp index 18784aeb..6ff5fb66 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -3760,12 +3760,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 diff --git a/DynObj.h b/DynObj.h index 2c675cc0..b5ff3e04 100644 --- a/DynObj.h +++ b/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; }; diff --git a/EU07.cpp b/EU07.cpp index 4265784f..1f0e01b9 100644 --- a/EU07.cpp +++ b/EU07.cpp @@ -718,6 +718,9 @@ int WINAPI WinMain(HINSTANCE hInstance, // instance fullscreen)) return 0; // quit if window was not created SetForegroundWindow(hWnd); + + GfxRenderer.Init(); + // McZapkie: proba przeplukania klawiatury Console *pConsole = new Console(); // Ra: nie wiem, czy ma to sens, ale jakoś zainicjowac trzeba while (Console::Pressed(VK_F10)) diff --git a/Globals.cpp b/Globals.cpp index 36a331af..532ace49 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -104,8 +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; -opengl_light Global::VehicleLight; -opengl_light Global::VehicleLightRear; +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}; @@ -577,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") { diff --git a/Globals.h b/Globals.h index 2690f9a0..0236006e 100644 --- a/Globals.h +++ b/Globals.h @@ -233,9 +233,7 @@ class Global #else // TODO: put these things in the renderer static opengl_light DayLight; - // TODO: possibly create a pool of few lights which can be attached to nearby vehicles - static opengl_light VehicleLight; - static opengl_light VehicleLightRear; + static int DynamicLightCount; #endif static GLfloat whiteLight[]; static GLfloat noLight[]; diff --git a/Ground.cpp b/Ground.cpp index d8185741..5a298282 100644 --- a/Ground.cpp +++ b/Ground.cpp @@ -1841,29 +1841,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 { @@ -1892,17 +1883,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? } @@ -1911,8 +1897,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 = ""; @@ -1986,6 +1971,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) @@ -4558,6 +4553,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 @@ -4808,6 +4822,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); @@ -5339,6 +5374,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 } diff --git a/Ground.h b/Ground.h index b78023d6..41f1672d 100644 --- a/Ground.h +++ b/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 event_map; -// typedef std::unordered_map groundnode_map; event_map m_eventmap; -// groundnode_map m_memcellmap, m_modelmap, m_trackmap; TNames 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); diff --git a/World.cpp b/World.cpp index 940ee222..9fd96101 100644 --- a/World.cpp +++ b/World.cpp @@ -512,25 +512,6 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) Global::DayLight.diffuse[ 0 ] = 255.0 / 255.0; Global::DayLight.diffuse[ 1 ] = 242.0 / 255.0; Global::DayLight.diffuse[ 2 ] = 231.0 / 255.0; - - Global::VehicleLight.id = opengl_renderer::vehiclelight; - // directional light - Global::VehicleLight.position[ 3 ] = 1.0f; - ::glLightf( opengl_renderer::vehiclelight, GL_SPOT_CUTOFF, 20.0f ); - ::glLightf( opengl_renderer::vehiclelight, GL_SPOT_EXPONENT, 10.0f ); - ::glLightf( opengl_renderer::vehiclelight, GL_CONSTANT_ATTENUATION, 0.0f ); - ::glLightf( opengl_renderer::vehiclelight, GL_LINEAR_ATTENUATION, 0.035f ); - // halogen light. TODO: allow light type definition - Global::VehicleLight.diffuse[ 0 ] = 255.0 / 255.0; - Global::VehicleLight.diffuse[ 1 ] = 241.0 / 255.0; - Global::VehicleLight.diffuse[ 2 ] = 224.0 / 255.0; - // rear light - Global::VehicleLightRear = Global::VehicleLight; - Global::VehicleLightRear.id = opengl_renderer::vehiclelightrear; - ::glLightf( opengl_renderer::vehiclelightrear, GL_SPOT_CUTOFF, 20.0f ); - ::glLightf( opengl_renderer::vehiclelightrear, GL_SPOT_EXPONENT, 10.0f ); - ::glLightf( opengl_renderer::vehiclelightrear, GL_CONSTANT_ATTENUATION, 0.0f ); - ::glLightf( opengl_renderer::vehiclelightrear, GL_LINEAR_ATTENUATION, 0.035f ); #endif Ground.Init(Global::SceneryFile, hDC); @@ -1256,6 +1237,8 @@ bool TWorld::Update() Ground.CheckQuery(); + Ground.Update_Lights(); + if( Train != nullptr ) { TSubModel::iInstance = reinterpret_cast( Train->Dynamic() ); Train->Update( dt ); @@ -1275,13 +1258,6 @@ bool TWorld::Update() ( Train->Dynamic()->fShade <= 0.0 ? ( Global::fLuminance <= 0.5 ) : ( Train->Dynamic()->fShade * Global::fLuminance <= 0.5 ) ) ); - - // match the vehicle light position with new position of the vehicle - Global::VehicleLight.set_position( Train->Dynamic()->GetPosition() + ( Train->Dynamic()->VectorFront() * Train->Dynamic()->GetLength() * 0.45 ) ); - Global::VehicleLight.direction = Train->Dynamic()->VectorFront(); - Global::VehicleLightRear.set_position( Train->Dynamic()->GetPosition() - ( Train->Dynamic()->VectorFront() * Train->Dynamic()->GetLength() * 0.45 ) ); - Global::VehicleLightRear.direction = Train->Dynamic()->VectorFront(); - Global::VehicleLightRear.direction.RotateY( M_PI ); } m_init = true; @@ -1556,78 +1532,11 @@ bool TWorld::Render() Environment.render(); } - // enable vehicle light, if it's present and on - if( nullptr != Train ) { + if( false == Ground.Render( Camera.Pos ) ) { return false; } - auto const &frontlights = Train->Controlled()->iLights[ 0 ]; - int const frontlightcount = 0 + - ( ( frontlights & 1 ) ? 1 : 0 ) + - ( ( frontlights & 4 ) ? 1 : 0 ) + - ( ( frontlights & 16 ) ? 1 : 0 ); - - if( ( true == Train->Controlled()->Battery ) - && ( frontlightcount > 0 ) ) { - // halogen light. TODO: allow light type definition - Global::VehicleLight.ambient[ 0 ] = 0.15f * 255.0 * frontlightcount / 255.0; - Global::VehicleLight.ambient[ 1 ] = 0.15f * 241.0 * frontlightcount / 255.0; - Global::VehicleLight.ambient[ 2 ] = 0.15f * 224.0 * frontlightcount / 255.0; - - ::glLightf( opengl_renderer::vehiclelight, GL_LINEAR_ATTENUATION, 0.3f / pow(frontlightcount, 2) ); - glEnable( GfxRenderer.vehiclelight ); - Global::VehicleLight.apply_intensity(); - Global::VehicleLight.apply_angle(); - } - else { - glDisable( GfxRenderer.vehiclelight ); - } - auto const &rearlights = Train->Controlled()->iLights[ 1 ]; - int const rearlightcount = 0 + - ( ( rearlights & 1 ) ? 1 : 0 ) + - ( ( rearlights & 4 ) ? 1 : 0 ) + - ( ( rearlights & 16 ) ? 1 : 0 ); - - if( ( true == Train->Controlled()->Battery ) - && ( rearlightcount > 0 ) ) { - // halogen light. TODO: allow light type definition - Global::VehicleLightRear.ambient[ 0 ] = 0.15f * 255.0 * rearlightcount / 255.0; - Global::VehicleLightRear.ambient[ 1 ] = 0.15f * 241.0 * rearlightcount / 255.0; - Global::VehicleLightRear.ambient[ 2 ] = 0.15f * 224.0 * rearlightcount / 255.0; - - ::glLightf( opengl_renderer::vehiclelightrear, GL_LINEAR_ATTENUATION, 0.3f / pow( rearlightcount, 2 ) ); - glEnable( GfxRenderer.vehiclelightrear ); - Global::VehicleLightRear.apply_intensity(); - Global::VehicleLightRear.apply_angle(); - } - else { - glDisable( GfxRenderer.vehiclelightrear ); - } - } - - 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(); -*/ Render_Cab(); Render_UI(); -// glFlush(); - // Global::bReCompile=false; //Ra: już zrobiona rekompilacja ResourceManager::Sweep( Timer::GetSimulationTime() ); return true; @@ -1652,6 +1561,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 ) && @@ -1777,18 +1687,18 @@ 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 else - glEnable( GL_LIGHTING ); // po renderowaniu drutów może być to wyłączone. TODO: have the wires render take care of its own shit -*/ +*/ 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 { #ifdef EU07_USE_OLD_LIGHTING_MODEL @@ -1874,10 +1784,6 @@ TWorld::Render_Cab() { glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseCabLight ); glLightfv( GL_LIGHT0, GL_SPECULAR, specularCabLight ); #else - // cab shouldn't get affected by the vehicle light, so we disable it here - ::glDisable( GfxRenderer.vehiclelight ); - ::glDisable( GfxRenderer.vehiclelightrear ); - if( dynamic->InteriorLightLevel > 0.0f ) { // crude way to light the cabin, until we have something more complete in place diff --git a/dumb3d.h b/dumb3d.h index 0d93b8e3..23dd5ce5 100644 --- a/dumb3d.h +++ b/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; @@ -435,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) diff --git a/lightarray.cpp b/lightarray.cpp new file mode 100644 index 00000000..6ad61a7f --- /dev/null +++ b/lightarray.cpp @@ -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; + } + } +} diff --git a/lightarray.h b/lightarray.h new file mode 100644 index 00000000..34b317d9 --- /dev/null +++ b/lightarray.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#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 lightrecord_array; + +// members + lightrecord_array data; +}; diff --git a/maszyna.vcxproj b/maszyna.vcxproj index 0f287655..b9d71414 100644 --- a/maszyna.vcxproj +++ b/maszyna.vcxproj @@ -104,6 +104,7 @@ + @@ -166,6 +167,7 @@ + @@ -222,4 +224,4 @@ - + \ No newline at end of file diff --git a/maszyna.vcxproj.filters b/maszyna.vcxproj.filters index e38ea0db..e124aab2 100644 --- a/maszyna.vcxproj.filters +++ b/maszyna.vcxproj.filters @@ -201,6 +201,9 @@ Source Files + + Source Files + @@ -392,6 +395,9 @@ Header Files + + Header Files + diff --git a/renderer.cpp b/renderer.cpp index 13fdb85b..809560cc 100644 --- a/renderer.cpp +++ b/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 ) { + + int 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 ); + } +} //--------------------------------------------------------------------------- diff --git a/renderer.h b/renderer.h index 69e39ca7..ed0c3ba5 100644 --- a/renderer.h +++ b/renderer.h @@ -11,6 +11,7 @@ http://mozilla.org/MPL/2.0/. #include "opengl/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 ] = 0.0f; 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 @@ -72,33 +73,50 @@ struct opengl_material { class opengl_renderer { public: - GLenum static const sunlight{ GL_LIGHT0 }; - GLenum static const vehiclelight{ GL_LIGHT1 }; - GLenum static const vehiclelightrear{ GL_LIGHT2 }; +// 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 opengllight_array; + +// members rendermode renderpass{ rendermode::color }; - + opengllight_array m_lights; texture_manager m_textures; }; diff --git a/sky.cpp b/sky.cpp index 78932cf7..7c3aa79f 100644 --- a/sky.cpp +++ b/sky.cpp @@ -36,7 +36,7 @@ void TSky::Render( float3 const &Tint ) glLightfv(GL_LIGHT0, GL_POSITION, lightPos); #else ::glEnable( GL_LIGHTING ); - ::glDisable( GL_LIGHT0 ); + GfxRenderer.Disable_Lights(); ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &Tint.x ); #endif if (Global::bUseVBO) @@ -56,7 +56,7 @@ void TSky::Render( float3 const &Tint ) #else GLfloat noambient[] = { 0.0f, 0.0f, 0.0f, 1.0f }; ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, noambient ); - ::glEnable( GL_LIGHT0 ); + ::glEnable( GL_LIGHT0 ); // other lights will be enabled during lights update ::glDisable( GL_LIGHTING ); #endif } From c49b774864ce497b88d37fccdd7082403a7e4b26 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Mon, 27 Feb 2017 13:24:34 +0100 Subject: [PATCH 40/40] light "fix" for multi-unit trains --- lightarray.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lightarray.cpp b/lightarray.cpp index 6ad61a7f..7f5a717d 100644 --- a/lightarray.cpp +++ b/lightarray.cpp @@ -16,6 +16,7 @@ http://mozilla.org/MPL/2.0/. #include "stdafx.h" #include "lightarray.h" #include "dynobj.h" +#include "driver.h" void light_array::insert( TDynamicObject const *Owner ) { @@ -65,6 +66,16 @@ light_array::update() { ( ( lightbits & 16 ) ? 1 : 0 ); light.intensity = 0.15f * light.count; // TODO: intensity can be affected further by dim switch or other factors + + // crude catch for unmanned modules which share the light state with the controlled unit. + // why don't they get their own light bits btw ._. + // TODO, TBD: have separate light bits for each vehicle, so this override isn't necessary + if( ( light.owner->Controller == AIdriver ) + && ( light.owner->Mechanik == nullptr ) ) { + + light.intensity = 0.0f; + light.count = 0; + } } else { // with battery off the lights are off