diff --git a/.gitignore b/.gitignore index b18c7752..549b13c4 100644 --- a/.gitignore +++ b/.gitignore @@ -67,6 +67,7 @@ Debug/ tmp/ bin/ ipch/ +ref/ *.aps builds/ \ No newline at end of file diff --git a/Camera.cpp b/Camera.cpp index 1c57d303..c714fb88 100644 --- a/Camera.cpp +++ b/Camera.cpp @@ -61,7 +61,7 @@ void TCamera::OnCursorMove(double x, double y) void TCamera::Update() { // ABu: zmiana i uniezaleznienie predkosci od FPS - double a = (Global::shiftState ? 5.00 : 1.00); + double a = ( Global::shiftState ? 5.00 : 1.00); if (Global::ctrlState) a = a * 100; // OldVelocity=Velocity; @@ -75,40 +75,6 @@ void TCamera::Update() Velocity.y += a; if (Console::Pressed(Global::Keys[k_MechDown])) Velocity.y -= a; - // McZapkie-170402: zeby nie bylo konfliktow - /* - if (Console::Pressed(VkKeyScan('d'))) - Velocity.x+= a*Timer::GetDeltaTime(); - if (Console::Pressed(VkKeyScan('a'))) - Velocity.x-= a*Timer::GetDeltaTime(); - if (Console::Pressed(VkKeyScan('w'))) - Velocity.z-= a*Timer::GetDeltaTime(); - if (Console::Pressed(VkKeyScan('s'))) - Velocity.z+= a*Timer::GetDeltaTime(); - - if (Console::Pressed(GLFW_KEY_KP_4) || Console::Pressed(GLFW_KEY_KP_7) || - Console::Pressed(GLFW_KEY_KP_1)) - Yaw+= +1*M_PI*Timer::GetDeltaTime(); - - if (Console::Pressed(GLFW_KEY_KP_6) || Console::Pressed(GLFW_KEY_KP_9) || - Console::Pressed(GLFW_KEY_KP_3)) - Yaw+= -1*M_PI*Timer::GetDeltaTime(); - - if (Pressed(GLFW_KEY_KP_2) || Console::Pressed(GLFW_KEY_KP_1) || - Console::Pressed(GLFW_KEY_KP_3)) - Pitch+= -1*M_PI*Timer::GetDeltaTime(); - - if (Console::Pressed(GLFW_KEY_KP_8) || Console::Pressed(GLFW_KEY_KP_7) || - Console::Pressed(GLFW_KEY_KP_9)) - Pitch+= +1*M_PI*Timer::GetDeltaTime(); - if (Console::Pressed(VkKeyScan('.'))) - Roll+= -1*M_PI*Timer::GetDeltaTime(); - if (Console::Pressed(VkKeyScan(','))) - Roll+= +1*M_PI*Timer::GetDeltaTime(); - - if (Console::Pressed(GLFW_KEY_KP_5)) - Pitch=Roll= 0.0f; - */ // McZapkie-170402: poruszanie i rozgladanie we free takie samo jak w follow if (Console::Pressed(Global::Keys[k_MechRight])) diff --git a/DynObj.h b/DynObj.h index b5ff3e04..b3a48742 100644 --- a/DynObj.h +++ b/DynObj.h @@ -444,7 +444,7 @@ public: // modele skÅ‚adowe pojazdu { return vUp; }; - inline vector3 VectorLeft() + inline vector3 VectorLeft() const { return vLeft; }; @@ -460,7 +460,7 @@ public: // modele skÅ‚adowe pojazdu { return MoverParameters->Dim.L; }; - inline double GetWidth() + inline double GetWidth() const { return MoverParameters->Dim.W; }; @@ -473,7 +473,7 @@ public: // modele skÅ‚adowe pojazdu // McZapkie-260202 void LoadMMediaFile(std::string BaseDir, std::string TypeName, std::string ReplacableSkin); - inline double ABuGetDirection() // ABu. + inline double ABuGetDirection() const // ABu. { return (Axle1.GetTrack() == MyTrack ? Axle1.GetDirection() : Axle0.GetDirection()); }; diff --git a/EU07.cpp b/EU07.cpp index 2ddaf4da..aca1353e 100644 --- a/EU07.cpp +++ b/EU07.cpp @@ -47,50 +47,81 @@ void cursor_pos_callback(GLFWwindow *window, double x, double y) glfwSetCursorPos(window, 0.0, 0.0); } -void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) +void key_callback( GLFWwindow *window, int key, int scancode, int action, int mods ) { - Global::shiftState = (mods & GLFW_MOD_SHIFT) ? true : false; - Global::ctrlState = (mods & GLFW_MOD_CONTROL) ? true : false; + Global::shiftState = ( mods & GLFW_MOD_SHIFT ) ? true : false; + Global::ctrlState = ( mods & GLFW_MOD_CONTROL ) ? true : false; - if (action == GLFW_PRESS || action == GLFW_REPEAT) - { - World.OnKeyDown(key); + if( ( key == GLFW_KEY_LEFT_SHIFT ) + || ( key == GLFW_KEY_LEFT_CONTROL ) + || ( key == GLFW_KEY_LEFT_ALT ) + || ( key == GLFW_KEY_RIGHT_SHIFT ) + || ( key == GLFW_KEY_RIGHT_CONTROL ) + || ( key == GLFW_KEY_RIGHT_ALT ) ) { + // don't bother passing these + return; + } - switch (key) - { - case GLFW_KEY_PAUSE: - if (Global::iPause & 1) - Global::iPause &= ~1; - else if (!(Global::iMultiplayer & 2) && - (mods & GLFW_MOD_CONTROL)) - Global::iPause ^= 2; - if (Global::iPause) - Global::iTextMode = GLFW_KEY_F1; - break; + if( action == GLFW_PRESS || action == GLFW_REPEAT ) + { + World.OnKeyDown( key ); - case GLFW_KEY_F7: - Global::bWireFrame = !Global::bWireFrame; - ++Global::iReCompile; - break; - } - } - else if (action == GLFW_RELEASE) - { - World.OnKeyUp(key); - } + switch( key ) + { + case GLFW_KEY_ESCAPE: { + //[Esc] pauzuje tylko bez Debugmode + if( DebugModeFlag ) + break; + + if( Global::iPause & 1 ) // jeÅ›li pauza startowa + Global::iPause &= ~1; // odpauzowanie, gdy po wczytaniu miaÅ‚o nie startować + else if( !( Global::iMultiplayer & 2 ) ) // w multiplayerze pauza nie ma sensu + if( !Global::ctrlState ) // z [Ctrl] to radiostop jest + Global::iPause ^= 2; // zmiana stanu zapauzowania + if( Global::iPause ) // jak pauza + Global::iTextMode = GLFW_KEY_F1; // to wyÅ›wietlić zegar i informacjÄ™ + break; + } + case GLFW_KEY_F7: + if( DebugModeFlag ) { // siatki wyÅ›wietlane tyko w trybie testowym + 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! + } + break; + } + } + else if( action == GLFW_RELEASE ) + { + World.OnKeyUp( key ); + } } -void focus_callback(GLFWwindow *window, int focus) +void focus_callback( GLFWwindow *window, int focus ) { - if (Global::bInactivePause) // jeÅ›li ma być pauzowanie okna w tle - if (focus) - Global::iPause &= ~4; // odpauzowanie, gdy jest na pierwszym planie - else - Global::iPause |= 4; // włączenie pauzy, gdy nieaktywy + if( Global::bInactivePause ) // jeÅ›li ma być pauzowanie okna w tle + if( focus ) + Global::iPause &= ~4; // odpauzowanie, gdy jest na pierwszym planie + else + Global::iPause |= 4; // włączenie pauzy, gdy nieaktywy } #ifdef _WINDOWS +extern "C" +{ + GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window); +} + LONG CALLBACK unhandled_handler(::EXCEPTION_POINTERS* e); +LRESULT APIENTRY WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +extern HWND Hwnd; +extern WNDPROC BaseWindowProc; #endif int main(int argc, char *argv[]) @@ -106,11 +137,11 @@ int main(int argc, char *argv[]) Global::LoadIniFile("eu07.ini"); Global::InitKeys(); - // hunter-271211: ukrywanie konsoli - if (Global::iWriteLogEnabled & 2) - { + // hunter-271211: ukrywanie konsoli + if( Global::iWriteLogEnabled & 2 ) + { AllocConsole(); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN); + SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), FOREGROUND_GREEN ); } for (int i = 1; i < argc; i++) @@ -142,75 +173,85 @@ int main(int argc, char *argv[]) } } - // match requested video mode to current to allow for - // fullwindow creation when resolution is the same - GLFWmonitor *monitor = glfwGetPrimaryMonitor(); - const GLFWvidmode *vmode = glfwGetVideoMode(monitor); + // match requested video mode to current to allow for + // fullwindow creation when resolution is the same + GLFWmonitor *monitor = glfwGetPrimaryMonitor(); + const GLFWvidmode *vmode = glfwGetVideoMode(monitor); - glfwWindowHint(GLFW_RED_BITS, vmode->redBits); - glfwWindowHint(GLFW_GREEN_BITS, vmode->greenBits); - glfwWindowHint(GLFW_BLUE_BITS, vmode->blueBits); - glfwWindowHint(GLFW_REFRESH_RATE, vmode->refreshRate); + glfwWindowHint(GLFW_RED_BITS, vmode->redBits); + glfwWindowHint(GLFW_GREEN_BITS, vmode->greenBits); + glfwWindowHint(GLFW_BLUE_BITS, vmode->blueBits); + glfwWindowHint(GLFW_REFRESH_RATE, vmode->refreshRate); - glfwWindowHint(GLFW_SAMPLES, Global::iMultisampling); + glfwWindowHint(GLFW_AUTO_ICONIFY, GLFW_FALSE); + glfwWindowHint(GLFW_SAMPLES, 1 << Global::iMultisampling); - GLFWwindow *window = - glfwCreateWindow(Global::iWindowWidth, Global::iWindowHeight, - "EU07++NG", Global::bFullScreen ? monitor : nullptr, nullptr); - - if (!window) + if (Global::bFullScreen) { - std::cout << "failed to create window" << std::endl; - return -1; - } - glfwMakeContextCurrent(window); - glfwSwapInterval(1); //vsync - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); //capture cursor - glfwSetCursorPos(window, 0.0, 0.0); - glfwSetFramebufferSizeCallback(window, window_resize_callback); - glfwSetCursorPosCallback(window, cursor_pos_callback); - glfwSetKeyCallback(window, key_callback); - glfwSetWindowFocusCallback(window, focus_callback); + // match screen dimensions with selected monitor, for 'borderless window' in fullscreen mode + Global::iWindowWidth = vmode->width; + Global::iWindowHeight = vmode->height; + } + + GLFWwindow *window = + glfwCreateWindow( Global::iWindowWidth, Global::iWindowHeight, + "EU07++NG", Global::bFullScreen ? monitor : nullptr, nullptr ); + + if (!window) { - int width, height; - glfwGetFramebufferSize(window, &width, &height); - window_resize_callback(window, width, height); - } + std::cout << "failed to create window" << std::endl; + return -1; + } + glfwMakeContextCurrent(window); + glfwSwapInterval(Global::VSync ? 1 : 0); //vsync + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); //capture cursor + glfwSetCursorPos(window, 0.0, 0.0); + glfwSetFramebufferSizeCallback(window, window_resize_callback); + glfwSetCursorPosCallback(window, cursor_pos_callback); + glfwSetKeyCallback(window, key_callback); + glfwSetWindowFocusCallback(window, focus_callback); + { + int width, height; + glfwGetFramebufferSize(window, &width, &height); + window_resize_callback(window, width, height); + } - if (glewInit() != GLEW_OK) + if (glewInit() != GLEW_OK) { - std::cout << "failed to init GLEW" << std::endl; - return -1; - } + std::cout << "failed to init GLEW" << std::endl; + return -1; + } - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); +#ifdef _WINDOWS + // setup wrapper for base glfw window proc, to handle copydata messages + Hwnd = glfwGetWin32Window( window ); + BaseWindowProc = (WNDPROC)::SetWindowLongPtr( Hwnd, GWLP_WNDPROC, (LONG_PTR)WndProc ); + // switch off the topmost flag + ::SetWindowPos( Hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE ); +#endif - Global::pWorld = &World; // Ra: wskaźnik potrzebny do usuwania pojazdów - if (!World.Init(window)) + GfxRenderer.Init(); + + Global::pWorld = &World; // Ra: wskaźnik potrzebny do usuwania pojazdów + if (!World.Init(window)) { - std::cout << "failed to init TWorld" << std::endl; - return -1; - } + std::cout << "failed to init TWorld" << std::endl; + return -1; + } - GfxRenderer.Init(); Console *pConsole = new Console(); // Ra: nie wiem, czy ma to sens, ale jakoÅ› zainicjowac trzeba - if (!joyGetNumDevs()) - WriteLog("No joystick"); - if (Global::iModifyTGA < 0) - { // tylko modyfikacja TGA, bez uruchamiania symulacji + if( !joyGetNumDevs() ) + WriteLog( "No joystick" ); + if( Global::iModifyTGA < 0 ) { // tylko modyfikacja TGA, bez uruchamiania symulacji Global::iMaxTextureSize = 64; //żeby nie zamulać pamiÄ™ci World.ModifyTGA(); // rekurencyjne przeglÄ…danie katalogów } - else - { - if (Global::iConvertModels < 0) - { + else { + if( Global::iConvertModels < 0 ) { Global::iConvertModels = -Global::iConvertModels; - World.CreateE3D("models\\"); // rekurencyjne przeglÄ…danie katalogów - World.CreateE3D("dynamic\\", true); + World.CreateE3D( "models\\" ); // rekurencyjne przeglÄ…danie katalogów + World.CreateE3D( "dynamic\\", true ); } // po zrobieniu E3D odpalamy normalnie sceneriÄ™, by jÄ… zobaczyć Console::On(); // włączenie konsoli @@ -222,8 +263,8 @@ int main(int argc, char *argv[]) Console::Off(); // wyłączenie konsoli (komunikacji zwrotnej) } - delete pConsole; TPythonInterpreter::killInstance(); + delete pConsole; glfwDestroyWindow(window); glfwTerminate(); diff --git a/Globals.cpp b/Globals.cpp index 341028b9..879847b9 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -123,6 +123,7 @@ int Global::iFeedbackMode = 1; // tryb pracy informacji zwrotnej int Global::iFeedbackPort = 0; // dodatkowy adres dla informacji zwrotnych bool Global::bFreeFly = false; bool Global::bFullScreen = false; +bool Global::VSync{ true }; bool Global::bInactivePause = true; // automatyczna pauza, gdy okno nieaktywne float Global::fMouseXScale = 1.5f; float Global::fMouseYScale = 0.2f; @@ -306,15 +307,18 @@ void Global::ConfigParse(cParser &Parser) { Parser.getTokens(); - Parser >> token; - Global::bFullScreen = (token == "yes"); + Parser >> Global::bFullScreen; + } + else if( token == "vsync" ) { + + Parser.getTokens(); + Parser >> Global::VSync; } else if (token == "freefly") { // Mczapkie-130302 Parser.getTokens(); - Parser >> token; - Global::bFreeFly = (token == "yes"); + Parser >> Global::bFreeFly; Parser.getTokens(3, false); Parser >> Global::pFreeCameraInit[0].x, Global::pFreeCameraInit[0].y, Global::pFreeCameraInit[0].z; @@ -323,23 +327,20 @@ void Global::ConfigParse(cParser &Parser) { Parser.getTokens(); - Parser >> token; - Global::bWireFrame = (token == "yes"); + Parser >> Global::bWireFrame; } else if (token == "debugmode") { // McZapkie! - DebugModeFlag uzywana w mover.pas, // warto tez blokowac cheaty gdy false Parser.getTokens(); - Parser >> token; - DebugModeFlag = (token == "yes"); + Parser >> DebugModeFlag; } else if (token == "soundenabled") { // McZapkie-040302 - blokada dzwieku - przyda // sie do debugowania oraz na komp. bez karty // dzw. Parser.getTokens(); - Parser >> token; - Global::bSoundEnabled = (token == "yes"); + Parser >> Global::bSoundEnabled; } // else if (str==AnsiString("renderalpha")) //McZapkie-1312302 - dwuprzebiegowe renderowanie // bRenderAlpha=(GetNextSymbol().LowerCase()==AnsiString("yes")); @@ -347,15 +348,13 @@ void Global::ConfigParse(cParser &Parser) { // McZapkie-030402 - logowanie parametrow // fizycznych dla kazdego pojazdu z maszynista Parser.getTokens(); - Parser >> token; - WriteLogFlag = (token == "yes"); + Parser >> WriteLogFlag; } else if (token == "physicsdeactivation") { // McZapkie-291103 - usypianie fizyki Parser.getTokens(); - Parser >> token; - PhysicActivationFlag = (token == "yes"); + Parser >> PhysicActivationFlag; } else if (token == "debuglog") { @@ -379,8 +378,7 @@ void Global::ConfigParse(cParser &Parser) { // McZapkie-240403 - czestotliwosc odswiezania ekranu Parser.getTokens(); - Parser >> token; - Global::bAdjustScreenFreq = (token == "yes"); + Parser >> Global::bAdjustScreenFreq; } else if (token == "mousescale") { @@ -392,15 +390,13 @@ void Global::ConfigParse(cParser &Parser) { // Winger 040204 - 'zywe' patyki dostosowujace sie do trakcji; Ra 2014-03: teraz Å‚amanie Parser.getTokens(); - Parser >> token; - Global::bEnableTraction = (token == "yes"); + Parser >> Global::bEnableTraction; } else if (token == "loadtraction") { // Winger 140404 - ladowanie sie trakcji Parser.getTokens(); - Parser >> token; - Global::bLoadTraction = (token == "yes"); + Parser >> Global::bLoadTraction; } else if (token == "friction") { // mnożnik tarcia - KURS90 @@ -413,8 +409,7 @@ void Global::ConfigParse(cParser &Parser) // Winger 160404 - zaleznosc napiecia loka od trakcji; // Ra 2014-03: teraz prÄ…d przy braku sieci Parser.getTokens(); - Parser >> token; - Global::bLiveTraction = (token == "yes"); + Parser >> Global::bLiveTraction; } else if (token == "skyenabled") { @@ -427,15 +422,13 @@ void Global::ConfigParse(cParser &Parser) { Parser.getTokens(); - Parser >> token; - Global::bManageNodes = (token == "yes"); + Parser >> Global::bManageNodes; } else if (token == "decompressdds") { Parser.getTokens(); - Parser >> token; - Global::bDecompressDDS = (token == "yes"); + Parser >> Global::bDecompressDDS; } else if (token == "defaultext") { @@ -458,8 +451,7 @@ void Global::ConfigParse(cParser &Parser) { Parser.getTokens(); - Parser >> token; - Global::bnewAirCouplers = (token == "yes"); + Parser >> Global::bnewAirCouplers; } else if (token == "defaultfiltering") { @@ -495,7 +487,10 @@ void Global::ConfigParse(cParser &Parser) Parser.getTokens(); Parser >> token; +/* Global::bUseVBO = (token == "yes"); +*/ + Global::bUseVBO = false; // temporarily disabled until render paths are sorted out } else if (token == "feedbackmode") { @@ -562,8 +557,7 @@ void Global::ConfigParse(cParser &Parser) { // podwójna jasność ambient Parser.getTokens(); - Parser >> token; - Global::bDoubleAmbient = (token == "yes"); + Parser >> Global::bDoubleAmbient; } else if (token == "movelight") { @@ -589,8 +583,7 @@ void Global::ConfigParse(cParser &Parser) { // podwójna jasność ambient Parser.getTokens(); - Parser >> token; - Global::bSmoothTraction = (token == "yes"); + Parser >> Global::bSmoothTraction; } else if (token == "timespeed") { @@ -608,8 +601,7 @@ void Global::ConfigParse(cParser &Parser) { // tekst generowany przez GLUT Parser.getTokens(); - Parser >> token; - Global::bGlutFont = (token == "yes"); + Parser >> Global::bGlutFont; } else if (token == "latitude") { @@ -627,8 +619,7 @@ void Global::ConfigParse(cParser &Parser) { // automatyczna pauza, gdy okno nieaktywne Parser.getTokens(); - Parser >> token; - Global::bInactivePause = (token == "yes"); + Parser >> Global::bInactivePause; } else if (token == "slowmotion") { @@ -646,22 +637,19 @@ void Global::ConfigParse(cParser &Parser) { // hunter-271211: ukrywanie konsoli Parser.getTokens(); - Parser >> token; - Global::bHideConsole = (token == "yes"); + Parser >> Global::bHideConsole; } else if (token == "oldsmudge") { Parser.getTokens(); - Parser >> token; - Global::bOldSmudge = (token == "yes"); + Parser >> Global::bOldSmudge; } else if (token == "rollfix") { // Ra: poprawianie przechyÅ‚ki, aby wewnÄ™trzna szyna byÅ‚a "pozioma" Parser.getTokens(); - Parser >> token; - Global::bRollFix = (token == "yes"); + Parser >> Global::bRollFix; } else if (token == "fpsaverage") { @@ -786,8 +774,7 @@ void Global::ConfigParse(cParser &Parser) { // czy grupować eventy o tych samych nazwach Parser.getTokens(); - Parser >> token; - Global::bJoinEvents = (token == "yes"); + Parser >> Global::bJoinEvents; } else if (token == "hiddenevents") { @@ -832,14 +819,12 @@ void Global::ConfigParse(cParser &Parser) // maciek001: ustawienia MWD else if (token == "mwdmasterenable") { // główne włączenie maszyny! Parser.getTokens(); - Parser >> token; - bMWDmasterEnable = (token == "yes"); + Parser >> bMWDmasterEnable; if (bMWDdebugEnable) WriteLog("SerialPort Master Enable"); } else if (token == "mwddebugenable") { // logowanie pracy Parser.getTokens(); - Parser >> token; - bMWDdebugEnable = (token == "yes"); + Parser >> bMWDdebugEnable; if (bMWDdebugEnable) WriteLog("MWD Debug Mode On"); } else if (token == "mwddebugmode") { // co ma być debugowane? @@ -859,14 +844,12 @@ void Global::ConfigParse(cParser &Parser) } else if (token == "mwdinputenable") { // włącz wejÅ›cia Parser.getTokens(); - Parser >> token; - bMWDInputEnable = (token == "yes"); + Parser >> bMWDInputEnable; if (bMWDdebugEnable && bMWDInputEnable) WriteLog("MWD Input Enable"); } else if (token == "mwdbreakenable") { // włącz obsÅ‚ugÄ™ hamulców Parser.getTokens(); - Parser >> token; - bMWDBreakEnable = (token == "yes"); + Parser >> bMWDBreakEnable; if (bMWDdebugEnable && bMWDBreakEnable) WriteLog("MWD Break Enable"); } else if (token == "mwdmainbreakconfig") { // ustawienia hamulca zespolonego @@ -1063,6 +1046,7 @@ void Global::InitKeys() Keys[k_Univ3] = ';'; Keys[k_Univ4] = '\''; } + /* vector3 Global::GetCameraPosition() { diff --git a/Globals.h b/Globals.h index 3fe324cc..ef8cb146 100644 --- a/Globals.h +++ b/Globals.h @@ -177,6 +177,7 @@ class Global static float fDistanceFactor; static int iBpp; static bool bFullScreen; + static bool VSync; static bool bFreeFly; // float RunningTime; static bool bWireFrame; diff --git a/Ground.cpp b/Ground.cpp index b1f5227b..236d7ac6 100644 --- a/Ground.cpp +++ b/Ground.cpp @@ -16,8 +16,6 @@ http://mozilla.org/MPL/2.0/. #include "stdafx.h" #include "Ground.h" -#include "GL/glew.h" - #include "Globals.h" #include "Logs.h" #include "usefull.h" @@ -42,6 +40,11 @@ http://mozilla.org/MPL/2.0/. #define _PROBLEND 1 //--------------------------------------------------------------------------- +extern "C" +{ + GLFWAPI HWND glfwGetWin32Window( GLFWwindow* window ); //m7todo: potrzebne do directsound +} + bool bCondition; // McZapkie: do testowania warunku na event multiple string LogComment; @@ -2499,11 +2502,11 @@ void TGround::FirstInit() WriteLog("FirstInit is done"); }; -bool TGround::Init(std::string asFile) +bool TGround::Init(std::string File) { // główne wczytywanie scenerii - if (ToLower(asFile).substr(0, 7) == "scenery") - asFile = asFile.erase(0, 8); // Ra: usuniÄ™cie niepotrzebnych znaków - zgodność wstecz z 2003 - WriteLog("Loading scenery from " + asFile); + if (ToLower(File).substr(0, 7) == "scenery") + File = File.erase(0, 8); // Ra: usuniÄ™cie niepotrzebnych znaków - zgodność wstecz z 2003 + WriteLog("Loading scenery from " + File); Global::pGround = this; // pTrain=NULL; pOrigin = aRotate = vector3(0, 0, 0); // zerowanie przesuniÄ™cia i obrotu @@ -2511,7 +2514,7 @@ bool TGround::Init(std::string asFile) // TFileStream *fs; // int size; std::string subpath = Global::asCurrentSceneryPath; // "scenery/"; - cParser parser(asFile, cParser::buffer_FILE, subpath, Global::bLoadTraction); + cParser parser(File, cParser::buffer_FILE, subpath, Global::bLoadTraction); std::string token; /* @@ -5021,6 +5024,7 @@ bool TGround::RenderAlphaVBO(vector3 pPosition) return true; }; +#ifdef _WINDOWS //--------------------------------------------------------------------------- void TGround::Navigate(std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam) { // wysÅ‚anie komunikatu do sterujÄ…cego @@ -5044,8 +5048,7 @@ void TGround::WyslijEvent(const std::string &e, const std::string &d) cData.dwData = 'EU07'; // sygnatura cData.cbData = (DWORD)(12 + i + j); // 8+dwa liczniki i dwa zera koÅ„czÄ…ce cData.lpData = &r; - //m7todo - //Navigate("TEU07SRK", WM_COPYDATA, (WPARAM)Global::hWnd, (LPARAM)&cData); + Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Global::window ), (LPARAM)&cData ); CommLog( Now() + " " + std::to_string(r.iComm) + " " + e + " sent" ); }; //--------------------------------------------------------------------------- @@ -5062,8 +5065,7 @@ void TGround::WyslijUszkodzenia(const std::string &t, char fl) cData.dwData = 'EU07'; // sygnatura cData.cbData = (DWORD)(11 + i); // 8+licznik i zero koÅ„czÄ…ce cData.lpData = &r; - //m7todo - //Navigate("TEU07SRK", WM_COPYDATA, (WPARAM)Global::hWnd, (LPARAM)&cData); + Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Global::window ), (LPARAM)&cData ); CommLog( Now() + " " + std::to_string(r.iComm) + " " + t + " sent"); }; //--------------------------------------------------------------------------- @@ -5079,8 +5081,7 @@ void TGround::WyslijString(const std::string &t, int n) cData.dwData = 'EU07'; // sygnatura cData.cbData = (DWORD)(10 + i); // 8+licznik i zero koÅ„czÄ…ce cData.lpData = &r; - //m7todo - //Navigate("TEU07SRK", WM_COPYDATA, (WPARAM)Global::hWnd, (LPARAM)&cData); + Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Global::window ), (LPARAM)&cData ); CommLog( Now() + " " + std::to_string(r.iComm) + " " + t + " sent"); }; //--------------------------------------------------------------------------- @@ -5160,8 +5161,7 @@ void TGround::WyslijNamiary(TGroundNode *t) cData.cbData = (DWORD)(10 + i + j); // 8+licznik i zero koÅ„czÄ…ce cData.lpData = &r; // WriteLog("Ramka gotowa"); - //m7todo - //Navigate("TEU07SRK", WM_COPYDATA, (WPARAM)Global::hWnd, (LPARAM)&cData); + Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Global::window ), (LPARAM)&cData ); // WriteLog("Ramka poszla!"); CommLog( Now() + " " + std::to_string(r.iComm) + " " + t->asName + " sent"); }; @@ -5204,8 +5204,7 @@ void TGround::WyslijObsadzone() cData.cbData = 8 + 1984; // 8+licznik i zero koÅ„czÄ…ce cData.lpData = &r; // WriteLog("Ramka gotowa"); - //m7todo - //Navigate("TEU07SRK", WM_COPYDATA, (WPARAM)Global::hWnd, (LPARAM)&cData); + Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Global::window ), (LPARAM)&cData ); CommLog( Now() + " " + std::to_string(r.iComm) + " obsadzone" + " sent"); } @@ -5229,9 +5228,10 @@ void TGround::WyslijParam(int nr, int fl) cData.dwData = 'EU07'; // sygnatura cData.cbData = 12 + i; // 12+rozmiar danych cData.lpData = &r; - //m7todo - //Navigate("TEU07SRK", WM_COPYDATA, (WPARAM)Global::hWnd, (LPARAM)&cData); + Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Global::window ), (LPARAM)&cData ); }; +#endif + //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- diff --git a/Ground.h b/Ground.h index 6ce96bf6..57fa0d82 100644 --- a/Ground.h +++ b/Ground.h @@ -323,7 +323,7 @@ class TGround TGround(); ~TGround(); void Free(); - bool Init(std::string asFile); + bool Init( std::string File ); void FirstInit(); void InitTracks(); void InitTraction(); diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 9cfb2398..09aa56cc 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -3005,98 +3005,105 @@ void TMoverParameters::UpdatePipePressure(double dt) // if (Hamulec is typeid(TWest)) return 0; - switch (BrakeValve) - { - case W: - { - if (BrakeLocHandle != NoHandle) + switch (BrakeValve) { + + case K: + case W: { + + if( BrakeLocHandle != NoHandle ) { + LocBrakePress = LocHandle->GetCP(); + + //(Hamulec as TWest).SetLBP(LocBrakePress); + Hamulec->SetLBP( LocBrakePress ); + } + if( MBPM < 2 ) + //(Hamulec as TWest).PLC(MaxBrakePress[LoadFlag]) + Hamulec->PLC( MaxBrakePress[ LoadFlag ] ); + else + //(Hamulec as TWest).PLC(TotalMass); + Hamulec->PLC( TotalMass ); + break; + } + + case LSt: + case EStED: { + + LocBrakePress = LocHandle->GetCP(); + for( int b = 0; b < 2; b++ ) + if( ( ( TrainType & ( dt_ET41 | dt_ET42 ) ) != 0 ) && + ( Couplers[ b ].Connected != NULL ) ) // nie podoba mi siÄ™ to rozwiÄ…zanie, chyba trzeba + // dodać jakiÅ› wpis do fizyki na to + if( ( ( Couplers[ b ].Connected->TrainType & ( dt_ET41 | dt_ET42 ) ) != 0 ) && + ( ( Couplers[ b ].CouplingFlag & 36 ) == 36 ) ) + LocBrakePress = Max0R( Couplers[ b ].Connected->LocHandle->GetCP(), LocBrakePress ); + + //if ((DynamicBrakeFlag) && (EngineType == ElectricInductionMotor)) + //{ + // //if (Vel > 10) + // // LocBrakePress = 0; + // //else if (Vel > 5) + // // LocBrakePress = (10 - Vel) / 5 * LocBrakePress; + //} + + //(Hamulec as TLSt).SetLBP(LocBrakePress); + Hamulec->SetLBP( LocBrakePress ); + if( ( BrakeValve == EStED ) ) + if( MBPM < 2 ) + Hamulec->PLC( MaxBrakePress[ LoadFlag ] ); + else + Hamulec->PLC( TotalMass ); + break; + } + + case CV1_L_TR: { LocBrakePress = LocHandle->GetCP(); - - //(Hamulec as TWest).SetLBP(LocBrakePress); - Hamulec->SetLBP(LocBrakePress); + //(Hamulec as TCV1L_TR).SetLBP(LocBrakePress); + Hamulec->SetLBP( LocBrakePress ); + break; } - if (MBPM < 2) - //(Hamulec as TWest).PLC(MaxBrakePress[LoadFlag]) - Hamulec->PLC(MaxBrakePress[LoadFlag]); - else - //(Hamulec as TWest).PLC(TotalMass); - Hamulec->PLC(TotalMass); - break; - } - case LSt: - case EStED: - { - LocBrakePress = LocHandle->GetCP(); - for (int b = 0; b < 2; b++) - if (((TrainType & (dt_ET41 | dt_ET42)) != 0) && - (Couplers[b].Connected != NULL)) // nie podoba mi siÄ™ to rozwiÄ…zanie, chyba trzeba - // dodać jakiÅ› wpis do fizyki na to - if (((Couplers[b].Connected->TrainType & (dt_ET41 | dt_ET42)) != 0) && - ((Couplers[b].CouplingFlag & 36) == 36)) - LocBrakePress = Max0R(Couplers[b].Connected->LocHandle->GetCP(), LocBrakePress); - - //if ((DynamicBrakeFlag) && (EngineType == ElectricInductionMotor)) - //{ - // //if (Vel > 10) - // // LocBrakePress = 0; - // //else if (Vel > 5) - // // LocBrakePress = (10 - Vel) / 5 * LocBrakePress; - //} - - //(Hamulec as TLSt).SetLBP(LocBrakePress); - Hamulec->SetLBP(LocBrakePress); - if ((BrakeValve == EStED)) - if (MBPM < 2) - Hamulec->PLC(MaxBrakePress[LoadFlag]); - else - Hamulec->PLC(TotalMass); - break; - } - - case CV1_L_TR: - { - LocBrakePress = LocHandle->GetCP(); - //(Hamulec as TCV1L_TR).SetLBP(LocBrakePress); - Hamulec->SetLBP(LocBrakePress); - break; - } - - case EP2: - { - Hamulec->PLC(TotalMass); - break; - } - case ESt3AL2: - case NESt3: - case ESt4: - case ESt3: - { - if (MBPM < 2) - //(Hamulec as TNESt3).PLC(MaxBrakePress[LoadFlag]) - Hamulec->PLC(MaxBrakePress[LoadFlag]); - else - //(Hamulec as TNESt3).PLC(TotalMass); - Hamulec->PLC(TotalMass); - LocBrakePress = LocHandle->GetCP(); - //(Hamulec as TNESt3).SetLBP(LocBrakePress); - Hamulec->SetLBP(LocBrakePress); - break; - } - case KE: - { - LocBrakePress = LocHandle->GetCP(); - //(Hamulec as TKE).SetLBP(LocBrakePress); - Hamulec->SetLBP(LocBrakePress); - if (MBPM < 2) - //(Hamulec as TKE).PLC(MaxBrakePress[LoadFlag]) - Hamulec->PLC(MaxBrakePress[LoadFlag]); - else - //(Hamulec as TKE).PLC(TotalMass); - Hamulec->PLC(TotalMass); - break; - } + case EP2: + { + Hamulec->PLC( TotalMass ); + break; + } + case ESt3AL2: + case NESt3: + case ESt4: + case ESt3: + { + if( MBPM < 2 ) + //(Hamulec as TNESt3).PLC(MaxBrakePress[LoadFlag]) + Hamulec->PLC( MaxBrakePress[ LoadFlag ] ); + else + //(Hamulec as TNESt3).PLC(TotalMass); + Hamulec->PLC( TotalMass ); + LocBrakePress = LocHandle->GetCP(); + //(Hamulec as TNESt3).SetLBP(LocBrakePress); + Hamulec->SetLBP( LocBrakePress ); + break; + } + case KE: + { + LocBrakePress = LocHandle->GetCP(); + //(Hamulec as TKE).SetLBP(LocBrakePress); + Hamulec->SetLBP( LocBrakePress ); + if( MBPM < 2 ) + //(Hamulec as TKE).PLC(MaxBrakePress[LoadFlag]) + Hamulec->PLC( MaxBrakePress[ LoadFlag ] ); + else + //(Hamulec as TKE).PLC(TotalMass); + Hamulec->PLC( TotalMass ); + break; + } + default: + { + // unsupported brake valve type, we should never land here +// ErrorLog( "Unsupported brake valve type (" + std::to_string( BrakeValve ) + ") in " + TypeName ); +// ::PostQuitMessage( 0 ); + break; + } } // switch if ((BrakeHandle == FVel6) && (ActiveCab != 0)) @@ -7252,8 +7259,8 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir) } if ( ( true == TestFlag( BrakeDelays, bdelay_G ) ) - && ( false == TestFlag(BrakeDelays, bdelay_R) ) - || ( Power > 1.0 ) ) // ustalanie srednicy przewodu glownego (lokomotywa lub napÄ™dowy + && ( ( false == TestFlag(BrakeDelays, bdelay_R ) ) + || ( Power > 1.0 ) ) ) // ustalanie srednicy przewodu glownego (lokomotywa lub napÄ™dowy Spg = 0.792; else Spg = 0.507; diff --git a/Model3d.cpp b/Model3d.cpp index d006bd17..4f894ef2 100644 --- a/Model3d.cpp +++ b/Model3d.cpp @@ -1800,7 +1800,7 @@ void TModel3d::SaveToBinFile(char const *FileName) Root->RaArrayFill(m_pVNT); sn_utils::ls_uint32(s, MAKE_ID4('V', 'N', 'T', '0')); sn_utils::ls_uint32(s, 8 + iNumVerts * 32); - for (size_t i = 0; i < iNumVerts; i++) + for (size_t i = 0; i < (size_t)iNumVerts; i++) m_pVNT[i].serialize(s); if (textures.size()) diff --git a/Segment.cpp b/Segment.cpp index 900d4380..85f67dc3 100644 --- a/Segment.cpp +++ b/Segment.cpp @@ -9,7 +9,6 @@ http://mozilla.org/MPL/2.0/. #include "stdafx.h" #include "Segment.h" -#include "GL/glew.h" #include "Globals.h" #include "Logs.h" diff --git a/Texture.cpp b/Texture.cpp index 55a47121..878c4f3d 100644 --- a/Texture.cpp +++ b/Texture.cpp @@ -703,6 +703,7 @@ texture_manager::GetTextureId( std::string Filename, std::string const &Dir, int if( true == filename.empty() ) { // there's nothing matching in the databank nor on the disk, report failure + ErrorLog( "Texture file missing: \"" + Filename + "\"" ); return npos; } diff --git a/Train.cpp b/Train.cpp index 6c21eaa7..1efc968a 100644 --- a/Train.cpp +++ b/Train.cpp @@ -671,7 +671,7 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || dsbSwitch->Play(0, 0, 0); // dźwiÄ™k tylko po naciÅ›niÄ™ciu klawisza } } - else if (cKey == VkKeyScan('q')) // ze Shiftem - włączenie AI + else if (cKey == GLFW_KEY_Q) // ze Shiftem - włączenie AI { // McZapkie-240302 - wlaczanie automatycznego pilota (zadziala tylko w // trybie debugmode) if (DynamicObject->Mechanik) @@ -1661,7 +1661,7 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || } // McZapkie-240302 - wylaczanie automatycznego pilota (w trybie ~debugmode // mozna tylko raz) - else if (cKey == VkKeyScan('q')) // bez Shift + else if (cKey == GLFW_KEY_Q) // bez Shift { if (DynamicObject->Mechanik) DynamicObject->Mechanik->TakeControl(false); @@ -2382,7 +2382,7 @@ if { // McZapkie: poruszanie sie po kabinie, w updatemechpos zawarte sa wiezy - auto step = 60.0f * Timer::GetDeltaTime(); + auto step = 1.5f; auto const camerayaw = Global::pCamera->Yaw; Math3D::vector3 direction( 0.0f, 0.0f, step ); direction.RotateY( camerayaw ); @@ -2396,7 +2396,7 @@ if right *= -1.0f; } // if (!GetAsyncKeyState(VK_SHIFT)<0) // bez shifta - if (!(Global::ctrlState)) // gdy [Ctrl] zwolniony (dodatkowe widoki) + if (!Global::ctrlState) // gdy [Ctrl] zwolniony (dodatkowe widoki) { if (cKey == Global::Keys[k_MechLeft]) { @@ -2441,7 +2441,7 @@ if if (DebugModeFlag) { // przesuwanie skÅ‚adu o 100m TDynamicObject *d = DynamicObject; - if (cKey == VkKeyScan('[')) + if (cKey == GLFW_KEY_LEFT_BRACKET) { while (d) { @@ -2455,7 +2455,7 @@ if d = d->Prev(); // w drugÄ… stronÄ™ też } } - else if (cKey == VkKeyScan(']')) + else if (cKey == GLFW_KEY_RIGHT_BRACKET) { while (d) { @@ -2470,12 +2470,12 @@ if } } } - if (cKey == VkKeyScan('-')) + if (cKey == GLFW_KEY_MINUS) { // zmniejszenie numeru kanaÅ‚u radiowego if (iRadioChannel > 0) --iRadioChannel; // 0=wyłączony } - else if (cKey == VkKeyScan('=')) + else if (cKey == GLFW_KEY_EQUAL) { // zmniejszenie numeru kanaÅ‚u radiowego if (iRadioChannel < 8) ++iRadioChannel; // 0=wyłączony @@ -2546,6 +2546,7 @@ void TTrain::UpdateMechPosition(double dt) // shake *= 1.25; } vMechVelocity -= (shake + vMechVelocity * 100) * (fMechSpringX + fMechSpringY + fMechSpringZ) / (200); +// vMechVelocity -= vMechVelocity * iVel * dt; // shake *= 0.95 * dt; // shake damping // McZapkie: @@ -2556,15 +2557,15 @@ void TTrain::UpdateMechPosition(double dt) vMechVelocity.y = -vMechVelocity.y; // ABu011104: 5*pMechShake.y, zeby ladnie pudlem rzucalo :) pNewMechPosition = pMechOffset + vector3(1.5 * pMechShake.x, 2.0 * pMechShake.y, 1.5 * pMechShake.z); - vMechMovement = 0.5 * vMechMovement; +// vMechMovement = 0.5 * vMechMovement; } else { // hamowanie rzucania przy spadku FPS pMechShake -= pMechShake * std::min(dt, 1.0); // po tym chyba potrafiÄ… zostać jakieÅ› uÅ‚amki, które powodujÄ… zjazd pMechOffset += vMechMovement * dt; - vMechVelocity.y = 0.5 * vMechVelocity.y; + vMechVelocity.y -= vMechVelocity.y * 50.0 * dt; pNewMechPosition = pMechOffset + vector3(pMechShake.x, 5 * pMechShake.y, pMechShake.z); - vMechMovement = 0.5 * vMechMovement; +// vMechMovement = 0.5 * vMechMovement; } // numer kabiny (-1: kabina B) if (DynamicObject->Mechanik) // może nie być? @@ -2611,6 +2612,21 @@ void TTrain::UpdateMechPosition(double dt) pMechPosition = DynamicObject->mMatrix * pNewMechPosition; // poÅ‚ożenie wzglÄ™dem Å›rodka pojazdu w ukÅ‚adzie scenerii pMechPosition += DynamicObject->GetPosition(); + + // framerate-independent speed reduction that doesn't break at high framerates... + Math3D::vector3 movementslowdown = vMechMovement * 35 * dt; + if( movementslowdown.LengthSquared() >= vMechMovement.LengthSquared() ) { + // if the reduction vector exceeds speed movement we're running at low fps, + // fallback on the old behaviour + vMechMovement *= 0.5; + } + else { + vMechMovement -= movementslowdown; + if( vMechMovement.LengthSquared() < 0.01 ) { + vMechMovement = Math3D::vector3(); + } + } + }; bool TTrain::Update( double const Deltatime ) @@ -5039,10 +5055,10 @@ bool TTrain::Update( double const Deltatime ) //Å›wiatÅ‚o wewnÄ™trzne przygaszone (255 216 176) if( mvOccupied->ConverterFlag == true ) { // jasnosc dla zalaczonej przetwornicy - DynamicObject->InteriorLightLevel = 0.75f; + DynamicObject->InteriorLightLevel = 0.4f; } else { - DynamicObject->InteriorLightLevel = 0.375f; + DynamicObject->InteriorLightLevel = 0.2f; } break; } diff --git a/TrkFoll.h b/TrkFoll.h index 5400e935..5723ccb1 100644 --- a/TrkFoll.h +++ b/TrkFoll.h @@ -34,7 +34,7 @@ class TTrackFollower ~TTrackFollower(); TTrack * SetCurrentTrack(TTrack *pTrack, int end); bool Move(double fDistance, bool bPrimary); - inline TTrack * GetTrack() + inline TTrack * GetTrack() const { return pCurrentTrack; }; @@ -43,7 +43,7 @@ class TTrackFollower return vAngles.x; }; // przechyÅ‚ka policzona przy ustalaniu pozycji //{return pCurrentSegment->GetRoll(fCurrentDistance)*fDirection;}; //zamiast liczyć można pobrać - inline double GetDirection() + inline double GetDirection() const { return fDirection; }; // zwrot na torze diff --git a/World.cpp b/World.cpp index 3ec2d46a..183068ea 100644 --- a/World.cpp +++ b/World.cpp @@ -90,22 +90,22 @@ void TWorld::TrainDelete(TDynamicObject *d) Global::pUserDynamic = NULL; // tego też nie ma }; -GLvoid TWorld::glPrint(const char *txt) // custom GL "Print" routine +GLvoid TWorld::glPrint( std::string const &Text ) // custom GL "Print" routine { // wypisywanie tekstu 2D na ekranie - //m7todo - if (!txt) + if (Text.empty()) return; + if (Global::bGlutFont) { // tekst generowany przez GLUT - size_t i, len = strlen(txt); - for (i = 0; i < len; i++) - glutBitmapCharacter(GLUT_BITMAP_8_BY_13, txt[i]); + for (size_t i = 0; i < Text.size(); i++) + glutBitmapCharacter(GLUT_BITMAP_8_BY_13, Text[i]); } else + { // generowanie przez Display Lists glPushAttrib(GL_LIST_BIT); // pushes the display list bits glListBase(base - 32); // sets the base character to 32 - glCallLists((GLsizei)strlen(txt), GL_UNSIGNED_BYTE, txt); // draws the display list text + glCallLists((GLsizei)Text.size(), GL_UNSIGNED_BYTE, Text.c_str()); // draws the display list text glPopAttrib(); // pops the display list bits } } @@ -257,7 +257,7 @@ bool TWorld::Init(GLFWwindow *w) glLoadIdentity(); glClearDepth( 1.0f ); // ZBuffer Value - glClearColor( 51.0f / 255.0f, 106.0f / 255.0f, 85.0f / 255.0f, 1.0f ); // Background Color + glClearColor( 51.0f / 255.0f, 102.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 glEnable(GL_TEXTURE_2D); // Enable Texture Mapping @@ -407,73 +407,46 @@ bool TWorld::Init(GLFWwindow *w) glTexCoord2f(0.0f, 1.0f); 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 * widthratio, -0.25f); - glPrint("Uruchamianie / Initializing..."); - glRasterPos2f(-0.85f * widthratio, -0.30f); - glPrint("Dzwiek / Sound..."); - } - glfwSwapBuffers(window); + + glColor3f(0.0f, 0.0f, 0.0f); + glRasterPos2f(-0.85f * widthratio, -0.25f); + glPrint("Uruchamianie / Initializing..."); + glfwSwapBuffers( window ); + /*-----------------------Sound Initialization-----------------------*/ + glRasterPos2f( -0.85f * widthratio, -0.30f ); + glPrint( "Dzwiek / Sound..." ); - TSoundsManager::Init(glfwGetWin32Window(window)); - - // TSoundsManager::LoadSounds( "" ); - /*---------------------Sound Initialization End---------------------*/ + TSoundsManager::Init( glfwGetWin32Window( window ) ); WriteLog("Sound Init OK"); - if (Global::detonatoryOK) - { - glRasterPos2f(-0.25f * widthratio, -0.30f); - glPrint("OK."); - } - - glfwSwapBuffers(window); + glRasterPos2f(-0.25f * widthratio, -0.30f); + glPrint("OK."); + glfwSwapBuffers( window ); + /*---------------------Sound Initialization End---------------------*/ - Paused = true; WriteLog("Textures init"); - if (Global::detonatoryOK) - { - glRasterPos2f(-0.85f * widthratio, -0.35f); - glPrint("Tekstury / Textures..."); - } - glfwSwapBuffers(window); - + glRasterPos2f(-0.85f * widthratio, -0.35f); + glPrint("Tekstury / Textures..."); + glfwSwapBuffers( window ); WriteLog("Textures init OK"); - if (Global::detonatoryOK) - { - glRasterPos2f( -0.25f * widthratio, -0.35f ); - glPrint("OK."); - } - glfwSwapBuffers(window); + glRasterPos2f( -0.25f * widthratio, -0.35f ); + glPrint("OK."); + glfwSwapBuffers( window ); WriteLog("Models init"); - if (Global::detonatoryOK) - { - glRasterPos2f( -0.85f * widthratio, -0.40f ); - glPrint("Modele / Models..."); - } - glfwSwapBuffers(window); - // McZapkie: dodalem sciezke zeby mozna bylo definiowac skad brac modele ale to malo eleganckie - // TModelsManager::LoadModels(asModelsPatch); + glRasterPos2f( -0.85f * widthratio, -0.40f ); + glPrint("Modele / Models..."); + glfwSwapBuffers( window ); TModelsManager::Init(); WriteLog("Models init OK"); - if (Global::detonatoryOK) - { - glRasterPos2f( -0.25f * widthratio, -0.40f ); - glPrint("OK."); - } - glfwSwapBuffers(window); + glRasterPos2f( -0.25f * widthratio, -0.40f ); + glPrint("OK."); + glfwSwapBuffers( window ); WriteLog("Ground init"); - if (Global::detonatoryOK) - { - glRasterPos2f( -0.85f * widthratio, -0.45f ); - glPrint("Sceneria / Scenery (please wait)..."); - } - glfwSwapBuffers(window); + glRasterPos2f( -0.85f * widthratio, -0.45f ); + glPrint("Sceneria / Scenery (please wait)..."); + glfwSwapBuffers( window ); #ifndef EU07_USE_OLD_LIGHTING_MODEL // setup lighting @@ -496,12 +469,10 @@ bool TWorld::Init(GLFWwindow *w) // Global::tSinceStart= 0; Environment.init(); WriteLog("Ground init OK"); - if (Global::detonatoryOK) - { - glRasterPos2f( -0.25f * widthratio, -0.45f ); - glPrint("OK."); - } - glfwSwapBuffers(window); + glRasterPos2f( -0.25f * widthratio, -0.45f ); + glColor3f( 0.0f, 0.0f, 0.0f ); + glPrint( "OK." ); + glfwSwapBuffers( window ); // TTrack *Track=Ground.FindGroundNode("train_start",TP_TRACK)->pTrack; @@ -513,12 +484,10 @@ bool TWorld::Init(GLFWwindow *w) Camera.Init(Global::pFreeCameraInit[0], Global::pFreeCameraInitAngle[0]); char buff[255] = "Player train init: "; - if (Global::detonatoryOK) - { - glRasterPos2f( -0.85f * widthratio, -0.50f ); - glPrint("Przygotowanie kabiny do sterowania..."); - } - glfwSwapBuffers(window); + glRasterPos2f( -0.85f * widthratio, -0.50f ); + glColor3f( 0.0f, 0.0f, 0.0f ); + glPrint( "Przygotowanie kabiny do sterowania..." ); + glfwSwapBuffers( window ); strcat(buff, Global::asHumanCtrlVehicle.c_str()); WriteLog(buff); @@ -534,11 +503,9 @@ bool TWorld::Init(GLFWwindow *w) mvControlled = Controlled->ControlledFind()->MoverParameters; Global::pUserDynamic = Controlled; // renerowanie pojazdu wzglÄ™dem kabiny WriteLog("Player train init OK"); - if (Global::detonatoryOK) - { - glRasterPos2f( -0.25f * widthratio, -0.50f ); - glPrint("OK."); - } + glRasterPos2f( -0.25f * widthratio, -0.50f ); + glColor3f( 0.0f, 0.0f, 0.0f ); + glPrint( "OK." ); FollowView(); glfwSwapBuffers(window); } @@ -546,12 +513,10 @@ bool TWorld::Init(GLFWwindow *w) { Error("Player train init failed!"); FreeFlyModeFlag = true; // Ra: automatycznie włączone latanie - if (Global::detonatoryOK) - { - glRasterPos2f( -0.85f * widthratio, -0.50f ); - glPrint("Blad inicjalizacji sterowanego pojazdu!"); - } - glfwSwapBuffers(window); + glRasterPos2f( -0.85f * widthratio, -0.50f ); + glColor3f( 0.0f, 0.0f, 0.0f ); + glPrint( "Blad inicjalizacji sterowanego pojazdu!" ); + glfwSwapBuffers( window ); Controlled = NULL; mvControlled = NULL; Camera.Type = tp_Free; @@ -562,11 +527,9 @@ bool TWorld::Init(GLFWwindow *w) if (Global::asHumanCtrlVehicle != "ghostview") { Error("Player train not exist!"); - if (Global::detonatoryOK) - { - glRasterPos2f( -0.85f * widthratio, -0.55f ); - glPrint("Wybrany pojazd nie istnieje w scenerii!"); - } + glRasterPos2f( -0.85f * widthratio, -0.55f ); + glColor3f( 0.0f, 0.0f, 0.0f ); + glPrint( "Wybrany pojazd nie istnieje w scenerii!" ); } FreeFlyModeFlag = true; // Ra: automatycznie włączone latanie glfwSwapBuffers(window); @@ -666,11 +629,11 @@ void TWorld::OnKeyDown(int cKey) case GLFW_KEY_F1: { if( DebugModeFlag ) { // additional time speedup keys in debug mode - if(Global::ctrlState) { + if (Global::ctrlState) { // ctrl-f3 GlobalTime->UpdateMTableTime( 20.0 * 60.0 ); } - else if(Global::shiftState) { + else if (Global::shiftState) { // shift-f3 GlobalTime->UpdateMTableTime( 5.0 * 60.0 ); } @@ -708,7 +671,8 @@ void TWorld::OnKeyDown(int cKey) break; } case GLFW_KEY_F4: { - InOutKey(); + + InOutKey( !Global::shiftState ); // distant view with Shift, short distance step out otherwise break; } case GLFW_KEY_F5: { @@ -721,7 +685,7 @@ void TWorld::OnKeyDown(int cKey) // przyspieszenie symulacji do testowania scenerii... uwaga na FPS! if( DebugModeFlag ) { - if( Global::ctrlState ) { Global::fTimeSpeed = (Global::shiftState ? 60.0 : 20.0 ); } + if( Global::ctrlState ) { Global::fTimeSpeed = ( Global::shiftState ? 60.0 : 20.0 ); } else { Global::fTimeSpeed = ( Global::shiftState ? 5.0 : 1.0 ); } } break; @@ -740,7 +704,7 @@ void TWorld::OnKeyDown(int cKey) if( Global::iTextMode == cKey ) { Global::iTextMode = ( Global::iPause && ( cKey != GLFW_KEY_F1 ) ? - GLFW_KEY_F1 : + GLFW_KEY_F1 : 0 ); // wyłączenie napisów, chyba że pauza } else { @@ -824,7 +788,7 @@ void TWorld::OnKeyDown(int cKey) if (temp) { if (Global::shiftState ? temp->MoverParameters->IncBrakeMult() : - temp->MoverParameters->DecBrakeMult()) + temp->MoverParameters->DecBrakeMult()) if (Train) { // dźwiÄ™k oczywiÅ›cie jest w kabinie Train->dsbSwitch->SetVolume(DSBVOLUME_MAX); @@ -925,7 +889,7 @@ void TWorld::OnMouseMove(double x, double y) Camera.OnCursorMove(x * Global::fMouseXScale / Global::ZoomFactor, -y * Global::fMouseYScale / Global::ZoomFactor); } -void TWorld::InOutKey() +void TWorld::InOutKey( bool const Near ) { // przełączenie widoku z kabiny na zewnÄ™trzny i odwrotnie FreeFlyModeFlag = !FreeFlyModeFlag; // zmiana widoku if (FreeFlyModeFlag) @@ -935,7 +899,7 @@ void TWorld::InOutKey() { // Train->Dynamic()->ABuSetModelShake(vector3(0,0,0)); Train->Silence(); // wyłączenie dźwiÄ™ków kabiny Train->Dynamic()->bDisplayCab = false; - DistantView(); + DistantView( Near ); } } else @@ -955,26 +919,39 @@ void TWorld::InOutKey() } }; -void TWorld::DistantView() +// places camera outside the controlled vehicle, or nearest if nothing is under control +// depending on provided switch the view is placed right outside, or at medium distance +void TWorld::DistantView( bool const Near ) { // ustawienie widoku pojazdu z zewnÄ…trz - if (Controlled) // jest pojazd do prowadzenia? - { // na prowadzony + + TDynamicObject const *vehicle{ nullptr }; + if( nullptr != Controlled ) { vehicle = Controlled; } + else if( nullptr != pDynamicNearest ) { vehicle = pDynamicNearest; } + else { return; } + + auto const cab = + ( vehicle->MoverParameters->ActiveCab == 0 ? + 1 : + vehicle->MoverParameters->ActiveCab ); + auto const left = vehicle->VectorLeft() * cab; + + if( true == Near ) { + Camera.Pos = - Controlled->GetPosition() + - (Controlled->MoverParameters->ActiveCab >= 0 ? 30 : -30) * Controlled->VectorFront() + - vector3(0, 5, 0); - Camera.LookAt = Controlled->GetPosition(); - Camera.RaLook(); // jednorazowe przestawienie kamery + vector3( Camera.Pos.x, vehicle->GetPosition().y, Camera.Pos.z ) + + left * vehicle->GetWidth() + + vector3( 1.25 * left.x, 1.6, 1.25 * left.z ); } - else if (pDynamicNearest) // jeÅ›li jest pojazd wykryty blisko - { // patrzenie na najbliższy pojazd - Camera.Pos = pDynamicNearest->GetPosition() + - (pDynamicNearest->MoverParameters->ActiveCab >= 0 ? 30 : -30) * - pDynamicNearest->VectorFront() + - vector3(0, 5, 0); - Camera.LookAt = pDynamicNearest->GetPosition(); - Camera.RaLook(); // jednorazowe przestawienie kamery + else { + + Camera.Pos = + vehicle->GetPosition() + + vehicle->VectorFront() * vehicle->MoverParameters->ActiveCab * 50.0 + + vector3( -10.0 * left.x, 1.6, -10.0 * left.z ); } + + Camera.LookAt = vehicle->GetPosition(); + Camera.RaLook(); // jednorazowe przestawienie kamery }; void TWorld::FollowView(bool wycisz) @@ -1130,20 +1107,7 @@ bool TWorld::Update() int n = int(iter); // ile kroków jako int fTimeBuffer -= iter * fMaxDt; // reszta czasu na potem (do bufora) if (n > 20) - n = 20; // Ra: jeżeli FPS jest zatrważajÄ…co niski, to fizyka nie może zająć caÅ‚kowicie -// procesora -#if 0 - Ground.UpdatePhys(fMaxDt,n); //Ra: teraz czas kroku jest (wzglÄ™dnie) staÅ‚y - if (DebugModeFlag) - if (Global::bActive) //nie przyspieszać, gdy jedzie w tle :) - if (GetAsyncKeyState(GLFW_KEY_ESCAPE)<0) - {//yB dodaÅ‚ przyspieszacz fizyki - Ground.UpdatePhys(fMaxDt,n); - Ground.UpdatePhys(fMaxDt,n); - Ground.UpdatePhys(fMaxDt,n); - Ground.UpdatePhys(fMaxDt,n); //w sumie 5 razy - } -#endif + n = 20; // Ra: jeżeli FPS jest zatrważajÄ…co niski, to fizyka nie może zająć caÅ‚kowicie procesora } // awaria PoKeys mogÅ‚a włączyć pauzÄ™ - przekazać informacjÄ™ if (Global::iMultiplayer) // dajemy znać do serwera o wykonaniu @@ -1216,7 +1180,7 @@ TWorld::Update_Camera( double const Deltatime ) { // Console::Update(); //tu jest zależne od FPS, co nie jest korzystne - if( glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS ) { + if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_LEFT ) == GLFW_PRESS ) { Camera.Reset(); // likwidacja obrotów - patrzy horyzontalnie na poÅ‚udnie // if (!FreeFlyModeFlag) //jeÅ›li wewnÄ…trz - patrzymy do tyÅ‚u // Camera.LookAt=Train->pMechPosition-Normalize(Train->GetDirection())*10; @@ -1242,14 +1206,14 @@ TWorld::Update_Camera( double const Deltatime ) if( FreeFlyModeFlag ) Camera.RaLook(); // jednorazowe przestawienie kamery } - else if(glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS) { //||Console::Pressed(VK_F4)) + else if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_RIGHT ) == GLFW_PRESS ) { //||Console::Pressed(VK_F4)) FollowView( false ); // bez wyciszania dźwiÄ™ków } - else if(glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS) { + else if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_MIDDLE ) == GLFW_PRESS ) { // middle mouse button controls zoom. - Global::ZoomFactor = std::min( 4.5f, Global::ZoomFactor + 15.0f * static_cast(Deltatime) ); + Global::ZoomFactor = std::min( 4.5f, Global::ZoomFactor + 15.0f * static_cast( Deltatime ) ); } - else if(glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE) != GLFW_PRESS) { + else if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_MIDDLE ) != GLFW_PRESS ) { // 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 ) ); @@ -1276,15 +1240,6 @@ TWorld::Update_Camera( double const Deltatime ) Console::Pressed( Global::Keys[ k_MechRight ] ) ) : false ) { // jeÅ›li lusterko lewe albo prawe (bez rzucania na razie) bool lr = Console::Pressed( Global::Keys[ k_MechLeft ] ); -#if 0 - Camera.Pos = Train->MirrorPosition( lr ); //robocza wartość - if( Controlled->MoverParameters->ActiveCab<0 ) lr = !lr; //w drugiej kabinie odwrotnie jest Å›rodek - Camera.LookAt = Controlled->GetPosition() + vector3( lr ? 2.0 : -2.0, Camera.Pos.y, 0 ); //trochÄ™ na zewnÄ…trz, użyć szerokoÅ›ci pojazdu - //Camera.LookAt=Train->pMechPosition+Train->GetDirection()*Train->Dynamic()->MoverParameters->ActiveCab; - Camera.Pos += Controlled->GetPosition(); - //Camera.RaLook(); //jednorazowe przestawienie kamery - Camera.Yaw = 0; //odchylenie na bok od Camera.LookAt -#else // Camera.Yaw powinno być wyzerowane, aby po powrocie patrzeć do przodu Camera.Pos = Controlled->GetPosition() + Train->MirrorPosition( lr ); // pozycja lusterka @@ -1305,7 +1260,6 @@ TWorld::Update_Camera( double const Deltatime ) Global::SetCameraRotation( M_PI - modelrotate ); // tu już trzeba uwzglÄ™dnić lusterka } -#endif Camera.Roll = atan( Train->pMechShake.x * Train->fMechRoll ); // hustanie kamery na boki Camera.Pitch = @@ -1463,7 +1417,7 @@ bool TWorld::Render() glMatrixMode( GL_PROJECTION ); // select the Projection Matrix glLoadIdentity(); // reset the Projection Matrix // calculate the aspect ratio of the window - gluPerspective( Global::FieldOfView / Global::ZoomFactor, (GLdouble)Global::ScreenWidth / (GLdouble)Global::ScreenHeight, 0.1f * Global::ZoomFactor, 2500.0f * Global::ZoomFactor ); + gluPerspective( Global::FieldOfView / Global::ZoomFactor, (GLdouble)Global::ScreenWidth / std::max((GLdouble)Global::ScreenHeight, 1.0), 0.1f * Global::ZoomFactor, 2500.0f * Global::ZoomFactor ); glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix glLoadIdentity(); @@ -1765,7 +1719,7 @@ TWorld::Render_UI() { 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 ); + gluPerspective( 45.0f, (GLdouble)Global::ScreenWidth / std::max((GLdouble)Global::ScreenHeight, 1.0), 0.2f, 2500.0f ); glMatrixMode( GL_MODELVIEW ); // Select The Modelview Matrix glLoadIdentity(); @@ -1931,7 +1885,7 @@ TWorld::Render_UI() { glTranslatef( 0.0f, 0.0f, -0.50f ); if( Global::iTextMode == GLFW_KEY_F1 ) { // tekst pokazywany po wciÅ›niÄ™ciu [F1] - // Global::iViewMode=GLFW_KEY_F1; + // Global::iViewMode=VK_F1; glColor3f( 1.0f, 1.0f, 1.0f ); // a, damy biaÅ‚ym OutText1 = "Time: " @@ -2291,7 +2245,7 @@ TWorld::Render_UI() { */ } else if( Global::iTextMode == GLFW_KEY_F10 ) { // tu mozna dodac dopisywanie do logu przebiegu lokomotywy - // Global::iViewMode=GLFW_KEY_F10; + // Global::iViewMode=VK_F10; // return false; OutText1 = ( "To quit press [Y] key." ); OutText3 = ( "Aby zakonczyc program, przycisnij klawisz [Y]." ); @@ -2488,9 +2442,9 @@ TWorld::Render_UI() { // ABu 150205: prosty help, zeby sie na forum nikt nie pytal, jak ma ruszyc :) if( Global::detonatoryOK ) { - // if (Console::Pressed(GLFW_KEY_F9)) ShowHints(); //to nie dziaÅ‚a prawidÅ‚owo - prosili wyłączyć + // if (Console::Pressed(VK_F9)) ShowHints(); //to nie dziaÅ‚a prawidÅ‚owo - prosili wyłączyć if( Global::iTextMode == GLFW_KEY_F9 ) { // informacja o wersji, sposobie wyÅ›wietlania i błędach OpenGL - // Global::iViewMode=GLFW_KEY_F9; + // Global::iViewMode=VK_F9; OutText1 = Global::asVersion; // informacja o wersji OutText2 = std::string( "Rendering mode: " ) + ( Global::bUseVBO ? "VBO" : "Display Lists" ); if( Global::iMultiplayer ) @@ -2974,6 +2928,8 @@ world_environment::update() { void world_environment::render() { + GfxRenderer.Bind( 0 ); + ::glDisable( GL_LIGHTING ); ::glDisable( GL_FOG ); ::glDisable( GL_DEPTH_TEST ); diff --git a/World.h b/World.h index 05bc89fb..7c750b13 100644 --- a/World.h +++ b/World.h @@ -18,6 +18,7 @@ http://mozilla.org/MPL/2.0/. #include "stars.h" #include "skydome.h" #include "mczapkie/mover.h" +#include "glfw/glfw3.h" // wrapper for environment elements -- sky, sun, stars, clouds etc class world_environment { @@ -36,14 +37,15 @@ private: class TWorld { - void InOutKey(); + void InOutKey( bool const Near = true ); void FollowView(bool wycisz = true); - void DistantView(); + void DistantView( bool const Near = false ); public: - bool Init(GLFWwindow *w); + bool Init( GLFWwindow *w ); + bool InitPerformed() { return m_init; } GLFWwindow *window; - GLvoid glPrint(const char *fmt); + GLvoid glPrint(std::string const &Text); void OnKeyDown(int cKey); void OnKeyUp(int cKey); // void UpdateWindow(); @@ -69,7 +71,7 @@ class TWorld world_environment Environment; TTrain *Train; TDynamicObject *pDynamicNearest; - bool Paused; + bool Paused{ true }; GLuint base; // numer DL dla znaków w napisach texture_manager::size_type light; // numer tekstury dla smugi TEvent *KeyEvents[10]; // eventy wyzwalane z klawiaury diff --git a/lightarray.cpp b/lightarray.cpp index 6ad61a7f..3ab1c448 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 ) { @@ -64,7 +65,24 @@ light_array::update() { ( ( 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 + if( light.count > 0 ) { + // TODO: intensity can be affected further by dim switch or other factors + light.intensity = std::max( 0.0f, std::log( (float)light.count + 1.0f ) ); +// light.intensity = std::max( 0.0f, std::log( (float)light.count + 3.0f ) ); + } + else { + light.intensity = 0.0f; + } + + // 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 diff --git a/renderer.cpp b/renderer.cpp index 2b38d068..246d577b 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -23,8 +23,8 @@ opengl_renderer::Init() { 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_SPOT_CUTOFF, 7.5f ); + ::glLightf( light.id, GL_SPOT_EXPONENT, 7.5f ); ::glLightf( light.id, GL_CONSTANT_ATTENUATION, 0.0f ); ::glLightf( light.id, GL_LINEAR_ATTENUATION, 0.035f ); @@ -66,7 +66,7 @@ opengl_renderer::Update_Lights( light_array const &Lights ) { 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 ) ); + ::glLightf( renderlight->id, GL_LINEAR_ATTENUATION, (0.25f * scenelight.count) / std::pow( scenelight.count, 2 ) ); ::glEnable( renderlight->id ); renderlight->apply_intensity(); @@ -85,9 +85,9 @@ opengl_renderer::Update_Lights( light_array const &Lights ) { void opengl_renderer::Disable_Lights() { - for( int idx = 0; idx < m_lights.size() + 1; ++idx ) { + for( size_t idx = 0; idx < m_lights.size() + 1; ++idx ) { - ::glDisable( GL_LIGHT0 + idx ); + ::glDisable( GL_LIGHT0 + (int)idx ); } } //--------------------------------------------------------------------------- diff --git a/skydome.cpp b/skydome.cpp index 560349d1..68a1f316 100644 --- a/skydome.cpp +++ b/skydome.cpp @@ -1,6 +1,5 @@ #include "stdafx.h" -#include "GL/glew.h" #include "skydome.h" #include "color.h" @@ -79,33 +78,45 @@ void CSkyDome::Generate() { 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; + int const latitudes = m_tesselation / 2 / 2; // half-sphere only int const longitudes = m_tesselation; - for( int i = 0; i < latitudes; ++i ) { + std::uint16_t index = 0; - float lat0 = M_PI * ( -0.5f + (float)( i ) / latitudes ); - float z0 = std::sin( lat0 ); - float zr0 = std::cos( lat0 ); + for( int i = 0; i <= latitudes; ++i ) { - float lat1 = M_PI * ( -0.5f + (float)( i + 1 ) / latitudes ); - float z1 = std::sin( lat1 ); - float zr1 = std::cos( lat1 ); + float const latitude = M_PI * ( -0.5f + (float)( i ) / latitudes / 2 ); // half-sphere only + float const z = std::sin( latitude ); + float const zr = std::cos( latitude ); - // quad strip - for( int j = 0; j <= longitudes / 2; ++j ) { + for( int j = 0; j <= longitudes; ++j ) { - float longitude = 2.0 * M_PI * (float)( j ) / longitudes; - float x = std::cos( longitude ); - float y = std::sin( longitude ); + float const longitude = 2.0 * M_PI * (float)( j ) / longitudes; + float const x = std::cos( longitude ); + float const y = std::sin( longitude ); +/* + m_vertices.emplace_back( float3( x * zr, y * zr - offset, z ) * radius ); + // we aren't using normals, but the code is left here in case it's ever needed +// m_normals.emplace_back( float3( x * zr, -y * zr, -z ) ); +*/ + // cartesian to opengl swap: -x, -z, -y + m_vertices.emplace_back( float3( -x * zr, -z - offset, -y * zr ) * radius ); + m_colours.emplace_back( float3( 0.75f, 0.75f, 0.75f ) ); // placeholder - 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 - offset, z1 ) * radius ); -// m_normals.emplace_back( float3( -x * zr1, -y * zr1, -z1 ) ); - m_colours.emplace_back( float3( 0.75f, 0.75f, 0.75f ) ); + if( (i == 0) || (j == 0) ) { + // initial edge of the dome, don't start indices yet + ++index; + } + else { + // indices for two triangles, formed between current and previous latitude + m_indices.emplace_back( index - 1 - (longitudes + 1) ); + m_indices.emplace_back( index - 1 ); + m_indices.emplace_back( index ); + m_indices.emplace_back( index ); + m_indices.emplace_back( index - ( longitudes + 1 ) ); + m_indices.emplace_back( index - 1 - ( longitudes + 1 ) ); + ++index; + } } } } @@ -123,26 +134,36 @@ void CSkyDome::Update( Math3D::vector3 const &Sun ) { // render skydome to screen void CSkyDome::Render() { - int const latitudes = m_tesselation / 2; - int const longitudes = m_tesselation; - int idx = 0; + if( m_vertexbuffer == -1 ) { + // build the buffers + ::glGenBuffers( 1, &m_vertexbuffer ); + ::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer ); + ::glBufferData( GL_ARRAY_BUFFER, m_vertices.size() * sizeof( float3 ), m_vertices.data(), GL_STATIC_DRAW ); - for( int i = 0; i < latitudes; ++i ) { + ::glGenBuffers( 1, &m_coloursbuffer ); + ::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer ); + ::glBufferData( GL_ARRAY_BUFFER, m_colours.size() * sizeof( float3 ), m_colours.data(), GL_DYNAMIC_DRAW ); - ::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(); + ::glGenBuffers( 1, &m_indexbuffer ); + ::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer ); + ::glBufferData( GL_ELEMENT_ARRAY_BUFFER, m_indices.size() * sizeof( unsigned short ), m_indices.data(), GL_STATIC_DRAW ); + // NOTE: vertex and index source data is superfluous past this point, but, eh } + // begin + ::glEnableClientState( GL_VERTEX_ARRAY ); + ::glEnableClientState( GL_COLOR_ARRAY ); + // positions + ::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer ); + ::glVertexPointer( 3, GL_FLOAT, sizeof( float3 ), reinterpret_cast( 0 ) ); + // colours + ::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer ); + ::glColorPointer( 3, GL_FLOAT, sizeof( float3 ), reinterpret_cast( 0 ) ); + // indices + ::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer ); + ::glDrawElements( GL_TRIANGLES, static_cast( m_indices.size() ), GL_UNSIGNED_SHORT, reinterpret_cast( 0 ) ); + // cleanup + ::glDisableClientState( GL_COLOR_ARRAY ); + ::glDisableClientState( GL_VERTEX_ARRAY ); } //******************************************************************************// @@ -329,16 +350,23 @@ void CSkyDome::RebuildColors() { color.y = 0.65f * color.z; color = color * ( 1.15f - vertex.y ); // simple gradient, darkening towards the top } - // save m_colours[ i ] = color; - averagecolor += color; + averagecolor += color * 8.0f; // save for edge cases each vertex goes in 8 triangles } - - m_averagecolour = averagecolor / m_vertices.size(); + // NOTE: average reduced to 25% makes nice tint value for clouds lit from behind + // down the road we could interpolate between it and full strength average, to improve accuracy of cloud appearance + m_averagecolour = averagecolor / m_indices.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 ); + + if( m_coloursbuffer != -1 ) { + // the colour buffer was already initialized, so on this run we update its content + ::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer ); + ::glBufferSubData( GL_ARRAY_BUFFER, 0, m_colours.size() * sizeof( float3 ), m_colours.data() ); + } + } //******************************************************************************// diff --git a/skydome.h b/skydome.h index 0fcfb329..ba625975 100644 --- a/skydome.h +++ b/skydome.h @@ -42,8 +42,12 @@ private: // data int const m_tesselation; std::vector m_vertices; + std::vector m_indices; // std::vector m_normals; std::vector m_colours; + GLuint m_vertexbuffer{ (GLuint)-1 }; + GLuint m_indexbuffer{ (GLuint)-1 }; + GLuint m_coloursbuffer{ (GLuint)-1 }; static float m_distributionluminance[ 5 ][ 2 ]; static float m_distributionxcomp[ 5 ][ 2 ]; diff --git a/stdafx.h b/stdafx.h index 5cacf298..df0d240a 100644 --- a/stdafx.h +++ b/stdafx.h @@ -59,7 +59,10 @@ #include #include "GL/glew.h" +#ifdef _WINDOWS #include "GL/wglew.h" - +#define GLFW_DLL +#endif +#define GLFW_INCLUDE_GLU //m7todo: jest tu bo nie chcia³o mi siê wpychaæ do wszystkich plików #include \ No newline at end of file diff --git a/windows.cpp b/windows.cpp index 3a24c7e7..a703a5b0 100644 --- a/windows.cpp +++ b/windows.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "World.h" #pragma warning (disable: 4091) #include @@ -43,4 +44,28 @@ LONG CALLBACK unhandled_handler(::EXCEPTION_POINTERS* e) ::CloseHandle(hFile); return EXCEPTION_CONTINUE_SEARCH; -} \ No newline at end of file +} + +HWND Hwnd; +WNDPROC BaseWindowProc; +PCOPYDATASTRUCT pDane; +extern TWorld World; + +LRESULT APIENTRY WndProc( HWND hWnd, // handle for this window + UINT uMsg, // message for this window + WPARAM wParam, // additional message information + LPARAM lParam) // additional message information +{ + switch( uMsg ) // check for windows messages + { + case WM_COPYDATA: { + // obsÅ‚uga danych przesÅ‚anych przez program sterujÄ…cy + pDane = (PCOPYDATASTRUCT)lParam; + if( pDane->dwData == 'EU07' ) // sygnatura danych + World.OnCommandGet( (DaneRozkaz *)( pDane->lpData ) ); + break; + } + } + // pass all unhandled messages to DefWindowProc + return CallWindowProc( BaseWindowProc, Hwnd, uMsg, wParam, lParam ); +}; \ No newline at end of file