Allow setting surface swap interval in opengl surface

This commit is contained in:
martinfouilleul 2023-02-08 11:49:00 +01:00
parent c982b524c0
commit e6e674ee04
8 changed files with 609 additions and 535 deletions

View File

@ -58,8 +58,10 @@ int main()
mp_init();
mp_clock_init(); //TODO put that in mp_init()?
mp_rect rect = {.x = 100, .y = 100, .w = 810, .h = 610};
mp_window window = mp_window_create(rect, "test", 0);
mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610};
mp_window window = mp_window_create(windowRect, "test", 0);
mp_rect contentRect = mp_window_get_content_rect(window);
//NOTE: create surface
#if defined(OS_MACOS)
@ -70,6 +72,8 @@ int main()
#error "unsupported OS"
#endif
mg_surface_swap_interval(surface, 0);
//TODO: create canvas
mg_canvas canvas = mg_canvas_create(surface);
mg_font font = create_font();
@ -79,7 +83,8 @@ int main()
mp_window_focus(window);
f32 x = 400, y = 300;
f32 dx = 5, dy = 5;
f32 speed = 0;
f32 dx = speed, dy = speed;
f64 frameTime = 0;
while(!mp_should_quit())
@ -110,24 +115,36 @@ int main()
{
if(event.key.action == MP_KEY_PRESS || event.key.action == MP_KEY_REPEAT)
{
/*
//*
if(event.key.code == MP_KEY_LEFT)
{
dx-=5.1;
if(x - 200 > 0)
{
x-=1;
}
}
else if(event.key.code == MP_KEY_RIGHT)
{
dx+=5.1;
if(x + 200 < contentRect.w)
{
x+=1;
}
}
else if(event.key.code == MP_KEY_UP)
{
dy+=5.1;
if(y + 200 < contentRect.h)
{
y+=1;
}
}
else if(event.key.code == MP_KEY_DOWN)
{
dy-=5.1;
if(y - 200 > 0)
{
y-=1;
}
}
*/
//*/
}
} break;
@ -138,19 +155,19 @@ int main()
if(x-200 < 0)
{
dx = 5;
dx = speed;
}
if(x+200 > 800)
if(x+200 > contentRect.w)
{
dx = -5;
dx = -speed;
}
if(y-200 < 0)
{
dy = 5;
dy = speed;
}
if(y+200 > 550)
if(y+200 > contentRect.h)
{
dy = -5;
dy = -speed;
}
x += dx;
y += dy;

View File

@ -321,6 +321,16 @@ void mg_surface_present(mg_surface surface)
}
}
void mg_surface_swap_interval(mg_surface surface, int swap)
{
DEBUG_ASSERT(__mgData.init);
mg_surface_data* surfaceData = mg_surface_data_from_handle(surface);
if(surfaceData)
{
surfaceData->swapInterval(surfaceData, swap);
}
}
void mg_surface_set_frame(mg_surface surface, mp_rect frame)
{
DEBUG_ASSERT(__mgData.init);

View File

@ -20,6 +20,7 @@ bool mg_surface_is_nil(mg_surface surface);
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);
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);

View File

@ -27,6 +27,7 @@ typedef struct mg_surface_data mg_surface_data;
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 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);
@ -39,6 +40,7 @@ typedef struct mg_surface_data
mg_surface_destroy_proc destroy;
mg_surface_prepare_proc prepare;
mg_surface_present_proc present;
mg_surface_swap_interval_proc swapInterval;
mg_surface_get_frame_proc getFrame;
mg_surface_set_frame_proc setFrame;
mg_surface_get_hidden_proc getHidden;

View File

