#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 // Window defines #include "GL/glew.h" // Dołączony jako pliki glew.c i glew.h //#include // OpenGL #include // biblioteka GLU; program kompiluje się bez niej, ale w celu uniknięcia w przyszłości niespodzianek to została dołączona #include // Define for sqrt //#include #include #include "RESOURCE.H" // About box resource identifiers. #include "loadOBJ.h" #include "lazik.hpp" #include "plane.hpp" //#include #include "GL/glm/glm.hpp" #include "GL/glfw3.h" #include #include "timeh.hpp" #include "texture.hpp" #include "shader.hpp" #include "FPSCounter.cpp" #include 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); int polygonmode = 0; std::time_t lastTime = std::time(nullptr); int monitormode = 1; int monitormodecounter = 0; std::time_t monitormodehelper; //Zmienne do ruchu ##############################################^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FPSCounter fpsCounter; static const int targetFPS = 144; // Celowany FPS //Fps counter void LimitFPS(int targetFPS) { static auto lastTime = std::chrono::high_resolution_clock::now(); auto currentTime = std::chrono::high_resolution_clock::now(); std::chrono::duration 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(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 = 0.0f; // Pozycja łazika w przód/tył float Sides = 0.0f; // Pozycja łazika w lewo/prawo float Rotation = 0.0f; // Rotacja łazika (w stopniach) float CameraHeight = 50.0f; // Wysokość kamery float MoveSpeed = 1.0f; // Prędkość poruszania się float velocity = 0.0f; // Aktualna prędkość łazika const float friction = 0.01f; // Współczynnik tarcia (μ) const float maxSpeed = 3.0f; // Maksymalna prędkość łazika const float acceleration = 0.2f; float rotationVelocity = 0.0f; // Prędkość obrotu łazika const float rotationAcceleration = 0.1f; // Przyspieszenie obrotu const float rotationFriction = 0.1f; // Współczynnik tarcia obrotu const float maxRotationSpeed = 3.0f; // 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 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 bool CheckAllFencesCollision(float roverXMin, float roverXMax, float roverZMin, float roverZMax, const std::vector& 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 } void UpdateRover(const std::vector& 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 if (keyAPressed) { rotationVelocity += rotationAcceleration; if (rotationVelocity > maxRotationSpeed) rotationVelocity = maxRotationSpeed; } else if (keyDPressed) { rotationVelocity -= rotationAcceleration; if (rotationVelocity < -maxRotationSpeed) rotationVelocity = -maxRotationSpeed; } else { // Hamowanie obrotu (wytracanie prędkości z powodu tarcia) if (rotationVelocity > 0) { rotationVelocity -= rotationFriction; if (rotationVelocity < 0) rotationVelocity = 0; } else if (rotationVelocity < 0) { rotationVelocity += rotationFriction; 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; // Wyliczamy narożniki łazika po obrocie float offsetX = roverHalfWidthX * cos(radNewRotation) + roverHalfLengthZ * sin(radNewRotation); float offsetZ = roverHalfLengthZ * cos(radNewRotation) + roverHalfWidthX * sin(radNewRotation); // Wyznaczamy nowe granice łazika float rotatedXMin = Sides - offsetX; float rotatedXMax = Sides + offsetX; float rotatedZMin = Foward - offsetZ; float rotatedZMax = Foward + offsetZ; // Sprawdzamy kolizję dla granic po obrocie if (CheckAllFencesCollision(rotatedXMin, rotatedXMax, rotatedZMin, rotatedZMax, fences)) { rotationVelocity = 0.0f; // Zatrzymujemy obrót w przypadku kolizji cout << "Kolizja podczas obrotu\n"; } else { // Aktualizujemy rotację tylko, 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 fences = { {-550.0f, 3.0f, 50.0f, 1310.0f, 4.0f, 0}, // 0 - pionowo { 50.0f, 3.0f, -600.0f, 1200.0f, 4.0f, 1}, // 1 - poziomo { 650.0f, 3.0f, 50.0f, 1310.0f, 4.0f, 0}, // 0 - pionowo { 50.0f, 3.0f, 695.0f, 1200.0f, 4.0f, 1} // 1 - poziomo }; // Change viewing volume and viewport. Called when window is resized void 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. 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); } 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(); } void platforma(GLfloat xc, GLfloat yc, GLfloat zc, GLfloat xlen, GLfloat zlen) { glColor3d(0.729, 0.91, 0.51); // jasnozielony, dla grass02.bmp (https://rgbcolorpicker.com/0-1) glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture[1]); glBegin(GL_QUADS); glTexCoord2d(1.0, 1.0); glVertex3d(xc - xlen, yc, zc - zlen); glTexCoord2d(1.0, 0.0); glVertex3d(xc + xlen, yc, zc - zlen); glTexCoord2d(0.0, 0.0); glVertex3d(xc + xlen, yc, zc + zlen); glTexCoord2d(0.0, 1.0); glVertex3d(xc - xlen, yc, zc + zlen); glEnd(); glDisable(GL_TEXTURE_2D); } 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); } 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"); 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 lightPos[] = {50.0f, -100.0f, 50.0f, 1.0f}; GLfloat specref[] = { 1.0f, 1.0f, 1.0f, 1.0f}; glEnable(GL_DEPTH_TEST); // Hidden surface removal glFrontFace(GL_CCW); // Counter clock-wise polygons face out //glEnable(GL_CULL_FACE); // Do not calculate inside of jet // !!! znacząco poprawia wydajność 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, lightPos); glEnable(GL_LIGHT0); // 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 glMaterialfv(GL_FRONT, GL_SPECULAR, specref); glMateriali(GL_FRONT, GL_SHININESS, 128); // White background glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Black brush //glColor3f(0.0, 0.0, 0.0); // Initialize GLEW timestampedCout("Inicjalizowanie GLEW..."); glewExperimental = true; // Needed for core profile if (glewInit() != GLEW_OK) { timestampedCout("Failed to initialize GLEW"); return; } timestampedCout("Zainicjalizowano GLEW."); // glfw3 jest w teorii niepotrzebny, ale może się przydać // do przepisania kodu na podobny do tego stąd: // https://github.com/opengl-tutorials/ogl/blob/master/tutorial07_model_loading/tutorial07.cpp timestampedCout("Inicjalizowanie GLFW3..."); if (!glfwInit()) { timestampedCout("Failed to initialize GLFW"); } timestampedCout("Zainicjalizowano GLFW3."); // glGenVertexArrays(1, &VertexArrayID); // glBindVertexArray(VertexArrayID); // Załaduj shadery // programID = LoadShaders("res/shaders/TransformVertexShader.vertexshader", "res/shaders/TextureFragmentShader.fragmentshader"); // MatrixID = glGetUniformLocation(programID, "MVP"); // user.passProgramID(programID); // Załaduj model z pliku .obj timestampedCout("Ladowanie modelu lazika..."); user.loadModel(); timestampedCout("Ladowanie modelu mapki..."); mapa.loadModel(); glfwSwapInterval(1); //glClearColor(0.0f, 0.0f, 0.4f, 0.0f); } void RenderScene(void) { //float normal[3]; // Storage for calculated surface normal // Save the matrix state and do the rotations 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); // gluLookAt( // 0, 0, 0, // the position of your camera, in world space // 0, 0, 0, // where you want to look at, in world space // 0, 1, 0 // probably glm::vec3(0,1,0), but (0,-1,0) would make you looking upside-down, which can be great too // ); switch (polygonmode) { case 1: glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break; default: glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } // Clear the screen glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Use our shader //timestampedCout("programID wynosi " << programID); //glUseProgram(programID); // // Bind our texture in Texture Unit 0 // glActiveTexture(GL_TEXTURE0); // glBindTexture(GL_TEXTURE_2D, Texture); // // Set our "myTextureSampler" sampler to use Texture Unit 0 // glUniform1i(TextureID, 0); //glLoadIdentity(); // Zresetowanie macierzy widoku // //############################################################################################ //Sterowanie //############################################################################################ gluLookAt( Foward - 100.0f * sin((Rotation + 180.0f) * GL_PI / 180.0f), // Pozycja kamery wokół łazika (w poziomie) CameraHeight, // Wysokość kamery Sides - 100.0f * cos((Rotation + 180.0f) * GL_PI / 180.0f), // Kamera wzdłuż osi X i Z Foward, 0.0f, Sides, // Punkt, na który patrzy kamera (łazik) 0.0f, 1.0f, 0.0f // Wektor "góry" ); // Rysowanie mapy (nie porusza się) glPushMatrix(); glColor3f(0.0, 1.0, 0.0); // Zielony kolor dla mapy platforma(50.0f, 0.0f, 45.0f, 600.0f, 650.0f); //mapa.draw(); glPopMatrix(); // Rysowanie łazika (porusza się i obraca) glPushMatrix(); glTranslatef(Foward, 0.0f, Sides); // Translacja łazika na jego pozycję glRotatef(Rotation, 0.0f, 1.0f, 0.0f); // Obrót łazika wokół własnej osi glColor3f(1.0, 0.0, 0.0); // Czerwony kolor dla łazika fpsCounter.update(); user.draw(); UpdateRover(fences); glPopMatrix(); //skrzynka(50); plot(-550.0f, 3.0f, 50.0f, 1310.0f, 4.0f, 0); // 0 - pionowo plot(50.0f, 3.0f, -600.0f, 1200.0f, 4.0f, 1); // 1 - poziomo plot(650.0f, 3.0f, 50.0f, 1310.0f, 4.0f, 0); plot(50.0f, 3.0f, 695.0f, 1200.0f, 4.0f, 1); // stodola(2.0f, 0.0f, -7.5f, 20.0f); stodola(10.0f, 0.0f, 2.0f, 40.0f); // Zamiana buforów (double buffering) //glColor3f(1.0, 0.0, 0.0); //user.draw(); //glColor3f(0.0, 1.0, 0.0); //mapa.draw(); //glColor3f(0.0, 0.0, 0.0); // Zamiana buforów (double buffering) // Swap buffers //glfwSwapBuffers(window); //glfwPollEvents(); //Wyrysowanie prostokata: //glRectd(-10.0,-10.0,20.0,20.0); glPopMatrix(); // wymagane glMatrixMode(GL_MODELVIEW); // zmniejsza zużycie GPU // Flush drawing commands //glFlush(); } // If necessary, creates a 3-3-2 palette for the device context listed. HPALETTE 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 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_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // 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_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 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_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 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_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 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: // 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 LimitFPS(targetFPS); // 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; 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(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; }