#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 "FPSCounter.cpp" 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 storeage 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[2]; // 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 = 0; int monitormodecounter = 0; std::time_t monitormodehelper; //Zmienne do ruchu ############################################## /* 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) // Zmienne do sterowania kamerą float CameraHeight = 50.0f; // Wysokość kamery void MoveRover(bool forward) { // Zamieniamy kąt na radiany float radRotation = Rotation * GL_PI / 180.0f; // Wektor ruchu w kierunku przód/tył (kierunek łazika) float moveX = cos(radRotation); float moveZ = sin(radRotation); // Ruch w przód if (forward) { Sides -= 1.1f * moveX; Foward -= 1.1f * moveZ; } // Ruch w tył else { Sides += 1.1f * moveX; Foward += 1.1f * moveZ; } } // Funkcja do obrotu kamery i łazika (A/D) void RotateRoverAndCamera(float angle) { Rotation += angle; if (Rotation >= 360.0f) Rotation -= 360.0f; if (Rotation < 0.0f) Rotation += 360.0f; } */ //Zmienne do ruchu ##############################################^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FPSCounter fpsCounter; //Fps counter 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.1f; // Współczynnik tarcia (μ) const float maxSpeed = 3.0f; // Maksymalna prędkość łazika const float acceleration = 0.1f; float rotationVelocity = 0.0f; // Prędkość obrotu łazika const float rotationAcceleration = 0.1f; // Przyspieszenie obrotu const float rotationFriction = 0.05f; // Współczynnik tarcia obrotu const float maxRotationSpeed = 5.0f; // Maksymalna prędkość obrotu // Funkcja do poruszania łazikiem void MoveRover(bool forward) { // Zamieniamy kąt na radiany float radRotation = Rotation * GL_PI / 180.0f; // Wektor ruchu w kierunku przód/tył (kierunek łazika) float moveX = cos(radRotation); float moveZ = sin(radRotation); // Ruch w przód if (forward) { Sides -= MoveSpeed * moveX; Foward -= MoveSpeed * moveZ; } // Ruch w tył else { Sides += MoveSpeed * moveX; Foward += MoveSpeed * moveZ; } } // Funkcja do obracania łazika wokół osi Y void RotateRoverAndCamera(float angle) { Rotation += angle; if (Rotation >= 360.0f) Rotation -= 360.0f; if (Rotation < 0.0f) Rotation += 360.0f; } void UpdateRover() { // 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; } } // Aktualizacja pozycji na podstawie prędkości float radRotation = Rotation * GL_PI / 180.0f; Sides -= velocity * cos(radRotation); Foward -= velocity * sin(radRotation); // Aktualizacja kąta obrotu Rotation += rotationVelocity; if (Rotation >= 360.0f) Rotation -= 360.0f; if (Rotation < 0.0f) Rotation += 360.0f; } // 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); } lazik user(10.0f, 0.0f, 0.0f, "res/models/lazik4.obj"); plane mapa(0.0f, 0.0f, 0.0f, "res/models/mapka2.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[] = { 0.0f, 150.0f, 150.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ść // 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."); // 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); } // prymitywny licznik FPS if (monitormode) { std::time_t now_t = std::time(nullptr); yRot -= 10; // showcase demo if (now_t > monitormodehelper) { std::cout << (int)(monitormodecounter / (now_t - monitormodehelper)) << " fps\n"; monitormodehelper = now_t; monitormodecounter = 0; } else { monitormodecounter++; } } // Clear the screen glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Use our shader //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 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 user.draw(); UpdateRover(); glPopMatrix(); fpsCounter.update(); // 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 udało się utworzyć konsoli.", "Błąd", 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(2, &texture[0]); // tworzy obiekt tekstury // ładuje pierwszy obraz tekstury: bitmapData = LoadBitmapFile((char*)"Bitmapy\\checker.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); // 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: bitmapData = LoadBitmapFile((char*)"Bitmapy\\crate.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_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: // 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; // Windows is telling the application that it may modify // the system palette. This message in essance asks the // application for a new palette. 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 '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; }