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!
This commit is contained in:
parent
7fbc4ba270
commit
7cf4c3d925
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<ShellScalingApi.h>
|
||||
#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);
|
||||
|
|
|
@ -10,9 +10,10 @@
|
|||
#ifndef __WIN32_APP_H_
|
||||
#define __WIN32_APP_H_
|
||||
|
||||
#include"mp_app.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include<windows.h>
|
||||
#include"mp_app.h"
|
||||
|
||||
typedef struct win32_window_data
|
||||
{
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
2
todo.txt
2
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
|
||||
|
|
Loading…
Reference in New Issue