[win32, graphics, wip] working on multi surface, currently using top-level transparent window and moving them to cover the 'parent' window area...

This commit is contained in:
martinfouilleul 2023-06-21 12:36:05 +02:00
parent c357da97f6
commit ae7a60b942
6 changed files with 95 additions and 14 deletions

View File

@ -1,4 +1,4 @@
set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext /I ../../ext/angle_headers 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

View File

@ -23,7 +23,7 @@ int main()
return(-1); return(-1);
} }
mg_surface_swap_interval(surface1, 0); mg_surface_swap_interval(surface1, 0);
//*
mg_surface surface2 = mg_surface_create_for_window(window, MG_CANVAS); mg_surface surface2 = mg_surface_create_for_window(window, MG_CANVAS);
if(mg_surface_is_nil(surface2)) if(mg_surface_is_nil(surface2))
{ {
@ -31,21 +31,21 @@ int main()
return(-1); return(-1);
} }
mg_surface_swap_interval(surface2, 0); mg_surface_swap_interval(surface2, 0);
//*/
mg_canvas canvas1 = mg_canvas_create(); mg_canvas canvas1 = mg_canvas_create();
if(mg_canvas_is_nil(canvas1)) if(mg_canvas_is_nil(canvas1))
{ {
printf("Error: couldn't create canvas 1\n"); printf("Error: couldn't create canvas 1\n");
return(-1); return(-1);
} }
//*
mg_canvas canvas2 = mg_canvas_create(); mg_canvas canvas2 = mg_canvas_create();
if(mg_canvas_is_nil(canvas2)) if(mg_canvas_is_nil(canvas2))
{ {
printf("Error: couldn't create canvas 2\n"); printf("Error: couldn't create canvas 2\n");
return(-1); return(-1);
} }
//*/
// start app // start app
mp_window_bring_to_front(window); mp_window_bring_to_front(window);
mp_window_focus(window); mp_window_focus(window);
@ -73,19 +73,26 @@ int main()
mg_surface_prepare(surface1); mg_surface_prepare(surface1);
mg_canvas_set_current(canvas1); 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_set_color_rgba(1, 0, 0, 1);
mg_rectangle_fill(100, 100, 300, 150); mg_rectangle_fill(100, 100, 300, 150);
mg_render(surface1, canvas1); mg_render(surface1, canvas1);
//*
mg_surface_prepare(surface2); mg_surface_prepare(surface2);
mg_canvas_set_current(canvas2); mg_canvas_set_current(canvas2);
mg_set_color_rgba(0, 0, 0, 0);
mg_clear();
mg_set_color_rgba(0, 0, 1, 1); mg_set_color_rgba(0, 0, 1, 1);
mg_rectangle_fill(300, 300, 300, 200); mg_rectangle_fill(300, 300, 300, 200);
mg_render(surface2, canvas2); mg_render(surface2, canvas2);
//*/
mg_surface_present(surface1); mg_surface_present(surface1);
mg_surface_present(surface2); mg_surface_present(surface2);

View File

@ -149,6 +149,7 @@ void mg_wgl_surface_prepare(mg_surface_data* interface)
void mg_wgl_surface_present(mg_surface_data* interface) void mg_wgl_surface_present(mg_surface_data* interface)
{ {
mg_wgl_surface* surface = (mg_wgl_surface*)interface; mg_wgl_surface* surface = (mg_wgl_surface*)interface;
SwapBuffers(surface->hDC); 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_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE, WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_TRANSPARENT_ARB, TRUE,
WGL_COLOR_BITS_ARB, 32, 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_DEPTH_BITS_ARB, 24,
WGL_STENCIL_BITS_ARB, 8, WGL_STENCIL_BITS_ARB, 8,
0}; 0};

View File

@ -7,6 +7,7 @@
* *
*****************************************************************/ *****************************************************************/
#include<dwmapi.h>
#include"mp_app.c" #include"mp_app.c"
void mp_init_keys() 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); 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 WinProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam)
{ {
LRESULT result = 0; LRESULT result = 0;
@ -290,8 +323,10 @@ LRESULT WinProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam)
mp_event event = {0}; mp_event event = {0};
event.window = mp_window_handle_from_ptr(mpWindow); event.window = mp_window_handle_from_ptr(mpWindow);
event.type = MP_EVENT_WINDOW_RESIZE; 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); mp_queue_event(&event);
win32_update_child_layers(mpWindow);
} break; } break;
case WM_MOVING: case WM_MOVING:
@ -303,8 +338,10 @@ LRESULT WinProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam)
mp_event event = {0}; mp_event event = {0};
event.window = mp_window_handle_from_ptr(mpWindow); event.window = mp_window_handle_from_ptr(mpWindow);
event.type = MP_EVENT_WINDOW_MOVE; 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); mp_queue_event(&event);
win32_update_child_layers(mpWindow);
} break; } break;
case WM_SETFOCUS: case WM_SETFOCUS:
@ -566,6 +603,7 @@ mp_window mp_window_create(mp_rect rect, const char* title, mp_window_style styl
quit:; quit:;
mp_window_data* window = mp_window_alloc(); mp_window_data* window = mp_window_alloc();
window->win32.hWnd = windowHandle; window->win32.hWnd = windowHandle;
window->win32.layers = (list_info){0};
SetPropW(windowHandle, L"MilePost", window); 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; RECT parentRect;
GetClientRect(window->win32.hWnd, &parentRect); GetClientRect(window->win32.hWnd, &parentRect);
POINT point = {0};
ClientToScreen(window->win32.hWnd, &point);
int width = parentRect.right - parentRect.left; int width = parentRect.right - parentRect.left;
int height = parentRect.bottom - parentRect.top; int height = parentRect.bottom - parentRect.top;
surface->layer.hWnd = CreateWindow("layer_window_class", "layer", surface->layer.hWnd = CreateWindow("layer_window_class", "layer",
WS_CHILD | WS_VISIBLE, WS_POPUP | WS_VISIBLE,
0, 0, width, height, point.x, point.y, width, height,
window->win32.hWnd, window->win32.hWnd,
0, 0,
layerWindowClass.hInstance, layerWindowClass.hInstance,
0); 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) void mg_surface_init_remote(mg_surface_data* surface, u32 width, u32 height)

View File

@ -20,10 +20,13 @@
typedef struct win32_window_data typedef struct win32_window_data
{ {
HWND hWnd; HWND hWnd;
list_info layers;
} win32_window_data; } win32_window_data;
typedef struct mp_layer typedef struct mp_layer
{ {
list_elt listElt;
mp_rect frame;
HWND hWnd; HWND hWnd;
} mp_layer; } mp_layer;

View File

@ -1,5 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 GUID -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
<assemblyIdentity <assemblyIdentity
version="0.0.0.1" version="0.0.0.1"
processorArchitecture="*" processorArchitecture="*"