Update windows/Window.cpp
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 5m22s
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 5m22s
On windows everything will be in the same cpp because their event loop is bad.
This commit is contained in:
@@ -1,140 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#include <ReWindow/types/Window.h>
|
||||
using namespace ReWindow;
|
||||
//Event loop.
|
||||
|
||||
// TODO move this. It can't be in the RWindow class because it has to be publicly visible.
|
||||
|
||||
inline LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
|
||||
RWindow* window = reinterpret_cast<RWindow*>( GetWindowLongPtr(hwnd, GWLP_USERDATA) );
|
||||
|
||||
switch (uMsg) {
|
||||
case WM_CLOSE: {
|
||||
DestroyWindow(hwnd);
|
||||
window->processOnClose();
|
||||
}
|
||||
|
||||
case WM_DESTROY: {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
case WM_SIZE: {
|
||||
window->SetSizeWithoutEvent({ LOWORD(lParam), HIWORD(lParam) });
|
||||
auto eventData = WindowResizeRequestEvent();
|
||||
eventData.Size = { window->GetWidth(), window->GetHeight() };
|
||||
window->SetLastKnownWindowSize({ window->GetWidth(), window->GetHeight() });
|
||||
// TODO: Implement eWindow->processOnResize()
|
||||
window->OnResizeRequest(eventData);
|
||||
window->OnResizeRequestEvent(eventData);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_SETFOCUS: {
|
||||
window->processFocusIn();
|
||||
window->SetFlag(WindowFlag::IN_FOCUS, true);
|
||||
|
||||
// TODO actually check if it's flashing.
|
||||
FLASHWINFO fi;
|
||||
fi.cbSize = sizeof(FLASHWINFO);
|
||||
fi.hwnd = hwnd;
|
||||
fi.dwFlags = FLASHW_STOP;
|
||||
fi.uCount = 0;
|
||||
fi.dwTimeout = 0;
|
||||
FlashWindowEx(&fi);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_KILLFOCUS: {
|
||||
window->processFocusOut();
|
||||
window->SetFlag(WindowFlag::IN_FOCUS, false);
|
||||
}
|
||||
|
||||
case WM_SETCURSOR: {
|
||||
if (LOWORD(lParam) == HTCLIENT && window->GetCursorVisible() == false)
|
||||
SetCursor(nullptr);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_KEYDOWN: {
|
||||
auto key = GetKeyFromWindowsScancode((WindowsScancode) wParam);
|
||||
//Key repeat fix.
|
||||
if (!window->previousKeyboard.PressedKeys[key])
|
||||
window->processKeyPress(key);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_KEYUP: {
|
||||
auto key = GetKeyFromWindowsScancode((WindowsScancode) wParam);
|
||||
window->processKeyRelease(key);
|
||||
break;
|
||||
}
|
||||
|
||||
//Mouse Buttons.
|
||||
case WM_MOUSEWHEEL: {
|
||||
int wheel_delta = GET_WHEEL_DELTA_WPARAM(wParam);
|
||||
// TODO: Determine sign of wheel_delta for each direction, (and on linux too), and document this.
|
||||
window->processMouseWheel(wheel_delta);\
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_LBUTTONDOWN: {
|
||||
window->processMousePress(MouseButtons::Left);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_LBUTTONUP: {
|
||||
window->processMouseRelease(MouseButtons::Left);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_RBUTTONDOWN: {
|
||||
window->processMousePress(MouseButtons::Right);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_RBUTTONUP: {
|
||||
window->processMouseRelease(MouseButtons::Right);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MBUTTONDOWN: {
|
||||
window->processMousePress(MouseButtons::Middle);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MBUTTONUP: {
|
||||
window->processMouseRelease(MouseButtons::Middle);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_XBUTTONDOWN: {
|
||||
WORD button = GET_XBUTTON_WPARAM(wParam);
|
||||
if (button == XBUTTON1)
|
||||
window->processMousePress(MouseButtons::Mouse4);
|
||||
|
||||
if (button == XBUTTON2)
|
||||
window->processMousePress(MouseButtons::Mouse5);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_XBUTTONUP: {
|
||||
WORD button = GET_XBUTTON_WPARAM(wParam);
|
||||
if (button == XBUTTON1)
|
||||
window->processMouseRelease(MouseButtons::Mouse4);
|
||||
|
||||
if (button == XBUTTON2)
|
||||
window->processMouseRelease(MouseButtons::Mouse5);
|
||||
break;
|
||||
}
|
||||
|
||||
//This is the same as "Motion Notify" in the X Window System.
|
||||
case WM_MOUSEMOVE:
|
||||
break;
|
||||
}
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
#endif
|
@@ -1,128 +0,0 @@
|
||||
#include <ReWindow/types/Window.h>
|
||||
#include <ReWindow/data/WindowsEventLoop.h>
|
||||
#include <ReWindow/Logger.h>
|
||||
#include <GL/gl.h>
|
||||
|
||||
class RWindow::Platform {
|
||||
public:
|
||||
HINSTANCE hInstance;
|
||||
HWND hwnd;
|
||||
HDC hdc;
|
||||
};
|
||||
|
||||
using namespace ReWindow;
|
||||
|
||||
HGLRC glContext;
|
||||
HMODULE gl_lib = nullptr;
|
||||
bool constructor_success = true;
|
||||
|
||||
namespace OpenGL {
|
||||
typedef const GLubyte* (APIENTRY *GLGETSTRINGPROC)(GLenum name);
|
||||
GLGETSTRINGPROC glGetString = nullptr;
|
||||
|
||||
typedef BOOL (WINAPI *WGLMAKECURRENTPROC)(HDC hdc, HGLRC hglrc);
|
||||
WGLMAKECURRENTPROC wglMakeCurrent = nullptr;
|
||||
|
||||
typedef FARPROC (WINAPI *WGLGETPROCADDRPROC)(LPCSTR lpszProc);
|
||||
WGLGETPROCADDRPROC wglGetProcAddress = nullptr;
|
||||
|
||||
|
||||
typedef HGLRC (WINAPI *WGLCREATECONTEXTPROC)(HDC hdc);
|
||||
WGLCREATECONTEXTPROC wglCreateContext = nullptr;
|
||||
|
||||
}
|
||||
bool OpenGLWindow::Open() {
|
||||
if (!constructor_success)
|
||||
return false;
|
||||
|
||||
platform->hInstance = GetModuleHandle(nullptr);
|
||||
|
||||
WNDCLASS wc = { };
|
||||
wc.lpfnWndProc = WindowProc;
|
||||
wc.hInstance = platform->hInstance;
|
||||
wc.lpszClassName = "RWindowClass";
|
||||
RegisterClass(&wc);
|
||||
platform->hwnd = CreateWindowEx(
|
||||
0,
|
||||
"RWindowClass",
|
||||
title.c_str(),
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, width, height,
|
||||
nullptr,
|
||||
nullptr,
|
||||
platform->hInstance,
|
||||
nullptr
|
||||
);
|
||||
SetWindowLongPtr(platform->hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
|
||||
PIXELFORMATDESCRIPTOR pfd = {
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
1,
|
||||
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
|
||||
PFD_TYPE_RGBA,
|
||||
24,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
24,
|
||||
8,
|
||||
0,
|
||||
PFD_MAIN_PLANE,
|
||||
0,
|
||||
0, 0, 0
|
||||
};
|
||||
|
||||
platform->hdc = GetDC(platform->hwnd);
|
||||
int pixelFormat = ChoosePixelFormat(platform->hdc, &pfd);
|
||||
SetPixelFormat(platform->hdc, pixelFormat, &pfd);
|
||||
glContext = OpenGL::wglCreateContext(platform->hdc);
|
||||
OpenGL::wglMakeCurrent(platform->hdc, glContext);
|
||||
ShowWindow(platform->hwnd, SW_SHOW);
|
||||
open = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string OpenGLWindow::GetGraphicsDriverVendor() {
|
||||
return std::string(reinterpret_cast<const char*>(OpenGL::glGetString(GL_VENDOR)));
|
||||
}
|
||||
|
||||
void OpenGLWindow::SwapBuffers() {
|
||||
::SwapBuffers(platform->hdc);
|
||||
}
|
||||
|
||||
void OpenGLWindow::SetVsyncEnabled(bool b) {
|
||||
typedef BOOL(WINAPI* PFNWGLSWAPINTERVALEXTPROC)(int interval);
|
||||
auto wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) OpenGL::wglGetProcAddress("wglSwapIntervalEXT");
|
||||
|
||||
if (wglSwapIntervalEXT)
|
||||
wglSwapIntervalEXT(b ? 1 : 0);
|
||||
}
|
||||
|
||||
bool OpenGLWindow::SoftwareRendered() {
|
||||
std::string renderer(reinterpret_cast<const char*>(OpenGL::glGetString(GL_RENDERER)));
|
||||
if (renderer.find("llvmpipe"))
|
||||
return true;
|
||||
if (renderer.find("softpipe"))
|
||||
return true;
|
||||
if (renderer.find("GDI Generic"))
|
||||
return true;
|
||||
if (GetGraphicsDriverVendor().find("Mesa"))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
OpenGLWindow::OpenGLWindow(const std::string& title, int width, int height, uint8_t gl_major, uint8_t gl_minor)
|
||||
: gl_major(gl_major), gl_minor(gl_minor), RWindow(title, width, height) {
|
||||
gl_lib = LoadLibrary("opengl32.dll");
|
||||
|
||||
if (!gl_lib)
|
||||
Logger::Error("opengl32.dll couldn't be found. If you have it, you can try putting it in the same directory as the executable."),
|
||||
constructor_success = false;
|
||||
|
||||
OpenGL::glGetString = (OpenGL::GLGETSTRINGPROC) GetProcAddress(gl_lib, "glGetString");
|
||||
OpenGL::wglMakeCurrent = (OpenGL::WGLMAKECURRENTPROC) GetProcAddress(gl_lib, "wglMakeCurrent");
|
||||
OpenGL::wglGetProcAddress = (OpenGL::WGLGETPROCADDRPROC) GetProcAddress(gl_lib, "wglGetProcAddress");
|
||||
OpenGL::wglCreateContext = (OpenGL::WGLCREATECONTEXTPROC) GetProcAddress(gl_lib, "wglCreateContext");
|
||||
}
|
||||
|
@@ -1,6 +1,8 @@
|
||||
#include <Windows.h>
|
||||
#include <gl/GL.h>
|
||||
#include <rewindow/types/window.h>
|
||||
#include <ReWindow/types/Window.h>
|
||||
#include <ReWindow/Logger.h>
|
||||
|
||||
|
||||
class ReWindow::RWindow::Platform {
|
||||
public:
|
||||
@@ -10,6 +12,135 @@ public:
|
||||
};
|
||||
|
||||
using namespace ReWindow;
|
||||
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
auto* window = reinterpret_cast<RWindow*>( GetWindowLongPtr(hwnd, GWLP_USERDATA) );
|
||||
|
||||
switch (uMsg) {
|
||||
case WM_CLOSE: {
|
||||
DestroyWindow(hwnd);
|
||||
window->processOnClose();
|
||||
}
|
||||
|
||||
case WM_DESTROY: {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
case WM_SIZE: {
|
||||
window->SetSizeWithoutEvent({ LOWORD(lParam), HIWORD(lParam) });
|
||||
auto eventData = WindowResizeRequestEvent();
|
||||
eventData.Size = { window->GetWidth(), window->GetHeight() };
|
||||
window->SetLastKnownWindowSize({ window->GetWidth(), window->GetHeight() });
|
||||
// TODO: Implement eWindow->processOnResize()
|
||||
window->OnResizeRequest(eventData);
|
||||
window->OnResizeRequestEvent(eventData);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_SETFOCUS: {
|
||||
window->processFocusIn();
|
||||
window->SetFlag(WindowFlag::IN_FOCUS, true);
|
||||
|
||||
// TODO actually check if it's flashing.
|
||||
FLASHWINFO fi;
|
||||
fi.cbSize = sizeof(FLASHWINFO);
|
||||
fi.hwnd = hwnd;
|
||||
fi.dwFlags = FLASHW_STOP;
|
||||
fi.uCount = 0;
|
||||
fi.dwTimeout = 0;
|
||||
FlashWindowEx(&fi);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_KILLFOCUS: {
|
||||
window->processFocusOut();
|
||||
window->SetFlag(WindowFlag::IN_FOCUS, false);
|
||||
}
|
||||
|
||||
case WM_SETCURSOR: {
|
||||
if (LOWORD(lParam) == HTCLIENT && window->GetCursorVisible() == false)
|
||||
SetCursor(nullptr);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_KEYDOWN: {
|
||||
auto key = GetKeyFromWindowsScancode((WindowsScancode) wParam);
|
||||
//Key repeat fix.
|
||||
if (!window->previousKeyboard.PressedKeys[key])
|
||||
window->processKeyPress(key);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_KEYUP: {
|
||||
auto key = GetKeyFromWindowsScancode((WindowsScancode) wParam);
|
||||
window->processKeyRelease(key);
|
||||
break;
|
||||
}
|
||||
|
||||
//Mouse Buttons.
|
||||
case WM_MOUSEWHEEL: {
|
||||
int wheel_delta = GET_WHEEL_DELTA_WPARAM(wParam);
|
||||
// TODO: Determine sign of wheel_delta for each direction, (and on linux too), and document this.
|
||||
window->processMouseWheel(wheel_delta);\
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_LBUTTONDOWN: {
|
||||
window->processMousePress(MouseButtons::Left);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_LBUTTONUP: {
|
||||
window->processMouseRelease(MouseButtons::Left);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_RBUTTONDOWN: {
|
||||
window->processMousePress(MouseButtons::Right);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_RBUTTONUP: {
|
||||
window->processMouseRelease(MouseButtons::Right);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MBUTTONDOWN: {
|
||||
window->processMousePress(MouseButtons::Middle);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MBUTTONUP: {
|
||||
window->processMouseRelease(MouseButtons::Middle);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_XBUTTONDOWN: {
|
||||
WORD button = GET_XBUTTON_WPARAM(wParam);
|
||||
if (button == XBUTTON1)
|
||||
window->processMousePress(MouseButtons::Mouse4);
|
||||
|
||||
if (button == XBUTTON2)
|
||||
window->processMousePress(MouseButtons::Mouse5);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_XBUTTONUP: {
|
||||
WORD button = GET_XBUTTON_WPARAM(wParam);
|
||||
if (button == XBUTTON1)
|
||||
window->processMouseRelease(MouseButtons::Mouse4);
|
||||
|
||||
if (button == XBUTTON2)
|
||||
window->processMouseRelease(MouseButtons::Mouse5);
|
||||
break;
|
||||
}
|
||||
|
||||
//This is the same as "Motion Notify" in the X Window System.
|
||||
case WM_MOUSEMOVE:
|
||||
break;
|
||||
}
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
bool fullscreenmode = false;
|
||||
bool open = false;
|
||||
|
||||
@@ -124,4 +255,119 @@ vsync(wVsync), flags{false,wFullscreen,wResizable,wVsync} {
|
||||
|
||||
void RWindow::UniqueFunctionNameForMessageBoxBecauseMicrosoftUsesMacros(const std::string& title, const std::string& message_box_text) {
|
||||
MessageBox(nullptr, message_box_text.c_str(), title.c_str(), MB_OK);
|
||||
}
|
||||
}
|
||||
|
||||
HGLRC glContext;
|
||||
HMODULE gl_lib = nullptr;
|
||||
bool constructor_success = true;
|
||||
|
||||
namespace OpenGL {
|
||||
typedef const GLubyte* (APIENTRY *GLGETSTRINGPROC)(GLenum name);
|
||||
GLGETSTRINGPROC glGetString = nullptr;
|
||||
|
||||
typedef BOOL (WINAPI *WGLMAKECURRENTPROC)(HDC hdc, HGLRC hglrc);
|
||||
WGLMAKECURRENTPROC wglMakeCurrent = nullptr;
|
||||
|
||||
typedef FARPROC (WINAPI *WGLGETPROCADDRPROC)(LPCSTR lpszProc);
|
||||
WGLGETPROCADDRPROC wglGetProcAddress = nullptr;
|
||||
|
||||
|
||||
typedef HGLRC (WINAPI *WGLCREATECONTEXTPROC)(HDC hdc);
|
||||
WGLCREATECONTEXTPROC wglCreateContext = nullptr;
|
||||
|
||||
}
|
||||
|
||||
bool OpenGLWindow::Open() {
|
||||
if (!constructor_success)
|
||||
return false;
|
||||
|
||||
platform->hInstance = GetModuleHandle(nullptr);
|
||||
|
||||
WNDCLASS wc = { };
|
||||
wc.lpfnWndProc = WindowProc;
|
||||
wc.hInstance = platform->hInstance;
|
||||
wc.lpszClassName = "RWindowClass";
|
||||
RegisterClass(&wc);
|
||||
platform->hwnd = CreateWindowEx(
|
||||
0,
|
||||
"RWindowClass",
|
||||
title.c_str(),
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, width, height,
|
||||
nullptr,
|
||||
nullptr,
|
||||
platform->hInstance,
|
||||
nullptr
|
||||
);
|
||||
SetWindowLongPtr(platform->hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
|
||||
PIXELFORMATDESCRIPTOR pfd = {
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
1,
|
||||
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
|
||||
PFD_TYPE_RGBA,
|
||||
24,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
24,
|
||||
8,
|
||||
0,
|
||||
PFD_MAIN_PLANE,
|
||||
0,
|
||||
0, 0, 0
|
||||
};
|
||||
|
||||
platform->hdc = GetDC(platform->hwnd);
|
||||
int pixelFormat = ChoosePixelFormat(platform->hdc, &pfd);
|
||||
SetPixelFormat(platform->hdc, pixelFormat, &pfd);
|
||||
glContext = OpenGL::wglCreateContext(platform->hdc);
|
||||
OpenGL::wglMakeCurrent(platform->hdc, glContext);
|
||||
ShowWindow(platform->hwnd, SW_SHOW);
|
||||
open = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string OpenGLWindow::GetGraphicsDriverVendor() {
|
||||
return std::string(reinterpret_cast<const char*>(OpenGL::glGetString(GL_VENDOR)));
|
||||
}
|
||||
|
||||
void OpenGLWindow::SwapBuffers() {
|
||||
::SwapBuffers(platform->hdc);
|
||||
}
|
||||
|
||||
void OpenGLWindow::SetVsyncEnabled(bool b) {
|
||||
typedef BOOL(WINAPI* PFNWGLSWAPINTERVALEXTPROC)(int interval);
|
||||
auto wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) OpenGL::wglGetProcAddress("wglSwapIntervalEXT");
|
||||
|
||||
if (wglSwapIntervalEXT)
|
||||
wglSwapIntervalEXT(b ? 1 : 0);
|
||||
}
|
||||
|
||||
bool OpenGLWindow::SoftwareRendered() {
|
||||
std::string renderer(reinterpret_cast<const char*>(OpenGL::glGetString(GL_RENDERER)));
|
||||
if (renderer.find("llvmpipe"))
|
||||
return true;
|
||||
if (renderer.find("softpipe"))
|
||||
return true;
|
||||
if (renderer.find("GDI Generic"))
|
||||
return true;
|
||||
if (GetGraphicsDriverVendor().find("Mesa"))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
OpenGLWindow::OpenGLWindow(const std::string& title, int width, int height, uint8_t gl_major, uint8_t gl_minor)
|
||||
: gl_major(gl_major), gl_minor(gl_minor), RWindow(title, width, height) {
|
||||
gl_lib = LoadLibrary("opengl32.dll");
|
||||
|
||||
if (!gl_lib)
|
||||
Logger::Error("opengl32.dll couldn't be found. If you have it, you can try putting it in the same directory as the executable."),
|
||||
constructor_success = false;
|
||||
|
||||
OpenGL::glGetString = (OpenGL::GLGETSTRINGPROC) GetProcAddress(gl_lib, "glGetString");
|
||||
OpenGL::wglMakeCurrent = (OpenGL::WGLMAKECURRENTPROC) GetProcAddress(gl_lib, "wglMakeCurrent");
|
||||
OpenGL::wglGetProcAddress = (OpenGL::WGLGETPROCADDRPROC) GetProcAddress(gl_lib, "wglGetProcAddress");
|
||||
OpenGL::wglCreateContext = (OpenGL::WGLCREATECONTEXTPROC) GetProcAddress(gl_lib, "wglCreateContext");
|
||||
}
|
||||
|
Reference in New Issue
Block a user