feat: rain +day_&_night
This commit is contained in:
96
DayNightCycle.hpp
Normal file
96
DayNightCycle.hpp
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
#ifndef DAYNIGHTCYCLE_HPP
|
||||||
|
#define DAYNIGHTCYCLE_HPP
|
||||||
|
|
||||||
|
#include "GL/glew.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class DayNightCycle {
|
||||||
|
private:
|
||||||
|
bool isNight;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Konstruktor - domyślnie startujemy w dzień
|
||||||
|
DayNightCycle() : isNight(false) {}
|
||||||
|
|
||||||
|
// Funkcja przełączająca stan
|
||||||
|
void toggle() {
|
||||||
|
isNight = !isNight;
|
||||||
|
if (isNight) {
|
||||||
|
std::cout << "Tryb: NOC" << std::endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cout << "Tryb: DZIEN" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zwraca informację czy jest noc (przydatne np. do włączania świateł łazika)
|
||||||
|
bool isNightMode() const {
|
||||||
|
return isNight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Główna funkcja ustawiająca światła i tło
|
||||||
|
void apply() {
|
||||||
|
if (isNight) {
|
||||||
|
// === USTAWIENIA NOCNE ===
|
||||||
|
|
||||||
|
// Kolor nieba (Tło) - Ciemny granat/czarny
|
||||||
|
glClearColor(0.05f, 0.05f, 0.1f, 1.0f);
|
||||||
|
|
||||||
|
// GL_LIGHT0 (Księżyc) - Zimne, słabe światło
|
||||||
|
GLfloat nightAmbient[] = { 0.1f, 0.1f, 0.2f, 1.0f };
|
||||||
|
GLfloat nightDiffuse[] = { 0.2f, 0.2f, 0.35f, 1.0f }; // Niebieskawy odcień
|
||||||
|
GLfloat nightSpecular[] = { 0.1f, 0.1f, 0.1f, 1.0f }; // Bardzo słaby połysk
|
||||||
|
|
||||||
|
glLightfv(GL_LIGHT0, GL_AMBIENT, nightAmbient);
|
||||||
|
glLightfv(GL_LIGHT0, GL_DIFFUSE, nightDiffuse);
|
||||||
|
glLightfv(GL_LIGHT0, GL_SPECULAR, nightSpecular);
|
||||||
|
|
||||||
|
// GL_LIGHT1 (Doświetlenie cieni) - Prawie wyłączone w nocy
|
||||||
|
GLfloat fillAmbient[] = { 0.02f, 0.02f, 0.05f, 1.0f };
|
||||||
|
GLfloat fillDiffuse[] = { 0.05f, 0.05f, 0.1f, 1.0f };
|
||||||
|
|
||||||
|
glLightfv(GL_LIGHT1, GL_AMBIENT, fillAmbient);
|
||||||
|
glLightfv(GL_LIGHT1, GL_DIFFUSE, fillDiffuse);
|
||||||
|
|
||||||
|
// Opcjonalnie: Włączamy gęstą czarną mgłę dla klimatu
|
||||||
|
glEnable(GL_FOG);
|
||||||
|
GLfloat fogColor[] = { 0.05f, 0.05f, 0.1f, 1.0f };
|
||||||
|
glFogfv(GL_FOG_COLOR, fogColor);
|
||||||
|
glFogi(GL_FOG_MODE, GL_EXP2);
|
||||||
|
glFogf(GL_FOG_DENSITY, 0.002f); // Gęstość mgły
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// === USTAWIENIA DZIENNE ===
|
||||||
|
|
||||||
|
// Kolor nieba (Tło) - Jasny błękit
|
||||||
|
glClearColor(0.53f, 0.81f, 0.92f, 1.0f);
|
||||||
|
|
||||||
|
// GL_LIGHT0 (Słońce) - Ciepłe, jasne światło
|
||||||
|
GLfloat dayAmbient[] = { 0.4f, 0.4f, 0.4f, 1.0f };
|
||||||
|
GLfloat dayDiffuse[] = { 0.9f, 0.9f, 0.8f, 1.0f }; // Lekko żółtawe
|
||||||
|
GLfloat daySpecular[] = { 0.5f, 0.5f, 0.5f, 1.0f };
|
||||||
|
|
||||||
|
glLightfv(GL_LIGHT0, GL_AMBIENT, dayAmbient);
|
||||||
|
glLightfv(GL_LIGHT0, GL_DIFFUSE, dayDiffuse);
|
||||||
|
glLightfv(GL_LIGHT0, GL_SPECULAR, daySpecular);
|
||||||
|
|
||||||
|
// GL_LIGHT1 (Doświetlenie cieni)
|
||||||
|
GLfloat fillAmbient[] = { 0.4f, 0.4f, 0.4f, 1.0f };
|
||||||
|
GLfloat fillDiffuse[] = { 0.3f, 0.3f, 0.4f, 1.0f }; // Niebieskawe cienie
|
||||||
|
|
||||||
|
glLightfv(GL_LIGHT1, GL_AMBIENT, fillAmbient);
|
||||||
|
glLightfv(GL_LIGHT1, GL_DIFFUSE, fillDiffuse);
|
||||||
|
|
||||||
|
// Wyłączamy mgłę w dzień (lub ustawiamy bardzo rzadką)
|
||||||
|
glDisable(GL_FOG);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pozycję światła ustawiamy taką samą dla obu (wysoko w górze)
|
||||||
|
// W przyszłości możesz tu zrobić animację przesuwania się słońca
|
||||||
|
GLfloat lightPos[] = { 100.0f, 150.0f, 100.0f, 0.0f }; // 0.0f na końcu = światło kierunkowe
|
||||||
|
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -135,11 +135,13 @@
|
|||||||
<ClCompile Include="timeh.cpp" />
|
<ClCompile Include="timeh.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="DayNightCycle.hpp" />
|
||||||
<ClInclude Include="fabula.hpp" />
|
<ClInclude Include="fabula.hpp" />
|
||||||
<ClInclude Include="lazik.hpp" />
|
<ClInclude Include="lazik.hpp" />
|
||||||
<ClInclude Include="loadOBJ.h" />
|
<ClInclude Include="loadOBJ.h" />
|
||||||
<ClInclude Include="Logger.hpp" />
|
<ClInclude Include="Logger.hpp" />
|
||||||
<ClInclude Include="plane.hpp" />
|
<ClInclude Include="plane.hpp" />
|
||||||
|
<ClInclude Include="rain.hpp" />
|
||||||
<ClInclude Include="RESOURCE.H" />
|
<ClInclude Include="RESOURCE.H" />
|
||||||
<ClInclude Include="shader.hpp" />
|
<ClInclude Include="shader.hpp" />
|
||||||
<ClInclude Include="teksturowane.hpp" />
|
<ClInclude Include="teksturowane.hpp" />
|
||||||
|
|||||||
@@ -83,6 +83,12 @@
|
|||||||
<ClInclude Include="Logger.hpp">
|
<ClInclude Include="Logger.hpp">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="rain.hpp">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="DayNightCycle.hpp">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="glfw3.dll">
|
<None Include="glfw3.dll">
|
||||||
|
|||||||
19
main.cpp
19
main.cpp
@@ -39,7 +39,8 @@
|
|||||||
#include "fabula.hpp"
|
#include "fabula.hpp"
|
||||||
#include "GL/wglew.h"
|
#include "GL/wglew.h"
|
||||||
#include "Logger.hpp"
|
#include "Logger.hpp"
|
||||||
|
#include "rain.hpp"
|
||||||
|
#include "DayNightCycle.hpp"
|
||||||
|
|
||||||
using namespace glm;
|
using namespace glm;
|
||||||
|
|
||||||
@@ -470,6 +471,10 @@ void SetDCPixelFormat(HDC hDC) {
|
|||||||
lazik user(10.0f, 0.0f, 0.0f, "res/models/lazik4.obj"); // obiekty eksportujemy z Forward Axis Z, Up Axis Y.
|
lazik user(10.0f, 0.0f, 0.0f, "res/models/lazik4.obj"); // obiekty eksportujemy z Forward Axis Z, Up Axis Y.
|
||||||
plane mapa( 0.0f, 0.0f, 0.0f, "res/models/mapka3_nofence_noplatform.obj");
|
plane mapa( 0.0f, 0.0f, 0.0f, "res/models/mapka3_nofence_noplatform.obj");
|
||||||
|
|
||||||
|
|
||||||
|
RainSystem rainSystem(2000, 250.0f, 200.0f);
|
||||||
|
DayNightCycle dayNight;
|
||||||
|
|
||||||
static void SetupRC() {
|
static void SetupRC() {
|
||||||
// 1. Podstawowe ustawienia OpenGL
|
// 1. Podstawowe ustawienia OpenGL
|
||||||
glEnable(GL_DEPTH_TEST); // Usuwanie niewidocznych powierzchni
|
glEnable(GL_DEPTH_TEST); // Usuwanie niewidocznych powierzchni
|
||||||
@@ -581,6 +586,8 @@ void static RenderScene(void) {
|
|||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
dayNight.apply();
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
// 1. OBSŁUGA KAMERY
|
// 1. OBSŁUGA KAMERY
|
||||||
// ==========================================
|
// ==========================================
|
||||||
@@ -697,6 +704,14 @@ void static RenderScene(void) {
|
|||||||
plot(450.0f, 3.0f, 10 * 90.0f, 900.0f, 4.0f, 1);
|
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);
|
plot(10 * 90.0f, 3.0f, 405.0f, 990.0f, 4.0f, 0);
|
||||||
|
|
||||||
|
// --- DESZCZ: Logika i Rysowanie ---
|
||||||
|
// Aktualizujemy pozycję deszczu przekazując deltaTime oraz pozycję gracza (Foward, Sides)
|
||||||
|
// Dzięki temu deszcz "chodzi" za nami.
|
||||||
|
rainSystem.update(deltaTime, Foward, Sides);
|
||||||
|
|
||||||
|
// Rysujemy deszcz
|
||||||
|
rainSystem.draw();
|
||||||
|
|
||||||
glFlush();
|
glFlush();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1062,6 +1077,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
case 112: // F1 - Widok z pierwszej osoby (FPV)
|
case 112: // F1 - Widok z pierwszej osoby (FPV)
|
||||||
fpv_view = !fpv_view;
|
fpv_view = !fpv_view;
|
||||||
if (fpv_view) panoramic_view = false; // Wyłącz panoramę, jeśli włączasz FPV
|
if (fpv_view) panoramic_view = false; // Wyłącz panoramę, jeśli włączasz FPV
|
||||||
|
case 'N': // Klawisz N przełącza dzień/noc
|
||||||
|
dayNight.toggle();
|
||||||
break;
|
break;
|
||||||
// Obsługa innych klawiszy
|
// Obsługa innych klawiszy
|
||||||
|
|
||||||
|
|||||||
137
rain.hpp
Normal file
137
rain.hpp
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
#ifndef RAIN_HPP
|
||||||
|
#define RAIN_HPP
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <ctime>
|
||||||
|
#include <cmath>
|
||||||
|
#include "GL/glew.h"
|
||||||
|
|
||||||
|
// Struktura pojedynczej kropli
|
||||||
|
struct RainDrop {
|
||||||
|
float x, y, z; // Pozycja
|
||||||
|
float speed; // Prędkość spadania
|
||||||
|
bool isSplash; // Czy to jest moment rozbicia?
|
||||||
|
float splashTime; // Czas trwania animacji rozbicia
|
||||||
|
float life; // Do losowania długości życia kropli
|
||||||
|
};
|
||||||
|
|
||||||
|
class RainSystem {
|
||||||
|
private:
|
||||||
|
std::vector<RainDrop> drops;
|
||||||
|
int maxDrops;
|
||||||
|
float range; // Promień wokół gracza, gdzie pada deszcz
|
||||||
|
float skyHeight; // Wysokość, z której spada deszcz
|
||||||
|
|
||||||
|
// Funkcja pomocnicza do losowania liczb float
|
||||||
|
float randomFloat(float min, float max) {
|
||||||
|
return min + static_cast<float>(rand()) / (static_cast<float>(RAND_MAX / (max - min)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
RainSystem(int count = 2000, float rangeRadius = 300.0f, float height = 200.0f) {
|
||||||
|
maxDrops = count;
|
||||||
|
range = rangeRadius;
|
||||||
|
skyHeight = height;
|
||||||
|
|
||||||
|
// Inicjalizacja kropel
|
||||||
|
for (int i = 0; i < maxDrops; i++) {
|
||||||
|
RainDrop drop;
|
||||||
|
drop.isSplash = false;
|
||||||
|
drop.splashTime = 0.0f;
|
||||||
|
drop.speed = randomFloat(200.0f, 300.0f); // Szybkość deszczu
|
||||||
|
|
||||||
|
// Losowa pozycja początkowa
|
||||||
|
drop.x = randomFloat(-range, range);
|
||||||
|
drop.y = randomFloat(0.0f, skyHeight * 2.0f); // Rozrzucamy je w pionie na start
|
||||||
|
drop.z = randomFloat(-range, range);
|
||||||
|
|
||||||
|
drops.push_back(drop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aktualizacja fizyki deszczu
|
||||||
|
void update(float deltaTime, float playerX, float playerZ) {
|
||||||
|
for (auto& drop : drops) {
|
||||||
|
if (drop.isSplash) {
|
||||||
|
// Obsługa animacji rozbicia
|
||||||
|
drop.splashTime -= deltaTime;
|
||||||
|
if (drop.splashTime <= 0.0f) {
|
||||||
|
// Koniec rozbicia, reset kropli do nieba
|
||||||
|
drop.isSplash = false;
|
||||||
|
drop.y = skyHeight + randomFloat(0.0f, 50.0f);
|
||||||
|
|
||||||
|
// Reset pozycji względem gracza (deszcz podąża za łazikiem)
|
||||||
|
drop.x = playerX + randomFloat(-range, range);
|
||||||
|
drop.z = playerZ + randomFloat(-range, range);
|
||||||
|
drop.speed = randomFloat(200.0f, 300.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Spadanie
|
||||||
|
drop.y -= drop.speed * deltaTime;
|
||||||
|
|
||||||
|
// Sprawdzenie kolizji z podłogą (y <= 0)
|
||||||
|
if (drop.y <= 0.0f) {
|
||||||
|
drop.y = 0.1f; // Lekko nad ziemią
|
||||||
|
drop.isSplash = true;
|
||||||
|
drop.splashTime = 0.2f; // Czas trwania "plusku" (0.2 sekundy)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jeśli gracz uciekł zbyt daleko od kropli, przenieś ją bliżej gracza
|
||||||
|
// (Optymalizacja: nie liczymy deszczu tam, gdzie nas nie ma)
|
||||||
|
if (std::abs(drop.x - playerX) > range) drop.x = playerX + randomFloat(-range, range);
|
||||||
|
if (std::abs(drop.z - playerZ) > range) drop.z = playerZ + randomFloat(-range, range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rysowanie deszczu
|
||||||
|
void draw() {
|
||||||
|
// Zapisujemy aktualny stan OpenGL
|
||||||
|
glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_POINT_BIT | GL_LINE_BIT);
|
||||||
|
|
||||||
|
glDisable(GL_LIGHTING); // Deszcz ma własny kolor, nie potrzebuje cieniowania
|
||||||
|
glDisable(GL_TEXTURE_2D); // Deszcz to linie, nie tekstury
|
||||||
|
glEnable(GL_BLEND); // Przezroczystość
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
glDepthMask(GL_FALSE); // Deszcz nie powinien zasłaniać obiektów w buforze głębokości (opcjonalne)
|
||||||
|
|
||||||
|
glLineWidth(1.0f);
|
||||||
|
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glColor4f(0.7f, 0.8f, 1.0f, 0.6f); // Jasnoniebieski, lekko przezroczysty
|
||||||
|
|
||||||
|
for (const auto& drop : drops) {
|
||||||
|
if (!drop.isSplash) {
|
||||||
|
// Rysuj spadającą linię (długość zależna od prędkości dla efektu rozmycia)
|
||||||
|
glVertex3f(drop.x, drop.y, drop.z);
|
||||||
|
glVertex3f(drop.x, drop.y + 4.0f, drop.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
// Rysowanie rozbryzgów (jako punkty)
|
||||||
|
glPointSize(3.0f); // Grubsze kropki dla rozbryzgów
|
||||||
|
glBegin(GL_POINTS);
|
||||||
|
glColor4f(0.9f, 0.9f, 1.0f, 0.8f); // Bardziej białe przy uderzeniu
|
||||||
|
|
||||||
|
for (const auto& drop : drops) {
|
||||||
|
if (drop.isSplash) {
|
||||||
|
// Mały losowy rozrzut dla efektu rozbicia
|
||||||
|
float splashOffset = (0.2f - drop.splashTime) * 10.0f; // Rozszerza się z czasem
|
||||||
|
|
||||||
|
// Rysujemy 3 małe kropelki odbijające się od ziemi
|
||||||
|
glVertex3f(drop.x + splashOffset, drop.y + splashOffset * 0.5f, drop.z);
|
||||||
|
glVertex3f(drop.x - splashOffset, drop.y + splashOffset * 0.5f, drop.z);
|
||||||
|
glVertex3f(drop.x, drop.y + splashOffset, drop.z + splashOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glDepthMask(GL_TRUE); // Przywracamy zapis do bufora głębokości
|
||||||
|
glPopAttrib(); // Przywracamy stare ustawienia
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user