diff --git a/main.cpp b/main.cpp index 1173b8c..bdb4f1e 100644 --- a/main.cpp +++ b/main.cpp @@ -61,6 +61,8 @@ static HINSTANCE hInstance; GLFWwindow* window; /////////////////////// void DisableQuickEdit(); + +void MakeShadowMatrix(GLfloat shadowMat[16], GLfloat groundplane[4], GLfloat lightpos[4]); // Rotation amounts static GLfloat xRot = 0.0f; static GLfloat yRot = 0.0f; @@ -94,7 +96,7 @@ FPSCounter fpsCounter; float deltaTime = 0.0f; -static const int targetFPS = 444; // Celowany FPS +static const int targetFPS = 144; // Celowany FPS //Fps counter static void LimitFPS(int targetFPS) { static auto lastTime = std::chrono::high_resolution_clock::now(); @@ -469,98 +471,92 @@ lazik user(10.0f, 0.0f, 0.0f, "res/models/lazik4.obj"); // obiekty eksportujemy plane mapa( 0.0f, 0.0f, 0.0f, "res/models/mapka3_nofence_noplatform.obj"); static void SetupRC() { - - glEnable(GL_MULTISAMPLE); // - glEnable(GL_LINE_SMOOTH); - glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); - // Light values and coordinates - GLfloat ambientLight[] = {0.3f, 0.3f, 0.3f, 1.0f}; - GLfloat diffuseLight[] = {0.7f, 0.7f, 0.7f, 1.0f}; - GLfloat specular[] = {1.0f, 1.0f, 1.0f, 1.0f}; - GLfloat specref[] = {1.0f, 1.0f, 1.0f, 1.0f}; - - // Multiple light positions (for light coming from all sides) - GLfloat lightPos1[] = { 50.0f, -100.0f, 50.0f, 1.0f}; // Light 0 position - GLfloat lightPos2[] = {-50.0f, -100.0f, 50.0f, 1.0f}; // Light 1 position - GLfloat lightPos3[] = { 50.0f, -100.0f, -50.0f, 1.0f}; // Light 2 position - GLfloat lightPos4[] = {-50.0f, -100.0f, -50.0f, 1.0f}; // Light 3 position - - glEnable(GL_DEPTH_TEST); // Hidden surface removal - glFrontFace(GL_CCW); // Counter clockwise polygons face out + // 1. Podstawowe ustawienia OpenGL + glEnable(GL_DEPTH_TEST); // Usuwanie niewidocznych powierzchni + glFrontFace(GL_CCW); // Przeciwnie do ruchu wskazówek zegara to przód glDepthFunc(GL_LESS); - // Enable lighting + glEnable(GL_MULTISAMPLE); // Antyaliasing + glEnable(GL_LINE_SMOOTH); + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + + // 2. KLUCZOWE: Normalizacja wektorów + // Bez tego, jeśli skalujesz modele, oświetlenie wariuje. + glEnable(GL_NORMALIZE); + + // 3. Konfiguracja kolorów światła + // Ambient - światło otoczenia (cienie nie będą czarne, ale lekko szare) + GLfloat ambientLight[] = { 0.4f, 0.4f, 0.4f, 1.0f }; + + // Diffuse - główny kolor światła słonecznego (lekko ciepły biały) + GLfloat diffuseLight[] = { 0.9f, 0.9f, 0.8f, 1.0f }; + + // Specular - kolor odbłysku (zmniejszamy intensywność, żeby nie raziło) + GLfloat specular[] = { 0.5f, 0.5f, 0.5f, 1.0f }; + + // 4. Pozycje świateł + // LIGHT0 - SŁOŃCE (Kluczowa zmiana) + // Czwarty parametr 0.0f oznacza światło KIERUNKOWE (z nieskończoności), a nie punktowe. + // Ustawiamy je wysoko w górze (Y=100) i pod kątem. + GLfloat sunPos[] = { 100.0f, 150.0f, 100.0f, 0.0f }; + + // LIGHT1 - Doświetlenie cieni (opcjonalne, "fill light" z drugiej strony) + GLfloat fillPos[] = { -100.0f, 50.0f, -100.0f, 0.0f }; + GLfloat fillDiffuse[] = { 0.3f, 0.3f, 0.4f, 1.0f }; // Niebieskawe, słabsze światło + + // 5. Włączenie oświetlenia glEnable(GL_LIGHTING); - // Setup and enable light 0 + // Konfiguracja Słońca (LIGHT0) glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight); glLightfv(GL_LIGHT0, GL_SPECULAR, specular); - glLightfv(GL_LIGHT0, GL_POSITION, lightPos1); + glLightfv(GL_LIGHT0, GL_POSITION, sunPos); glEnable(GL_LIGHT0); - // Setup and enable light 1 - glLightfv(GL_LIGHT1, GL_AMBIENT, ambientLight); - glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuseLight); - glLightfv(GL_LIGHT1, GL_SPECULAR, specular); - glLightfv(GL_LIGHT1, GL_POSITION, lightPos2); + // Konfiguracja doświetlenia (LIGHT1) - łagodzi ostre cienie + glLightfv(GL_LIGHT1, GL_AMBIENT, ambientLight); // Wspólny ambient + glLightfv(GL_LIGHT1, GL_DIFFUSE, fillDiffuse); + glLightfv(GL_LIGHT1, GL_POSITION, fillPos); glEnable(GL_LIGHT1); + // LIGHT2 i LIGHT3 możesz wyłączyć dla wydajności, chyba że robisz reflektory łazika - // Setup and enable light 2 - glLightfv(GL_LIGHT2, GL_AMBIENT, ambientLight); - glLightfv(GL_LIGHT2, GL_DIFFUSE, diffuseLight); - glLightfv(GL_LIGHT2, GL_SPECULAR, specular); - glLightfv(GL_LIGHT2, GL_POSITION, lightPos3); - glEnable(GL_LIGHT2); - - // Setup and enable light 3 - // glLightfv(GL_LIGHT3, GL_AMBIENT, ambientLight); - // glLightfv(GL_LIGHT3, GL_DIFFUSE, diffuseLight); - // glLightfv(GL_LIGHT3, GL_SPECULAR, specular); - // glLightfv(GL_LIGHT3, GL_POSITION, lightPos4); - // glEnable(GL_LIGHT3); - - // Enable color tracking + // 6. Materiały glEnable(GL_COLOR_MATERIAL); - - // Set Material properties to follow glColor values + // Kolor obiektu wpływa na światło rozproszone (diffuse) i otoczenia (ambient) glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); - // All materials hereafter have full specular reflectivity - // with a high shine - GLfloat specref2[] = {0.2f, 0.2f, 0.2f, 0.2f}; + // Zmniejszamy połyskliwość, żeby trawa nie wyglądała jak szkło + GLfloat specref2[] = { 0.1f, 0.1f, 0.1f, 1.0f }; // Bardzo słaby odbłysk materiału glMaterialfv(GL_FRONT, GL_SPECULAR, specref2); - glMateriali(GL_FRONT, GL_SHININESS, 128); + glMateriali(GL_FRONT, GL_SHININESS, 10); // Zmniejszono ze 128 na 10 (bardziej matowe) - // White background - glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + // Tło (Błękitne niebo zamiast białego) + glClearColor(0.53f, 0.81f, 0.92f, 1.0f); - // Initialize GLEW + // --- Reszta Twojej inicjalizacji (GLEW, GLFW, modele) bez zmian --- timestampedCout("Inicjalizowanie GLEW..."); - glewExperimental = true; // Needed for core profile + glewExperimental = true; if (glewInit() != GLEW_OK) { timestampedCout("Failed to initialize GLEW"); return; } - + // ... reszta kodu SetupRC ... timestampedCout("Zainicjalizowano GLEW."); - // Sprawdź czy rozszerzenie jest dostępne i wyłącz V-Sync if (wglewIsSupported("WGL_EXT_swap_control")) { - wglSwapIntervalEXT(0); // 0 = WYŁĄCZ V-Sync (nielimitowane FPS) + wglSwapIntervalEXT(0); timestampedCout("V-Sync wylaczony (unlocked FPS)."); } else { timestampedCout("Brak obslugi WGL_EXT_swap_control - nie mozna programowo wylaczyc V-Sync."); } - // Initialize GLFW3 timestampedCout("Inicjalizowanie GLFW3..."); if (!glfwInit()) { timestampedCout("Failed to initialize GLFW"); } timestampedCout("Zainicjalizowano GLFW3."); - // Load models timestampedCout("Ladowanie modelu lazika..."); user.loadModel(); timestampedCout("Ladowanie modelu mapki..."); @@ -1240,4 +1236,37 @@ void DisableQuickEdit() { // Wyłączamy opcję ENABLE_QUICK_EDIT_MODE oraz ENABLE_INSERT_MODE SetConsoleMode(hInput, prev_mode & ~ENABLE_QUICK_EDIT_MODE & ~ENABLE_INSERT_MODE); +} +// Funkcja tworząca macierz cienia (Shadow Matrix) +// groundplane: równanie płaszczyzny (Ax + By + Cz + D = 0) +// lightpos: pozycja światła +void MakeShadowMatrix(GLfloat shadowMat[16], GLfloat groundplane[4], GLfloat lightpos[4]) +{ + GLfloat dot; + + // Iloczyn skalarny normalnej płaszczyzny i wektora światła + dot = groundplane[0] * lightpos[0] + + groundplane[1] * lightpos[1] + + groundplane[2] * lightpos[2] + + groundplane[3] * lightpos[3]; + + shadowMat[0] = dot - lightpos[0] * groundplane[0]; + shadowMat[4] = 0.f - lightpos[0] * groundplane[1]; + shadowMat[8] = 0.f - lightpos[0] * groundplane[2]; + shadowMat[12] = 0.f - lightpos[0] * groundplane[3]; + + shadowMat[1] = 0.f - lightpos[1] * groundplane[0]; + shadowMat[5] = dot - lightpos[1] * groundplane[1]; + shadowMat[9] = 0.f - lightpos[1] * groundplane[2]; + shadowMat[13] = 0.f - lightpos[1] * groundplane[3]; + + shadowMat[2] = 0.f - lightpos[2] * groundplane[0]; + shadowMat[6] = 0.f - lightpos[2] * groundplane[1]; + shadowMat[10] = dot - lightpos[2] * groundplane[2]; + shadowMat[14] = 0.f - lightpos[2] * groundplane[3]; + + shadowMat[3] = 0.f - lightpos[3] * groundplane[0]; + shadowMat[7] = 0.f - lightpos[3] * groundplane[1]; + shadowMat[11] = 0.f - lightpos[3] * groundplane[2]; + shadowMat[15] = dot - lightpos[3] * groundplane[3]; } \ No newline at end of file