[surface] abstracted child window layer from win32 surfaces
This commit is contained in:
parent
5ac512c15e
commit
9ea9ea7636
|
@ -19,8 +19,7 @@ typedef struct mg_egl_surface
|
||||||
{
|
{
|
||||||
mg_surface_data interface;
|
mg_surface_data interface;
|
||||||
|
|
||||||
HWND hWnd;
|
mp_layer layer;
|
||||||
vec2 contentsScaling;
|
|
||||||
|
|
||||||
EGLDisplay eglDisplay;
|
EGLDisplay eglDisplay;
|
||||||
EGLConfig eglConfig;
|
EGLConfig eglConfig;
|
||||||
|
@ -46,7 +45,7 @@ void mg_egl_surface_destroy(mg_surface_data* interface)
|
||||||
eglDestroyContext(surface->eglDisplay, surface->eglContext);
|
eglDestroyContext(surface->eglDisplay, surface->eglContext);
|
||||||
eglDestroySurface(surface->eglDisplay, surface->eglSurface);
|
eglDestroySurface(surface->eglDisplay, surface->eglSurface);
|
||||||
|
|
||||||
DestroyWindow(surface->hWnd);
|
mp_layer_cleanup(&surface->layer);
|
||||||
free(surface);
|
free(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,74 +71,32 @@ void mg_egl_surface_swap_interval(mg_surface_data* interface, int swap)
|
||||||
vec2 mg_egl_surface_contents_scaling(mg_surface_data* interface)
|
vec2 mg_egl_surface_contents_scaling(mg_surface_data* interface)
|
||||||
{
|
{
|
||||||
mg_egl_surface* surface = (mg_egl_surface*)interface;
|
mg_egl_surface* surface = (mg_egl_surface*)interface;
|
||||||
return(surface->contentsScaling);
|
return(mp_layer_contents_scaling(&surface->layer));
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_rect mg_egl_surface_get_frame(mg_surface_data* interface)
|
mp_rect mg_egl_surface_get_frame(mg_surface_data* interface)
|
||||||
{
|
{
|
||||||
mp_rect res = {0};
|
|
||||||
mg_egl_surface* surface = (mg_egl_surface*)interface;
|
mg_egl_surface* surface = (mg_egl_surface*)interface;
|
||||||
if(surface)
|
return(mp_layer_get_frame(&surface->layer));
|
||||||
{
|
|
||||||
RECT rect = {0};
|
|
||||||
GetClientRect(surface->hWnd, &rect);
|
|
||||||
|
|
||||||
vec2 scale = surface->contentsScaling;
|
|
||||||
|
|
||||||
res = (mp_rect){rect.left/scale.x,
|
|
||||||
rect.bottom/scale.y,
|
|
||||||
(rect.right - rect.left)/scale.x,
|
|
||||||
(rect.bottom - rect.top)/scale.y};
|
|
||||||
}
|
|
||||||
return(res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_egl_surface_set_frame(mg_surface_data* interface, mp_rect frame)
|
void mg_egl_surface_set_frame(mg_surface_data* interface, mp_rect frame)
|
||||||
{
|
{
|
||||||
mg_egl_surface* surface = (mg_egl_surface*)interface;
|
mg_egl_surface* surface = (mg_egl_surface*)interface;
|
||||||
if(surface)
|
mp_layer_set_frame(&surface->layer, frame);
|
||||||
{
|
|
||||||
HWND parent = GetParent(surface->hWnd);
|
|
||||||
RECT parentContentRect;
|
|
||||||
GetClientRect(parent, &parentContentRect);
|
|
||||||
int parentHeight = parentContentRect.bottom - parentContentRect.top;
|
|
||||||
|
|
||||||
SetWindowPos(surface->hWnd,
|
|
||||||
HWND_TOP,
|
|
||||||
frame.x * surface->contentsScaling.x,
|
|
||||||
parentHeight - (frame.y + frame.h) * surface->contentsScaling.y,
|
|
||||||
frame.w * surface->contentsScaling.x,
|
|
||||||
frame.h * surface->contentsScaling.y,
|
|
||||||
SWP_NOACTIVATE | SWP_NOZORDER);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_egl_surface_set_hidden(mg_surface_data* interface, bool hidden)
|
void mg_egl_surface_set_hidden(mg_surface_data* interface, bool hidden)
|
||||||
{
|
{
|
||||||
mg_egl_surface* surface = (mg_egl_surface*)interface;
|
mg_egl_surface* surface = (mg_egl_surface*)interface;
|
||||||
if(surface)
|
mp_layer_set_hidden(&surface->layer, hidden);
|
||||||
{
|
|
||||||
ShowWindow(surface->hWnd, hidden ? SW_HIDE : SW_NORMAL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mg_egl_surface_get_hidden(mg_surface_data* interface)
|
bool mg_egl_surface_get_hidden(mg_surface_data* interface)
|
||||||
{
|
{
|
||||||
bool hidden = false;
|
|
||||||
mg_egl_surface* surface = (mg_egl_surface*)interface;
|
mg_egl_surface* surface = (mg_egl_surface*)interface;
|
||||||
if(surface)
|
return(mp_layer_get_hidden(&surface->layer));
|
||||||
{
|
|
||||||
hidden = !IsWindowVisible(surface->hWnd);
|
|
||||||
}
|
}
|
||||||
return(hidden);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LRESULT mg_egl_surface_window_proc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
return(DefWindowProc(windowHandle, message, wParam, lParam));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
mg_surface mg_egl_surface_create_for_window(mp_window window)
|
mg_surface mg_egl_surface_create_for_window(mp_window window)
|
||||||
{
|
{
|
||||||
|
@ -148,31 +105,6 @@ mg_surface mg_egl_surface_create_for_window(mp_window window)
|
||||||
mp_window_data* windowData = mp_window_ptr_from_handle(window);
|
mp_window_data* windowData = mp_window_ptr_from_handle(window);
|
||||||
if(windowData)
|
if(windowData)
|
||||||
{
|
{
|
||||||
//NOTE(martin): create a child window for the surface
|
|
||||||
WNDCLASS childWindowClass = {.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
|
|
||||||
.lpfnWndProc = mg_egl_surface_window_proc,
|
|
||||||
.hInstance = GetModuleHandleW(NULL),
|
|
||||||
.lpszClassName = "egl_surface_window_class",
|
|
||||||
.hCursor = LoadCursor(0, IDC_ARROW)};
|
|
||||||
|
|
||||||
if(!RegisterClass(&childWindowClass))
|
|
||||||
{
|
|
||||||
//TODO: error
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_rect frame = mp_window_get_content_rect(window);
|
|
||||||
|
|
||||||
u32 dpi = GetDpiForWindow(windowData->win32.hWnd);
|
|
||||||
vec2 contentsScaling = (vec2){(float)dpi/96., (float)dpi/96.};
|
|
||||||
|
|
||||||
HWND childWindow = CreateWindow("egl_surface_window_class", "Test",
|
|
||||||
WS_CHILD|WS_VISIBLE,
|
|
||||||
0, 0, frame.w*contentsScaling.x, frame.h*contentsScaling.y,
|
|
||||||
windowData->win32.hWnd,
|
|
||||||
0,
|
|
||||||
childWindowClass.hInstance,
|
|
||||||
0);
|
|
||||||
|
|
||||||
mg_egl_surface* surface = malloc_type(mg_egl_surface);
|
mg_egl_surface* surface = malloc_type(mg_egl_surface);
|
||||||
memset(surface, 0, sizeof(mg_egl_surface));
|
memset(surface, 0, sizeof(mg_egl_surface));
|
||||||
|
|
||||||
|
@ -187,8 +119,7 @@ mg_surface mg_egl_surface_create_for_window(mp_window window)
|
||||||
surface->interface.getHidden = mg_egl_surface_get_hidden;
|
surface->interface.getHidden = mg_egl_surface_get_hidden;
|
||||||
surface->interface.setHidden = mg_egl_surface_set_hidden;
|
surface->interface.setHidden = mg_egl_surface_set_hidden;
|
||||||
|
|
||||||
surface->hWnd = childWindow;
|
mp_layer_init_for_window(&surface->layer, windowData);
|
||||||
surface->contentsScaling = contentsScaling;
|
|
||||||
|
|
||||||
EGLAttrib displayAttribs[] = {
|
EGLAttrib displayAttribs[] = {
|
||||||
EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE,
|
EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE,
|
||||||
|
@ -217,7 +148,7 @@ mg_surface mg_egl_surface_create_for_window(mp_window window)
|
||||||
EGLint const surfaceAttributes[] = {EGL_NONE};
|
EGLint const surfaceAttributes[] = {EGL_NONE};
|
||||||
surface->eglSurface = eglCreateWindowSurface(surface->eglDisplay,
|
surface->eglSurface = eglCreateWindowSurface(surface->eglDisplay,
|
||||||
surface->eglConfig,
|
surface->eglConfig,
|
||||||
surface->hWnd,
|
mp_layer_native_surface(&surface->layer),
|
||||||
surfaceAttributes);
|
surfaceAttributes);
|
||||||
|
|
||||||
eglBindAPI(EGL_OPENGL_ES_API);
|
eglBindAPI(EGL_OPENGL_ES_API);
|
|
@ -2,7 +2,7 @@
|
||||||
*
|
*
|
||||||
* file: glsl_shaders.h
|
* file: glsl_shaders.h
|
||||||
* note: string literals auto-generated by embed_text.py
|
* note: string literals auto-generated by embed_text.py
|
||||||
* date: 20/022023
|
* date: 21/022023
|
||||||
*
|
*
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
#ifndef __GLSL_SHADERS_H__
|
#ifndef __GLSL_SHADERS_H__
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MG_COMPILE_BACKEND_GLES
|
#if MG_COMPILE_BACKEND_GLES
|
||||||
#include"win32_egl_surface.c"
|
#include"egl_surface.c"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif defined(OS_MACOS)
|
#elif defined(OS_MACOS)
|
||||||
|
|
|
@ -115,10 +115,9 @@ typedef struct mg_wgl_surface
|
||||||
{
|
{
|
||||||
mg_surface_data interface;
|
mg_surface_data interface;
|
||||||
|
|
||||||
HWND hWnd;
|
mp_layer layer;
|
||||||
HDC hDC;
|
HDC hDC;
|
||||||
HGLRC glContext;
|
HGLRC glContext;
|
||||||
vec2 contentsScaling;
|
|
||||||
|
|
||||||
//NOTE: this may be a bit wasteful to have one api struct per surface, but win32 docs says that loading procs
|
//NOTE: this may be a bit wasteful to have one api struct per surface, but win32 docs says that loading procs
|
||||||
// from different contexts might select different implementations (eg. depending on context version/pixel format)
|
// from different contexts might select different implementations (eg. depending on context version/pixel format)
|
||||||
|
@ -135,7 +134,7 @@ void mg_wgl_surface_destroy(mg_surface_data* interface)
|
||||||
}
|
}
|
||||||
wglDeleteContext(surface->glContext);
|
wglDeleteContext(surface->glContext);
|
||||||
|
|
||||||
DestroyWindow(surface->hWnd);
|
mp_layer_cleanup(&surface->layer);
|
||||||
|
|
||||||
free(surface);
|
free(surface);
|
||||||
}
|
}
|
||||||
|
@ -163,68 +162,32 @@ void mg_wgl_surface_swap_interval(mg_surface_data* interface, int swap)
|
||||||
vec2 mg_wgl_surface_contents_scaling(mg_surface_data* interface)
|
vec2 mg_wgl_surface_contents_scaling(mg_surface_data* interface)
|
||||||
{
|
{
|
||||||
mg_wgl_surface* surface = (mg_wgl_surface*)interface;
|
mg_wgl_surface* surface = (mg_wgl_surface*)interface;
|
||||||
return(surface->contentsScaling);
|
return(mp_layer_contents_scaling(&surface->layer));
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_rect mg_wgl_surface_get_frame(mg_surface_data* interface)
|
mp_rect mg_wgl_surface_get_frame(mg_surface_data* interface)
|
||||||
{
|
{
|
||||||
mp_rect res = {0};
|
|
||||||
mg_wgl_surface* surface = (mg_wgl_surface*)interface;
|
mg_wgl_surface* surface = (mg_wgl_surface*)interface;
|
||||||
if(surface)
|
return(mp_layer_get_frame(&surface->layer));
|
||||||
{
|
|
||||||
RECT rect = {0};
|
|
||||||
GetClientRect(surface->hWnd, &rect);
|
|
||||||
|
|
||||||
vec2 scale = surface->contentsScaling;
|
|
||||||
|
|
||||||
res = (mp_rect){rect.left/scale.x,
|
|
||||||
rect.bottom/scale.y,
|
|
||||||
(rect.right - rect.left)/scale.x,
|
|
||||||
(rect.bottom - rect.top)/scale.y};
|
|
||||||
}
|
|
||||||
return(res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_wgl_surface_set_frame(mg_surface_data* interface, mp_rect frame)
|
void mg_wgl_surface_set_frame(mg_surface_data* interface, mp_rect frame)
|
||||||
{
|
{
|
||||||
mg_wgl_surface* surface = (mg_wgl_surface*)interface;
|
mg_wgl_surface* surface = (mg_wgl_surface*)interface;
|
||||||
if(surface)
|
mp_layer_set_frame(&surface->layer, frame);
|
||||||
{
|
|
||||||
HWND parent = GetParent(surface->hWnd);
|
|
||||||
RECT parentContentRect;
|
|
||||||
GetClientRect(parent, &parentContentRect);
|
|
||||||
int parentHeight = parentContentRect.bottom - parentContentRect.top;
|
|
||||||
|
|
||||||
SetWindowPos(surface->hWnd,
|
|
||||||
HWND_TOP,
|
|
||||||
frame.x * surface->contentsScaling.x,
|
|
||||||
parentHeight - (frame.y + frame.h) * surface->contentsScaling.y,
|
|
||||||
frame.w * surface->contentsScaling.x,
|
|
||||||
frame.h * surface->contentsScaling.y,
|
|
||||||
SWP_NOACTIVATE | SWP_NOZORDER);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_wgl_surface_set_hidden(mg_surface_data* interface, bool hidden)
|
void mg_wgl_surface_set_hidden(mg_surface_data* interface, bool hidden)
|
||||||
{
|
{
|
||||||
mg_wgl_surface* surface = (mg_wgl_surface*)interface;
|
mg_wgl_surface* surface = (mg_wgl_surface*)interface;
|
||||||
if(surface)
|
mp_layer_set_hidden(&surface->layer, hidden);
|
||||||
{
|
|
||||||
ShowWindow(surface->hWnd, hidden ? SW_HIDE : SW_NORMAL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mg_wgl_surface_get_hidden(mg_surface_data* interface)
|
bool mg_wgl_surface_get_hidden(mg_surface_data* interface)
|
||||||
{
|
{
|
||||||
bool hidden = false;
|
|
||||||
mg_wgl_surface* surface = (mg_wgl_surface*)interface;
|
mg_wgl_surface* surface = (mg_wgl_surface*)interface;
|
||||||
if(surface)
|
return(mp_layer_get_hidden(&surface->layer));
|
||||||
{
|
|
||||||
hidden = !IsWindowVisible(surface->hWnd);
|
|
||||||
}
|
}
|
||||||
return(hidden);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void* mg_wgl_get_proc(const char* name)
|
void* mg_wgl_get_proc(const char* name)
|
||||||
{
|
{
|
||||||
|
@ -242,11 +205,6 @@ void* mg_wgl_get_proc(const char* name)
|
||||||
return(p);
|
return(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT mg_wgl_surface_window_proc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
return(DefWindowProc(windowHandle, message, wParam, lParam));
|
|
||||||
}
|
|
||||||
|
|
||||||
mg_surface mg_wgl_surface_create_for_window(mp_window window)
|
mg_surface mg_wgl_surface_create_for_window(mp_window window)
|
||||||
{
|
{
|
||||||
mg_surface surfaceHandle = mg_surface_nil();
|
mg_surface surfaceHandle = mg_surface_nil();
|
||||||
|
@ -256,30 +214,22 @@ mg_surface mg_wgl_surface_create_for_window(mp_window window)
|
||||||
{
|
{
|
||||||
wgl_init();
|
wgl_init();
|
||||||
|
|
||||||
//NOTE(martin): create a child window for the surface
|
//NOTE: fill surface data and load api
|
||||||
WNDCLASS childWindowClass = {.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
|
mg_wgl_surface* surface = malloc_type(mg_wgl_surface);
|
||||||
.lpfnWndProc = mg_wgl_surface_window_proc,
|
|
||||||
.hInstance = GetModuleHandleW(NULL),
|
|
||||||
.lpszClassName = "wgl_surface_window_class",
|
|
||||||
.hCursor = LoadCursor(0, IDC_ARROW)};
|
|
||||||
|
|
||||||
if(!RegisterClass(&childWindowClass))
|
surface->interface.backend = MG_BACKEND_GL;
|
||||||
{
|
surface->interface.destroy = mg_wgl_surface_destroy;
|
||||||
//TODO: error
|
surface->interface.prepare = mg_wgl_surface_prepare;
|
||||||
}
|
surface->interface.present = mg_wgl_surface_present;
|
||||||
|
surface->interface.swapInterval = mg_wgl_surface_swap_interval;
|
||||||
|
surface->interface.contentsScaling = mg_wgl_surface_contents_scaling;
|
||||||
|
surface->interface.getFrame = mg_wgl_surface_get_frame;
|
||||||
|
surface->interface.setFrame = mg_wgl_surface_set_frame;
|
||||||
|
surface->interface.getHidden = mg_wgl_surface_get_hidden;
|
||||||
|
surface->interface.setHidden = mg_wgl_surface_set_hidden;
|
||||||
|
|
||||||
mp_rect frame = mp_window_get_content_rect(window);
|
mp_layer_init_for_window(&surface->layer, windowData);
|
||||||
|
surface->hDC = GetDC(surface->layer.hWnd);
|
||||||
u32 dpi = GetDpiForWindow(windowData->win32.hWnd);
|
|
||||||
vec2 contentsScaling = (vec2){(float)dpi/96., (float)dpi/96.};
|
|
||||||
|
|
||||||
HWND childWindow = CreateWindow("wgl_surface_window_class", "Test",
|
|
||||||
WS_CHILD|WS_VISIBLE,
|
|
||||||
0, 0, frame.w*contentsScaling.x, frame.h*contentsScaling.y,
|
|
||||||
windowData->win32.hWnd,
|
|
||||||
0,
|
|
||||||
childWindowClass.hInstance,
|
|
||||||
0);
|
|
||||||
|
|
||||||
//NOTE(martin): create the pixel format and gl context
|
//NOTE(martin): create the pixel format and gl context
|
||||||
PIXELFORMATDESCRIPTOR pixelFormatDesc =
|
PIXELFORMATDESCRIPTOR pixelFormatDesc =
|
||||||
|
@ -312,17 +262,16 @@ mg_surface mg_wgl_surface_create_for_window(mp_window window)
|
||||||
WGL_STENCIL_BITS_ARB, 8,
|
WGL_STENCIL_BITS_ARB, 8,
|
||||||
0};
|
0};
|
||||||
|
|
||||||
HDC hDC = GetDC(childWindow);
|
|
||||||
u32 numFormats = 0;
|
u32 numFormats = 0;
|
||||||
int pixelFormat = 0;
|
int pixelFormat = 0;
|
||||||
|
|
||||||
wglChoosePixelFormatARB(hDC, pixelFormatAttrs, 0, 1, &pixelFormat, &numFormats);
|
wglChoosePixelFormatARB(surface->hDC, pixelFormatAttrs, 0, 1, &pixelFormat, &numFormats);
|
||||||
|
|
||||||
if(!pixelFormat)
|
if(!pixelFormat)
|
||||||
{
|
{
|
||||||
//TODO: error
|
//TODO: error
|
||||||
}
|
}
|
||||||
SetPixelFormat(hDC, pixelFormat, &pixelFormatDesc);
|
SetPixelFormat(surface->hDC, pixelFormat, &pixelFormatDesc);
|
||||||
|
|
||||||
int contextAttrs[] = {
|
int contextAttrs[] = {
|
||||||
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
|
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
|
||||||
|
@ -330,38 +279,18 @@ mg_surface mg_wgl_surface_create_for_window(mp_window window)
|
||||||
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
|
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||||
0};
|
0};
|
||||||
|
|
||||||
HGLRC glContext = wglCreateContextAttribsARB(hDC, __mgWGLDummyContext.glContext, contextAttrs);
|
surface->glContext = wglCreateContextAttribsARB(surface->hDC, __mgWGLDummyContext.glContext, contextAttrs);
|
||||||
|
|
||||||
if(!glContext)
|
if(!surface->glContext)
|
||||||
{
|
{
|
||||||
//TODO error
|
//TODO error
|
||||||
int error = GetLastError();
|
int error = GetLastError();
|
||||||
printf("error: %i\n", error);
|
printf("error: %i\n", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE: make gl context current
|
//NOTE: make gl context current and load api
|
||||||
wglMakeCurrent(hDC, glContext);
|
wglMakeCurrent(surface->hDC, surface->glContext);
|
||||||
wglSwapIntervalEXT(1);
|
wglSwapIntervalEXT(1);
|
||||||
|
|
||||||
//NOTE: fill surface data and load api
|
|
||||||
mg_wgl_surface* surface = malloc_type(mg_wgl_surface);
|
|
||||||
|
|
||||||
surface->interface.backend = MG_BACKEND_GL;
|
|
||||||
surface->interface.destroy = mg_wgl_surface_destroy;
|
|
||||||
surface->interface.prepare = mg_wgl_surface_prepare;
|
|
||||||
surface->interface.present = mg_wgl_surface_present;
|
|
||||||
surface->interface.swapInterval = mg_wgl_surface_swap_interval;
|
|
||||||
surface->interface.contentsScaling = mg_wgl_surface_contents_scaling;
|
|
||||||
surface->interface.getFrame = mg_wgl_surface_get_frame;
|
|
||||||
surface->interface.setFrame = mg_wgl_surface_set_frame;
|
|
||||||
surface->interface.getHidden = mg_wgl_surface_get_hidden;
|
|
||||||
surface->interface.setHidden = mg_wgl_surface_set_hidden;
|
|
||||||
|
|
||||||
surface->hWnd = childWindow;
|
|
||||||
surface->hDC = hDC;
|
|
||||||
surface->glContext = glContext;
|
|
||||||
surface->contentsScaling = contentsScaling;
|
|
||||||
|
|
||||||
mg_gl_load_gl43(&surface->api, mg_wgl_get_proc);
|
mg_gl_load_gl43(&surface->api, mg_wgl_get_proc);
|
||||||
|
|
||||||
surfaceHandle = mg_surface_alloc_handle((mg_surface_data*)surface);
|
surfaceHandle = mg_surface_alloc_handle((mg_surface_data*)surface);
|
||||||
|
|
|
@ -777,6 +777,94 @@ mp_rect mp_window_get_content_rect(mp_window window)
|
||||||
return(rect);
|
return(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
void mp_layer_init_for_window(mp_layer* layer, mp_window_data* window)
|
||||||
|
{
|
||||||
|
//NOTE(martin): create a child window for the surface
|
||||||
|
WNDCLASS layerWindowClass = {.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
|
||||||
|
.lpfnWndProc = DefWindowProc,
|
||||||
|
.hInstance = GetModuleHandleW(NULL),
|
||||||
|
.lpszClassName = "layer_window_class",
|
||||||
|
.hCursor = LoadCursor(0, IDC_ARROW)};
|
||||||
|
|
||||||
|
RegisterClass(&layerWindowClass);
|
||||||
|
|
||||||
|
RECT parentRect;
|
||||||
|
GetClientRect(window->win32.hWnd, &parentRect);
|
||||||
|
int width = parentRect.right - parentRect.left;
|
||||||
|
int height = parentRect.bottom - parentRect.top;
|
||||||
|
|
||||||
|
layer->hWnd = CreateWindow("layer_window_class", "layer",
|
||||||
|
WS_CHILD | WS_VISIBLE,
|
||||||
|
0, 0, width, height,
|
||||||
|
window->win32.hWnd,
|
||||||
|
0,
|
||||||
|
layerWindowClass.hInstance,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mp_layer_cleanup(mp_layer* layer)
|
||||||
|
{
|
||||||
|
DestroyWindow(layer->hWnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* mp_layer_native_surface(mp_layer* layer)
|
||||||
|
{
|
||||||
|
return((void*)layer->hWnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 mp_layer_contents_scaling(mp_layer* layer)
|
||||||
|
{
|
||||||
|
u32 dpi = GetDpiForWindow(layer->hWnd);
|
||||||
|
vec2 contentsScaling = (vec2){(float)dpi/96., (float)dpi/96.};
|
||||||
|
return(contentsScaling);
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_rect mp_layer_get_frame(mp_layer* layer)
|
||||||
|
{
|
||||||
|
RECT rect = {0};
|
||||||
|
GetClientRect(layer->hWnd, &rect);
|
||||||
|
|
||||||
|
vec2 scale = mp_layer_contents_scaling(layer);
|
||||||
|
|
||||||
|
mp_rect res = {rect.left/scale.x,
|
||||||
|
rect.bottom/scale.y,
|
||||||
|
(rect.right - rect.left)/scale.x,
|
||||||
|
(rect.bottom - rect.top)/scale.y};
|
||||||
|
return(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mp_layer_set_frame(mp_layer* layer, mp_rect frame)
|
||||||
|
{
|
||||||
|
HWND parent = GetParent(layer->hWnd);
|
||||||
|
RECT parentContentRect;
|
||||||
|
|
||||||
|
GetClientRect(parent, &parentContentRect);
|
||||||
|
int parentHeight = parentContentRect.bottom - parentContentRect.top;
|
||||||
|
|
||||||
|
vec2 scale = mp_layer_contents_scaling(layer);
|
||||||
|
|
||||||
|
SetWindowPos(layer->hWnd,
|
||||||
|
HWND_TOP,
|
||||||
|
frame.x * scale.x,
|
||||||
|
parentHeight - (frame.y + frame.h) * scale.y,
|
||||||
|
frame.w * scale.x,
|
||||||
|
frame.h * scale.y,
|
||||||
|
SWP_NOACTIVATE | SWP_NOZORDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mp_layer_set_hidden(mp_layer* layer, bool hidden)
|
||||||
|
{
|
||||||
|
ShowWindow(layer->hWnd, hidden ? SW_HIDE : SW_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mp_layer_get_hidden(mp_layer* layer)
|
||||||
|
{
|
||||||
|
bool hidden = !IsWindowVisible(layer->hWnd);
|
||||||
|
return(hidden);
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////// WIP ///////////////////////////////////////////////
|
/////////////////////////////////////////// WIP ///////////////////////////////////////////////
|
||||||
//TODO: this is thrown here for a quick test. We should:
|
//TODO: this is thrown here for a quick test. We should:
|
||||||
// - check for errors
|
// - check for errors
|
||||||
|
|
|
@ -16,12 +16,17 @@
|
||||||
#define UNICODE
|
#define UNICODE
|
||||||
#include<windows.h>
|
#include<windows.h>
|
||||||
|
|
||||||
|
|
||||||
typedef struct win32_window_data
|
typedef struct win32_window_data
|
||||||
{
|
{
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
|
|
||||||
} win32_window_data;
|
} win32_window_data;
|
||||||
|
|
||||||
|
typedef struct mp_layer
|
||||||
|
{
|
||||||
|
HWND hWnd;
|
||||||
|
} mp_layer;
|
||||||
|
|
||||||
#define MP_PLATFORM_WINDOW_DATA win32_window_data win32;
|
#define MP_PLATFORM_WINDOW_DATA win32_window_data win32;
|
||||||
|
|
||||||
typedef struct win32_app_data
|
typedef struct win32_app_data
|
||||||
|
|
30
todo.txt
30
todo.txt
|
@ -4,27 +4,24 @@ Overview
|
||||||
[.] Make backend selection easier
|
[.] Make backend selection easier
|
||||||
[.] option macros to select backend-specific APIs to include when building an app
|
[.] option macros to select backend-specific APIs to include when building an app
|
||||||
(ie, include gl_api.h when using gl backend)
|
(ie, include gl_api.h when using gl backend)
|
||||||
[ ] error on bad option macro combinations
|
[/] error on bad option macro combinations
|
||||||
[ ] write doc about backend option macros
|
[/] write doc about backend option macros
|
||||||
|
|
||||||
[>] Image API and backend
|
[?] could have an internal, per-platform mp_layer struct that handles resizing/hiding etc...
|
||||||
[ ] Build image atlas on top
|
-> avoid duplication of frame/hiding and duplication of egl code.
|
||||||
[ ] Baked fonts?
|
[/] EGL surfaces: See how we can isolate platform-specific stuff and just deal with one egl impl...
|
||||||
|
|
||||||
[x] Allow different versions of GL/GLES to co-exist
|
|
||||||
[/] Allow selecting version of GL/GLES context when creating surface
|
|
||||||
- pass/set attributes when creating surface?
|
|
||||||
|
|
||||||
[ ] Check that we can make GLES and GL surfaces co-exist in the app
|
[ ] Check that we can make GLES and GL surfaces co-exist in the app
|
||||||
[ ] Allow controlling surface overlaying
|
[ ] Allow controlling surface overlaying
|
||||||
|
|
||||||
[/] could have an internal, per-platform mp_layer struct that handles resizing/hiding etc...
|
[/] Allow selecting version of GL/GLES context when creating surface
|
||||||
-> avoid duplication of frame/hiding and duplication of egl code.
|
- pass/set attributes when creating surface?
|
||||||
[/] EGL surfaces: See how we can isolate platform-specific stuff and just deal with one egl impl...
|
|
||||||
[/] Automatic surface resizing
|
[/] Automatic surface resizing
|
||||||
[/] Keep dummy window/dummy context around for gl context creation, and don't reload wgl functions every time
|
|
||||||
|
|
||||||
[!] Make linking with libEGL optional, even if EGL backend is compiled in milepost?
|
[!] Make linking with libEGL optional, even if EGL backend is compiled in milepost?
|
||||||
|
- use dead_strip_dylib on osx?
|
||||||
|
- use /DELAYLOAD:lib on windows?
|
||||||
|
|
||||||
[!] Bundle examples with their own resources?? (e.g. avoiding clashes in metal libs files in bin directory)
|
[!] Bundle examples with their own resources?? (e.g. avoiding clashes in metal libs files in bin directory)
|
||||||
|
|
||||||
[!] Sort out gles contents scaling for high dpi on osx
|
[!] Sort out gles contents scaling for high dpi on osx
|
||||||
|
@ -33,10 +30,13 @@ Overview
|
||||||
[!] Fix canvas perf issue on OSX
|
[!] Fix canvas perf issue on OSX
|
||||||
|
|
||||||
|
|
||||||
|
[>] Image API and backend
|
||||||
|
[ ] Build image atlas on top
|
||||||
|
[ ] Baked fonts?
|
||||||
|
|
||||||
|
|
||||||
[ ] Delegated drawing API+Impl
|
[ ] Delegated drawing API+Impl
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[ ] Make building apps simpler
|
[ ] Make building apps simpler
|
||||||
[ ] single include path
|
[ ] single include path
|
||||||
[ ] script for embedding dependencies / create app bundle
|
[ ] script for embedding dependencies / create app bundle
|
||||||
|
|
Loading…
Reference in New Issue