From c586a7909c98feb5e07f4934ad7e4cedf78dcaab Mon Sep 17 00:00:00 2001 From: Jiri Bluebear Dluhos Date: Mon, 25 Mar 2019 23:10:38 +0100 Subject: [PATCH 01/25] Support for building under Linux (with SDL2). --- NonEuclidean/Engine.cpp | 313 ++++------------------------------ NonEuclidean/Engine.h | 34 +++- NonEuclidean/Engine_SDL2.cpp | 130 ++++++++++++++ NonEuclidean/Engine_Win32.cpp | 298 ++++++++++++++++++++++++++++++++ NonEuclidean/Input.cpp | 46 ++++- NonEuclidean/Input.h | 5 + NonEuclidean/Main.cpp | 19 ++- NonEuclidean/Makefile | 31 ++++ NonEuclidean/Player.cpp | 4 +- NonEuclidean/Shader.h | 2 + NonEuclidean/Timer.h | 48 ++++++ 11 files changed, 641 insertions(+), 289 deletions(-) create mode 100644 NonEuclidean/Engine_SDL2.cpp create mode 100644 NonEuclidean/Engine_Win32.cpp create mode 100644 NonEuclidean/Makefile diff --git a/NonEuclidean/Engine.cpp b/NonEuclidean/Engine.cpp index 8409651..b2ebeba 100644 --- a/NonEuclidean/Engine.cpp +++ b/NonEuclidean/Engine.cpp @@ -6,7 +6,11 @@ #include "Level4.h" #include "Level5.h" #include "Level6.h" -#include +#if defined(_WIN32) + #include +#else + #include +#endif #include #include #include @@ -17,20 +21,13 @@ const Input* GH_INPUT = nullptr; int GH_REC_LEVEL = 0; int64_t GH_FRAME = 0; -LRESULT WINAPI StaticWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - Engine* eng = (Engine*)GetWindowLongPtr(hWnd, GWLP_USERDATA); - if (eng) { - return eng->WindowProc(hWnd, uMsg, wParam, lParam); - } - return DefWindowProc(hWnd, uMsg, wParam, lParam); -} - -Engine::Engine() : hWnd(NULL), hDC(NULL), hRC(NULL) { +Engine::Engine() { GH_ENGINE = this; GH_INPUT = &input; isFullscreen = false; - SetProcessDPIAware(); + isGood = InitOSWrapper(); + CreateGLWindow(); InitGLObjects(); SetupInputs(); @@ -52,82 +49,36 @@ Engine::Engine() : hWnd(NULL), hDC(NULL), hRC(NULL) { } Engine::~Engine() { - ClipCursor(NULL); - wglMakeCurrent(NULL, NULL); - ReleaseDC(hWnd, hDC); - wglDeleteContext(hRC); - DestroyWindow(hWnd); + DestroyGLWindow(); } int Engine::Run() { - if (!hWnd || !hDC || !hRC) { - return 1; - } + EnterMessageLoop(); + DestroyGLObjects(); + return 0; +} - //Recieve events from this window - SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)this); - - //Setup the timer - const int64_t ticks_per_step = timer.SecondsToTicks(GH_DT); - int64_t cur_ticks = timer.GetTicks(); - GH_FRAME = 0; - - //Game loop - MSG msg; - while (true) { - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - //Handle windows messages - if (msg.message == WM_QUIT) { - break; - } else { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } else { - //Confine the cursor - ConfineCursor(); - - if (input.key_press['1']) { - LoadScene(0); - } else if (input.key_press['2']) { - LoadScene(1); - } else if (input.key_press['3']) { - LoadScene(2); - } else if (input.key_press['4']) { - LoadScene(3); - } else if (input.key_press['5']) { - LoadScene(4); - } else if (input.key_press['6']) { - LoadScene(5); - } else if (input.key_press['7']) { - LoadScene(6); - } +void Engine::PeriodicRender(int64_t cur_ticks) { - //Used fixed time steps for updates - const int64_t new_ticks = timer.GetTicks(); - for (int i = 0; cur_ticks < new_ticks && i < GH_MAX_STEPS; ++i) { - Update(); - cur_ticks += ticks_per_step; - GH_FRAME += 1; - input.EndFrame(); - } - cur_ticks = (cur_ticks < new_ticks ? new_ticks: cur_ticks); - - //Setup camera for rendering - const float n = GH_CLAMP(NearestPortalDist() * 0.5f, GH_NEAR_MIN, GH_NEAR_MAX); - main_cam.worldView = player->WorldToCam(); - main_cam.SetSize(iWidth, iHeight, n, GH_FAR); - main_cam.UseViewport(); - - //Render scene - GH_REC_LEVEL = GH_MAX_RECURSION; - Render(main_cam, 0, nullptr); - SwapBuffers(hDC); - } + //Used fixed time steps for updates + const int64_t new_ticks = timer.GetTicks(); + for (int i = 0; cur_ticks < new_ticks && i < GH_MAX_STEPS; ++i) { + Update(); + cur_ticks += ticks_per_step; + GH_FRAME += 1; + input.EndFrame(); } + cur_ticks = (cur_ticks < new_ticks ? new_ticks: cur_ticks); - DestroyGLObjects(); - return 0; + //Setup camera for rendering + const float n = GH_CLAMP(NearestPortalDist() * 0.5f, GH_NEAR_MIN, GH_NEAR_MAX); + main_cam.worldView = player->WorldToCam(); + main_cam.SetSize(iWidth, iHeight, n, GH_FAR); + main_cam.UseViewport(); + + //Render scene + GH_REC_LEVEL = GH_MAX_RECURSION; + Render(main_cam, 0, nullptr); } void Engine::LoadScene(int ix) { @@ -269,149 +220,6 @@ void Engine::Render(const Camera& cam, GLuint curFBO, const Portal* skipPortal) #endif } -LRESULT Engine::WindowProc(HWND hCurWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - static PAINTSTRUCT ps; - static BYTE lpb[256]; - static UINT dwSize = sizeof(lpb); - - switch (uMsg) { - case WM_SYSCOMMAND: - if (wParam == SC_SCREENSAVE || wParam == SC_MONITORPOWER) { - return 0; - } - break; - - case WM_PAINT: - BeginPaint(hCurWnd, &ps); - EndPaint(hCurWnd, &ps); - return 0; - - case WM_SIZE: - iWidth = LOWORD(lParam); - iHeight = HIWORD(lParam); - PostMessage(hCurWnd, WM_PAINT, 0, 0); - return 0; - - case WM_KEYDOWN: - //Ignore repeat keys - if (lParam & 0x40000000) { return 0; } - input.key[wParam & 0xFF] = true; - input.key_press[wParam & 0xFF] = true; - if (wParam == VK_ESCAPE) { - PostQuitMessage(0); - } - return 0; - - case WM_SYSKEYDOWN: - if (wParam == VK_RETURN) { - ToggleFullscreen(); - return 0; - } - break; - - case WM_KEYUP: - input.key[wParam & 0xFF] = false; - return 0; - - case WM_INPUT: - dwSize = sizeof(lpb); - GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)); - input.UpdateRaw((const RAWINPUT*)lpb); - break; - - case WM_CLOSE: - PostQuitMessage(0); - return 0; - } - - return DefWindowProc(hCurWnd, uMsg, wParam, lParam); -} - -void Engine::CreateGLWindow() { - WNDCLASSEX wc; - hInstance = GetModuleHandle(NULL); - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_OWNDC; - wc.lpfnWndProc = (WNDPROC)StaticWindowProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = NULL; - wc.lpszMenuName = NULL; - wc.lpszClassName = GH_CLASS; - wc.hIconSm = NULL; - - if (!RegisterClassEx(&wc)) { - MessageBoxEx(NULL, "RegisterClass() failed: Cannot register window class.", "Error", MB_OK, 0); - return; - } - - //Always start in windowed mode - iWidth = GH_SCREEN_WIDTH; - iHeight = GH_SCREEN_HEIGHT; - - //Create the window - hWnd = CreateWindowEx( - WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, - GH_CLASS, - GH_TITLE, - WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, - GH_SCREEN_X, - GH_SCREEN_Y, - iWidth, - iHeight, - NULL, - NULL, - hInstance, - NULL); - - if (hWnd == NULL) { - MessageBoxEx(NULL, "CreateWindow() failed: Cannot create a window.", "Error", MB_OK, 0); - return; - } - - hDC = GetDC(hWnd); - - PIXELFORMATDESCRIPTOR pfd; - memset(&pfd, 0, sizeof(pfd)); - pfd.nSize = sizeof(pfd); - pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = 32; - pfd.cDepthBits = 32; - pfd.iLayerType = PFD_MAIN_PLANE; - - const int pf = ChoosePixelFormat(hDC, &pfd); - if (pf == 0) { - MessageBoxEx(NULL, "ChoosePixelFormat() failed: Cannot find a suitable pixel format.", "Error", MB_OK, 0); - return; - } - - if (SetPixelFormat(hDC, pf, &pfd) == FALSE) { - MessageBoxEx(NULL, "SetPixelFormat() failed: Cannot set format specified.", "Error", MB_OK, 0); - return; - } - - DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd); - - hRC = wglCreateContext(hDC); - wglMakeCurrent(hDC, hRC); - - if (GH_START_FULLSCREEN) { - ToggleFullscreen(); - } - if (GH_HIDE_MOUSE) { - ShowCursor(FALSE); - } - - ShowWindow(hWnd, SW_SHOW); - SetForegroundWindow(hWnd); - SetFocus(hWnd); -} - void Engine::InitGLObjects() { //Initialize extensions glewInit(); @@ -427,8 +235,7 @@ void Engine::InitGLObjects() { //Check GL functionality glGetQueryiv(GL_SAMPLES_PASSED_ARB, GL_QUERY_COUNTER_BITS_ARB, &occlusionCullingSupported); - //Attempt to enalbe vsync (if failure then oh well) - wglSwapIntervalEXT(1); + EnableVSync(); } void Engine::DestroyGLObjects() { @@ -437,43 +244,6 @@ void Engine::DestroyGLObjects() { vPortals.clear(); } -void Engine::SetupInputs() { - static const int HID_USAGE_PAGE_GENERIC = 0x01; - static const int HID_USAGE_GENERIC_MOUSE = 0x02; - static const int HID_USAGE_GENERIC_JOYSTICK = 0x04; - static const int HID_USAGE_GENERIC_GAMEPAD = 0x05; - - RAWINPUTDEVICE Rid[3]; - - //Mouse - Rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC; - Rid[0].usUsage = HID_USAGE_GENERIC_MOUSE; - Rid[0].dwFlags = RIDEV_INPUTSINK; - Rid[0].hwndTarget = hWnd; - - //Joystick - Rid[1].usUsagePage = HID_USAGE_PAGE_GENERIC; - Rid[1].usUsage = HID_USAGE_GENERIC_JOYSTICK; - Rid[1].dwFlags = 0; - Rid[1].hwndTarget = 0; - - //Gamepad - Rid[2].usUsagePage = HID_USAGE_PAGE_GENERIC; - Rid[2].usUsage = HID_USAGE_GENERIC_GAMEPAD; - Rid[2].dwFlags = 0; - Rid[2].hwndTarget = 0; - - RegisterRawInputDevices(Rid, 3, sizeof(Rid[0])); -} - -void Engine::ConfineCursor() { - if (GH_HIDE_MOUSE) { - RECT rect; - GetWindowRect(hWnd, &rect); - SetCursorPos((rect.right + rect.left) / 2, (rect.top + rect.bottom) / 2); - } -} - float Engine::NearestPortalDist() const { float dist = FLT_MAX; for (size_t i = 0; i < vPortals.size(); ++i) { @@ -481,22 +251,3 @@ float Engine::NearestPortalDist() const { } return dist; } - -void Engine::ToggleFullscreen() { - isFullscreen = !isFullscreen; - if (isFullscreen) { - iWidth = GetSystemMetrics(SM_CXSCREEN); - iHeight = GetSystemMetrics(SM_CYSCREEN); - SetWindowLong(hWnd, GWL_STYLE, WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); - SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW); - SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, - iWidth, iHeight, SWP_SHOWWINDOW); - } else { - iWidth = GH_SCREEN_WIDTH; - iHeight = GH_SCREEN_HEIGHT; - SetWindowLong(hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); - SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE); - SetWindowPos(hWnd, HWND_TOP, GH_SCREEN_X, GH_SCREEN_Y, - iWidth, iHeight, SWP_SHOWWINDOW); - } -} diff --git a/NonEuclidean/Engine.h b/NonEuclidean/Engine.h index ea8e9d1..d15d1a6 100644 --- a/NonEuclidean/Engine.h +++ b/NonEuclidean/Engine.h @@ -9,7 +9,11 @@ #include "Scene.h" #include "Sky.h" #include -#include +#if defined(_WIN32) + #include +#else + #include "SDL.h" +#endif #include #include @@ -23,26 +27,46 @@ class Engine { void Render(const Camera& cam, GLuint curFBO, const Portal* skipPortal); void LoadScene(int ix); +#if defined(_WIN32) LRESULT WindowProc(HWND hCurWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +#endif const Player& GetPlayer() const { return *player; } float NearestPortalDist() const; private: + bool InitOSWrapper(); void CreateGLWindow(); + void DestroyGLWindow(); void InitGLObjects(); void DestroyGLObjects(); void SetupInputs(); void ConfineCursor(); void ToggleFullscreen(); + int EnterMessageLoop(); + void PeriodicRender(int64_t cur_ticks); + void SwapBuffers(); + void EnableVSync(); - HDC hDC; // device context - HGLRC hRC; // opengl context - HWND hWnd; // window - HINSTANCE hInstance; // process id +#if defined(_WIN32) + HWND hWnd = nullptr; // window + HDC hDC = nullptr; // device context + HGLRC hRC = nullptr; // opengl context + HINSTANCE hInstance; // process id LONG iWidth; // window width LONG iHeight; // window height +#else + SDL_Window* window = nullptr; + SDL_GLContext glContext = nullptr; + int iWidth = 0; + int iHeight = 0; +#endif + + int64_t ticks_per_step = 0; + + bool isGood = false; // initialized without problems + bool isWindowGood = false; // window successfully created and initialized bool isFullscreen; // fullscreen state Camera main_cam; diff --git a/NonEuclidean/Engine_SDL2.cpp b/NonEuclidean/Engine_SDL2.cpp new file mode 100644 index 0000000..deb11ca --- /dev/null +++ b/NonEuclidean/Engine_SDL2.cpp @@ -0,0 +1,130 @@ +#include "Engine.h" +#include "Physical.h" +#include "Level1.h" +#include "Level2.h" +#include "Level3.h" +#include "Level4.h" +#include "Level5.h" +#include "Level6.h" +#include "SDL.h" +#include +#include +#include +#include + +// --- SDL2-specific code ------------------------------------------------ + +bool Engine::InitOSWrapper() { + if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { + SDL_Log("Unable to initialize SDL: %s", SDL_GetError()); + return false; + } + + atexit(SDL_Quit); // SDL will be shut down automatically on app exit + return true; +} + +void Engine::SetupInputs() { + // not needed +} + +void Engine::CreateGLWindow() { + iWidth = GH_SCREEN_WIDTH; + iHeight = GH_SCREEN_HEIGHT; + + window = SDL_CreateWindow( + GH_TITLE, + GH_SCREEN_X, GH_SCREEN_Y, + iWidth, iHeight, + SDL_WINDOW_OPENGL|SDL_WINDOW_ALLOW_HIGHDPI| + (GH_START_FULLSCREEN ? SDL_WINDOW_FULLSCREEN : 0) + ); + if (!window) { + SDL_Log("Unable to create GL window: %s", SDL_GetError()); + return; + } + + // window successfully created + + glContext = SDL_GL_CreateContext(window); + if (!glContext) { + SDL_Log("Unable to create GL context: %s", SDL_GetError()); + return; + } + + // GL context is created and is current for the calling thread + + isWindowGood = true; +} + +void Engine::DestroyGLWindow() { + if (glContext) { + SDL_GL_DeleteContext(glContext); + } + if (window) { + SDL_DestroyWindow(window); + } +} + +void Engine::EnableVSync() { + + // try adaptive vsync first, if not supported, go full vsync + if (SDL_GL_SetSwapInterval(-1) != 0) { + SDL_GL_SetSwapInterval(1); + } +} + +int Engine::EnterMessageLoop() { + + //Setup the timer + ticks_per_step = timer.SecondsToTicks(GH_DT); + int64_t cur_ticks = timer.GetTicks(); + GH_FRAME = 0; + + SDL_Event event; + while(true) { + if (SDL_PollEvent(&event)) { + if (event.type == SDL_QUIT) { + break; + } + } + else { + + input.UpdateRaw(); + + //Confine the cursor + ConfineCursor(); + + if (input.key_press['1']) { + LoadScene(0); + } else if (input.key_press['2']) { + LoadScene(1); + } else if (input.key_press['3']) { + LoadScene(2); + } else if (input.key_press['4']) { + LoadScene(3); + } else if (input.key_press['5']) { + LoadScene(4); + } else if (input.key_press['6']) { + LoadScene(5); + } else if (input.key_press['7']) { + LoadScene(6); + } + + PeriodicRender(cur_ticks); + SwapBuffers(); + } + } + + return 0; +} + +void Engine::ConfineCursor() +{ + // TODO +} + +void Engine::SwapBuffers() +{ + SDL_GL_SwapWindow(window); +} diff --git a/NonEuclidean/Engine_Win32.cpp b/NonEuclidean/Engine_Win32.cpp new file mode 100644 index 0000000..ef326cf --- /dev/null +++ b/NonEuclidean/Engine_Win32.cpp @@ -0,0 +1,298 @@ +#include "Engine.h" +#include "Physical.h" +#include "Level1.h" +#include "Level2.h" +#include "Level3.h" +#include "Level4.h" +#include "Level5.h" +#include "Level6.h" +#if defined(_WIN32) + #include +#endif +#include +#include +#include + +// --- Windows-specific code ------------------------------------------------ + +#if defined(_WIN32) + +LRESULT WINAPI StaticWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + Engine* eng = (Engine*)GetWindowLongPtr(hWnd, GWLP_USERDATA); + if (eng) { + return eng->WindowProc(hWnd, uMsg, wParam, lParam); + } + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + +LRESULT Engine::WindowProc(HWND hCurWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + static PAINTSTRUCT ps; + static BYTE lpb[256]; + static UINT dwSize = sizeof(lpb); + + switch (uMsg) { + case WM_SYSCOMMAND: + if (wParam == SC_SCREENSAVE || wParam == SC_MONITORPOWER) { + return 0; + } + break; + + case WM_PAINT: + BeginPaint(hCurWnd, &ps); + EndPaint(hCurWnd, &ps); + return 0; + + case WM_SIZE: + iWidth = LOWORD(lParam); + iHeight = HIWORD(lParam); + PostMessage(hCurWnd, WM_PAINT, 0, 0); + return 0; + + case WM_KEYDOWN: + //Ignore repeat keys + if (lParam & 0x40000000) { return 0; } + input.key[wParam & 0xFF] = true; + input.key_press[wParam & 0xFF] = true; + if (wParam == VK_ESCAPE) { + PostQuitMessage(0); + } + return 0; + + case WM_SYSKEYDOWN: + if (wParam == VK_RETURN) { + ToggleFullscreen(); + return 0; + } + break; + + case WM_KEYUP: + input.key[wParam & 0xFF] = false; + return 0; + + case WM_INPUT: + dwSize = sizeof(lpb); + GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)); + input.UpdateRaw((const RAWINPUT*)lpb); + break; + + case WM_CLOSE: + PostQuitMessage(0); + return 0; + } + + return DefWindowProc(hCurWnd, uMsg, wParam, lParam); +} + +bool Engine::InitOSWrapper() { + return true; // there is no wrapper, we are using Windows API directly +} + +void Engine::ToggleFullscreen() { + isFullscreen = !isFullscreen; + if (isFullscreen) { + iWidth = GetSystemMetrics(SM_CXSCREEN); + iHeight = GetSystemMetrics(SM_CYSCREEN); + SetWindowLong(hWnd, GWL_STYLE, WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); + SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW); + SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, + iWidth, iHeight, SWP_SHOWWINDOW); + } else { + iWidth = GH_SCREEN_WIDTH; + iHeight = GH_SCREEN_HEIGHT; + SetWindowLong(hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); + SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE); + SetWindowPos(hWnd, HWND_TOP, GH_SCREEN_X, GH_SCREEN_Y, + iWidth, iHeight, SWP_SHOWWINDOW); + } +} + +void Engine::SetupInputs() { + static const int HID_USAGE_PAGE_GENERIC = 0x01; + static const int HID_USAGE_GENERIC_MOUSE = 0x02; + static const int HID_USAGE_GENERIC_JOYSTICK = 0x04; + static const int HID_USAGE_GENERIC_GAMEPAD = 0x05; + + RAWINPUTDEVICE Rid[3]; + + //Mouse + Rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC; + Rid[0].usUsage = HID_USAGE_GENERIC_MOUSE; + Rid[0].dwFlags = RIDEV_INPUTSINK; + Rid[0].hwndTarget = hWnd; + + //Joystick + Rid[1].usUsagePage = HID_USAGE_PAGE_GENERIC; + Rid[1].usUsage = HID_USAGE_GENERIC_JOYSTICK; + Rid[1].dwFlags = 0; + Rid[1].hwndTarget = 0; + + //Gamepad + Rid[2].usUsagePage = HID_USAGE_PAGE_GENERIC; + Rid[2].usUsage = HID_USAGE_GENERIC_GAMEPAD; + Rid[2].dwFlags = 0; + Rid[2].hwndTarget = 0; + + RegisterRawInputDevices(Rid, 3, sizeof(Rid[0])); +} + +void Engine::ConfineCursor() { + if (GH_HIDE_MOUSE) { + RECT rect; + GetWindowRect(hWnd, &rect); + SetCursorPos((rect.right + rect.left) / 2, (rect.top + rect.bottom) / 2); + } +} + +void Engine::CreateGLWindow() { + SetProcessDPIAware(); + + WNDCLASSEX wc; + hInstance = GetModuleHandle(NULL); + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = CS_OWNDC; + wc.lpfnWndProc = (WNDPROC)StaticWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = GH_CLASS; + wc.hIconSm = NULL; + + if (!RegisterClassEx(&wc)) { + MessageBoxEx(NULL, "RegisterClass() failed: Cannot register window class.", "Error", MB_OK, 0); + return; + } + + //Always start in windowed mode + iWidth = GH_SCREEN_WIDTH; + iHeight = GH_SCREEN_HEIGHT; + + //Create the window + hWnd = CreateWindowEx( + WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, + GH_CLASS, + GH_TITLE, + WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, + GH_SCREEN_X, + GH_SCREEN_Y, + iWidth, + iHeight, + NULL, + NULL, + hInstance, + NULL); + + if (hWnd == NULL) { + MessageBoxEx(NULL, "CreateWindow() failed: Cannot create a window.", "Error", MB_OK, 0); + return; + } + + hDC = GetDC(hWnd); + + PIXELFORMATDESCRIPTOR pfd; + memset(&pfd, 0, sizeof(pfd)); + pfd.nSize = sizeof(pfd); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 32; + pfd.cDepthBits = 32; + pfd.iLayerType = PFD_MAIN_PLANE; + + const int pf = ChoosePixelFormat(hDC, &pfd); + if (pf == 0) { + MessageBoxEx(NULL, "ChoosePixelFormat() failed: Cannot find a suitable pixel format.", "Error", MB_OK, 0); + return; + } + + if (SetPixelFormat(hDC, pf, &pfd) == FALSE) { + MessageBoxEx(NULL, "SetPixelFormat() failed: Cannot set format specified.", "Error", MB_OK, 0); + return; + } + + DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + + hRC = wglCreateContext(hDC); + wglMakeCurrent(hDC, hRC); + + if (GH_START_FULLSCREEN) { + ToggleFullscreen(); + } + if (GH_HIDE_MOUSE) { + ShowCursor(FALSE); + } + + ShowWindow(hWnd, SW_SHOW); + SetForegroundWindow(hWnd); + SetFocus(hWnd); +} + +void Engine::DestroyGLWindow() { + ClipCursor(NULL); + wglMakeCurrent(NULL, NULL); + ReleaseDC(hWnd, hDC); + wglDeleteContext(hRC); + DestroyWindow(hWnd); +} + +int Engine::EnterMessageLoop() { + if (!hWnd || !hDC || !hRC) { + return 1; + } + + //Recieve events from this window + SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)this); + + //Setup the timer + ticks_per_step = timer.SecondsToTicks(GH_DT); + int64_t cur_ticks = timer.GetTicks(); + GH_FRAME = 0; + + //Game loop + MSG msg; + while (true) { + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + //Handle windows messages + if (msg.message == WM_QUIT) { + break; + } else { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } else { + //Confine the cursor + ConfineCursor(); + + if (input.key_press['1']) { + LoadScene(0); + } else if (input.key_press['2']) { + LoadScene(1); + } else if (input.key_press['3']) { + LoadScene(2); + } else if (input.key_press['4']) { + LoadScene(3); + } else if (input.key_press['5']) { + LoadScene(4); + } else if (input.key_press['6']) { + LoadScene(5); + } else if (input.key_press['7']) { + LoadScene(6); + } + + PeriodicRender(cur_ticks); + SwapBuffers(hDC); + } + } + + return 0; +} + +void Engine::EnableVSync() { + //Attempt to enalbe vsync (if failure then oh well) + wglSwapIntervalEXT(1); +} + +#endif // _WIN32 diff --git a/NonEuclidean/Input.cpp b/NonEuclidean/Input.cpp index 3faaa4f..1843e2b 100644 --- a/NonEuclidean/Input.cpp +++ b/NonEuclidean/Input.cpp @@ -1,6 +1,10 @@ #include "Input.h" #include "GameHeader.h" -#include +#if defined(_WIN32) + #include +#else + #include "SDL.h" +#endif #include Input::Input() { @@ -16,6 +20,8 @@ void Input::EndFrame() { mouse_ddy = 0.0f; } +#if defined(_WIN32) + void Input::UpdateRaw(const tagRAWINPUT* raw) { static BYTE buffer[2048]; static UINT buffer_size = sizeof(buffer); @@ -44,3 +50,41 @@ void Input::UpdateRaw(const tagRAWINPUT* raw) { //TODO: } } + +#else + +void Input::UpdateRaw() { + + // read mouse position and buttons + int mouse_x, mouse_y; + uint32_t state = SDL_GetRelativeMouseState(&mouse_x, &mouse_y); + mouse_dx = (float)mouse_x; + mouse_dy = (float)mouse_y; + mouse_ddx += mouse_dx; + mouse_ddy += mouse_dy; + if (state & SDL_BUTTON(SDL_BUTTON_LEFT)) { + mouse_button[0] = true; + mouse_button_press[0] = true; + } + if (state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) { + mouse_button[1] = true; + mouse_button_press[1] = true; + } + if (state & SDL_BUTTON(SDL_BUTTON_RIGHT)) { + mouse_button[2] = true; + mouse_button_press[2] = true; + } + + // read key state + const uint8_t* immediate_keys = SDL_GetKeyboardState(nullptr); + for (int k='A'; k<='Z'; k++) { + key[k] = immediate_keys[SDL_SCANCODE_A + (k - 'A')]; + key_press[k] = immediate_keys[SDL_SCANCODE_A + (k - 'A')]; + } + for (int k='0'; k<='9'; k++) { + key[k] = immediate_keys[SDL_SCANCODE_0 + (k - '0')]; + key_press[k] = immediate_keys[SDL_SCANCODE_0 + (k - '0')]; + } +} + +#endif diff --git a/NonEuclidean/Input.h b/NonEuclidean/Input.h index febe919..775564b 100644 --- a/NonEuclidean/Input.h +++ b/NonEuclidean/Input.h @@ -6,7 +6,12 @@ class Input { Input(); void EndFrame(); + +#if defined(_WIN32) void UpdateRaw(const tagRAWINPUT* raw); +#else + void UpdateRaw(); +#endif //Keyboard bool key[256]; diff --git a/NonEuclidean/Main.cpp b/NonEuclidean/Main.cpp index d2a2e11..96362cd 100644 --- a/NonEuclidean/Main.cpp +++ b/NonEuclidean/Main.cpp @@ -1,6 +1,12 @@ -#define _CRT_SECURE_NO_WARNINGS +#if defined(_WIN32) + #define _CRT_SECURE_NO_WARNINGS +#endif #include "Engine.h" +#if defined(_WIN32) + +// --- Windows -------------------------------------------------------------- + int APIENTRY WinMain(HINSTANCE hCurrentInst, HINSTANCE hPreviousInst, LPSTR lpszCmdLine, int nCmdShow) { //Open console in debug mode #ifdef _DEBUG @@ -14,3 +20,14 @@ int APIENTRY WinMain(HINSTANCE hCurrentInst, HINSTANCE hPreviousInst, LPSTR lpsz Engine engine; return engine.Run(); } + +#else + +// --- non-Windows ---------------------------------------------------------- + +int main(int argc, char** argv) { + Engine engine; + return engine.Run(); +} + +#endif diff --git a/NonEuclidean/Makefile b/NonEuclidean/Makefile new file mode 100644 index 0000000..d0b064c --- /dev/null +++ b/NonEuclidean/Makefile @@ -0,0 +1,31 @@ +CXX=g++ -c +CXXFLAGS=-O2 -ggdb -I/usr/include/SDL2 +LINK=g++ +LINKFLAGS=-lm -lSDL2 -lSDL2main -lGLEW -lGL + +EXE=NonEuclidean + +HEADERS=Camera.h Collider.h Engine.h Floorplan.h FrameBuffer.h GameHeader.h \ + Ground.h House.h Input.h Mesh.h Object.h Physical.h Pillar.h PillarRoom.h \ + Player.h Portal.h Resources.h Scene.h Shader.h Sky.h Sphere.h Statue.h \ + Texture.h Timer.h Tunnel.h Vector.h \ + Level1.h Level2.h Level3.h Level4.h Level5.h Level6.h + +OBJS=Camera.o Collider.o Engine.o Engine_Win32.o Engine_SDL2.o \ + FrameBuffer.o Input.o \ + Level1.o Level2.o Level3.o Level4.o Level5.o Level6.o \ + Main.o Mesh.o Object.o Physical.o Player.o Portal.o \ + Resources.o Shader.o Texture.o + +.PHONY: all clean + +all: ${EXE} + +clean: + rm ${OBJS} + +${EXE}: ${OBJS} + ${LINK} ${LINKFLAGS} $^ -o ${EXE} + +%.o : %.cpp ${HEADERS} + ${CXX} ${CXXFLAGS} $*.cpp -o $*.o diff --git a/NonEuclidean/Player.cpp b/NonEuclidean/Player.cpp index 69c66e7..a4f18b4 100644 --- a/NonEuclidean/Player.cpp +++ b/NonEuclidean/Player.cpp @@ -1,7 +1,9 @@ #include "Player.h" #include "Input.h" #include "GameHeader.h" -#include +#if defined(_WIN32) + #include +#endif #include Player::Player() { diff --git a/NonEuclidean/Shader.h b/NonEuclidean/Shader.h index 6ff91ea..b17a3f2 100644 --- a/NonEuclidean/Shader.h +++ b/NonEuclidean/Shader.h @@ -1,4 +1,6 @@ #pragma once +#include +#include #include #include diff --git a/NonEuclidean/Timer.h b/NonEuclidean/Timer.h index 9713a11..501bd54 100644 --- a/NonEuclidean/Timer.h +++ b/NonEuclidean/Timer.h @@ -1,4 +1,9 @@ #pragma once + +#if defined(_WIN32) + +// --- Windows -------------------------------------------------------------- + #include class Timer { @@ -35,3 +40,46 @@ class Timer { LARGE_INTEGER frequency; // ticks per second LARGE_INTEGER t1, t2; // ticks }; + +#else + +// --- non-Windows ---------------------------------------------------------- + +#include "SDL.h" + +class Timer { +public: + Timer() { + frequency = SDL_GetPerformanceFrequency(); + } + + void Start() { + t1 = SDL_GetPerformanceCounter(); + } + + float Stop() { + t2 = SDL_GetPerformanceCounter(); + return float(t2 - t1) / frequency; + } + + int64_t GetTicks() { + t2 = SDL_GetPerformanceCounter(); + return t2; + } + + int64_t SecondsToTicks(float s) { + return int64_t(float(frequency) * s); + } + + float StopStart() { + const float result = Stop(); + t1 = t2; + return result; + } + +private: + int64_t frequency; // ticks per second + int64_t t1, t2; // ticks +}; + +#endif From e09f089e0a4f78aa7cc603fd506ec365a630ebdf Mon Sep 17 00:00:00 2001 From: Jiri Bluebear Dluhos Date: Mon, 25 Mar 2019 23:17:03 +0100 Subject: [PATCH 02/25] Fixed tabs/spaces. --- NonEuclidean/Engine_SDL2.cpp | 78 ++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/NonEuclidean/Engine_SDL2.cpp b/NonEuclidean/Engine_SDL2.cpp index deb11ca..5126346 100644 --- a/NonEuclidean/Engine_SDL2.cpp +++ b/NonEuclidean/Engine_SDL2.cpp @@ -15,41 +15,41 @@ // --- SDL2-specific code ------------------------------------------------ bool Engine::InitOSWrapper() { - if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { - SDL_Log("Unable to initialize SDL: %s", SDL_GetError()); - return false; - } + if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { + SDL_Log("Unable to initialize SDL: %s", SDL_GetError()); + return false; + } - atexit(SDL_Quit); // SDL will be shut down automatically on app exit - return true; + atexit(SDL_Quit); // SDL will be shut down automatically on app exit + return true; } void Engine::SetupInputs() { - // not needed + // not needed } void Engine::CreateGLWindow() { - iWidth = GH_SCREEN_WIDTH; - iHeight = GH_SCREEN_HEIGHT; - - window = SDL_CreateWindow( - GH_TITLE, - GH_SCREEN_X, GH_SCREEN_Y, - iWidth, iHeight, - SDL_WINDOW_OPENGL|SDL_WINDOW_ALLOW_HIGHDPI| - (GH_START_FULLSCREEN ? SDL_WINDOW_FULLSCREEN : 0) + iWidth = GH_SCREEN_WIDTH; + iHeight = GH_SCREEN_HEIGHT; + + window = SDL_CreateWindow( + GH_TITLE, + GH_SCREEN_X, GH_SCREEN_Y, + iWidth, iHeight, + SDL_WINDOW_OPENGL|SDL_WINDOW_ALLOW_HIGHDPI| + (GH_START_FULLSCREEN ? SDL_WINDOW_FULLSCREEN : 0) ); if (!window) { - SDL_Log("Unable to create GL window: %s", SDL_GetError()); - return; + SDL_Log("Unable to create GL window: %s", SDL_GetError()); + return; } // window successfully created glContext = SDL_GL_CreateContext(window); if (!glContext) { - SDL_Log("Unable to create GL context: %s", SDL_GetError()); - return; + SDL_Log("Unable to create GL context: %s", SDL_GetError()); + return; } // GL context is created and is current for the calling thread @@ -58,20 +58,20 @@ void Engine::CreateGLWindow() { } void Engine::DestroyGLWindow() { - if (glContext) { - SDL_GL_DeleteContext(glContext); - } - if (window) { - SDL_DestroyWindow(window); - } + if (glContext) { + SDL_GL_DeleteContext(glContext); + } + if (window) { + SDL_DestroyWindow(window); + } } void Engine::EnableVSync() { - // try adaptive vsync first, if not supported, go full vsync - if (SDL_GL_SetSwapInterval(-1) != 0) { - SDL_GL_SetSwapInterval(1); - } + // try adaptive vsync first, if not supported, go full vsync + if (SDL_GL_SetSwapInterval(-1) != 0) { + SDL_GL_SetSwapInterval(1); + } } int Engine::EnterMessageLoop() { @@ -83,14 +83,14 @@ int Engine::EnterMessageLoop() { SDL_Event event; while(true) { - if (SDL_PollEvent(&event)) { - if (event.type == SDL_QUIT) { - break; - } - } - else { + if (SDL_PollEvent(&event)) { + if (event.type == SDL_QUIT) { + break; + } + } + else { - input.UpdateRaw(); + input.UpdateRaw(); //Confine the cursor ConfineCursor(); @@ -121,10 +121,10 @@ int Engine::EnterMessageLoop() { void Engine::ConfineCursor() { - // TODO + // TODO } void Engine::SwapBuffers() { - SDL_GL_SwapWindow(window); + SDL_GL_SwapWindow(window); } From d2ab3e264565e7150e8ee789f608a3bc07cfa1c9 Mon Sep 17 00:00:00 2001 From: Srinivasa Date: Tue, 4 Aug 2020 18:04:21 +0530 Subject: [PATCH 03/25] Update .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 5a5e0d9..f5a7390 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ Release/ Floorplan/ Thumbs.db glew-2.1.0 +*.o +.vscode +NonEuclidean From 9ec9533757287cd92868ee8184e5b8715eba33f0 Mon Sep 17 00:00:00 2001 From: Srinivasa Date: Tue, 4 Aug 2020 18:08:34 +0530 Subject: [PATCH 04/25] ignore executable instead of whole directory --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f5a7390..9f793de 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,4 @@ Thumbs.db glew-2.1.0 *.o .vscode -NonEuclidean +NonEuclidean/NonEuclidean From 8065b61ae70aef92c535716a6d5856690d0bd586 Mon Sep 17 00:00:00 2001 From: Srinivasa Date: Tue, 4 Aug 2020 18:09:12 +0530 Subject: [PATCH 05/25] Replace gl_FragColor with fragColor --- NonEuclidean/Shaders/pink.frag | 4 ++-- NonEuclidean/Shaders/portal.frag | 4 ++-- NonEuclidean/Shaders/sky.frag | 4 ++-- NonEuclidean/Shaders/texture.frag | 4 ++-- NonEuclidean/Shaders/texture_array.frag | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/NonEuclidean/Shaders/pink.frag b/NonEuclidean/Shaders/pink.frag index a94e6db..68c6545 100644 --- a/NonEuclidean/Shaders/pink.frag +++ b/NonEuclidean/Shaders/pink.frag @@ -5,8 +5,8 @@ precision highp float; uniform sampler2D tex; //Outputs -out vec4 gl_FragColor; +out vec4 fragColor; void main(void) { - gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0); + fragColor = vec4(1.0, 0.0, 1.0, 1.0); } diff --git a/NonEuclidean/Shaders/portal.frag b/NonEuclidean/Shaders/portal.frag index b8b65cb..a7980b1 100644 --- a/NonEuclidean/Shaders/portal.frag +++ b/NonEuclidean/Shaders/portal.frag @@ -6,10 +6,10 @@ uniform sampler2D tex; in vec4 ex_uv; //Outputs -out vec4 gl_FragColor; +out vec4 fragColor; void main(void) { vec2 uv = (ex_uv.xy / ex_uv.w); uv = uv*0.5 + 0.5; - gl_FragColor = vec4(texture2D(tex, uv).rgb, 1.0); + fragColor = vec4(texture2D(tex, uv).rgb, 1.0); } diff --git a/NonEuclidean/Shaders/sky.frag b/NonEuclidean/Shaders/sky.frag index 88acd21..d0d5320 100644 --- a/NonEuclidean/Shaders/sky.frag +++ b/NonEuclidean/Shaders/sky.frag @@ -9,7 +9,7 @@ precision highp float; in vec3 ex_normal; //Outputs -out vec4 gl_FragColor; +out vec4 fragColor; void main(void) { vec3 n = normalize(ex_normal); @@ -20,5 +20,5 @@ void main(void) { float s = dot(n, LIGHT) - 1.0 + SUN_SIZE; float sun = min(exp(s * SUN_SHARPNESS / SUN_SIZE), 1.0); - gl_FragColor = vec4(max(sky, sun), 1.0); + fragColor = vec4(max(sky, sun), 1.0); } diff --git a/NonEuclidean/Shaders/texture.frag b/NonEuclidean/Shaders/texture.frag index 64a95f5..6826085 100644 --- a/NonEuclidean/Shaders/texture.frag +++ b/NonEuclidean/Shaders/texture.frag @@ -9,9 +9,9 @@ in vec2 ex_uv; in vec3 ex_normal; //Outputs -out vec4 gl_FragColor; +out vec4 fragColor; void main(void) { float s = dot(ex_normal, LIGHT)*0.5 + 0.5; - gl_FragColor = vec4(texture(tex, ex_uv).rgb * s, 1.0); + fragColor = vec4(texture(tex, ex_uv).rgb * s, 1.0); } diff --git a/NonEuclidean/Shaders/texture_array.frag b/NonEuclidean/Shaders/texture_array.frag index 305c653..95f086f 100644 --- a/NonEuclidean/Shaders/texture_array.frag +++ b/NonEuclidean/Shaders/texture_array.frag @@ -9,9 +9,9 @@ in vec3 ex_uv; in vec3 ex_normal; //Outputs -out vec4 gl_FragColor; +out vec4 fragColor; void main(void) { float s = dot(ex_normal, LIGHT)*0.25 + 0.75; - gl_FragColor = vec4(texture(tex, ex_uv).rgb * s, 1.0); + fragColor = vec4(texture(tex, ex_uv).rgb * s, 1.0); } From 2d01866609dd1e9b386a9ec38f12220f1df8099f Mon Sep 17 00:00:00 2001 From: Srinivasa Date: Tue, 4 Aug 2020 18:09:52 +0530 Subject: [PATCH 06/25] Fix number keypress detection --- NonEuclidean/Input.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NonEuclidean/Input.cpp b/NonEuclidean/Input.cpp index 1843e2b..51e7bee 100644 --- a/NonEuclidean/Input.cpp +++ b/NonEuclidean/Input.cpp @@ -82,8 +82,8 @@ void Input::UpdateRaw() { key_press[k] = immediate_keys[SDL_SCANCODE_A + (k - 'A')]; } for (int k='0'; k<='9'; k++) { - key[k] = immediate_keys[SDL_SCANCODE_0 + (k - '0')]; - key_press[k] = immediate_keys[SDL_SCANCODE_0 + (k - '0')]; + key[k] = immediate_keys[SDL_SCANCODE_1 + (k - '1')]; + key_press[k] = immediate_keys[SDL_SCANCODE_1 + (k - '1')]; } } From 983700597a08919ffbd34793475293de5a81d2c4 Mon Sep 17 00:00:00 2001 From: Srinivasa Date: Tue, 4 Aug 2020 18:24:46 +0530 Subject: [PATCH 07/25] Exit if escape is pressed --- NonEuclidean/Input.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NonEuclidean/Input.cpp b/NonEuclidean/Input.cpp index 51e7bee..0b02ba0 100644 --- a/NonEuclidean/Input.cpp +++ b/NonEuclidean/Input.cpp @@ -77,6 +77,11 @@ void Input::UpdateRaw() { // read key state const uint8_t* immediate_keys = SDL_GetKeyboardState(nullptr); + + if (immediate_keys[SDL_SCANCODE_ESCAPE]) { + exit(0); + } + for (int k='A'; k<='Z'; k++) { key[k] = immediate_keys[SDL_SCANCODE_A + (k - 'A')]; key_press[k] = immediate_keys[SDL_SCANCODE_A + (k - 'A')]; From 471be26f4d7e37291ffd535e9e8d9f22262a6915 Mon Sep 17 00:00:00 2001 From: Srinivasa Date: Tue, 4 Aug 2020 19:10:56 +0530 Subject: [PATCH 08/25] Made fullscreen toggle work --- NonEuclidean/Engine_SDL2.cpp | 21 ++++++++++++++++++++- NonEuclidean/Input.cpp | 4 ++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/NonEuclidean/Engine_SDL2.cpp b/NonEuclidean/Engine_SDL2.cpp index 5126346..47207a4 100644 --- a/NonEuclidean/Engine_SDL2.cpp +++ b/NonEuclidean/Engine_SDL2.cpp @@ -28,6 +28,23 @@ void Engine::SetupInputs() { // not needed } +void Engine::ToggleFullscreen() { + if (isFullscreen) { + iWidth=GH_SCREEN_WIDTH; + iHeight=GH_SCREEN_HEIGHT; + SDL_SetWindowFullscreen(window,0); + SDL_SetWindowSize(window,iWidth,iHeight); + } + else { + SDL_DisplayMode DM; + SDL_GetCurrentDisplayMode(0, &DM); + iWidth=DM.w; + iHeight=DM.h; + SDL_SetWindowFullscreen(window,SDL_WINDOW_FULLSCREEN); + } + isFullscreen = !isFullscreen; +} + void Engine::CreateGLWindow() { iWidth = GH_SCREEN_WIDTH; iHeight = GH_SCREEN_HEIGHT; @@ -91,7 +108,9 @@ int Engine::EnterMessageLoop() { else { input.UpdateRaw(); - + if (input.key_press['\n'] && event.key.repeat == 0) { + ToggleFullscreen(); + } //Confine the cursor ConfineCursor(); diff --git a/NonEuclidean/Input.cpp b/NonEuclidean/Input.cpp index 0b02ba0..35bb57c 100644 --- a/NonEuclidean/Input.cpp +++ b/NonEuclidean/Input.cpp @@ -82,6 +82,10 @@ void Input::UpdateRaw() { exit(0); } + if(immediate_keys[SDL_SCANCODE_RETURN] && (immediate_keys[SDL_SCANCODE_LALT] || immediate_keys[SDL_SCANCODE_RALT])) { + key_press['\n'] =1; + } + for (int k='A'; k<='Z'; k++) { key[k] = immediate_keys[SDL_SCANCODE_A + (k - 'A')]; key_press[k] = immediate_keys[SDL_SCANCODE_A + (k - 'A')]; From 2f77387d93ad3c01c6aa186554033d67b8f4bbc9 Mon Sep 17 00:00:00 2001 From: Srinivasa Date: Wed, 5 Aug 2020 09:12:44 +0530 Subject: [PATCH 09/25] Did few fixes --- NonEuclidean/Engine.cpp | 2 +- NonEuclidean/Engine.h | 5 ++--- NonEuclidean/Engine_SDL2.cpp | 20 +++++++++----------- NonEuclidean/Input.cpp | 2 +- NonEuclidean/Makefile | 2 +- NonEuclidean/Timer.h | 2 +- 6 files changed, 15 insertions(+), 18 deletions(-) diff --git a/NonEuclidean/Engine.cpp b/NonEuclidean/Engine.cpp index b2ebeba..e5a9e76 100644 --- a/NonEuclidean/Engine.cpp +++ b/NonEuclidean/Engine.cpp @@ -58,7 +58,7 @@ int Engine::Run() { return 0; } -void Engine::PeriodicRender(int64_t cur_ticks) { +void Engine::PeriodicRender(int64_t &cur_ticks) { //Used fixed time steps for updates const int64_t new_ticks = timer.GetTicks(); diff --git a/NonEuclidean/Engine.h b/NonEuclidean/Engine.h index d15d1a6..7ec6061 100644 --- a/NonEuclidean/Engine.h +++ b/NonEuclidean/Engine.h @@ -12,7 +12,7 @@ #if defined(_WIN32) #include #else - #include "SDL.h" + #include #endif #include #include @@ -44,8 +44,7 @@ class Engine { void ConfineCursor(); void ToggleFullscreen(); int EnterMessageLoop(); - void PeriodicRender(int64_t cur_ticks); - void SwapBuffers(); + void PeriodicRender(int64_t &cur_ticks); void EnableVSync(); #if defined(_WIN32) diff --git a/NonEuclidean/Engine_SDL2.cpp b/NonEuclidean/Engine_SDL2.cpp index 47207a4..6a8d6fb 100644 --- a/NonEuclidean/Engine_SDL2.cpp +++ b/NonEuclidean/Engine_SDL2.cpp @@ -6,7 +6,7 @@ #include "Level4.h" #include "Level5.h" #include "Level6.h" -#include "SDL.h" +#include #include #include #include @@ -92,7 +92,10 @@ void Engine::EnableVSync() { } int Engine::EnterMessageLoop() { - + if (GH_HIDE_MOUSE) { + SDL_SetWindowGrab(window,SDL_TRUE); + SDL_ShowCursor(SDL_DISABLE); + } //Setup the timer ticks_per_step = timer.SecondsToTicks(GH_DT); int64_t cur_ticks = timer.GetTicks(); @@ -131,7 +134,7 @@ int Engine::EnterMessageLoop() { } PeriodicRender(cur_ticks); - SwapBuffers(); + SDL_GL_SwapWindow(window); } } @@ -139,11 +142,6 @@ int Engine::EnterMessageLoop() { } void Engine::ConfineCursor() -{ - // TODO -} - -void Engine::SwapBuffers() -{ - SDL_GL_SwapWindow(window); -} +{ + //not needed +} \ No newline at end of file diff --git a/NonEuclidean/Input.cpp b/NonEuclidean/Input.cpp index 35bb57c..f513ae5 100644 --- a/NonEuclidean/Input.cpp +++ b/NonEuclidean/Input.cpp @@ -3,7 +3,7 @@ #if defined(_WIN32) #include #else - #include "SDL.h" + #include #endif #include diff --git a/NonEuclidean/Makefile b/NonEuclidean/Makefile index d0b064c..2589551 100644 --- a/NonEuclidean/Makefile +++ b/NonEuclidean/Makefile @@ -1,5 +1,5 @@ CXX=g++ -c -CXXFLAGS=-O2 -ggdb -I/usr/include/SDL2 +CXXFLAGS=-O2 -ggdb LINK=g++ LINKFLAGS=-lm -lSDL2 -lSDL2main -lGLEW -lGL diff --git a/NonEuclidean/Timer.h b/NonEuclidean/Timer.h index 501bd54..04ab8a1 100644 --- a/NonEuclidean/Timer.h +++ b/NonEuclidean/Timer.h @@ -45,7 +45,7 @@ class Timer { // --- non-Windows ---------------------------------------------------------- -#include "SDL.h" +#include class Timer { public: From 56808437d07740140b49b3ebe67759e5ddc6932a Mon Sep 17 00:00:00 2001 From: Srinivasa Date: Wed, 5 Aug 2020 09:18:09 +0530 Subject: [PATCH 10/25] Updated README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9084b5c..41d0b30 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # NonEuclidean -A NonEuclidean rendering engine for Windows, written in C++ OpenGL. +A NonEuclidean rendering engine for Win32(Windows) and SDL2(Windows,Linux,MacOs,etc.), written in C++ OpenGL. To see what this code is about, check out this video: https://youtu.be/kEB11PQ9Eo8 ## Source Code Dependencies -Add glew-2.1.0 to the main directory +Add glew-2.1.0 to the main directory(Win32) ## Controls * **Mouse** - Look around From 5dc16f16fcf017dbda1e0cfc349758d16b4ff72d Mon Sep 17 00:00:00 2001 From: Srinivasa Date: Wed, 5 Aug 2020 10:58:07 +0530 Subject: [PATCH 11/25] Do keypress handling in SDL eventloop --- NonEuclidean/Engine_SDL2.cpp | 74 +++++++++++++++++++++++------------- NonEuclidean/Input.cpp | 20 ---------- 2 files changed, 48 insertions(+), 46 deletions(-) diff --git a/NonEuclidean/Engine_SDL2.cpp b/NonEuclidean/Engine_SDL2.cpp index 6a8d6fb..1754d77 100644 --- a/NonEuclidean/Engine_SDL2.cpp +++ b/NonEuclidean/Engine_SDL2.cpp @@ -107,35 +107,57 @@ int Engine::EnterMessageLoop() { if (event.type == SDL_QUIT) { break; } - } - else { - - input.UpdateRaw(); - if (input.key_press['\n'] && event.key.repeat == 0) { - ToggleFullscreen(); + else if (event.type == SDL_KEYDOWN && event.key.repeat == 0) { + auto keycode = event.key.keysym.sym; + auto mod = event.key.keysym.mod; + if (keycode == SDLK_ESCAPE) { + break; + } + else if (keycode == SDLK_RETURN && (mod == KMOD_LALT || mod == KMOD_RALT) ) { + ToggleFullscreen(); + } + else if (keycode >= 'a' && keycode <= 'z') + { + input.key_press[toupper(keycode)] = true; + input.key[toupper(keycode)] = true; + } + else if (keycode >= '0' && keycode <= '9') { + input.key_press[keycode] = true; + input.key[keycode] = true; + } } - //Confine the cursor - ConfineCursor(); - - if (input.key_press['1']) { - LoadScene(0); - } else if (input.key_press['2']) { - LoadScene(1); - } else if (input.key_press['3']) { - LoadScene(2); - } else if (input.key_press['4']) { - LoadScene(3); - } else if (input.key_press['5']) { - LoadScene(4); - } else if (input.key_press['6']) { - LoadScene(5); - } else if (input.key_press['7']) { - LoadScene(6); + else if (event.type == SDL_KEYUP) { + auto keycode = event.key.keysym.sym; + if (keycode >= 'a' && keycode <= 'z') + { + input.key[toupper(keycode)] = false; + } + else if (keycode >= '0' && keycode <= '9') { + input.key[keycode] = false; + } } - - PeriodicRender(cur_ticks); - SDL_GL_SwapWindow(window); } + + input.UpdateRaw(); + + if (input.key_press['1']) { + LoadScene(0); + } else if (input.key_press['2']) { + LoadScene(1); + } else if (input.key_press['3']) { + LoadScene(2); + } else if (input.key_press['4']) { + LoadScene(3); + } else if (input.key_press['5']) { + LoadScene(4); + } else if (input.key_press['6']) { + LoadScene(5); + } else if (input.key_press['7']) { + LoadScene(6); + } + + PeriodicRender(cur_ticks); + SDL_GL_SwapWindow(window); } return 0; diff --git a/NonEuclidean/Input.cpp b/NonEuclidean/Input.cpp index f513ae5..9753762 100644 --- a/NonEuclidean/Input.cpp +++ b/NonEuclidean/Input.cpp @@ -74,26 +74,6 @@ void Input::UpdateRaw() { mouse_button[2] = true; mouse_button_press[2] = true; } - - // read key state - const uint8_t* immediate_keys = SDL_GetKeyboardState(nullptr); - - if (immediate_keys[SDL_SCANCODE_ESCAPE]) { - exit(0); - } - - if(immediate_keys[SDL_SCANCODE_RETURN] && (immediate_keys[SDL_SCANCODE_LALT] || immediate_keys[SDL_SCANCODE_RALT])) { - key_press['\n'] =1; - } - - for (int k='A'; k<='Z'; k++) { - key[k] = immediate_keys[SDL_SCANCODE_A + (k - 'A')]; - key_press[k] = immediate_keys[SDL_SCANCODE_A + (k - 'A')]; - } - for (int k='0'; k<='9'; k++) { - key[k] = immediate_keys[SDL_SCANCODE_1 + (k - '1')]; - key_press[k] = immediate_keys[SDL_SCANCODE_1 + (k - '1')]; - } } #endif From 3d6753dbe0b8101f93f9609f20aedffec8a40d6c Mon Sep 17 00:00:00 2001 From: Srinivasa314 <62195746+Srinivasa314@users.noreply.github.com> Date: Wed, 5 Aug 2020 11:41:03 +0530 Subject: [PATCH 12/25] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 41d0b30..9cf1814 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # NonEuclidean -A NonEuclidean rendering engine for Win32(Windows) and SDL2(Windows,Linux,MacOs,etc.), written in C++ OpenGL. +A NonEuclidean rendering engine for Win32 and SDL2, written in C++ OpenGL. To see what this code is about, check out this video: https://youtu.be/kEB11PQ9Eo8 From 74a796b61b11f929b2b36f39e0d132481ab71b84 Mon Sep 17 00:00:00 2001 From: Srinivasa Date: Wed, 5 Aug 2020 11:52:48 +0530 Subject: [PATCH 13/25] Compile in release mode --- NonEuclidean/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NonEuclidean/Makefile b/NonEuclidean/Makefile index 2589551..bfed07f 100644 --- a/NonEuclidean/Makefile +++ b/NonEuclidean/Makefile @@ -1,5 +1,5 @@ CXX=g++ -c -CXXFLAGS=-O2 -ggdb +CXXFLAGS=-O3 LINK=g++ LINKFLAGS=-lm -lSDL2 -lSDL2main -lGLEW -lGL From 66585b34971b1d9e1621ba44b6742a3f4f8876cc Mon Sep 17 00:00:00 2001 From: Srinivasa314 <62195746+Srinivasa314@users.noreply.github.com> Date: Wed, 5 Aug 2020 13:00:58 +0530 Subject: [PATCH 14/25] Update NonEuclidean.vcxproj --- NonEuclidean/NonEuclidean.vcxproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NonEuclidean/NonEuclidean.vcxproj b/NonEuclidean/NonEuclidean.vcxproj index 7be5694..c104ce1 100644 --- a/NonEuclidean/NonEuclidean.vcxproj +++ b/NonEuclidean/NonEuclidean.vcxproj @@ -154,6 +154,7 @@ + @@ -209,4 +210,4 @@ - \ No newline at end of file + From 83d73e563309357934c497a5253135d8919229e5 Mon Sep 17 00:00:00 2001 From: Srinivasa Date: Wed, 5 Aug 2020 15:47:13 +0530 Subject: [PATCH 15/25] Change g++ to c++ --- NonEuclidean/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NonEuclidean/Makefile b/NonEuclidean/Makefile index bfed07f..622013d 100644 --- a/NonEuclidean/Makefile +++ b/NonEuclidean/Makefile @@ -1,6 +1,6 @@ -CXX=g++ -c +CXX=c++ -c CXXFLAGS=-O3 -LINK=g++ +LINK=c++ LINKFLAGS=-lm -lSDL2 -lSDL2main -lGLEW -lGL EXE=NonEuclidean From f6ca63c1bbf5c597da5087db83dab8f0fd50aa8a Mon Sep 17 00:00:00 2001 From: Srinivasa Date: Wed, 5 Aug 2020 16:23:50 +0530 Subject: [PATCH 16/25] Add build instructions --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9cf1814..53fc4e4 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,17 @@ To see what this code is about, check out this video: https://youtu.be/kEB11PQ9Eo8 ## Source Code Dependencies -Add glew-2.1.0 to the main directory(Win32) +Win32 - Add glew-2.1.0 to the main directory +SDL - Install glew and SDL libraries + +## Building +Win32 - Open NonEuclidean.sln +SDL : +```sh +cd NonEuclidean +make all +./NonEuclidean +``` ## Controls * **Mouse** - Look around From 8ff86b7583531e00e1a26c6a8c2cb3c16fd6ec8d Mon Sep 17 00:00:00 2001 From: Srinivasa314 <62195746+Srinivasa314@users.noreply.github.com> Date: Wed, 5 Aug 2020 16:25:41 +0530 Subject: [PATCH 17/25] Add newlines --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 53fc4e4..a76cb90 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,12 @@ https://youtu.be/kEB11PQ9Eo8 ## Source Code Dependencies Win32 - Add glew-2.1.0 to the main directory + SDL - Install glew and SDL libraries ## Building Win32 - Open NonEuclidean.sln + SDL : ```sh cd NonEuclidean From 00399db8768cf2cebb3ff2d6c69b055ec4c498ca Mon Sep 17 00:00:00 2001 From: Srinivasa Date: Sun, 13 Sep 2020 12:36:16 +0530 Subject: [PATCH 18/25] Make window centered --- NonEuclidean/Engine_SDL2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NonEuclidean/Engine_SDL2.cpp b/NonEuclidean/Engine_SDL2.cpp index 1754d77..68bb66a 100644 --- a/NonEuclidean/Engine_SDL2.cpp +++ b/NonEuclidean/Engine_SDL2.cpp @@ -51,7 +51,7 @@ void Engine::CreateGLWindow() { window = SDL_CreateWindow( GH_TITLE, - GH_SCREEN_X, GH_SCREEN_Y, + SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, iWidth, iHeight, SDL_WINDOW_OPENGL|SDL_WINDOW_ALLOW_HIGHDPI| (GH_START_FULLSCREEN ? SDL_WINDOW_FULLSCREEN : 0) From 2932025a7a7954b860560916819dfee35ec03d89 Mon Sep 17 00:00:00 2001 From: Srinivasa Date: Sun, 13 Sep 2020 12:40:25 +0530 Subject: [PATCH 19/25] Use SDL2 API for confining cursor --- NonEuclidean/Engine_SDL2.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/NonEuclidean/Engine_SDL2.cpp b/NonEuclidean/Engine_SDL2.cpp index 68bb66a..0819f76 100644 --- a/NonEuclidean/Engine_SDL2.cpp +++ b/NonEuclidean/Engine_SDL2.cpp @@ -93,8 +93,7 @@ void Engine::EnableVSync() { int Engine::EnterMessageLoop() { if (GH_HIDE_MOUSE) { - SDL_SetWindowGrab(window,SDL_TRUE); - SDL_ShowCursor(SDL_DISABLE); + SDL_SetRelativeMouseMode(SDL_TRUE); } //Setup the timer ticks_per_step = timer.SecondsToTicks(GH_DT); From 8bbf7232055963a430beff7279539dd348679953 Mon Sep 17 00:00:00 2001 From: Srinivasa Date: Sun, 13 Sep 2020 14:23:14 +0530 Subject: [PATCH 20/25] Fix fullscreen shortcut in Xorg --- NonEuclidean/Engine_SDL2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NonEuclidean/Engine_SDL2.cpp b/NonEuclidean/Engine_SDL2.cpp index 0819f76..bef4969 100644 --- a/NonEuclidean/Engine_SDL2.cpp +++ b/NonEuclidean/Engine_SDL2.cpp @@ -112,7 +112,7 @@ int Engine::EnterMessageLoop() { if (keycode == SDLK_ESCAPE) { break; } - else if (keycode == SDLK_RETURN && (mod == KMOD_LALT || mod == KMOD_RALT) ) { + else if (keycode == SDLK_RETURN && (mod & KMOD_LALT || mod & KMOD_RALT) ) { ToggleFullscreen(); } else if (keycode >= 'a' && keycode <= 'z') From db50d85663120d3b37cb92d32c68efd2b5961296 Mon Sep 17 00:00:00 2001 From: Srinivasa Mahesh Date: Sun, 14 Mar 2021 11:10:05 +0530 Subject: [PATCH 21/25] fix linker error in OSX --- NonEuclidean/Makefile | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/NonEuclidean/Makefile b/NonEuclidean/Makefile index 622013d..74b0532 100644 --- a/NonEuclidean/Makefile +++ b/NonEuclidean/Makefile @@ -1,7 +1,17 @@ CXX=c++ -c CXXFLAGS=-O3 LINK=c++ -LINKFLAGS=-lm -lSDL2 -lSDL2main -lGLEW -lGL +LINKFLAGS=-lm -lSDL2 -lSDL2main -lGLEW + +UNAME := $(shell uname) + +ifeq ($(UNAME), Linux) +LINKFLAGS += -lGL +endif + +ifeq ($(UNAME), Darwin) +LINKFLAGS += -framework OpenGL +endif EXE=NonEuclidean From 9605024a2d192268c3ccf6dfb003f7c24138328d Mon Sep 17 00:00:00 2001 From: Srinivasa Mahesh Date: Wed, 17 Mar 2021 18:22:47 +0530 Subject: [PATCH 22/25] set glewExperimental to true --- NonEuclidean/Engine.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/NonEuclidean/Engine.cpp b/NonEuclidean/Engine.cpp index e5a9e76..e1b668a 100644 --- a/NonEuclidean/Engine.cpp +++ b/NonEuclidean/Engine.cpp @@ -222,6 +222,7 @@ void Engine::Render(const Camera& cam, GLuint curFBO, const Portal* skipPortal) void Engine::InitGLObjects() { //Initialize extensions + glewExperimental = GL_TRUE; glewInit(); //Basic global variables From 4831ce94afbf2167505b7ff6daf37e516428d29f Mon Sep 17 00:00:00 2001 From: Srinivasa Mahesh Date: Wed, 17 Mar 2021 18:23:54 +0530 Subject: [PATCH 23/25] put -std=c++11 in CXXFLAGS --- NonEuclidean/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NonEuclidean/Makefile b/NonEuclidean/Makefile index 74b0532..47f0947 100644 --- a/NonEuclidean/Makefile +++ b/NonEuclidean/Makefile @@ -1,5 +1,5 @@ CXX=c++ -c -CXXFLAGS=-O3 +CXXFLAGS=-O3 -std=c++11 LINK=c++ LINKFLAGS=-lm -lSDL2 -lSDL2main -lGLEW From 4fca8e3436062a9a4837d0809d0a1602519576fe Mon Sep 17 00:00:00 2001 From: Srinivasa Mahesh Date: Sun, 11 Sep 2022 09:35:54 +0530 Subject: [PATCH 24/25] make it work on mac os and support hidpi --- NonEuclidean/Engine_SDL2.cpp | 40 ++++++++++++++++++++++---------- NonEuclidean/Shaders/portal.frag | 2 +- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/NonEuclidean/Engine_SDL2.cpp b/NonEuclidean/Engine_SDL2.cpp index bef4969..ed24ba8 100644 --- a/NonEuclidean/Engine_SDL2.cpp +++ b/NonEuclidean/Engine_SDL2.cpp @@ -19,7 +19,9 @@ bool Engine::InitOSWrapper() { SDL_Log("Unable to initialize SDL: %s", SDL_GetError()); return false; } - + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); atexit(SDL_Quit); // SDL will be shut down automatically on app exit return true; } @@ -28,19 +30,33 @@ void Engine::SetupInputs() { // not needed } +// adapted from https://github.com/g8kig/LiteXL-PPC +static int query_surface_scale(SDL_Window *window) { + int w_pixels, h_pixels; + int w_points, h_points; + SDL_GL_GetDrawableSize(window, &w_pixels, &h_pixels); + SDL_GetWindowSize(window, &w_points, &h_points); + /* We consider that the ratio pixel/point will always be an integer and + it is the same along the x and the y axis. */ + assert(w_pixels % w_points == 0 && h_pixels % h_points == 0 && w_pixels / w_points == h_pixels / h_points); + return w_pixels / w_points; +} + void Engine::ToggleFullscreen() { if (isFullscreen) { iWidth=GH_SCREEN_WIDTH; iHeight=GH_SCREEN_HEIGHT; SDL_SetWindowFullscreen(window,0); - SDL_SetWindowSize(window,iWidth,iHeight); + int scale = query_surface_scale(window); + SDL_SetWindowSize(window,iWidth/scale,iHeight/scale); } else { - SDL_DisplayMode DM; - SDL_GetCurrentDisplayMode(0, &DM); - iWidth=DM.w; - iHeight=DM.h; - SDL_SetWindowFullscreen(window,SDL_WINDOW_FULLSCREEN); + int scale = query_surface_scale(window); + SDL_SetWindowFullscreen(window,SDL_WINDOW_FULLSCREEN_DESKTOP); + SDL_GetWindowSize(window,&iWidth,&iHeight); + iWidth*=scale; + iHeight*=scale; + SDL_SetWindowSize(window,iWidth,iHeight); } isFullscreen = !isFullscreen; } @@ -48,7 +64,6 @@ void Engine::ToggleFullscreen() { void Engine::CreateGLWindow() { iWidth = GH_SCREEN_WIDTH; iHeight = GH_SCREEN_HEIGHT; - window = SDL_CreateWindow( GH_TITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, @@ -56,6 +71,10 @@ void Engine::CreateGLWindow() { SDL_WINDOW_OPENGL|SDL_WINDOW_ALLOW_HIGHDPI| (GH_START_FULLSCREEN ? SDL_WINDOW_FULLSCREEN : 0) ); + int scale = query_surface_scale(window); + SDL_SetWindowSize(window,iWidth/scale,iHeight/scale); + SDL_SetWindowGrab(window,SDL_TRUE); + SDL_SetRelativeMouseMode(SDL_TRUE); if (!window) { SDL_Log("Unable to create GL window: %s", SDL_GetError()); return; @@ -92,9 +111,6 @@ void Engine::EnableVSync() { } int Engine::EnterMessageLoop() { - if (GH_HIDE_MOUSE) { - SDL_SetRelativeMouseMode(SDL_TRUE); - } //Setup the timer ticks_per_step = timer.SecondsToTicks(GH_DT); int64_t cur_ticks = timer.GetTicks(); @@ -165,4 +181,4 @@ int Engine::EnterMessageLoop() { void Engine::ConfineCursor() { //not needed -} \ No newline at end of file +} diff --git a/NonEuclidean/Shaders/portal.frag b/NonEuclidean/Shaders/portal.frag index a7980b1..4bf6fdf 100644 --- a/NonEuclidean/Shaders/portal.frag +++ b/NonEuclidean/Shaders/portal.frag @@ -11,5 +11,5 @@ out vec4 fragColor; void main(void) { vec2 uv = (ex_uv.xy / ex_uv.w); uv = uv*0.5 + 0.5; - fragColor = vec4(texture2D(tex, uv).rgb, 1.0); + fragColor = vec4(texture(tex, uv).rgb, 1.0); } From 49d09a04cf4ee54f54e974aacdd61b5af887d662 Mon Sep 17 00:00:00 2001 From: Srikanth Date: Sun, 11 Sep 2022 10:35:33 +0530 Subject: [PATCH 25/25] Fix fractional scaling and sluggish mouse movement --- NonEuclidean/Engine_SDL2.cpp | 40 ++++++++++++++++-------------------- NonEuclidean/Input.cpp | 12 ++++------- NonEuclidean/Input.h | 2 +- 3 files changed, 23 insertions(+), 31 deletions(-) diff --git a/NonEuclidean/Engine_SDL2.cpp b/NonEuclidean/Engine_SDL2.cpp index ed24ba8..b4f1a39 100644 --- a/NonEuclidean/Engine_SDL2.cpp +++ b/NonEuclidean/Engine_SDL2.cpp @@ -30,16 +30,13 @@ void Engine::SetupInputs() { // not needed } -// adapted from https://github.com/g8kig/LiteXL-PPC -static int query_surface_scale(SDL_Window *window) { +// from https://github.com/g8kig/LiteXL-PPC +static double query_surface_scale(SDL_Window *window) { int w_pixels, h_pixels; int w_points, h_points; SDL_GL_GetDrawableSize(window, &w_pixels, &h_pixels); SDL_GetWindowSize(window, &w_points, &h_points); - /* We consider that the ratio pixel/point will always be an integer and - it is the same along the x and the y axis. */ - assert(w_pixels % w_points == 0 && h_pixels % h_points == 0 && w_pixels / w_points == h_pixels / h_points); - return w_pixels / w_points; + return double(w_pixels) / double(w_points); } void Engine::ToggleFullscreen() { @@ -47,15 +44,15 @@ void Engine::ToggleFullscreen() { iWidth=GH_SCREEN_WIDTH; iHeight=GH_SCREEN_HEIGHT; SDL_SetWindowFullscreen(window,0); - int scale = query_surface_scale(window); - SDL_SetWindowSize(window,iWidth/scale,iHeight/scale); + double scale = query_surface_scale(window); + SDL_SetWindowSize(window,int(iWidth/scale),int(iHeight/scale)); } else { - int scale = query_surface_scale(window); + double scale = query_surface_scale(window); SDL_SetWindowFullscreen(window,SDL_WINDOW_FULLSCREEN_DESKTOP); SDL_GetWindowSize(window,&iWidth,&iHeight); - iWidth*=scale; - iHeight*=scale; + iWidth=int(iWidth*scale); + iHeight=int(iHeight*scale); SDL_SetWindowSize(window,iWidth,iHeight); } isFullscreen = !isFullscreen; @@ -71,10 +68,10 @@ void Engine::CreateGLWindow() { SDL_WINDOW_OPENGL|SDL_WINDOW_ALLOW_HIGHDPI| (GH_START_FULLSCREEN ? SDL_WINDOW_FULLSCREEN : 0) ); - int scale = query_surface_scale(window); - SDL_SetWindowSize(window,iWidth/scale,iHeight/scale); - SDL_SetWindowGrab(window,SDL_TRUE); - SDL_SetRelativeMouseMode(SDL_TRUE); + double scale = query_surface_scale(window); + SDL_SetWindowSize(window,int(iWidth/scale),int(iHeight/scale)); + SDL_SetWindowGrab(window,SDL_TRUE); + SDL_SetRelativeMouseMode(SDL_TRUE); if (!window) { SDL_Log("Unable to create GL window: %s", SDL_GetError()); return; @@ -118,15 +115,15 @@ int Engine::EnterMessageLoop() { SDL_Event event; while(true) { - if (SDL_PollEvent(&event)) { + while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { - break; + return 0; } else if (event.type == SDL_KEYDOWN && event.key.repeat == 0) { auto keycode = event.key.keysym.sym; auto mod = event.key.keysym.mod; if (keycode == SDLK_ESCAPE) { - break; + return 0; } else if (keycode == SDLK_RETURN && (mod & KMOD_LALT || mod & KMOD_RALT) ) { ToggleFullscreen(); @@ -151,10 +148,11 @@ int Engine::EnterMessageLoop() { input.key[keycode] = false; } } + else if (event.type==SDL_MOUSEMOTION){ + input.UpdateRaw(event.motion.state,event.motion.xrel,event.motion.yrel); + } } - input.UpdateRaw(); - if (input.key_press['1']) { LoadScene(0); } else if (input.key_press['2']) { @@ -174,8 +172,6 @@ int Engine::EnterMessageLoop() { PeriodicRender(cur_ticks); SDL_GL_SwapWindow(window); } - - return 0; } void Engine::ConfineCursor() diff --git a/NonEuclidean/Input.cpp b/NonEuclidean/Input.cpp index 9753762..1cf6d41 100644 --- a/NonEuclidean/Input.cpp +++ b/NonEuclidean/Input.cpp @@ -53,24 +53,20 @@ void Input::UpdateRaw(const tagRAWINPUT* raw) { #else -void Input::UpdateRaw() { - - // read mouse position and buttons - int mouse_x, mouse_y; - uint32_t state = SDL_GetRelativeMouseState(&mouse_x, &mouse_y); +void Input::UpdateRaw(unsigned state,int mouse_x,int mouse_y) { mouse_dx = (float)mouse_x; mouse_dy = (float)mouse_y; mouse_ddx += mouse_dx; mouse_ddy += mouse_dy; - if (state & SDL_BUTTON(SDL_BUTTON_LEFT)) { + if (state & SDL_BUTTON_LMASK) { mouse_button[0] = true; mouse_button_press[0] = true; } - if (state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) { + if (state & SDL_BUTTON_MMASK) { mouse_button[1] = true; mouse_button_press[1] = true; } - if (state & SDL_BUTTON(SDL_BUTTON_RIGHT)) { + if (state & SDL_BUTTON_RMASK) { mouse_button[2] = true; mouse_button_press[2] = true; } diff --git a/NonEuclidean/Input.h b/NonEuclidean/Input.h index 775564b..0ee2831 100644 --- a/NonEuclidean/Input.h +++ b/NonEuclidean/Input.h @@ -10,7 +10,7 @@ class Input { #if defined(_WIN32) void UpdateRaw(const tagRAWINPUT* raw); #else - void UpdateRaw(); + void UpdateRaw(unsigned state,int mouse_x,int mouse_y); #endif //Keyboard