summaryrefslogtreecommitdiffstats
path: root/tools/gfx/window.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2018-08-10 22:21:44 -0700
committerGitHub <noreply@github.com>2018-08-10 22:21:44 -0700
commit56d8a752d84e984afab20de5980edf10fe6c06f5 (patch)
treeeb1491b940daebc6afd200202347191d77f76112 /tools/gfx/window.cpp
parent73ff6907d723003d30e400f661876e7960de574f (diff)
Improve model-viewer support for lights (#626)
* Improve model-viewer support for lights The main visible change here is that the model-viewer example supports multiple light sources, with a basic UI for adding new light sources to the scene, and for manipulating the ones that are there. Along the way I also refactored the `IMaterial` decomposition to be a bit less naive, while still only including a completely naive Blinn-Phong implementation. I also went ahead and spruced up the `cube.obj` file so that it has multiple materials, although it is still a completely uninteresting asset. * Fixup: Windows SDK version
Diffstat (limited to 'tools/gfx/window.cpp')
-rw-r--r--tools/gfx/window.cpp84
1 files changed, 81 insertions, 3 deletions
diff --git a/tools/gfx/window.cpp b/tools/gfx/window.cpp
index 9bc63b896..d777dc8a6 100644
--- a/tools/gfx/window.cpp
+++ b/tools/gfx/window.cpp
@@ -16,6 +16,7 @@
#if _WIN32
#include <Windows.h>
+#include <Windowsx.h>
#else
#error "The slang-graphics library currently only supports Windows platforms"
#endif
@@ -110,8 +111,10 @@ int runWindowsApplication(
struct Window
{
- HWND handle;
- WNDPROC nativeHook;
+ HWND handle;
+ WNDPROC nativeHook;
+ EventHandler eventHandler;
+ void* userData;
};
void setNativeWindowHook(Window* window, WNDPROC proc)
@@ -119,6 +122,28 @@ void setNativeWindowHook(Window* window, WNDPROC proc)
window->nativeHook = proc;
}
+static KeyCode translateKeyCode(int vkey)
+{
+ switch( vkey )
+ {
+ default:
+ return KeyCode::Unknown;
+
+#define CASE(FROM, TO) case FROM: return KeyCode::TO;
+ CASE('A', A); CASE('B', B); CASE('C', C); CASE('D', D); CASE('E', E);
+ CASE('F', F); CASE('G', G); CASE('H', H); CASE('I', I); CASE('J', J);
+ CASE('K', K); CASE('L', M); CASE('M', M); CASE('N', N); CASE('O', O);
+ CASE('P', P); CASE('Q', Q); CASE('R', R); CASE('S', S); CASE('T', T);
+ CASE('U', U); CASE('V', V); CASE('W', W); CASE('X', X); CASE('Y', Y);
+ CASE('Z', Z);
+#undef CASE
+
+#define CASE(FROM, TO) case VK_##FROM: return KeyCode::TO;
+ CASE(SPACE, Space);
+#undef CASE
+ }
+}
+
static LRESULT CALLBACK windowProc(
HWND windowHandle,
UINT message,
@@ -139,7 +164,8 @@ static LRESULT CALLBACK windowProc(
}
}
- // TODO: Actually implement some reasonable logic here.
+ auto eventHandler = window ? window->eventHandler : nullptr;
+
switch (message)
{
case WM_CREATE:
@@ -152,6 +178,51 @@ static LRESULT CALLBACK windowProc(
}
break;
+ case WM_KEYDOWN:
+ case WM_KEYUP:
+ {
+ int virtualKey = (int) wParam;
+ auto keyCode = translateKeyCode(virtualKey);
+ if(eventHandler)
+ {
+ Event event;
+ event.window = window;
+ event.code = message == WM_KEYDOWN ? EventCode::KeyDown : EventCode::KeyUp;
+ event.u.key = keyCode;
+ eventHandler(event);
+ }
+ }
+ break;
+
+ case WM_LBUTTONDOWN:
+ case WM_LBUTTONUP:
+ {
+ if(eventHandler)
+ {
+ Event event;
+ event.window = window;
+ event.code = message == WM_LBUTTONDOWN ? EventCode::MouseDown : EventCode::MouseUp;
+ event.u.mouse.x = (float) GET_X_LPARAM(lParam);
+ event.u.mouse.y = (float) GET_Y_LPARAM(lParam);
+ eventHandler(event);
+ }
+ }
+ break;
+
+ case WM_MOUSEMOVE:
+ {
+ if(eventHandler)
+ {
+ Event event;
+ event.window = window;
+ event.code = EventCode::MouseMoved;
+ event.u.mouse.x = (float) GET_X_LPARAM(lParam);
+ event.u.mouse.y = (float) GET_Y_LPARAM(lParam);
+ eventHandler(event);
+ }
+ }
+ break;
+
case WM_CLOSE:
PostQuitMessage(0);
return 0;
@@ -192,6 +263,8 @@ Window* createWindow(WindowDesc const& desc)
Window* window = new Window();
window->handle = nullptr;
window->nativeHook = nullptr;
+ window->eventHandler = desc.eventHandler;
+ window->userData = desc.userData;
OSString windowTitle(desc.title);
@@ -232,6 +305,11 @@ void* getPlatformWindowHandle(Window* window)
return window->handle;
}
+void* getUserData(Window* window)
+{
+ return window->userData;
+}
+
bool dispatchEvents(ApplicationContext* context)
{
for(;;)