Files
grafikaKBT/main.cpp
2026-02-02 00:33:08 +01:00

218 lines
7.4 KiB
C++

#define _CRT_SECURE_NO_WARNINGS
#ifdef _MSC_VER
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#endif
#include "Global.h"
#include "Utils.h"
#include "Render.h"
#include "Physics.h"
#include "RESOURCE.H"
#include "Logger.hpp"
#include "fabula.hpp"
// Deklaracje funkcji lokalnych w Main
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
BOOL APIENTRY AboutDlgProc(HWND hDlg, UINT message, UINT wParam, LONG lParam);
// Zmienne globalne tylko dla okna
static LPCTSTR lpszAppName = "grafikaKBT";
static HINSTANCE hInstance;
static const int targetFPS = 144;
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
CreateConsole();
DisableQuickEdit();
AsyncLogger::getInstance().start();
MSG msg;
WNDCLASS wc{};
HWND hWnd;
hInstance = hInst;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
wc.lpszClassName = lpszAppName;
if (RegisterClass(&wc) == 0) return FALSE;
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
// 2. Utwórz okno z pełnym zestawem przycisków (WS_OVERLAPPEDWINDOW)
hWnd = CreateWindow(
lpszAppName, lpszAppName,
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
0, 0, // Pozycja startowa (lewy górny róg)
screenWidth, screenHeight, // Rozmiar (wstępnie cały ekran)
NULL, NULL, hInstance, NULL);
if (hWnd == NULL) return FALSE;
HDC hDC = GetDC(hWnd);
const WORD ID_TIMER = 1;
SetTimer(hWnd, ID_TIMER, 100, NULL);
ShowWindow(hWnd, SW_SHOWMAXIMIZED);
UpdateWindow(hWnd);
ZeroMemory(&msg, sizeof(msg));
auto lastFrameTime = std::chrono::high_resolution_clock::now();
while (msg.message != WM_QUIT) {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
auto currentFrameTime = std::chrono::high_resolution_clock::now();
std::chrono::duration<float> timeSpan = currentFrameTime - lastFrameTime;
deltaTime = timeSpan.count();
lastFrameTime = currentFrameTime;
RenderScene();
SwapBuffers(hDC);
GAME_LOG("Klatka wyrenderowana. FPS: " << fpsCounter.getFPS());
LimitFPS(targetFPS);
}
}
ReleaseDC(hWnd, hDC);
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
static HGLRC hRC;
static HDC hDC;
switch (message) {
case WM_CREATE:
hDC = GetDC(hWnd);
SetDCPixelFormat(hDC);
GetOpenGLPalette(hDC);
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
SetupRC();
// Ładowanie tekstur (uproszczone dla czytelności, można wydzielić funkcję LoadTextures)
{
GLfloat fLargest;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
glGenTextures(4, &texture[0]);
// Tutaj możesz przenieść logikę ładowania tekstur do np. Utils.cpp -> LoadAllTextures()
// Aby nie zaśmiecać WndProc.
const char* texFiles[] = {
"res/img/woodenTextureHighExposure.bmp",
"res/img/grass02.bmp",
"res/img/barnroof.bmp",
"res/img/brickwall.bmp"
};
for (int i = 0; i < 4; i++) {
bitmapData = LoadBitmapFile((char*)texFiles[i], &bitmapInfoHeader);
if (bitmapData) {
glBindTexture(GL_TEXTURE_2D, texture[i]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); // lub GL_CLAMP zależnie od idx
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, bitmapInfoHeader.biWidth, bitmapInfoHeader.biHeight, GL_RGB, GL_UNSIGNED_BYTE, bitmapData);
free(bitmapData);
}
}
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
break;
case WM_DESTROY:
user.unload();
wglMakeCurrent(hDC, NULL);
wglDeleteContext(hRC);
PostQuitMessage(0);
AsyncLogger::getInstance().stop();
break;
case WM_SIZE:
ChangeSize(LOWORD(lParam), HIWORD(lParam));
break;
case WM_MOUSEWHEEL:
{
int zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
CameraHeight -= (float)zDelta * 0.1f;
if (CameraHeight < 20.0f) CameraHeight = 20.0f; // Stała MinDistance
if (CameraHeight > 1000.0f) CameraHeight = 1000.0f; // Stała MaxDistance
}
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;
case 112: // F1
fpv_view = !fpv_view;
if (fpv_view) panoramic_view = false;
break;
case 'N': dayNight.toggle(); break;
}
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 = yRot = zRot = 0; break;
case ' ': polygonmode = !polygonmode; 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 116: // F5
case 16: // Shift
panoramic_view = !panoramic_view; break;
case 8: // Backspace
nadpiszNowaSiatke(biezacy_wzor); // Zakładam, że ta zmienna jest w fabula.hpp
break;
}
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case ID_FILE_EXIT: DestroyWindow(hWnd); break;
case ID_HELP_ABOUT: DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_ABOUT), hWnd, (DLGPROC)AboutDlgProc); break;
}
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0L);
}
BOOL APIENTRY AboutDlgProc(HWND hDlg, UINT message, UINT wParam, LONG lParam) {
if (message == WM_INITDIALOG) {
// ... (Kod dialogu bez zmian, ewentualnie dodaj include gluGetString)
return TRUE;
}
if (message == WM_COMMAND && LOWORD(wParam) == IDOK) EndDialog(hDlg, TRUE);
if (message == WM_CLOSE) EndDialog(hDlg, TRUE);
return FALSE;
}