@ -127,6 +127,15 @@ void mg_metal_surface_present(mg_surface_data* interface)
}
}
void mg_metal_surface_swap_interval(mg_surface_data* interface, int swap)
{
mg_metal_surface* surface = (mg_metal_surface*)interface;
////////////////////////////////////////////////////////////////
//TODO
////////////////////////////////////////////////////////////////
}
void mg_metal_surface_set_frame(mg_surface_data* interface, mp_rect frame)
{
mg_metal_surface* surface = (mg_metal_surface*)interface;
@ -192,6 +201,7 @@ mg_surface mg_metal_surface_create_for_window(mp_window window)
surface->interface.destroy = mg_metal_surface_destroy;
surface->interface.prepare = mg_metal_surface_prepare;
surface->interface.present = mg_metal_surface_present;
surface->interface.swapInterval = mg_metal_surface_swap_interval;
surface->interface.getFrame = mg_metal_surface_get_frame;
surface->interface.setFrame = mg_metal_surface_set_frame;
surface->interface.getHidden = mg_metal_surface_get_hidden;

View File

@ -516,6 +516,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);
*/
HWND windowHandle = CreateWindow("ApplicationWindowClass", "Test Window",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
rect.w, rect.h,
@ -721,6 +731,21 @@ void mp_window_bring_to_front(mp_window window)
}
}
mp_rect mp_window_get_content_rect(mp_window window)
{
mp_rect rect = {0};
mp_window_data* windowData = mp_window_ptr_from_handle(window);
if(windowData)
{
RECT winRect;
if(GetClientRect(windowData->win32.hWnd, &winRect))
{
rect = (mp_rect){0, 0, winRect.right - winRect.left, winRect.bottom - winRect.top};
}
}
return(rect);
}
/////////////////////////////////////////// WIP ///////////////////////////////////////////////
//TODO: this is thrown here for a quick test. We should:
// - check for errors

View File

@ -39,10 +39,15 @@ void mg_gl_surface_prepare(mg_surface_data* interface)
void mg_gl_surface_present(mg_surface_data* interface)
{
mg_gl_surface* surface = (mg_gl_surface*)interface;
SwapBuffers(surface->hDC);
}
void mg_gl_surface_swap_interval(mg_surface_data* interface, int swap)
{
mg_gl_surface* surface = (mg_gl_surface*)interface;
wglSwapIntervalEXT(swap);
}
mp_rect mg_gl_surface_get_frame(mg_surface_data* interface)
{
mg_gl_surface* surface = (mg_gl_surface*)interface;
@ -186,9 +191,7 @@ mg_surface mg_gl_surface_create_for_window(mp_window window)
//NOTE: make gl context current
wglMakeCurrent(hDC, glContext);
//TODO: set this back to 1 after testing
wglSwapIntervalEXT(0);
wglSwapIntervalEXT(1);
//TODO save important info in surface_data and return a handle
mg_gl_surface* surface = malloc_type(mg_gl_surface);
@ -196,6 +199,7 @@ mg_surface mg_gl_surface_create_for_window(mp_window window)
surface->interface.destroy = mg_gl_surface_destroy;
surface->interface.prepare = mg_gl_surface_prepare;
surface->interface.present = mg_gl_surface_present;
surface->interface.swapInterval = mg_gl_surface_swap_interval;
surface->interface.getFrame = mg_gl_surface_get_frame;
//TODO: get/set frame/hidden

View File

@ -3,17 +3,22 @@ Canvas renderer perf
--------------------
[.] Perf
[x] Split vertex data into per-vertex and per-shape data. Keep only pos, cubics, and shapeID in vertex data
[>] make zIndex implicit when calling push_vertex
[>] rename zIndex with "shapeIndex" everywhere
[>] remove color args in functions that don't need it anymore
[?] use half-floats or short fixed-point for pos and uv, packing them in two ints
[?] pre-compute triangle edges/bounding boxes?
[ ] Use clip rects
[>] Add surface scaling for high dpi surfaces
[x] Allow setting swap interval
[!] Allow swap interval of 0 on macos
[>] Use clip rects in tiling/drawing pass
[ ] Clean canvas code
[ ] make zIndex implicit when calling push_vertex
[ ] rename zIndex with "shapeIndex" everywhere
[ ] remove color args in functions that don't need it anymore
[ ] Clean shaders (folder/filenames, version string, debug flags, ...)
[ ] Correctly handle surface size
[ ] Add surface scaling for high dpi surfaces
[ ] Allow setting swap interval
[ ] Fix resource loading path in examples (to load font relative to executable)