From ae7a60b942b993a31ce7fe491fdff09aea195fbf Mon Sep 17 00:00:00 2001 From: martinfouilleul Date: Wed, 21 Jun 2023 12:36:05 +0200 Subject: [PATCH] [win32, graphics, wip] working on multi surface, currently using top-level transparent window and moving them to cover the 'parent' window area... --- examples/multi_surface/build.bat | 2 +- examples/multi_surface/main.c | 17 +++++--- src/wgl_surface.c | 6 +++ src/win32_app.c | 75 ++++++++++++++++++++++++++++---- src/win32_app.h | 3 ++ src/win32_manifest.xml | 6 +++ 6 files changed, 95 insertions(+), 14 deletions(-) diff --git a/examples/multi_surface/build.bat b/examples/multi_surface/build.bat index 4943561..8c8ae06 100644 --- a/examples/multi_surface/build.bat +++ b/examples/multi_surface/build.bat @@ -1,4 +1,4 @@ set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext /I ../../ext/angle_headers -cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.dll.lib /out:../../bin/example_multi_surface.exe +cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /MANIFEST:EMBED /MANIFESTINPUT:../../src/win32_manifest.xml /LIBPATH:../../bin milepost.dll.lib /out:../../bin/example_multi_surface.exe diff --git a/examples/multi_surface/main.c b/examples/multi_surface/main.c index 6ac7f7a..cd50b97 100644 --- a/examples/multi_surface/main.c +++ b/examples/multi_surface/main.c @@ -23,7 +23,7 @@ int main() return(-1); } mg_surface_swap_interval(surface1, 0); - +//* mg_surface surface2 = mg_surface_create_for_window(window, MG_CANVAS); if(mg_surface_is_nil(surface2)) { @@ -31,21 +31,21 @@ int main() return(-1); } mg_surface_swap_interval(surface2, 0); - +//*/ mg_canvas canvas1 = mg_canvas_create(); if(mg_canvas_is_nil(canvas1)) { printf("Error: couldn't create canvas 1\n"); return(-1); } - +//* mg_canvas canvas2 = mg_canvas_create(); if(mg_canvas_is_nil(canvas2)) { printf("Error: couldn't create canvas 2\n"); return(-1); } - +//*/ // start app mp_window_bring_to_front(window); mp_window_focus(window); @@ -73,19 +73,26 @@ int main() mg_surface_prepare(surface1); mg_canvas_set_current(canvas1); + mg_set_color_rgba(0, 0, 0.5, 0.5); + mg_clear(); + mg_set_color_rgba(1, 0, 0, 1); mg_rectangle_fill(100, 100, 300, 150); mg_render(surface1, canvas1); +//* mg_surface_prepare(surface2); mg_canvas_set_current(canvas2); + mg_set_color_rgba(0, 0, 0, 0); + mg_clear(); + mg_set_color_rgba(0, 0, 1, 1); mg_rectangle_fill(300, 300, 300, 200); mg_render(surface2, canvas2); - +//*/ mg_surface_present(surface1); mg_surface_present(surface2); diff --git a/src/wgl_surface.c b/src/wgl_surface.c index 5a2866d..406ebc4 100644 --- a/src/wgl_surface.c +++ b/src/wgl_surface.c @@ -149,6 +149,7 @@ void mg_wgl_surface_prepare(mg_surface_data* interface) void mg_wgl_surface_present(mg_surface_data* interface) { mg_wgl_surface* surface = (mg_wgl_surface*)interface; + SwapBuffers(surface->hDC); } @@ -223,7 +224,12 @@ mg_surface_data* mg_wgl_surface_create_for_window(mp_window window) WGL_SUPPORT_OPENGL_ARB, GL_TRUE, WGL_DOUBLE_BUFFER_ARB, GL_TRUE, WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, + WGL_TRANSPARENT_ARB, TRUE, WGL_COLOR_BITS_ARB, 32, + WGL_RED_BITS_ARB, 8, + WGL_GREEN_BITS_ARB, 8, + WGL_BLUE_BITS_ARB, 8, + WGL_ALPHA_BITS_ARB, 8, WGL_DEPTH_BITS_ARB, 24, WGL_STENCIL_BITS_ARB, 8, 0}; diff --git a/src/win32_app.c b/src/win32_app.c index 258e1e4..32cb448 100644 --- a/src/win32_app.c +++ b/src/win32_app.c @@ -7,6 +7,7 @@ * *****************************************************************/ +#include #include"mp_app.c" void mp_init_keys() @@ -245,6 +246,38 @@ static void process_wheel_event(mp_window_data* window, f32 x, f32 y) mp_queue_event(&event); } +static void win32_update_child_layers(mp_window_data* window) +{ + RECT clientRect; + GetClientRect(window->win32.hWnd, &clientRect); + POINT point = {0}; + ClientToScreen(window->win32.hWnd, &point); + + int w = clientRect.right - clientRect.left; + int h = clientRect.bottom - clientRect.top; + + HWND insertAfter = window->win32.hWnd; + + for_list(&window->win32.layers, layer, mp_layer, listElt) + { + mp_rect clipped = {0}; + clipped.x = Clamp(layer->frame.x, 0, w); + clipped.y = Clamp(layer->frame.y, 0, h); + clipped.w = Clamp(layer->frame.w, 0, w - layer->frame.x); + clipped.h = Clamp(layer->frame.h, 0, h - layer->frame.y); + + SetWindowPos(layer->hWnd, + insertAfter, + point.x + clipped.x, + point.y + clipped.y, + clipped.w, + clipped.h, + SWP_NOACTIVATE|SWP_NOOWNERZORDER); + + insertAfter = layer->hWnd; + } +} + LRESULT WinProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam) { LRESULT result = 0; @@ -290,8 +323,10 @@ LRESULT WinProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam) mp_event event = {0}; event.window = mp_window_handle_from_ptr(mpWindow); event.type = MP_EVENT_WINDOW_RESIZE; - event.frame.rect = (mp_rect){rect->bottom, rect->left, rect->top - rect->bottom, rect->right - rect->left}; + event.frame.rect = (mp_rect){rect->left, rect->bottom, rect->bottom - rect->top, rect->right - rect->left}; mp_queue_event(&event); + + win32_update_child_layers(mpWindow); } break; case WM_MOVING: @@ -303,8 +338,10 @@ LRESULT WinProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam) mp_event event = {0}; event.window = mp_window_handle_from_ptr(mpWindow); event.type = MP_EVENT_WINDOW_MOVE; - event.frame.rect = (mp_rect){rect->bottom, rect->left, rect->top - rect->bottom, rect->right - rect->left}; + event.frame.rect = (mp_rect){rect->left, rect->bottom, rect->bottom - rect->top, rect->right - rect->left}; mp_queue_event(&event); + + win32_update_child_layers(mpWindow); } break; case WM_SETFOCUS: @@ -566,6 +603,7 @@ mp_window mp_window_create(mp_rect rect, const char* title, mp_window_style styl quit:; mp_window_data* window = mp_window_alloc(); window->win32.hWnd = windowHandle; + window->win32.layers = (list_info){0}; SetPropW(windowHandle, L"MilePost", window); @@ -992,16 +1030,37 @@ void mg_surface_init_for_window(mg_surface_data* surface, mp_window_data* window RECT parentRect; GetClientRect(window->win32.hWnd, &parentRect); + POINT point = {0}; + ClientToScreen(window->win32.hWnd, &point); + int width = parentRect.right - parentRect.left; int height = parentRect.bottom - parentRect.top; surface->layer.hWnd = CreateWindow("layer_window_class", "layer", - WS_CHILD | WS_VISIBLE, - 0, 0, width, height, - window->win32.hWnd, - 0, - layerWindowClass.hInstance, - 0); + WS_POPUP | WS_VISIBLE, + point.x, point.y, width, height, + window->win32.hWnd, + 0, + layerWindowClass.hInstance, + 0); + + HRGN region = CreateRectRgn(0, 0, -1, -1); + + DWM_BLURBEHIND bb = {0}; + bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; + bb.hRgnBlur = region; + bb.fEnable = TRUE; + + HRESULT res = DwmEnableBlurBehindWindow(surface->layer.hWnd, &bb); + + DeleteObject(region); + if(res != S_OK) + { + log_error("couldn't enable blur behind\n"); + } + + surface->layer.frame = (mp_rect){0, 0, width, height}; + list_append(&window->win32.layers, &surface->layer.listElt); } void mg_surface_init_remote(mg_surface_data* surface, u32 width, u32 height) diff --git a/src/win32_app.h b/src/win32_app.h index 6ea0110..bb0ed90 100644 --- a/src/win32_app.h +++ b/src/win32_app.h @@ -20,10 +20,13 @@ typedef struct win32_window_data { HWND hWnd; + list_info layers; } win32_window_data; typedef struct mp_layer { + list_elt listElt; + mp_rect frame; HWND hWnd; } mp_layer; diff --git a/src/win32_manifest.xml b/src/win32_manifest.xml index b28a978..a8575cd 100644 --- a/src/win32_manifest.xml +++ b/src/win32_manifest.xml @@ -1,5 +1,11 @@ + + + + + +