diff --git a/main.cpp b/main.cpp index bdb4f1e..93eb29e 100644 --- a/main.cpp +++ b/main.cpp @@ -567,128 +567,137 @@ static void SetupRC() { void static RenderScene(void) { - - // PS: to nie zadziała, bo okno nie jest tworzone przez glfw - // Ustawienie liczby próbek dla antyaliasingu - glfwWindowHint(GLFW_SAMPLES, 16); // 4x MSAA (Wielokrotne próbkowanie) - - // Włączenie antyaliasingu (MSAA) + // Ustawienia wstępne + glfwWindowHint(GLFW_SAMPLES, 16); glEnable(GL_MULTISAMPLE); + glEnable(GL_NORMALIZE); + glLoadIdentity(); - // Przywrócenie macierzy modelu i ustawienie obrotów - glPushMatrix(); + // Tryb rysowania (linie/wypełnienie) + switch (polygonmode) { + case 1: glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break; + default: glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // ========================================== + // 1. OBSŁUGA KAMERY + // ========================================== + float rad = Rotation * GL_PI / 180.0f; + + if (panoramic_view) { + // Widok z góry + gluLookAt(Foward, 400.0f, Sides, Foward, 0.0f, Sides, 1.0f, 0.0f, 0.0f); + } + else if (fpv_view) { + // Widok FPV + float lookAtX = Foward - 10.0f * sin(rad); + float lookAtZ = Sides - 10.0f * cos(rad); + gluLookAt(Foward, 15.0f, Sides, lookAtX, 15.0f, lookAtZ, 0.0f, 1.0f, 0.0f); + } + else { + // Widok TPP + float camX = Foward + CameraHeight * sin(rad); + float camZ = Sides + CameraHeight * cos(rad); + gluLookAt(camX, CameraHeight * 0.4f, camZ, Foward, 10.0f, Sides, 0.0f, 1.0f, 0.0f); + } + + // Debugerskie obroty całej sceny glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); glRotatef(zRot, 0.0f, 0.0f, 1.0f); - // Ustawienie trybu rysowania wielokątów - switch (polygonmode) { - case 1: - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // Rysowanie linii - break; - default: - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // Wypełnianie poligonów - } + // ========================================== + // 2. RYSOWANIE PODŁOGI I ELEMENTÓW GRY (TILES) + // ========================================== + // PRZENIESIONE NA GÓRĘ: Rysujemy to najpierw, żeby cienie padały NA te obiekty. - // Czyszczenie ekranu przed rysowaniem - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - // Widok panoramiczny (SHIFT/F5) - // Pomocnicza konwersja na radiany - float rad = Rotation * GL_PI / 180.0f; - - if (panoramic_view) { - // --- WIDOK Z GÓRY --- - maxRotationSpeed = 1.0f; - rotationFriction = 0.5f; - float mapZoom = 400.0f; - gluLookAt(Foward, mapZoom, Sides, Foward, 0.0f, Sides, 1.0f, 0.0f, 0.0f); - } - else if (fpv_view) { - // --- WIDOK FIRST PERSON (FPV) --- - maxRotationSpeed = 0.5f; - rotationFriction = 0.1f; - - float rad = Rotation * GL_PI / 180.0f; - - // Pozycja oczu: środek łazika + lekko w górę - float eyeX = Foward; - float eyeY = 15.0f; // Wysokość "oczu" nad ziemią - float eyeZ = Sides; - - // Kierunek patrzenia: zgodnie z rotacją łazika - // Używamy ujemnego sin/cos, bo w Twoim kodzie Rotation steruje modelem w ten sposób - float lookAtX = Foward - 10.0f * sin(rad); - float lookAtZ = Sides - 10.0f * cos(rad); - - gluLookAt( - eyeX, eyeY, eyeZ, // Oko jest wewnątrz/nad łazikiem - lookAtX, eyeY, lookAtZ, // Patrzymy przed siebie (na tej samej wysokości) - 0.0f, 1.0f, 0.0f // Góra to oś Y - ); - } - else { - // --- WIDOK TRZECIOOSOBOWY (TPP) --- - maxRotationSpeed = 0.5f; - rotationFriction = 0.1f; - float rad = Rotation * GL_PI / 180.0f; - float camX = Foward + CameraHeight * sin(rad); - float camZ = Sides + CameraHeight * cos(rad); - float dynamicHeight = CameraHeight * 0.4f; - - gluLookAt(camX, dynamicHeight, camZ, Foward, 10.0f, Sides, 0.0f, 1.0f, 0.0f); - - } - - - // Rysowanie mapy + // a) Platforma bazowa glPushMatrix(); - // glColor3f(0.0, 1.0, 0.0); // Zielony kolor - // mapa.draw(); // nie rysuj mapy/terenu .obj - - // Platforma niebędąca częścią siatki: - glColor3d(0.031, 0.51, 0.094); // ciemnozielony + glColor3d(0.031, 0.51, 0.094); platforma(450.0f, 0.0f, -45.0f, 450.0f, 45.0f); glPopMatrix(); - // Rysowanie łazika + // b) Logika gry (Kratki na ziemi) + // Obliczamy pozycję, ale nie rysujemy jeszcze łazika + short grid_x, grid_z; + ustalPozycjeGracza(Foward, Sides, grid_x, grid_z); + + // Najpierw aktualizujemy stan siatki + ustawSiatkeNaWzorNieNadpisujacPostepu(); + aktualizujBiezacaKratke(grid_x, grid_z); + + // TERAZ RYSUJEMY KRATKI (żeby cień mógł na nie paść) + // Zakładam, że ta funkcja rysuje GL_QUADS na Y ~ 0.0 + tworzKratkiZSiatki(); + + + // ========================================== + // 3. RYSOWANIE WSZYSTKICH CIENI + // ========================================== + { + GLfloat lightPos[] = { 100.0f, 150.0f, 100.0f, 0.0f }; + // Podnosimy cień minimalnie wyżej (0.15f), żeby na pewno był nad kratkami gry + GLfloat groundPlane[] = { 0.0f, 1.0f, 0.0f, 0.15f }; + + GLfloat shadowMatrix[16]; + MakeShadowMatrix(shadowMatrix, groundPlane, lightPos); + + glPushMatrix(); + // Spłaszczamy wszystko do cienia + glMultMatrixf(shadowMatrix); + + // Wyłączamy światło i tekstury dla cienia + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); // Wyłączamy Depth Test, żeby cień nie migotał z kratkami + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(0.0f, 0.0f, 0.0f, 0.5f); // Półprzezroczysty czarny + + // A. Cień Łazika + glPushMatrix(); + glTranslatef(Foward, 0.0f, Sides); + glRotatef(Rotation, 0.0f, 1.0f, 0.0f); + user.draw(); + glPopMatrix(); + + + // Przywracamy ustawienia + glDisable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + glEnable(GL_TEXTURE_2D); + glEnable(GL_LIGHTING); + glPopMatrix(); + } + + // ========================================== + // 4. RYSOWANIE PRAWDZIWYCH OBIEKTÓW 3D + // ========================================== + + // A. Łazik glPushMatrix(); - glTranslatef(Foward, 0.0f, Sides); // Translacja łazika - glRotatef(Rotation, 0.0f, 1.0f, 0.0f); // Obrót łazika - glColor3f(1.0, 0.0, 0.0); // Czerwony kolor dla łazika - user.draw(); // Rysuj łazik z pomocą lazik.cpp + glTranslatef(Foward, 0.0f, Sides); + glRotatef(Rotation, 0.0f, 1.0f, 0.0f); + glColor3f(1.0f, 1.0f, 1.0f); // Reset koloru + user.draw(); + UpdateRover(fences); fpsCounter.update(); glPopMatrix(); - // std::cout << "X: " << Foward << " Z: " << Sides << " Rotation: " << Rotation << "\n"; - - // Rysowanie innych obiektów - // 1 pole siatki = 90x90m - plot( 450.0f, 3.0f, -90.0f, 900.0f, 4.0f, 1); // 1 - poziomo - plot( 0.0f, 3.0f, 405.0f, 990.0f, 4.0f, 0); // 0 - pionowo - plot( 450.0f, 3.0f, 10*90.0f, 900.0f, 4.0f, 1); // 1 - poziomo - plot(10*90.0f, 3.0f, 405.0f, 990.0f, 4.0f, 0); // 0 - pionowo + // B. Stodoła stodola(45.0f, 0.0f, -45.0f, 70.0f); - // Mechanika gry - short grid_x, grid_z; - ustalPozycjeGracza(Foward, Sides, grid_x, grid_z); - // std::cout << "grid_X: " << grid_x << " grid_Z: " << grid_z << " status: " << siatka[10*grid_x + (9 - grid_z)] << "\n"; - ustawSiatkeNaWzorNieNadpisujacPostepu(); - tworzKratkiZSiatki(); - aktualizujBiezacaKratke(grid_x, grid_z); + // C. Płotki + plot(450.0f, 3.0f, -90.0f, 900.0f, 4.0f, 1); + plot(0.0f, 3.0f, 405.0f, 990.0f, 4.0f, 0); + plot(450.0f, 3.0f, 10 * 90.0f, 900.0f, 4.0f, 1); + plot(10 * 90.0f, 3.0f, 405.0f, 990.0f, 4.0f, 0); - // Zamiana buforów (double buffering) - // glfwSwapBuffers(window); // Przełączenie buforów - // glfwPollEvents(); // Obsługa zdarzeń - - glPopMatrix(); // Przywrócenie poprzedniej macierzy - glMatrixMode(GL_MODELVIEW); // Ustawienie trybu modelu-widoku - - // Wymuszenie wykonania wszystkich rysunków glFlush(); - }