From 7cf4c3d9252a9acf1b4c243aebc672e7c243016d Mon Sep 17 00:00:00 2001 From: martinfouilleul Date: Wed, 8 Feb 2023 18:22:54 +0100 Subject: [PATCH] opengl surface/renderer: set surface scaling according to dpi of first monitor. Use that dpi to scale backing texture of canvas renderer. Note: changing monitor isn't handled yet! --- examples/perf_text/build.bat | 2 +- examples/perf_text/main.c | 19 +++-- examples/win_canvas/build.bat | 2 +- src/gl_canvas.c | 13 +++- src/gles_canvas_shaders/gles_canvas_draw.glsl | 37 +++++----- src/gles_canvas_shaders/gles_canvas_tile.glsl | 9 ++- src/graphics.c | 13 ++++ src/graphics.h | 1 + src/graphics_internal.h | 2 + src/win32_app.c | 35 ++++++--- src/win32_app.h | 73 ++++++++++--------- src/win32_gl_loader.h | 2 + src/win32_gl_surface.c | 21 +++++- todo.txt | 2 +- 14 files changed, 144 insertions(+), 87 deletions(-) diff --git a/examples/perf_text/build.bat b/examples/perf_text/build.bat index 372691f..43ec66e 100644 --- a/examples/perf_text/build.bat +++ b/examples/perf_text/build.bat @@ -1,4 +1,4 @@ set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext -cl /we4013 /Zi /Zc:preprocessor /DMG_IMPLEMENTS_BACKEND_GL /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib user32.lib opengl32.lib gdi32.lib /out:../../bin/perf_text.exe +cl /we4013 /Zi /Zc:preprocessor /DMG_IMPLEMENTS_BACKEND_GL /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib user32.lib opengl32.lib gdi32.lib shcore.lib /out:../../bin/perf_text.exe diff --git a/examples/perf_text/main.c b/examples/perf_text/main.c index ec16b43..ab3722d 100644 --- a/examples/perf_text/main.c +++ b/examples/perf_text/main.c @@ -81,6 +81,8 @@ int main() mp_rect rect = {.x = 100, .y = 100, .w = 980, .h = 600}; mp_window window = mp_window_create(rect, "test", 0); + mp_rect contentRect = mp_window_get_content_rect(window); + //NOTE: create surface, canvas and font #if defined(OS_MACOS) @@ -90,12 +92,13 @@ int main() #else #error "unsupported OS" #endif + mg_surface_swap_interval(surface, 0); mg_canvas canvas = mg_canvas_create(surface); mg_font font = create_font(); mg_font_extents extents = mg_font_get_extents(font); - f32 fontScale = mg_font_get_scale_for_em_pixels(font, 12); + f32 fontScale = mg_font_get_scale_for_em_pixels(font, 14); f32 lineHeight = fontScale*(extents.ascent + extents.descent + extents.leading); @@ -130,14 +133,14 @@ int main() } f32 textX = 10; - f32 textY = 600 - lineHeight; + f32 textY = contentRect.h - lineHeight - 10; mg_surface_prepare(surface); mg_set_color_rgba(1, 1, 1, 1); mg_clear(); mg_set_font(font); - mg_set_font_size(12); + mg_set_font_size(14); mg_set_color_rgba(0, 0, 0, 1); mg_move_to(textX, textY); @@ -155,7 +158,7 @@ int main() break; } } - ASSERT(subIndex < 512 && (startIndex+subIndex)<=codePointCount); + u32 glyphs[512]; mg_font_get_glyph_indices(font, (str32){subIndex, codePoints+startIndex}, (str32){512, glyphs}); @@ -171,12 +174,10 @@ int main() startIndex += subIndex; } - f64 startFlushTime = mp_get_time(MP_CLOCK_MONOTONIC); - mg_set_color_rgba(0, 0, 1, 1); mg_set_font(font); - mg_set_font_size(12); - mg_move_to(50, 50); + mg_set_font_size(14); + mg_move_to(10, 10 + lineHeight); str8 text = str8_pushf(mem_scratch(), "Milepost vector graphics test program (frame time = %fs, fps = %f)...", @@ -185,6 +186,8 @@ int main() mg_text_outlines(text); mg_fill(); + + f64 startFlushTime = mp_get_time(MP_CLOCK_MONOTONIC); mg_flush(); f64 startPresentTime = mp_get_time(MP_CLOCK_MONOTONIC); diff --git a/examples/win_canvas/build.bat b/examples/win_canvas/build.bat index 8a4c8c1..fbd4a7f 100644 --- a/examples/win_canvas/build.bat +++ b/examples/win_canvas/build.bat @@ -1,3 +1,3 @@ set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext /I ../../ext/angle_headers -cl /we4013 /Zi /Zc:preprocessor /DMG_IMPLEMENTS_BACKEND_GL /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib user32.lib opengl32.lib gdi32.lib /out:../../bin/example_canvas.exe +cl /we4013 /Zi /Zc:preprocessor /DMG_IMPLEMENTS_BACKEND_GL /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib user32.lib opengl32.lib gdi32.lib shcore.lib /out:../../bin/example_canvas.exe diff --git a/src/gl_canvas.c b/src/gl_canvas.c index 304a508..3075180 100644 --- a/src/gl_canvas.c +++ b/src/gl_canvas.c @@ -181,10 +181,11 @@ void mg_gl_canvas_draw_batch(mg_canvas_backend* interface, u32 shapeCount, u32 v mg_gl_send_buffers(backend, shapeCount, vertexCount, indexCount); mp_rect frame = mg_surface_get_frame(backend->surface); + vec2 contentsScaling = mg_surface_contents_scaling(backend->surface); const int tileSize = 16; - const int tileCountX = (frame.w + tileSize - 1)/tileSize; - const int tileCountY = (frame.h + tileSize - 1)/tileSize; + const int tileCountX = (frame.w*contentsScaling.x + tileSize - 1)/tileSize; + const int tileCountY = (frame.h*contentsScaling.y + tileSize - 1)/tileSize; const int tileArraySize = MG_GL_CANVAS_TILE_ARRAY_SIZE; //TODO: ensure there's enough space in tile buffer @@ -208,6 +209,7 @@ void mg_gl_canvas_draw_batch(mg_canvas_backend* interface, u32 shapeCount, u32 v glUniform2ui(1, tileCountX, tileCountY); glUniform1ui(2, tileSize); glUniform1ui(3, tileArraySize); + glUniform2f(4, contentsScaling.x, contentsScaling.y); u32 threadCount = indexCount/3; glDispatchCompute((threadCount + 255)/256, 1, 1); @@ -222,7 +224,7 @@ void mg_gl_canvas_draw_batch(mg_canvas_backend* interface, u32 shapeCount, u32 v glDispatchCompute(tileCountX * tileCountY, 1, 1); - //NOTE: then we fire the fragment shader that will select only triangles in its tile + //NOTE: then we fire the drawing shader that will select only triangles in its tile glUseProgram(backend->drawProgram); glBindImageTexture(0, backend->outTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8); @@ -231,6 +233,7 @@ void mg_gl_canvas_draw_batch(mg_canvas_backend* interface, u32 shapeCount, u32 v glUniform2ui(1, tileCountX, tileCountY); glUniform1ui(2, tileSize); glUniform1ui(3, tileArraySize); + glUniform2f(4, contentsScaling.x, contentsScaling.y); glDispatchCompute(tileCountX, tileCountY, 1); @@ -330,9 +333,11 @@ mg_canvas_backend* mg_gl_canvas_create(mg_surface surface) glBufferData(GL_SHADER_STORAGE_BUFFER, MG_GL_CANVAS_TILE_ARRAY_BUFFER_SIZE, 0, GL_DYNAMIC_COPY); mp_rect frame = mg_surface_get_frame(backend->surface); + vec2 contentsScaling = mg_surface_contents_scaling(backend->surface); + glGenTextures(1, &backend->outTexture); glBindTexture(GL_TEXTURE_2D, backend->outTexture); - glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, frame.w, frame.h); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, frame.w*contentsScaling.x, frame.h*contentsScaling.y); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); diff --git a/src/gles_canvas_shaders/gles_canvas_draw.glsl b/src/gles_canvas_shaders/gles_canvas_draw.glsl index b6024f6..48a2b07 100644 --- a/src/gles_canvas_shaders/gles_canvas_draw.glsl +++ b/src/gles_canvas_shaders/gles_canvas_draw.glsl @@ -42,8 +42,9 @@ layout(location = 0) uniform uint indexCount; layout(location = 1) uniform uvec2 tileCount; layout(location = 2) uniform uint tileSize; layout(location = 3) uniform uint tileArraySize; -layout(rgba8, binding = 0) uniform restrict writeonly image2D outTexture; +layout(location = 4) uniform vec2 scaling; +layout(rgba8, binding = 0) uniform restrict writeonly image2D outTexture; bool is_top_left(ivec2 a, ivec2 b) { @@ -63,25 +64,25 @@ void main() uint tileIndex = tileCoord.y * tileCount.x + tileCoord.x; uint tileCounter = tileCounterBuffer.elements[tileIndex]; - const float subPixelFactor = 16.; + const float subPixelFactor = 256.; ivec2 centerPoint = ivec2((vec2(pixelCoord) + vec2(0.5, 0.5)) * subPixelFactor); //* const int sampleCount = 8; - ivec2 samplePoints[sampleCount] = ivec2[sampleCount](centerPoint + ivec2(1, 3), - centerPoint + ivec2(-1, -3), - centerPoint + ivec2(5, -1), - centerPoint + ivec2(-3, 5), - centerPoint + ivec2(-5, -5), - centerPoint + ivec2(-7, 1), - centerPoint + ivec2(3, -7), - centerPoint + ivec2(7, 7)); + ivec2 samplePoints[sampleCount] = ivec2[sampleCount](centerPoint + ivec2(1, 3)*16, + centerPoint + ivec2(-1, -3)*16, + centerPoint + ivec2(5, -1)*16, + centerPoint + ivec2(-3, 5)*16, + centerPoint + ivec2(-5, -5)*16, + centerPoint + ivec2(-7, 1)*16, + centerPoint + ivec2(3, -7)*16, + centerPoint + ivec2(7, 7)*16); /*/ const int sampleCount = 4; - ivec2 samplePoints[sampleCount] = ivec2[sampleCount](centerPoint + ivec2(-2, 6), - centerPoint + ivec2(6, 2), - centerPoint + ivec2(-6, -2), - centerPoint + ivec2(2, -6)); + ivec2 samplePoints[sampleCount] = ivec2[sampleCount](centerPoint + ivec2(-2, 6)*16, + centerPoint + ivec2(6, 2)*16, + centerPoint + ivec2(-6, -2)*16, + centerPoint + ivec2(2, -6)*16); //*/ //DEBUG /* @@ -132,13 +133,13 @@ void main() uint i1 = indexBuffer.elements[triangleIndex+1u]; uint i2 = indexBuffer.elements[triangleIndex+2u]; - ivec2 p0 = ivec2((vertexBuffer.elements[i0].pos) * subPixelFactor); - ivec2 p1 = ivec2((vertexBuffer.elements[i1].pos) * subPixelFactor); - ivec2 p2 = ivec2((vertexBuffer.elements[i2].pos) * subPixelFactor); + ivec2 p0 = ivec2((vertexBuffer.elements[i0].pos * scaling) * subPixelFactor); + ivec2 p1 = ivec2((vertexBuffer.elements[i1].pos * scaling) * subPixelFactor); + ivec2 p2 = ivec2((vertexBuffer.elements[i2].pos * scaling) * subPixelFactor); int zIndex = vertexBuffer.elements[i0].zIndex; vec4 color = shapeBuffer.elements[zIndex].color; - ivec4 clip = ivec4(round((shapeBuffer.elements[zIndex].clip + vec4(0.5, 0.5, 0.5, 0.5)) * subPixelFactor)); + ivec4 clip = ivec4(round((shapeBuffer.elements[zIndex].clip * vec4(scaling, scaling) + vec4(0.5, 0.5, 0.5, 0.5)) * subPixelFactor)); //NOTE(martin): reorder triangle counter-clockwise and compute bias for each edge int cw = (p1 - p0).x*(p2 - p0).y - (p1 - p0).y*(p2 - p0).x; diff --git a/src/gles_canvas_shaders/gles_canvas_tile.glsl b/src/gles_canvas_shaders/gles_canvas_tile.glsl index f14d952..96c03b1 100644 --- a/src/gles_canvas_shaders/gles_canvas_tile.glsl +++ b/src/gles_canvas_shaders/gles_canvas_tile.glsl @@ -40,6 +40,7 @@ layout(location = 0) uniform uint indexCount; layout(location = 1) uniform uvec2 tileCount; layout(location = 2) uniform uint tileSize; layout(location = 3) uniform uint tileArraySize; +layout(location = 4) uniform vec2 scaling; void main() { @@ -53,12 +54,12 @@ void main() uint i1 = indexBuffer.elements[triangleIndex+1u]; uint i2 = indexBuffer.elements[triangleIndex+2u]; - vec2 p0 = vertexBuffer.elements[i0].pos; - vec2 p1 = vertexBuffer.elements[i1].pos; - vec2 p2 = vertexBuffer.elements[i2].pos; + vec2 p0 = vertexBuffer.elements[i0].pos * scaling; + vec2 p1 = vertexBuffer.elements[i1].pos * scaling; + vec2 p2 = vertexBuffer.elements[i2].pos * scaling; int shapeIndex = vertexBuffer.elements[i0].zIndex; - vec4 clip = shapeBuffer.elements[shapeIndex].clip; + vec4 clip = shapeBuffer.elements[shapeIndex].clip * vec4(scaling, scaling); vec4 fbox = vec4(max(min(min(p0.x, p1.x), p2.x), clip.x), max(min(min(p0.y, p1.y), p2.y), clip.y), diff --git a/src/graphics.c b/src/graphics.c index 2bc14c0..ec3eefe 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -331,6 +331,19 @@ void mg_surface_swap_interval(mg_surface surface, int swap) } } +vec2 mg_surface_contents_scaling(mg_surface surface) +{ + DEBUG_ASSERT(__mgData.init); + vec2 scaling = {1, 1}; + mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); + if(surfaceData) + { + scaling = surfaceData->contentsScaling(surfaceData); + } + return(scaling); +} + + void mg_surface_set_frame(mg_surface surface, mp_rect frame) { DEBUG_ASSERT(__mgData.init); diff --git a/src/graphics.h b/src/graphics.h index 825c892..577bc54 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -21,6 +21,7 @@ void mg_surface_destroy(mg_surface surface); void mg_surface_prepare(mg_surface surface); void mg_surface_present(mg_surface surface); void mg_surface_swap_interval(mg_surface surface, int swap); +vec2 mg_surface_contents_scaling(mg_surface surface); mp_rect mg_surface_get_frame(mg_surface surface); void mg_surface_set_frame(mg_surface surface, mp_rect frame); bool mg_surface_get_hidden(mg_surface surface); diff --git a/src/graphics_internal.h b/src/graphics_internal.h index e764021..d408e77 100644 --- a/src/graphics_internal.h +++ b/src/graphics_internal.h @@ -28,6 +28,7 @@ typedef void (*mg_surface_destroy_proc)(mg_surface_data* surface); typedef void (*mg_surface_prepare_proc)(mg_surface_data* surface); typedef void (*mg_surface_present_proc)(mg_surface_data* surface); typedef void (*mg_surface_swap_interval_proc)(mg_surface_data* surface, int swap); +typedef vec2 (*mg_surface_contents_scaling_proc)(mg_surface_data* surface); typedef mp_rect (*mg_surface_get_frame_proc)(mg_surface_data* surface); typedef void (*mg_surface_set_frame_proc)(mg_surface_data* surface, mp_rect frame); typedef bool (*mg_surface_get_hidden_proc)(mg_surface_data* surface); @@ -41,6 +42,7 @@ typedef struct mg_surface_data mg_surface_prepare_proc prepare; mg_surface_present_proc present; mg_surface_swap_interval_proc swapInterval; + mg_surface_contents_scaling_proc contentsScaling; mg_surface_get_frame_proc getFrame; mg_surface_set_frame_proc setFrame; mg_surface_get_hidden_proc getHidden; diff --git a/src/win32_app.c b/src/win32_app.c index 6cd7015..59ffbf4 100644 --- a/src/win32_app.c +++ b/src/win32_app.c @@ -156,6 +156,8 @@ void mp_init() __mpApp.win32.savedConsoleCodePage = GetConsoleOutputCP(); SetConsoleOutputCP(CP_UTF8); + + SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE); } } @@ -258,6 +260,12 @@ LRESULT WinProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam) mp_queue_event(&event); } break; + case WM_DPICHANGED: + { + printf("DPI changed!\n"); + + } break; + //TODO: enter/exit size & move case WM_SIZING: @@ -502,6 +510,12 @@ void mp_pump_events(f64 timeout) // window management //-------------------------------------------------------------------- +//WARN: the following header pulls in objbase.h (even with WIN32_LEAN_AND_MEAN), which +// #defines interface to struct... so make sure to #undef interface since it's a +// name we want to be able to use throughout the codebase +#include +#undef interface + mp_window mp_window_create(mp_rect rect, const char* title, mp_window_style style) { WNDCLASS windowClass = {.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC, @@ -516,19 +530,16 @@ mp_window mp_window_create(mp_rect rect, const char* title, mp_window_style styl goto quit; } - /* - //NOTE: get primary monitor dimensions - const POINT ptZero = { 0, 0 }; - HMONITOR monitor = MonitorFromPoint(ptZero, MONITOR_DEFAULTTOPRIMARY); - MONITORINFO monitorInfo = {.cbSize = sizeof(MONITORINFO)}; - GetMonitorInfo(monitor, &monitorInfo); - RECT adjustRect = {rect.x, monitorInfo.rcMonitor.bottom - rect.y - rect.h, rect.w, rect.h}; - AdjustWindowRect(&adjustRect, WS_OVERLAPPEDWINDOW, false); - */ + u32 dpiX, dpiY; + HMONITOR monitor = MonitorFromPoint((POINT){rect.x, rect.y}, MONITOR_DEFAULTTOPRIMARY); + GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY); + + f32 dpiScalingX = (f32)dpiX/96.; + f32 dpiScalingY = (f32)dpiY/96.; HWND windowHandle = CreateWindow("ApplicationWindowClass", "Test Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, - rect.w, rect.h, + rect.w * dpiScalingX, rect.h * dpiScalingY, 0, 0, windowClass.hInstance, 0); if(!windowHandle) @@ -740,7 +751,9 @@ mp_rect mp_window_get_content_rect(mp_window window) RECT winRect; if(GetClientRect(windowData->win32.hWnd, &winRect)) { - rect = (mp_rect){0, 0, winRect.right - winRect.left, winRect.bottom - winRect.top}; + u32 dpi = GetDpiForWindow(windowData->win32.hWnd); + f32 scale = (float)dpi/96.; + rect = (mp_rect){0, 0, (winRect.right - winRect.left)/scale, (winRect.bottom - winRect.top)/scale}; } } return(rect); diff --git a/src/win32_app.h b/src/win32_app.h index c9ddb8e..60611dd 100644 --- a/src/win32_app.h +++ b/src/win32_app.h @@ -1,36 +1,37 @@ -//***************************************************************** -// -// $file: win32_app.h $ -// $author: Martin Fouilleul $ -// $date: 20/12/2022 $ -// $revision: $ -// $note: (C) 2022 by Martin Fouilleul - all rights reserved $ -// -//***************************************************************** -#ifndef __WIN32_APP_H_ -#define __WIN32_APP_H_ - -#define WIN32_LEAN_AND_MEAN -#include -#include"mp_app.h" - -typedef struct win32_window_data -{ - HWND hWnd; - -} win32_window_data; - -#define MP_PLATFORM_WINDOW_DATA win32_window_data win32; - -typedef struct win32_app_data -{ - u32 savedConsoleCodePage; - - int mouseCaptureMask; - bool mouseTracked; - -} win32_app_data; - -#define MP_PLATFORM_APP_DATA win32_app_data win32; - -#endif __WIN32_APP_H_ +//***************************************************************** +// +// $file: win32_app.h $ +// $author: Martin Fouilleul $ +// $date: 20/12/2022 $ +// $revision: $ +// $note: (C) 2022 by Martin Fouilleul - all rights reserved $ +// +//***************************************************************** +#ifndef __WIN32_APP_H_ +#define __WIN32_APP_H_ + +#include"mp_app.h" + +#define WIN32_LEAN_AND_MEAN +#include + +typedef struct win32_window_data +{ + HWND hWnd; + +} win32_window_data; + +#define MP_PLATFORM_WINDOW_DATA win32_window_data win32; + +typedef struct win32_app_data +{ + u32 savedConsoleCodePage; + + int mouseCaptureMask; + bool mouseTracked; + +} win32_app_data; + +#define MP_PLATFORM_APP_DATA win32_app_data win32; + +#endif __WIN32_APP_H_ diff --git a/src/win32_gl_loader.h b/src/win32_gl_loader.h index 9b90d91..bfebdb1 100644 --- a/src/win32_gl_loader.h +++ b/src/win32_gl_loader.h @@ -44,6 +44,8 @@ GL_PROC(GLDISPATCHCOMPUTE, glDispatchCompute) \ GL_PROC(GLUNIFORM1UI, glUniform1ui) \ GL_PROC(GLUNIFORM2UI, glUniform2ui) \ + GL_PROC(GLUNIFORM1F, glUniform1f) \ + GL_PROC(GLUNIFORM2F, glUniform2f) \ GL_PROC(GLBINDIMAGETEXTURE, glBindImageTexture) \ GL_PROC(GLACTIVETEXTURE, glActiveTexture) \ GL_PROC(GLUNIFORM1I, glUniform1i) \ diff --git a/src/win32_gl_surface.c b/src/win32_gl_surface.c index ce5120f..a3223c5 100644 --- a/src/win32_gl_surface.c +++ b/src/win32_gl_surface.c @@ -6,12 +6,11 @@ * @revision: * *****************************************************************/ - #define WIN32_GL_LOADER_IMPL #include"win32_gl_loader.h" +#include"win32_app.h" #include"graphics_internal.h" -#include"win32_app.h" typedef struct mg_gl_surface { @@ -20,6 +19,7 @@ typedef struct mg_gl_surface HWND hWnd; HDC hDC; HGLRC glContext; + vec2 contentsScaling; } mg_gl_surface; @@ -48,13 +48,24 @@ void mg_gl_surface_swap_interval(mg_surface_data* interface, int swap) wglSwapIntervalEXT(swap); } +vec2 mg_gl_contents_scaling(mg_surface_data* interface) +{ + mg_gl_surface* surface = (mg_gl_surface*)interface; + return(surface->contentsScaling); +} + mp_rect mg_gl_surface_get_frame(mg_surface_data* interface) { mg_gl_surface* surface = (mg_gl_surface*)interface; RECT rect = {0}; GetClientRect(surface->hWnd, &rect); - mp_rect res = {rect.left, rect.bottom, rect.right - rect.left, rect.bottom - rect.top}; + vec2 scale = surface->contentsScaling; + + 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); } @@ -200,6 +211,7 @@ mg_surface mg_gl_surface_create_for_window(mp_window window) surface->interface.prepare = mg_gl_surface_prepare; surface->interface.present = mg_gl_surface_present; surface->interface.swapInterval = mg_gl_surface_swap_interval; + surface->interface.contentsScaling = mg_gl_contents_scaling; surface->interface.getFrame = mg_gl_surface_get_frame; //TODO: get/set frame/hidden @@ -207,6 +219,9 @@ mg_surface mg_gl_surface_create_for_window(mp_window window) surface->hDC = hDC; surface->glContext = glContext; + u32 dpi = GetDpiForWindow(windowData->win32.hWnd); + surface->contentsScaling = (vec2){(float)dpi/96., (float)dpi/96.}; + surfaceHandle = mg_surface_alloc_handle((mg_surface_data*)surface); } diff --git a/todo.txt b/todo.txt index 0f00ba9..ff22248 100644 --- a/todo.txt +++ b/todo.txt @@ -10,7 +10,7 @@ Canvas renderer perf by subpixel precision and truncating... -> ie sampling at the middle of pixels vs at integer coordinates... [ ] What alignment gives crisp-ier lines? -[>] Add surface scaling for high dpi surfaces +[>] Add surface scaling for high dpi surfaces and check that our fonts are renderer smoothly [x] Allow setting swap interval [!] Allow swap interval of 0 on macos