Files
grafikaKBT/main.cpp
2025-01-20 05:05:03 +01:00

1767 lines
60 KiB
C++

#define _CRT_SECURE_NO_WARNINGS
#ifdef _MSC_VER // Check if MS Visual C compiler
# pragma comment(lib, "opengl32.lib") // Compiler-specific directive to avoid manually configuration
# pragma comment(lib, "glu32.lib") // Link libraries
#endif
#ifdef _MSC_VER
# ifndef _MBCS
# define _MBCS
# endif
# ifdef _UNICODE
# undef _UNICODE
# endif
# ifdef UNICODE
# undef UNICODE
# endif
#endif
// #define GLEW_STATIC
#include <windows.h> // Window defines
#include "GL/glew.h" // Dołączony jako pliki glew.c i glew.h
//#include <gl/gl.h> // OpenGL
#include <gl/glu.h> // biblioteka GLU; program kompiluje się bez niej, ale w celu uniknięcia w przyszłości niespodzianek to została dołączona
#include <math.h> // Define for sqrt
//#include <stdio.h>
#include <iostream>
#include "RESOURCE.H" // About box resource identifiers.
#include "loadOBJ.h"
#include "lazik.hpp"
#include "plane.hpp"
//#include <vector>
#include "GL/glm/glm.hpp"
#include "GL/glfw3.h"
#include <ctime>
#include "timeh.hpp"
#include "texture.hpp"
#include "shader.hpp"
#include "FPSCounter.cpp"
#include <thread>
using namespace glm;
#define glRGB(x, y, z) glColor3ub((GLubyte)x, (GLubyte)y, (GLubyte)z)
#define BITMAP_ID 0x4D42 // identyfikator formatu BMP
#define GL_PI 3.1415
//#define getTime lastTime = std::time(nullptr);
//#define timestampedCout(msg) {getTime; std::cout << "( " << lastTime << ") " << msg << "\n";}
//using namespace std;
HPALETTE hPalette = NULL;
// Application name and instance storage
static LPCTSTR lpszAppName = "grafikaKBT";
static HINSTANCE hInstance;
GLFWwindow* window;
// Rotation amounts
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;
static GLfloat zRot = 0.0f;
static GLsizei lastHeight;
static GLsizei lastWidth;
// Opis tekstury
BITMAPINFOHEADER bitmapInfoHeader; // nagłówek obrazu
unsigned char* bitmapData; // dane tekstury
unsigned int texture[4]; // obiekt tekstury
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
BOOL APIENTRY AboutDlgProc(HWND hDlg, UINT message, UINT wParam, LONG lParam);
void SetDCPixelFormat(HDC hDC);
static void platforma(GLfloat xc, GLfloat yc, GLfloat zc, GLfloat xlen, GLfloat zlen);
void sprawdzPostepGry();
void ustalPozycjeGracza(GLfloat gracz_x, GLfloat gracz_z, short &grid_x, short &grid_z);
void ustawSiatkeNaWzorNieNadpisujacPostepu();
void nadpiszNowaSiatke(short nowy_wzor);
void tworzKratke(unsigned int grid_x, unsigned int grid_z, unsigned short grid_value);
void tworzKratkiZSiatki();
void aktualizujBiezacaKratke(short grid_x, short grid_z);
int polygonmode = 0;
std::time_t lastTime = std::time(nullptr);
int monitormode = 1;
int monitormodecounter = 0;
std::time_t monitormodehelper;
short biezacy_wzor = 0;
bool panoramic_view = 0;
//Zmienne do ruchu ##############################################^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FPSCounter fpsCounter;
static const int targetFPS = 144; // Celowany FPS
//Fps counter
static void LimitFPS(int targetFPS) {
static auto lastTime = std::chrono::high_resolution_clock::now();
auto currentTime = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = currentTime - lastTime;
// Obliczamy czas na jedną klatkę
double frameTime = 1.0 / targetFPS; // Czas na jedną klatkę w sekundach
double timeToWait = frameTime - elapsed.count(); // Obliczamy czas do czekania
if (timeToWait > 0.0) {
// Jeśli czas do czekania jest większy niż 0, to śpimy przez tę wartość
std::this_thread::sleep_for(std::chrono::duration<double>(timeToWait));
}
lastTime = currentTime; // Zaktualizuj czas dla następnej iteracji
}
bool Kolizja = false;
bool keyWPressed = false;
bool keySPressed = false;
bool keyAPressed = false;
bool keyDPressed = false;
float Foward = 45.0f; // Pozycja łazika w przód/tył
float Sides = -45.0f; // Pozycja łazika w lewo/prawo
float Rotation = 270.0f; // Rotacja łazika (w stopniach)
float CameraHeight = 50.0f; // Wysokość kamery
float MoveSpeed = 0.5f; // Prędkość poruszania się
float velocity = 0.0f; // Aktualna prędkość łazika
float rotationVelocity = 0.0f; // Prędkość obrotu łazika
const float friction = 0.1f; // Współczynnik tarcia (μ)
const float maxSpeed = 2.0f; // Maksymalna prędkość łazika
const float acceleration = 0.2f;
float rotationAcceleration = 0.075f; // Przyspieszenie obrotu
float rotationFriction = 0.1f; // Współczynnik tarcia obrotu
float maxRotationSpeed = 0.5f; // Maksymalna prędkość obrotu
// Struktura do reprezentacji płotu
struct Plot {
GLfloat xc; // Środek płotu w osi X
GLfloat yc; // Środek płotu w osi Y (nieużywane w kolizji, ale może być pomocne)
GLfloat zc; // Środek płotu w osi Z
GLfloat length; // Długość płotu
GLfloat gruboscY; // Grubość płotu
bool mod_x; // 0 - płot pionowy, 1 - płot poziomy
};
// Funkcja sprawdzająca kolizję z płotem
// Funkcja sprawdzająca kolizję z płotem, uwzględniając wymiary łazika
static bool CheckFenceCollision(float roverXMin, float roverXMax, float roverZMin, float roverZMax, const Plot& plot) {
if (plot.mod_x == 0) { // Płot pionowy (równoległy do osi Z)
float xMin = plot.xc - plot.gruboscY / 2.0f;
float xMax = plot.xc + plot.gruboscY / 2.0f;
float zMin = plot.zc - plot.length / 2.0f;
float zMax = plot.zc + plot.length / 2.0f;
// Sprawdzenie, czy którykolwiek fragment łazika wchodzi w obszar płotu
if (roverXMax >= xMin && roverXMin <= xMax && // Kolizja w osi X
roverZMax >= zMin && roverZMin <= zMax) { // Kolizja w osi Z
return true;
}
}
else { // Płot poziomy (równoległy do osi X)
float xMin = plot.xc - plot.length / 2.0f;
float xMax = plot.xc + plot.length / 2.0f;
float zMin = plot.zc - plot.gruboscY / 2.0f;
float zMax = plot.zc + plot.gruboscY / 2.0f;
// Sprawdzenie, czy którykolwiek fragment łazika wchodzi w obszar płotu
if (roverXMax >= xMin && roverXMin <= xMax && // Kolizja w osi X
roverZMax >= zMin && roverZMin <= zMax) { // Kolizja w osi Z
return true;
}
}
return false;
}
// Funkcja ogólna do sprawdzania kolizji ze wszystkimi płotami
static bool CheckAllFencesCollision(float roverXMin, float roverXMax, float roverZMin, float roverZMax, const std::vector<Plot>& fences) {
for (const auto& fence : fences) {
if (CheckFenceCollision(roverXMin, roverXMax, roverZMin, roverZMax, fence)) {
return true; // Kolizja wykryta z którymś płotem
}
}
return false; // Brak kolizji
}
static void UpdateRover(const std::vector<Plot>& fences) {
// Przyspieszanie w przód
if (keyWPressed) {
velocity += acceleration;
if (velocity > maxSpeed) velocity = maxSpeed;
}
// Przyspieszanie w tył
else if (keySPressed) {
velocity -= acceleration;
if (velocity < -maxSpeed) velocity = -maxSpeed;
}
// Hamowanie (wytracanie prędkości z powodu tarcia)
else {
if (velocity > 0) {
velocity -= friction;
if (velocity < 0) velocity = 0;
}
else if (velocity < 0) {
velocity += friction;
if (velocity > 0) velocity = 0;
}
}
// Obracanie (rotacja z driftowaniem)
if (keyAPressed) {
rotationVelocity += rotationAcceleration;
if (rotationVelocity > maxRotationSpeed) rotationVelocity = maxRotationSpeed;
}
else if (keyDPressed) {
rotationVelocity -= rotationAcceleration;
if (rotationVelocity < -maxRotationSpeed) rotationVelocity = -maxRotationSpeed;
}
else {
// Jeśli żadna z klawiszy A/D nie jest wciśnięta, to stopniowo spowalniamy rotację (drift)
float driftFactor = 0.1f; // Mniejsza wartość = dłuższy drift
if (rotationVelocity > 0) {
rotationVelocity -= rotationFriction * driftFactor;
if (rotationVelocity < 0) rotationVelocity = 0;
}
else if (rotationVelocity < 0) {
rotationVelocity += rotationFriction * driftFactor;
if (rotationVelocity > 0) rotationVelocity = 0;
}
}
// Wyliczenie nowej pozycji na podstawie prędkości
float radRotation = Rotation * GL_PI / 180.0f; // Przeliczamy rotację na radiany
float newSides = Sides - velocity * cos(radRotation); // Nowa pozycja w osi X
float newFoward = Foward - velocity * sin(radRotation); // Nowa pozycja w osi Z
// Wymiary łazika (połówki w osi X i Z)
const float roverHalfWidthX = 19.0f; // 38/2
const float roverHalfLengthZ = 12.0f; // 24/2
// Wyliczenie obszaru zajmowanego przez łazik
float roverXMin = newSides - roverHalfWidthX;
float roverXMax = newSides + roverHalfWidthX;
float roverZMin = newFoward - roverHalfLengthZ;
float roverZMax = newFoward + roverHalfLengthZ;
// Sprawdzanie kolizji przed aktualizacją pozycji
if (!Kolizja == true) {
if (CheckAllFencesCollision(roverZMin, roverZMax, roverXMin, roverXMax, fences)) {
// Jeśli jest kolizja, zatrzymujemy łazik
velocity = 0.0f;
//cout << "Kolizja podczas ruchu\n";
}
else {
// Jeśli brak kolizji, aktualizujemy pozycję
Sides = newSides;
Foward = newFoward;
}
// Sprawdzanie kolizji podczas obrotu
if (rotationVelocity != 0.0f) {
// Wyliczamy nową rotację
float newRotation = Rotation + rotationVelocity;
float radNewRotation = newRotation * GL_PI / 180.0f;
// Obracamy narożniki łazika
std::vector<std::pair<float, float>> corners(4);
corners[0] = {Sides - roverHalfWidthX, Foward - roverHalfLengthZ}; // Lewy dolny
corners[1] = {Sides + roverHalfWidthX, Foward - roverHalfLengthZ}; // Prawy dolny
corners[2] = {Sides - roverHalfWidthX, Foward + roverHalfLengthZ}; // Lewy górny
corners[3] = {Sides + roverHalfWidthX, Foward + roverHalfLengthZ}; // Prawy górny
bool collisionDetected = false;
// Obracamy wszystkie narożniki
for (auto& corner : corners) {
float x = corner.first;
float z = corner.second;
corner.first = Sides + (x - Sides) * cos(radNewRotation) - (z - Foward) * sin(radNewRotation);
corner.second = Foward + (x - Sides) * sin(radNewRotation) + (z - Foward) * cos(radNewRotation);
// Sprawdzamy kolizję na podstawie obróconych narożników
if (CheckAllFencesCollision(corner.first, corner.first, corner.second, corner.second, fences)) {
collisionDetected = true;
break;
}
if (CheckAllFencesCollision( corner.second, corner.second, corner.first, corner.first, fences)) {
collisionDetected = true;
break;
}
}
if (collisionDetected) {
rotationVelocity = 0.0f; // Zatrzymujemy obrót
//cout << "Kolizja podczas obrotu\n";
} else {
// Aktualizujemy rotację, jeśli nie ma kolizji
Rotation = newRotation;
if (Rotation >= 360.0f) Rotation -= 360.0f;
if (Rotation < 0.0f) Rotation += 360.0f;
}
}
}
else {
// Jeśli kolizje są wyłączone, aktualizujemy wszystko bez sprawdzania
Sides = newSides;
Foward = newFoward;
Rotation += rotationVelocity;
if (Rotation >= 360.0f) Rotation -= 360.0f;
if (Rotation < 0.0f) Rotation += 360.0f;
}
}
std::vector<Plot> fences = {
{ 450.0f, 3.0f, -90.0f, 900.0f, 4.0f, 1}, // 1 - poziomo
{ 0.0f, 3.0f, 405.0f, 990.0f, 4.0f, 0}, // 0 - pionowo
{ 450.0f, 3.0f, 10*90.0f, 900.0f, 4.0f, 1}, // 1 - poziomo
{10*90.0f, 3.0f, 405.0f, 990.0f, 4.0f, 0} // 0 - pionowo
};
std::vector<std::vector<bool>> wzory = {
// GK
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 0, 1, 0, 0, 1, 0,
0, 1, 0, 0, 0, 1, 0, 1, 1, 0,
1, 1, 0, 0, 0, 1, 1, 1, 0, 0,
1, 0, 0, 0, 0, 1, 1, 0, 0, 0,
1, 0, 1, 1, 0, 1, 1, 0, 0, 0,
1, 0, 0, 1, 1, 1, 1, 1, 0, 0,
1, 1, 0, 0, 1, 1, 0, 1, 1, 0,
0, 1, 1, 1, 1, 1, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
// Ślimak
{0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 1, 1, 1, 1, 1, 1, 0,
1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
1, 0, 1, 0, 1, 0, 0, 0, 1, 0,
1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
1, 0, 0, 0, 0, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
// Sygnał TTL
{0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
// Okrąg
{0, 0, 1, 1, 1, 1, 1, 0, 0, 0,
0, 1, 1, 0, 0, 0, 1, 1, 1, 0,
0, 1, 0, 0, 0, 0, 0, 0, 1, 0,
1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
0, 1, 0, 0, 0, 0, 0, 0, 1, 0,
0, 1, 1, 0, 0, 0, 0, 1, 1, 0,
0, 0, 1, 1, 1, 0, 0, 1, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1},
// Kwadrat
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
1, 0, 0, 0, 0, 0, 0, 1, 0, 0,
1, 0, 0, 0, 0, 0, 0, 1, 0, 0,
1, 0, 0, 0, 0, 0, 0, 1, 1, 1,
1, 0, 0, 0, 0, 0, 0, 1, 1, 1,
1, 0, 0, 0, 0, 0, 0, 1, 0, 0,
1, 0, 0, 0, 0, 0, 0, 1, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
// ABACABA
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 1, 0, 0, 0, 1, 0, 0,
0, 0, 0, 1, 0, 0, 0, 1, 0, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
// Paski
{1, 1, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 1, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 1, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 1, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 1,
1, 0, 1, 0, 1, 0, 1, 1, 1, 0,
1, 0, 1, 0, 1, 1, 1, 0, 1, 0,
1, 0, 1, 1, 1, 0, 1, 0, 1, 0,
1, 1, 1, 0, 1, 0, 1, 0, 1, 0},
// Puste pole
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
std::vector<unsigned short> siatka = {
// Możliwe stany pól siatki:
// - 0 - niezamalowana, nie do zamalowania (zielony)
// - 1 - niezamalowana, do zamalowania (złoty)
// - 2 - zamalowana, nie do zamalowania (czerwony)
// - 3 - zamalowana, do zamalowania (jasnozielony)
// 1. bit mówi o tym, czy jest do zamalowania
// 2. bit mówi o tym, czy jest zamalowana
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
void sprawdzPostepGry() {
unsigned short zgodne_pola = 0;
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
std::cout << "zgp: " << zgodne_pola << "\n";
unsigned short pole_w_siatce = siatka[10*i + (9 - j)];
bool pole_we_wzorach = wzory[biezacy_wzor][10*i + (9 - j)];
if (pole_w_siatce == 0 && pole_we_wzorach == 0) zgodne_pola++;
else if (pole_w_siatce == 3 && pole_we_wzorach == 1) zgodne_pola++;
else {
std::cout << "dla i=" << i << " j=" << j << " otrzymano p_w_s " << pole_w_siatce << " a spodziewano sie p_w_w: " << pole_we_wzorach << "\n";
return;
}
}
}
if (zgodne_pola == 100) {
biezacy_wzor = (biezacy_wzor + 1) % (wzory.size() + 1);
nadpiszNowaSiatke(biezacy_wzor);
} else {
std::cout << "zgodne_pola: " << zgodne_pola << "\n";
}
}
void ustalPozycjeGracza(GLfloat gracz_x, GLfloat gracz_z, short &grid_x, short &grid_z) {
grid_x = static_cast<int>(gracz_x) / 90;
grid_z = static_cast<int>(gracz_z) / 90;
// zapobiega rysowaniu ze "spawna"
if (gracz_x < 0 && gracz_x > -90) grid_x = -1; // ten przypadek dotyczy tylko noclipa
if (gracz_z < 0 && gracz_z > -90) grid_z = -1;
}
void ustawSiatkeNaWzorNieNadpisujacPostepu() {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
bool ma_byc_zamalowana = wzory[biezacy_wzor][10*i + (10 - j)];
if (ma_byc_zamalowana) siatka[10*i + (10 - j)] |= 1;
else siatka[10*i + (10 - j)] = siatka[10*i + (10 - j)] - siatka[10*i + (10 - j)] % 2;
}
}
}
void nadpiszNowaSiatke(short nowy_wzor) {
std::cout << "Przepisz zawartosc siatki!\n";
biezacy_wzor = nowy_wzor;
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
siatka[10*i + (10 - j)] = static_cast<unsigned short>(wzory[biezacy_wzor][10*i + (10 - j)]);
}
}
}
void tworzKratke(unsigned int grid_x, unsigned int grid_z, unsigned short grid_value) {
// https://rgbcolorpicker.com/0-1
switch (grid_value) {
case 0:
// niezamalowana, nie do zamalowania (zielony)
glColor3d(0.031, 0.51, 0.094);
break;
case 1:
// niezamalowana, do zamalowania (złoty)
glColor3d(0.7, 0.5, 0.259);
break;
case 2:
// zamalowana, nie do zamalowania (czerwony)
glColor3d(1, 0.122, 0);
break;
case 3:
// zamalowana, do zamalowania (biały)
glColor3d(1, 1, 1);
break;
}
platforma(45.0f + grid_x * 90.0f, 0.0f, 45.0f + grid_z * 90.0f, 45.0f, 45.0f);
}
void tworzKratkiZSiatki() {
for (int i = 0; i < 10; i++) {
// Aby nie musieć rysować wzorów w odbiciu
// lustrzanym, musimy tutaj przyjąć inną sekwencję
for (int j = 0; j < 10; j++) {
tworzKratke(i, j, siatka[10*i + (9 - j)]);
}
}
}
void aktualizujBiezacaKratke(short grid_x, short grid_z) {
if (grid_x < 0 || grid_z < 0) return;
unsigned short a = siatka[10*grid_x + (9 - grid_z)];
siatka[10*grid_x + (9 - grid_z)] |= 2;
// jeżeli coś się zmieniło
if (siatka[10*grid_x + (9 - grid_z)] != a) {
sprawdzPostepGry();
}
}
// Change viewing volume and viewport. Called when window is resized
void static ChangeSize(GLsizei w, GLsizei h) {
GLfloat nRange = 100.0f;
//GLfloat fAspect;
// Prevent a divide by zero
if (h == 0) h = 1;
lastWidth = w;
lastHeight = h;
//fAspect = (GLfloat)w / (GLfloat)h;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
// Reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// // Establish clipping volume (left, right, bottom, top, near, far)
// if (w <= h) glOrtho(-nRange, nRange, -nRange * h / w, nRange * h / w, -nRange, nRange);
// else glOrtho(-nRange * w / h, nRange * w / h, -nRange, nRange, -nRange, nRange);
// Establish clipping volume (left, right, bottom, top, near, far)
if (w <= h) glOrtho(-nRange, nRange, -nRange * h / w, nRange * h / w, -20 * nRange, 20 * nRange);
else glOrtho(-nRange * w / h, nRange * w / h, -nRange, nRange, -20 * nRange, 20 * nRange);
// Establish perspective:
/*
gluPerspective(60.0f, fAspect, 1.0, 400);
*/
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
// LoadBitmapFile
// opis: ładuje mapę bitową z pliku i zwraca jej adres.
// Wypełnia strukturę nagłówka.
// Nie obsługuje map 8-bitowych.
static unsigned char* LoadBitmapFile(char* filename, BITMAPINFOHEADER* bitmapInfoHeader) {
FILE* filePtr; // wskaźnik pozycji pliku
BITMAPFILEHEADER bitmapFileHeader; // nagłówek pliku
unsigned char* bitmapImage; // dane obrazu
int imageIdx = 0; // licznik pikseli
unsigned char tempRGB; // zmienna zamiany składowych
// otwiera plik w trybie "read binary"
filePtr = fopen(filename, "rb");
if (filePtr == NULL) return NULL;
// wczytuje nagłówek pliku
fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, filePtr);
// sprawdza, czy jest to plik formatu BMP
if (bitmapFileHeader.bfType != BITMAP_ID) {
fclose(filePtr);
return NULL;
}
// wczytuje nagłówek obrazu
fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, filePtr);
// ustawia wskaźnik pozycji pliku na początku danych obrazu
fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);
// przydziela pamięć buforowi obrazu
bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);
// sprawdza, czy udało się przydzielić pamięć
if (!bitmapImage) {
free(bitmapImage);
fclose(filePtr);
return NULL;
}
// wczytuje dane obrazu
fread(bitmapImage, 1, bitmapInfoHeader->biSizeImage, filePtr);
// sprawdza, czy dane zostały wczytane
if (bitmapImage == NULL) {
fclose(filePtr);
return NULL;
}
// zamienia miejscami składowe R i B
for (imageIdx = 0; imageIdx < bitmapInfoHeader->biSizeImage; imageIdx += 3) {
tempRGB = bitmapImage[imageIdx];
bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
bitmapImage[imageIdx + 2] = tempRGB;
}
// zamyka plik i zwraca wskaźnik bufora zawierającego wczytany obraz
fclose(filePtr);
return bitmapImage;
}
void SetDCPixelFormat(HDC hDC) {
int nPixelFormat;
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure
1, // Version of this structure
PFD_DRAW_TO_WINDOW | // Draw to Window (not to bitmap)
PFD_SUPPORT_OPENGL | // Support OpenGL calls in window
PFD_DOUBLEBUFFER, // Double buffered
PFD_TYPE_RGBA, // RGBA Color mode
24, // Want 24bit color
0,0,0,0,0,0, // Not used to select mode
0,0, // Not used to select mode
0,0,0,0,0, // Not used to select mode
32, // Size of depth buffer
0, // Not used to select mode
0, // Not used to select mode
PFD_MAIN_PLANE, // Draw in main plane
0, // Not used to select mode
0,0,0 }; // Not used to select mode
// Choose a pixel format that best matches that described in pfd
nPixelFormat = ChoosePixelFormat(hDC, &pfd);
// Set the pixel format for the device context
SetPixelFormat(hDC, nPixelFormat, &pfd);
}
static void skrzynka(GLfloat k) {
glColor3d(0.8, 0.7, 0.3);
glEnable(GL_TEXTURE_2D); // Włącz teksturowanie
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glNormal3d(0, 0, 1);
glTexCoord2d(1.0, 1.0); glVertex3d( k, k, k);
glTexCoord2d(0.0, 1.0); glVertex3d(-k, k, k);
glTexCoord2d(0.0, 0.0); glVertex3d(-k, -k, k);
glTexCoord2d(1.0, 0.0); glVertex3d( k, -k, k);
glEnd();
glBindTexture(GL_TEXTURE_2D, texture[1]);
glBegin(GL_QUADS);
glNormal3d(1, 0, 0);
glTexCoord2d(1.0, 1.0); glVertex3d(k, k, k);
glTexCoord2d(0.0, 1.0); glVertex3d(k, -k, k);
glTexCoord2d(0.0, 0.0); glVertex3d(k, -k, -k);
glTexCoord2d(1.0, 0.0); glVertex3d(k, k, -k);
glEnd();
glDisable(GL_TEXTURE_2D); // Wyłącz teksturowanie
glBegin(GL_QUADS);
glNormal3d(0, 0, -1);
glVertex3d( k, k, -k);
glVertex3d( k, -k, -k);
glVertex3d(-k, -k, -k);
glVertex3d(-k, k, -k);
glNormal3d(-1, 0, 0);
glVertex3d(-k, k, -k);
glVertex3d(-k, -k, -k);
glVertex3d(-k, -k, k);
glVertex3d(-k, k, k);
glNormal3d(0, 1, 0);
glVertex3d( k, k, k);
glVertex3d( k, k, -k);
glVertex3d(-k, k, -k);
glVertex3d(-k, k, k);
glNormal3d(0, -1, 0);
glVertex3d( k, -k, k);
glVertex3d(-k, -k, k);
glVertex3d(-k, -k, -k);
glVertex3d( k, -k, -k);
glEnd();
}
static void platforma(GLfloat xc, GLfloat yc, GLfloat zc, GLfloat xlen, GLfloat zlen) {
// glColor3d(0.729, 0.91, 0.51); // jasnozielony, dla grass02.bmp
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[1]); // Wybieramy teksturę
// Ustawienie powtarzania tekstury
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); // Powtarzanie w kierunku S
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); // Powtarzanie w kierunku T
glBegin(GL_QUADS);
// Powtarzające się współrzędne tekstury (np. *5, aby powtórzyła się 5 razy)
glTexCoord2d(5.0, 5.0); glVertex3d(xc - xlen, yc, zc - zlen); // Lewy dolny
glTexCoord2d(5.0, 0.0); glVertex3d(xc + xlen, yc, zc - zlen); // Prawy dolny
glTexCoord2d(0.0, 0.0); glVertex3d(xc + xlen, yc, zc + zlen); // Prawy górny
glTexCoord2d(0.0, 5.0); glVertex3d(xc - xlen, yc, zc + zlen); // Lewy górny
glEnd();
glDisable(GL_TEXTURE_2D);
}
static void stodola(GLfloat xc, GLfloat yc, GLfloat zc, GLfloat krawedz) {
glEnable(GL_TEXTURE_2D);
// ściany stodoły z bruku (brickwall)
glColor3d(0.612f, 0.573f, 0.478f); // ciemny szary popadający w brąz (https://rgbcolorpicker.com/0-1)
glBindTexture(GL_TEXTURE_2D, texture[3]);
glBegin(GL_QUADS);
glTexCoord2d(1.0, 1.0); glVertex3d(xc - krawedz/2, yc, zc - krawedz/2);
glTexCoord2d(1.0, 0.0); glVertex3d(xc - krawedz/2, yc + krawedz, zc - krawedz/2);
glTexCoord2d(0.0, 0.0); glVertex3d(xc + krawedz/2, yc + krawedz, zc - krawedz/2);
glTexCoord2d(0.0, 1.0); glVertex3d(xc + krawedz/2, yc, zc - krawedz/2);
glTexCoord2d(1.0, 1.0); glVertex3d(xc - krawedz/2, yc, zc - krawedz/2);
glTexCoord2d(1.0, 0.0); glVertex3d(xc - krawedz/2, yc + krawedz, zc - krawedz/2);
glTexCoord2d(0.0, 0.0); glVertex3d(xc - krawedz/2, yc + krawedz, zc + krawedz/2);
glTexCoord2d(0.0, 1.0); glVertex3d(xc - krawedz/2, yc, zc + krawedz/2);
glTexCoord2d(1.0, 1.0); glVertex3d(xc - krawedz/2, yc, zc + krawedz/2);
glTexCoord2d(1.0, 0.0); glVertex3d(xc - krawedz/2, yc + krawedz, zc + krawedz/2);
glTexCoord2d(0.0, 0.0); glVertex3d(xc + krawedz/2, yc + krawedz, zc + krawedz/2);
glTexCoord2d(0.0, 1.0); glVertex3d(xc + krawedz/2, yc, zc + krawedz/2);
glEnd();
// przód i tył dachu
glColor3d(0.612f, 0.573f, 0.478f);
glBindTexture(GL_TEXTURE_2D, texture[3]);
glBegin(GL_TRIANGLES);
glTexCoord2f(1.0, 1.0); glVertex3f(xc - krawedz/2, yc + krawedz, zc - krawedz/2);
glTexCoord2f(1.0, 0.0); glVertex3f(xc - krawedz/2, yc + 1.5 * krawedz, zc);
glTexCoord2f(0.0, 0.0); glVertex3f(xc - krawedz/2, yc + krawedz, zc + krawedz/2);
glTexCoord2f(1.0, 1.0); glVertex3f(xc + krawedz/2, yc + krawedz, zc - krawedz/2);
glTexCoord2f(1.0, 0.0); glVertex3f(xc + krawedz/2, yc + 1.5 * krawedz, zc);
glTexCoord2f(0.0, 0.0); glVertex3f(xc + krawedz/2, yc + krawedz, zc + krawedz/2);
glEnd();
// dach stodoły (barnroof)
glColor3d(0.639, 0.553, 0.322); // wyblakły brązowy
glBindTexture(GL_TEXTURE_2D, texture[2]);
glBegin(GL_QUADS);
glTexCoord2d(1.0, 1.0); glVertex3d(xc - krawedz/2, yc + krawedz, zc + krawedz/2);
glTexCoord2d(1.0, 0.0); glVertex3d(xc - krawedz/2, yc + 1.5 * krawedz, zc);
glTexCoord2d(0.0, 0.0); glVertex3d(xc + krawedz/2, yc + 1.5 * krawedz, zc);
glTexCoord2d(0.0, 1.0); glVertex3d(xc + krawedz/2, yc + krawedz, zc + krawedz/2);
glTexCoord2d(1.0, 1.0); glVertex3d(xc - krawedz/2, yc + krawedz, zc - krawedz/2);
glTexCoord2d(1.0, 0.0); glVertex3d(xc - krawedz/2, yc + 1.5 * krawedz, zc);
glTexCoord2d(0.0, 0.0); glVertex3d(xc + krawedz/2, yc + 1.5 * krawedz, zc);
glTexCoord2d(0.0, 1.0); glVertex3d(xc + krawedz/2, yc + krawedz, zc - krawedz/2);
glEnd();
glDisable(GL_TEXTURE_2D);
}
static void plot(GLfloat xc, GLfloat yc, GLfloat zc, GLfloat length, GLfloat gruboscY, bool mod_x)
{
GLfloat grubosc = 1.0f;
// timestampedCout("main.cpp (plot): otrzymano xc=" << xc << " yc=" << yc << " zc=" << zc << " length=" << length << " mod_x=" << mod_x);
GLfloat gruboscX = grubosc + mod_x * length;
GLfloat gruboscZ = grubosc + !mod_x * length;
// timestampedCout("main.cpp (plot): gruboscX=" << gruboscX << " gruboscY=" << gruboscY << " gruboscZ=" << gruboscZ);
// d-----------c Y
// / /| ^
// a-----------b | \
// | h | g C->X
// | |/ |
// e-----------f v
// Z (płaszczyzna XZ, Y to trzeci wymiar)
GLfloat a1_x = xc - gruboscX / 2, a1_y = yc + 1 + gruboscY, a1_z = zc + gruboscZ / 2; // 3
GLfloat b1_x = xc + gruboscX / 2, b1_y = yc + 1 + gruboscY, b1_z = zc + gruboscZ / 2;
GLfloat c1_x = xc + gruboscX / 2, c1_y = yc + 1 + gruboscY, c1_z = zc - gruboscZ / 2;
GLfloat d1_x = xc - gruboscX / 2, d1_y = yc + 1 + gruboscY, d1_z = zc - gruboscZ / 2;
GLfloat e1_x = xc - gruboscX / 2, e1_y = yc + 1 , e1_z = zc + gruboscZ / 2; // 1
GLfloat f1_x = xc + gruboscX / 2, f1_y = yc + 1 , f1_z = zc + gruboscZ / 2;
GLfloat g1_x = xc + gruboscX / 2, g1_y = yc + 1 , g1_z = zc - gruboscZ / 2;
GLfloat h1_x = xc - gruboscX / 2, h1_y = yc + 1 , h1_z = zc - gruboscZ / 2;
GLfloat a2_x = a1_x, a2_y = a1_y - 1 - gruboscY, a2_z = a1_z; //zc - 1; // -4
GLfloat b2_x = b1_x, b2_y = b1_y - 1 - gruboscY, b2_z = b1_z; //zc - 1;
GLfloat c2_x = c1_x, c2_y = c1_y - 1 - gruboscY, c2_z = c1_z; //zc - 1;
GLfloat d2_x = d1_x, d2_y = d1_y - 1 - gruboscY, d2_z = d1_z; //zc - 1;
GLfloat e2_x = e1_x, e2_y = e1_y - 1 - gruboscY, e2_z = e1_z; //zc - 2;
GLfloat f2_x = f1_x, f2_y = f1_y - 1 - gruboscY, f2_z = f1_z; //zc - 2;
GLfloat g2_x = g1_x, g2_y = g1_y - 1 - gruboscY, g2_z = g1_z; //zc - 2;
GLfloat h2_x = h1_x, h2_y = h1_y - 1 - gruboscY, h2_z = h1_z; //zc - 2;
glColor3d(0.71, 0.522, 0.067);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
// Góra (1_x, 1_y, 1_z):
// ABCD
glTexCoord2d(1.0, 1.0); glVertex3d(a1_x, a1_y, a1_z);
glTexCoord2d(1.0, 0.0); glVertex3d(b1_x, b1_y, b1_z);
glTexCoord2d(0.0, 0.0); glVertex3d(c1_x, c1_y, c1_z);
glTexCoord2d(0.0, 1.0); glVertex3d(d1_x, d1_y, d1_z);
// EFGH
glTexCoord2d(1.0, 1.0); glVertex3d(e1_x, e1_y, e1_z);
glTexCoord2d(1.0, 0.0); glVertex3d(f1_x, f1_y, f1_z);
glTexCoord2d(0.0, 0.0); glVertex3d(g1_x, g1_y, g1_z);
glTexCoord2d(0.0, 1.0); glVertex3d(h1_x, h1_y, h1_z);
// BCGF
glTexCoord2d(1.0, 1.0); glVertex3d(b1_x, b1_y, b1_z);
glTexCoord2d(1.0, 0.0); glVertex3d(c1_x, c1_y, c1_z);
glTexCoord2d(0.0, 0.0); glVertex3d(g1_x, g1_y, g1_z);
glTexCoord2d(0.0, 1.0); glVertex3d(f1_x, f1_y, f1_z);
// ADHE
glTexCoord2d(1.0, 1.0); glVertex3d(a1_x, a1_y, a1_z);
glTexCoord2d(1.0, 0.0); glVertex3d(b1_x, b1_y, b1_z);
glTexCoord2d(0.0, 0.0); glVertex3d(c1_x, c1_y, c1_z);
glTexCoord2d(0.0, 1.0); glVertex3d(d1_x, d1_y, d1_z);
// ABFE
glTexCoord2d(1.0, 1.0); glVertex3d(a1_x, a1_y, a1_z);
glTexCoord2d(1.0, 0.0); glVertex3d(b1_x, b1_y, b1_z);
glTexCoord2d(0.0, 0.0); glVertex3d(f1_x, f1_y, f1_z);
glTexCoord2d(0.0, 1.0); glVertex3d(e1_x, e1_y, e1_z);
// DCGH
glTexCoord2d(1.0, 1.0); glVertex3d(d1_x, d1_y, d1_z);
glTexCoord2d(1.0, 0.0); glVertex3d(c1_x, c1_y, c1_z);
glTexCoord2d(0.0, 0.0); glVertex3d(g1_x, g1_y, g1_z);
glTexCoord2d(0.0, 1.0); glVertex3d(h1_x, h1_y, h1_z);
// Dół (2_x, 2_y, 2_z):
// ABCD
glTexCoord2d(1.0, 1.0); glVertex3d(a2_x, a2_y, a2_z);
glTexCoord2d(1.0, 0.0); glVertex3d(b2_x, b2_y, b2_z);
glTexCoord2d(0.0, 0.0); glVertex3d(c2_x, c2_y, c2_z);
glTexCoord2d(0.0, 1.0); glVertex3d(d2_x, d2_y, d2_z);
// EFGH
glTexCoord2d(1.0, 1.0); glVertex3d(e2_x, e2_y, e2_z);
glTexCoord2d(1.0, 0.0); glVertex3d(f2_x, f2_y, f2_z);
glTexCoord2d(0.0, 0.0); glVertex3d(g2_x, g2_y, g2_z);
glTexCoord2d(0.0, 1.0); glVertex3d(h2_x, h2_y, h2_z);
// BCGF
glTexCoord2d(1.0, 1.0); glVertex3d(b2_x, b2_y, b2_z);
glTexCoord2d(1.0, 0.0); glVertex3d(c2_x, c2_y, c2_z);
glTexCoord2d(0.0, 0.0); glVertex3d(g2_x, g2_y, g2_z);
glTexCoord2d(0.0, 1.0); glVertex3d(f2_x, f2_y, f2_z);
// ADHE
glTexCoord2d(1.0, 1.0); glVertex3d(a2_x, a2_y, a2_z);
glTexCoord2d(1.0, 0.0); glVertex3d(b2_x, b2_y, b2_z);
glTexCoord2d(0.0, 0.0); glVertex3d(c2_x, c2_y, c2_z);
glTexCoord2d(0.0, 1.0); glVertex3d(d2_x, d2_y, d2_z);
// ABFE
glTexCoord2d(1.0, 1.0); glVertex3d(a2_x, a2_y, a2_z);
glTexCoord2d(1.0, 0.0); glVertex3d(b2_x, b2_y, b2_z);
glTexCoord2d(0.0, 0.0); glVertex3d(f2_x, f2_y, f2_z);
glTexCoord2d(0.0, 1.0); glVertex3d(e2_x, e2_y, e2_z);
// DCGH
glTexCoord2d(1.0, 1.0); glVertex3d(d2_x, d2_y, d2_z);
glTexCoord2d(1.0, 0.0); glVertex3d(c2_x, c2_y, c2_z);
glTexCoord2d(0.0, 0.0); glVertex3d(g2_x, g2_y, g2_z);
glTexCoord2d(0.0, 1.0); glVertex3d(h2_x, h2_y, h2_z);
// Pachołki
// d-----------c Y
// / /| ^
// a-----------b | \
// | h | g C->X
// | |/ |
// e-----------f v
// Z (płaszczyzna XZ, Y to trzeci wymiar)
GLfloat p_a_x, p_a_y, p_a_z;
GLfloat p_b_x, p_b_y, p_b_z;
GLfloat p_c_x, p_c_y, p_c_z;
GLfloat p_d_x, p_d_y, p_d_z;
GLfloat p_e_x, p_e_y, p_e_z;
GLfloat p_f_x, p_f_y, p_f_z;
GLfloat p_g_x, p_g_y, p_g_z;
GLfloat p_h_x, p_h_y, p_h_z;
if (!mod_x) {
p_a_x = xc + gruboscX / 2, p_a_y = yc + 1.5f * gruboscY, p_a_z = zc; // +3 dla y
p_b_x = xc - gruboscX / 2, p_b_y = yc + 1.5f * gruboscY, p_b_z = zc; // +3 dla y
p_c_x = xc + gruboscX / 2, p_c_y = yc + 1.5f * gruboscY, p_c_z = zc; // +3 dla y
p_d_x = xc - gruboscX / 2, p_d_y = yc + 1.5f * gruboscY, p_d_z = zc; // +3 dla y
p_e_x = xc + gruboscX / 2, p_e_y = yc - 6 , p_e_z = zc;
p_f_x = xc - gruboscX / 2, p_f_y = yc - 6 , p_f_z = zc;
p_g_x = xc + gruboscX / 2, p_g_y = yc - 6 , p_g_z = zc;
p_h_x = xc - gruboscX / 2, p_h_y = yc - 6 , p_h_z = zc;
} else {
p_a_x = xc, p_a_y = yc + 1.5f * gruboscY, p_a_z = zc - gruboscZ / 2; // +3 dla y
p_b_x = xc, p_b_y = yc + 1.5f * gruboscY, p_b_z = zc - gruboscZ / 2; // +3 dla y
p_c_x = xc, p_c_y = yc + 1.5f * gruboscY, p_c_z = zc + gruboscZ / 2; // +3 dla y
p_d_x = xc, p_d_y = yc + 1.5f * gruboscY, p_d_z = zc + gruboscZ / 2; // +3 dla y
p_e_x = xc, p_e_y = yc - 6 , p_e_z = zc - gruboscZ / 2;
p_f_x = xc, p_f_y = yc - 6 , p_f_z = zc - gruboscZ / 2;
p_g_x = xc, p_g_y = yc - 6 , p_g_z = zc + gruboscZ / 2;
p_h_x = xc, p_h_y = yc - 6 , p_h_z = zc + gruboscZ / 2;
}
for (int i = 0; i < 2; i++) {
// d-----------c Y
// / /| ^
// a-----------b | \
// | h | g C->X
// | |/ |
// e-----------f v
// Z (płaszczyzna XZ, Y to trzeci wymiar)
// timestampedCout("main.cpp (plot): p_a_x=" << p_a_x << " p_b_x=" << p_b_x << " p_c_x=" << p_c_x << " p_d_x=" << p_d_x);
// ABCD
glTexCoord2d(1.0, 1.0); glVertex3d(p_a_x + (2*i-1) * (gruboscX/2 - 8) * mod_x, p_a_y, p_a_z + (2*i-1) * (gruboscZ/2 - 5) * !mod_x);
glTexCoord2d(1.0, 0.0); glVertex3d(p_b_x + (2*i-1) * (gruboscX/2 - 5) * mod_x, p_b_y, p_b_z + (2*i-1) * (gruboscZ/2 - 5) * !mod_x);
glTexCoord2d(0.0, 0.0); glVertex3d(p_c_x + (2*i-1) * (gruboscX/2 - 5) * mod_x, p_c_y, p_c_z + (2*i-1) * (gruboscZ/2 - 8) * !mod_x);
glTexCoord2d(0.0, 1.0); glVertex3d(p_d_x + (2*i-1) * (gruboscX/2 - 8) * mod_x, p_d_y, p_d_z + (2*i-1) * (gruboscZ/2 - 8) * !mod_x);
// EFGH
glTexCoord2d(1.0, 1.0); glVertex3d(p_e_x + (2*i-1) * (gruboscX/2 - 8) * mod_x, p_e_y, p_e_z + (2*i-1) * (gruboscZ/2 - 5) * !mod_x);
glTexCoord2d(1.0, 0.0); glVertex3d(p_f_x + (2*i-1) * (gruboscX/2 - 5) * mod_x, p_f_y, p_f_z + (2*i-1) * (gruboscZ/2 - 5) * !mod_x);
glTexCoord2d(0.0, 0.0); glVertex3d(p_g_x + (2*i-1) * (gruboscX/2 - 5) * mod_x, p_g_y, p_g_z + (2*i-1) * (gruboscZ/2 - 8) * !mod_x);
glTexCoord2d(0.0, 1.0); glVertex3d(p_h_x + (2*i-1) * (gruboscX/2 - 8) * mod_x, p_h_y, p_h_z + (2*i-1) * (gruboscZ/2 - 8) * !mod_x);
// BCGF
glTexCoord2d(1.0, 1.0); glVertex3d(p_b_x + (2*i-1) * (gruboscX/2 - 5) * mod_x, p_b_y, p_b_z + (2*i-1) * (gruboscZ/2 - 5) * !mod_x);
glTexCoord2d(1.0, 0.0); glVertex3d(p_c_x + (2*i-1) * (gruboscX/2 - 5) * mod_x, p_c_y, p_c_z + (2*i-1) * (gruboscZ/2 - 8) * !mod_x);
glTexCoord2d(0.0, 0.0); glVertex3d(p_g_x + (2*i-1) * (gruboscX/2 - 5) * mod_x, p_g_y, p_g_z + (2*i-1) * (gruboscZ/2 - 8) * !mod_x);
glTexCoord2d(0.0, 1.0); glVertex3d(p_f_x + (2*i-1) * (gruboscX/2 - 5) * mod_x, p_f_y, p_f_z + (2*i-1) * (gruboscZ/2 - 5) * !mod_x);
// ADHE
glTexCoord2d(1.0, 1.0); glVertex3d(p_a_x + (2*i-1) * (gruboscX/2 - 8) * mod_x, p_a_y, p_a_z + (2*i-1) * (gruboscZ/2 - 5) * !mod_x);
glTexCoord2d(1.0, 0.0); glVertex3d(p_d_x + (2*i-1) * (gruboscX/2 - 8) * mod_x, p_d_y, p_d_z + (2*i-1) * (gruboscZ/2 - 8) * !mod_x);
glTexCoord2d(0.0, 0.0); glVertex3d(p_h_x + (2*i-1) * (gruboscX/2 - 8) * mod_x, p_h_y, p_h_z + (2*i-1) * (gruboscZ/2 - 8) * !mod_x);
glTexCoord2d(0.0, 1.0); glVertex3d(p_e_x + (2*i-1) * (gruboscX/2 - 8) * mod_x, p_e_y, p_e_z + (2*i-1) * (gruboscZ/2 - 5) * !mod_x);
// ABFE
glTexCoord2d(1.0, 1.0); glVertex3d(p_a_x + (2*i-1) * (gruboscX/2 - 8) * mod_x, p_a_y, p_a_z + (2*i-1) * (gruboscZ/2 - 5) * !mod_x);
glTexCoord2d(1.0, 0.0); glVertex3d(p_b_x + (2*i-1) * (gruboscX/2 - 5) * mod_x, p_b_y, p_b_z + (2*i-1) * (gruboscZ/2 - 5) * !mod_x);
glTexCoord2d(0.0, 0.0); glVertex3d(p_f_x + (2*i-1) * (gruboscX/2 - 5) * mod_x, p_f_y, p_f_z + (2*i-1) * (gruboscZ/2 - 5) * !mod_x);
glTexCoord2d(0.0, 1.0); glVertex3d(p_e_x + (2*i-1) * (gruboscX/2 - 8) * mod_x, p_e_y, p_e_z + (2*i-1) * (gruboscZ/2 - 5) * !mod_x);
// DCGH
glTexCoord2d(1.0, 1.0); glVertex3d(p_d_x + (2*i-1) * (gruboscX/2 - 8) * mod_x, p_d_y, p_d_z + (2*i-1) * (gruboscZ/2 - 8) * !mod_x);
glTexCoord2d(1.0, 0.0); glVertex3d(p_c_x + (2*i-1) * (gruboscX/2 - 5) * mod_x, p_c_y, p_c_z + (2*i-1) * (gruboscZ/2 - 8) * !mod_x);
glTexCoord2d(0.0, 0.0); glVertex3d(p_g_x + (2*i-1) * (gruboscX/2 - 5) * mod_x, p_g_y, p_g_z + (2*i-1) * (gruboscZ/2 - 8) * !mod_x);
glTexCoord2d(0.0, 1.0); glVertex3d(p_h_x + (2*i-1) * (gruboscX/2 - 8) * mod_x, p_h_y, p_h_z + (2*i-1) * (gruboscZ/2 - 8) * !mod_x);
}
glEnd();
glDisable(GL_TEXTURE_2D);
}
//GLuint programID, VertexArrayID, MatrixID;
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");
static void SetupRC() {
// 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
glDepthFunc(GL_LESS);
// Enable lighting
glEnable(GL_LIGHTING);
// Setup and enable light 0
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos1);
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);
glEnable(GL_LIGHT1);
// 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
glEnable(GL_COLOR_MATERIAL);
// Set Material properties to follow glColor values
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};
glMaterialfv(GL_FRONT, GL_SPECULAR, specref2);
glMateriali(GL_FRONT, GL_SHININESS, 128);
// White background
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
// Initialize GLEW
timestampedCout("Inicjalizowanie GLEW...");
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK) {
timestampedCout("Failed to initialize GLEW");
return;
}
timestampedCout("Zainicjalizowano GLEW.");
// 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...");
mapa.loadModel();
glfwSwapInterval(1);
}
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)
//glEnable(GL_MULTISAMPLE);
// Przywrócenie macierzy modelu i ustawienie obrotów
glPushMatrix();
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
}
// Czyszczenie ekranu przed rysowaniem
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Przywrócenie macierzy widoku
if (panoramic_view) {
maxRotationSpeed = 1.0f;
rotationFriction = 0.5f;
gluLookAt(
Foward, // Pozycja kamery
123, // Wysokość kamery, nie ma znaczenia bo nie mamy perspektywy
Sides - 1.0f, // Kamera wzdłuż osi X i Z, z jakiegoś powodu działa po "- 1.0f"
Foward, 0.0f, Sides, // Punkt patrzenia (łazik)
0.0f, 1.0f, 0.0f // Wektor "góry"
);
} else {
maxRotationSpeed = 0.5f;
rotationFriction = 0.1f;
gluLookAt(
Foward - 50.0f * sin((Rotation + 180.0f) * GL_PI / 180.0f), // Pozycja kamery
CameraHeight / 4, // Wysokość kamery
Sides - 50.0f * cos((Rotation + 180.0f) * GL_PI / 180.0f), // Kamera wzdłuż osi X i Z
Foward, 0.0f, Sides, // Punkt patrzenia (łazik)
0.0f, 1.0f, 0.0f // Wektor "góry"
);
}
// Rysowanie mapy
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
platforma(450.0f, 0.0f, -45.0f, 450.0f, 45.0f);
glPopMatrix();
// Rysowanie łazika
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();
UpdateRover(fences);
fpsCounter.update();
glPopMatrix();
// std::cout << "X: " << Foward << " Z: " << Sides << " Rotation: " << Rotation << "\n";
// Rysowanie innych obiektów
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
stodola(45.0f, 0.0f, -45.0f, 70.0f);
// Mechanika gry
// 1 pole siatki = 90x90m
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);
// 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();
}
// If necessary, creates a 3-3-2 palette for the device context listed.
HPALETTE static GetOpenGLPalette(HDC hDC) {
HPALETTE hRetPal = NULL; // Handle to palette to be created
PIXELFORMATDESCRIPTOR pfd; // Pixel Format Descriptor
LOGPALETTE* pPal; // Pointer to memory for logical palette
int nPixelFormat; // Pixel format index
int nColors; // Number of entries in palette
int i; // Counting variable
BYTE RedRange, GreenRange, BlueRange;
// Range for each color entry (7,7,and 3)
// Get the pixel format index and retrieve the pixel format description
nPixelFormat = GetPixelFormat(hDC);
DescribePixelFormat(hDC, nPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
// Does this pixel format require a palette? If not, do not create a
// palette and just return NULL
if (!(pfd.dwFlags & PFD_NEED_PALETTE)) return NULL;
// Number of entries in palette. 8 bits yeilds 256 entries
nColors = 1 << pfd.cColorBits;
// Allocate space for a logical palette structure plus all the palette entries
pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) + nColors * sizeof(PALETTEENTRY));
// Fill in palette header
pPal->palVersion = 0x300; // Windows 3.0
pPal->palNumEntries = nColors; // table size
// Build mask of all 1's. This creates a number represented by having
// the low order x bits set, where x = pfd.cRedBits, pfd.cGreenBits, and
// pfd.cBlueBits.
RedRange = (1 << pfd.cRedBits) - 1;
GreenRange = (1 << pfd.cGreenBits) - 1;
BlueRange = (1 << pfd.cBlueBits) - 1;
// Loop through all the palette entries
for (i = 0; i < nColors; i++) {
// Fill in the 8-bit equivalents for each component
pPal->palPalEntry[i].peRed = (i >> pfd.cRedShift) & RedRange;
pPal->palPalEntry[i].peRed = (unsigned char)(
(double)pPal->palPalEntry[i].peRed * 255.0 / RedRange);
pPal->palPalEntry[i].peGreen = (i >> pfd.cGreenShift) & GreenRange;
pPal->palPalEntry[i].peGreen = (unsigned char)(
(double)pPal->palPalEntry[i].peGreen * 255.0 / GreenRange);
pPal->palPalEntry[i].peBlue = (i >> pfd.cBlueShift) & BlueRange;
pPal->palPalEntry[i].peBlue = (unsigned char)(
(double)pPal->palPalEntry[i].peBlue * 255.0 / BlueRange);
// pPal->palPalEntry[i].peFlags = (unsigned char) NULL;
pPal->palPalEntry[i].peFlags = 0;
}
// Create the palette
hRetPal = CreatePalette(pPal);
// Go ahead and select and realize the palette for this device context
SelectPalette(hDC, hRetPal, FALSE);
RealizePalette(hDC);
// Free the memory used for the logical palette structure
free(pPal);
// Return the handle to the new palette
return hRetPal;
}
void static CreateConsole() {
// Tworzenie nowej konsoli
if (AllocConsole()) {
// Przekierowanie standardowych strumieni do konsoli
FILE* conin;
FILE* conout;
FILE* conerr;
freopen_s(&conin, "conin$", "r", stdin);
freopen_s(&conout, "conout$", "w", stdout);
freopen_s(&conerr, "conout$", "w", stderr);
}
else {
MessageBox(NULL, "Nie udalo sie utworzyc konsoli.", "Blad", MB_OK | MB_ICONERROR);
}
}
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
CreateConsole();
MSG msg; // Windows message structure
WNDCLASS wc{}; // Windows class structure
HWND hWnd; // Storeage for window handle
hInstance = hInst;
// Register Window style
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
// No need for background brush for OpenGL window
wc.hbrBackground = NULL;
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
wc.lpszClassName = lpszAppName;
// Register the window class
if (RegisterClass(&wc) == 0) return FALSE;
// Create the main application window
hWnd = CreateWindow(
lpszAppName,
lpszAppName,
// OpenGL requires WS_CLIPCHILDREN and WS_CLIPSIBLINGS
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
// Window position and size
50, 50,
800, 800,
NULL,
NULL,
hInstance,
NULL);
// If window was not created, quit
if (hWnd == NULL) return FALSE;
const WORD ID_TIMER = 1;
SetTimer(hWnd, ID_TIMER, 100, NULL);
// Display the window
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
// Process application messages until the application closes
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
// Window procedure, handles all messages for this program
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
static HGLRC hRC; // Permenant Rendering context
static HDC hDC; // Private GDI Device context
float radRotation = Rotation * GL_PI / 180.0f;
switch (message) {
// Window creation, setup for OpenGL
case WM_CREATE:
// Store the device context
hDC = GetDC(hWnd);
// Select the pixel format
SetDCPixelFormat(hDC);
// Create palette if needed
hPalette = GetOpenGLPalette(hDC);
// Create the rendering context and make it current
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
SetupRC();
glGenTextures(3, &texture[0]); // tworzy obiekt tekstury
// ładuje pierwszy obraz tekstury (płotki):
bitmapData = LoadBitmapFile((char*)"res/img/woodenTextureHighExposure.bmp", &bitmapInfoHeader);
glBindTexture(GL_TEXTURE_2D, texture[0]); // aktywuje obiekt tekstury
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
// tworzy obraz tekstury
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, bitmapInfoHeader.biWidth,
bitmapInfoHeader.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, bitmapData);
if (bitmapData) free(bitmapData);
// ładuje drugi obraz tekstury (ziemia):
bitmapData = LoadBitmapFile((char*)"res/img/grass02.bmp", &bitmapInfoHeader);
glBindTexture(GL_TEXTURE_2D, texture[1]); // aktywuje obiekt tekstury
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
// tworzy obraz tekstury
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, bitmapInfoHeader.biWidth,
bitmapInfoHeader.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, bitmapData);
if (bitmapData) free(bitmapData);
// ładuje trzeci obraz tekstury (dach stodoły):
bitmapData = LoadBitmapFile((char*)"res/img/barnroof.bmp", &bitmapInfoHeader);
glBindTexture(GL_TEXTURE_2D, texture[2]); // aktywuje obiekt tekstury
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
// tworzy obraz tekstury
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, bitmapInfoHeader.biWidth,
bitmapInfoHeader.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, bitmapData);
if (bitmapData) free(bitmapData);
// ładuje czwarty obraz tekstury (kamienista ściana):
bitmapData = LoadBitmapFile((char*)"res/img/brickwall.bmp", &bitmapInfoHeader);
glBindTexture(GL_TEXTURE_2D, texture[3]); // aktywuje obiekt tekstury
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
// tworzy obraz tekstury
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, bitmapInfoHeader.biWidth,
bitmapInfoHeader.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, bitmapData);
if (bitmapData) free(bitmapData);
// ustalenie sposobu mieszania tekstury z tłem
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
break;
// Window is being destroyed, cleanup
case WM_DESTROY:
user.unload();
//glDeleteProgram(programID);
//glDeleteVertexArrays(1, &VertexArrayID);
// Deselect the current rendering context and delete it
wglMakeCurrent(hDC, NULL);
wglDeleteContext(hRC);
// Delete the palette if it was created
if (hPalette != NULL) DeleteObject(hPalette);
// Tell the application to terminate after the window
// is gone.
PostQuitMessage(0);
break;
// Window is resized.
case WM_SIZE:
// Call our function which modifies the clipping
// volume and viewport
ChangeSize(LOWORD(lParam), HIWORD(lParam));
break;
// The painting function. This message sent by Windows
// whenever the screen needs updating.
case WM_PAINT:
LimitFPS(targetFPS);
// Call OpenGL drawing code
RenderScene();
SwapBuffers(hDC);
// Validate the newly painted client area
if (!monitormode) ValidateRect(hWnd, NULL);
else InvalidateRect(hWnd, NULL, FALSE);
//break;
// Limit FPS
// Uaktualniaj FPS
// Ogranicz FPS
case WM_QUERYNEWPALETTE:
// If the palette was created.
if (hPalette) {
int nRet;
// Selects the palette into the current device context
SelectPalette(hDC, hPalette, FALSE);
// Map entries from the currently selected palette to
// the system palette. The return value is the number
// of palette entries modified.
nRet = RealizePalette(hDC);
// Repaint, forces remap of palette in current window
InvalidateRect(hWnd, NULL, FALSE);
return nRet;
}
break;
// This window may set the palette, even though it is not the
// currently active window.
case WM_PALETTECHANGED:
// Don't do anything if the palette does not exist, or if
// this is the window that changed the palette.
if ((hPalette != NULL) && ((HWND)wParam != hWnd)) {
// Select the palette into the device context
SelectPalette(hDC, hPalette, FALSE);
// Map entries to system palette
RealizePalette(hDC);
// Remap the current colors to the newly realized palette
UpdateColors(hDC);
return 0;
}
break;
case WM_KEYUP:
switch (wParam) {
case 'W':
keyWPressed = false;
break;
case 'S':
keySPressed = false;
break;
case 'A':
keyAPressed = false;
break;
case 'D':
keyDPressed = false;
break;
// Obsługa innych klawiszy
}
break;
case WM_KEYDOWN:
switch (wParam) {
case VK_UP:
xRot -= 5.0f;
break;
case VK_DOWN:
xRot += 5.0f;
break;
case VK_LEFT:
yRot -= 5.0f;
break;
case VK_RIGHT:
yRot += 5.0f;
break;
case 'Q':
zRot += 5.0f;
break;
case 'E':
zRot -= 5.0f;
break;
case 'R':
xRot = 0;
yRot = 0;
zRot = 0;
break;
case ' ': // 32
polygonmode = !polygonmode;
if (polygonmode) timestampedCout("Uwaga! Tryb wireframe jest niewydajny i powinien sluzyc tylko do debugowania!");
break;
case 'K':
Kolizja = !Kolizja;
break;
case 'W':
keyWPressed = true;
break;
case 'S':
keySPressed = true;
break;
case 'A':
keyAPressed = true;
break;
case 'D':
keyDPressed = true;
break;
// case 114: // F3
// monitormode = !monitormode;
// if (monitormode) {
// monitormodehelper = std::time(nullptr) - 1;
// timestampedCout("Wlaczono tryb monitorowania wydajnosci.");
// }
// if (!monitormode) timestampedCout("Wylaczono tryb monitorowania wydajnosci.");
// break;
case 116: // F5 włącza widok panoramiczny
panoramic_view = !panoramic_view;
break;
case 16: // Shift również
panoramic_view = !panoramic_view;
break;
case 8: // Backspace czyści postęp
nadpiszNowaSiatke(biezacy_wzor);
break;
default:
timestampedCout("Nacisnieto nierozpoznany klawisz: " << (int)wParam);
}
xRot = (const int)xRot % 360;
yRot = (const int)yRot % 360;
zRot = (const int)zRot % 360;
InvalidateRect(hWnd, NULL, FALSE);
break;
// A menu command
case WM_COMMAND:
switch (LOWORD(wParam)) {
// Exit the program
case ID_FILE_EXIT:
DestroyWindow(hWnd);
break;
// Display the about box
case ID_HELP_ABOUT:
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_ABOUT), hWnd, (DLGPROC)AboutDlgProc);
break;
}
break;
case WM_TIMER:
RenderScene();
SwapBuffers(hDC);
ValidateRect(hWnd, NULL);
break;
default: // Passes it on if unproccessed
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0L);
}
// Dialog procedure.
BOOL APIENTRY AboutDlgProc(HWND hDlg, UINT message, UINT wParam, LONG lParam) {
switch (message) {
// Initialize the dialog box
case WM_INITDIALOG:
int i;
GLenum glError;
// glGetString demo
SetDlgItemText(hDlg, IDC_OPENGL_VENDOR, reinterpret_cast<LPCSTR>(glGetString(GL_VENDOR)));
SetDlgItemText(hDlg, IDC_OPENGL_RENDERER, (LPCSTR)glGetString(GL_RENDERER));
SetDlgItemText(hDlg, IDC_OPENGL_VERSION, (LPCSTR)glGetString(GL_VERSION));
SetDlgItemText(hDlg, IDC_OPENGL_EXTENSIONS, (LPCSTR)glGetString(GL_EXTENSIONS));
// gluGetString demo
SetDlgItemText(hDlg, IDC_GLU_VERSION, (LPCSTR)gluGetString(GLU_VERSION));
SetDlgItemText(hDlg, IDC_GLU_EXTENSIONS, (LPCSTR)gluGetString(GLU_EXTENSIONS));
// Display any recent error messages
i = 0;
do {
glError = glGetError();
SetDlgItemText(hDlg, IDC_ERROR1 + i, (LPCSTR)gluErrorString(glError));
i++;
} while (i < 6 && glError != GL_NO_ERROR);
return (TRUE);
break;
// Process command messages
case WM_COMMAND:
// Validate and Make the changes
if (LOWORD(wParam) == IDOK) EndDialog(hDlg, TRUE);
break;
// Closed from sysbox
case WM_CLOSE:
EndDialog(hDlg, TRUE);
break;
}
return FALSE;
}