Cross-Platform OpenGL Windowing Library
Revision | 2cbe4e6af63e182d33f1a0974b0c01fa5e60361f (tree) |
---|---|
Time | 2020-01-04 17:57:28 |
Author | AlaskanEmily <emily@alas...> |
Commiter | AlaskanEmily |
Add VSync and Adaptive VSync flags to Glow_CreateWindow
@@ -28,6 +28,14 @@ extern "C" { | ||
28 | 28 | /* Flags for Glow_CreateWindow */ |
29 | 29 | #define GLOW_RESIZABLE (1<<0) |
30 | 30 | #define GLOW_UNDECORATED (1<<1) |
31 | +#define GLOW_VSYNC (1<<2) | |
32 | + | |
33 | +/* Enables adaptive VSync, if the OpenGL context supports it. If it does not, | |
34 | + * then Glow will fall back to regular VSync if that flag is also specified. | |
35 | + * If only the adaptive VSync flag was set, and adaptive VSync is not | |
36 | + * supported, then no VSync will be enabled. | |
37 | + */ | |
38 | +#define GLOW_ADAPTIVE_VSYNC (1<<3) | |
31 | 39 | |
32 | 40 | /******************************************************************************/ |
33 | 41 |
@@ -21,6 +21,7 @@ struct Glow_Context{ | ||
21 | 21 | struct Glow_Window{ |
22 | 22 | SDL_Window *win; |
23 | 23 | struct Glow_Context ctx; |
24 | + SDL_bool vsync, adaptive_vsync; | |
24 | 25 | }; |
25 | 26 | |
26 | 27 | /******************************************************************************/ |
@@ -120,6 +121,9 @@ void Glow_CreateWindow(struct Glow_Window *out, | ||
120 | 121 | out->ctx.win = out->win = SDL_CreateWindow(title, |
121 | 122 | SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, sdl_flags); |
122 | 123 | out->ctx.ctx = NULL; |
124 | + | |
125 | + out->vsync = (flags & GLOW_VSYNC) != 0; | |
126 | + out->adaptive_vsync = (flags & GLOW_ADAPTIVE_VSYNC) != 0; | |
123 | 127 | } |
124 | 128 | |
125 | 129 | /******************************************************************************/ |
@@ -295,6 +299,18 @@ int Glow_CreateContext(struct Glow_Window *win, | ||
295 | 299 | SDL_GL_CONTEXT_PROFILE_CORE); |
296 | 300 | out->ctx = SDL_GL_CreateContext(win->win); |
297 | 301 | out->win = win->win; |
302 | + | |
303 | + if(win->adaptive_vsync){ | |
304 | + /* Try to set it to adaptive, otherwise fallback to regular vsync if | |
305 | + * win->vsync is set. | |
306 | + */ | |
307 | + SDL_GL_SetSwapInterval(-1); | |
308 | + if(win->vsync && SDL_GL_GetSwapInterval() != -1) | |
309 | + SDL_GL_SetSwapInterval(1); | |
310 | + } | |
311 | + else if(win->vsync) | |
312 | + SDL_GL_SetSwapInterval(1); | |
313 | + | |
298 | 314 | return 0; |
299 | 315 | } |
300 | 316 |
@@ -31,6 +31,7 @@ struct Glow_Window { | ||
31 | 31 | HDC dc; |
32 | 32 | HWND win; |
33 | 33 | struct Glow_Context ctx; |
34 | + BOOL vsync, adaptive_vsync; | |
34 | 35 | }; |
35 | 36 | |
36 | 37 | /******************************************************************************/ |
@@ -178,14 +179,68 @@ static const PIXELFORMATDESCRIPTOR glow_pixel_format = { | ||
178 | 179 | |
179 | 180 | /******************************************************************************/ |
180 | 181 | |
181 | -static LRESULT WINAPI glow_window_proc(HWND wnd, UINT msg, WPARAM parm, LPARAM lparam){ | |
182 | +static LRESULT WINAPI glow_window_proc(HWND wnd, | |
183 | + UINT msg, | |
184 | + WPARAM parm, | |
185 | + LPARAM lparam){ | |
186 | + | |
182 | 187 | if(msg == WM_CREATE){ |
183 | - struct Glow_Window *const window = (struct Glow_Window *)(((CREATESTRUCT*)lparam)->lpCreateParams); | |
184 | - const int let = ChoosePixelFormat((window->dc = GetDC(wnd)), &glow_pixel_format); | |
188 | + struct Glow_Window *const window = | |
189 | + (struct Glow_Window *)(((CREATESTRUCT*)lparam)->lpCreateParams); | |
190 | + const int let = | |
191 | + ChoosePixelFormat((window->dc = GetDC(wnd)), &glow_pixel_format); | |
192 | + | |
193 | + /* This will get set to -1 if adaptive vsync works. */ | |
194 | + int interval = 1; | |
195 | + const char *const ext = glGetString(GL_EXTENSIONS); | |
196 | + | |
185 | 197 | SetPixelFormat(window->dc, let, &glow_pixel_format); |
186 | 198 | window->ctx.ctx = wglCreateContext(window->dc); |
187 | 199 | window->ctx.dc = window->dc; |
188 | 200 | wglMakeCurrent(window->dc, window->ctx.ctx); |
201 | + | |
202 | + /* Try to get VSync or, if requested, adaptive VSync. */ | |
203 | + if((window->adaptive_vsync || window->vsync) && | |
204 | + strstr(ext, "WGL_EXT_swap_control") != NULL){ | |
205 | + | |
206 | + typedef BOOL(*wgl_swap_interval_func)(int); | |
207 | + | |
208 | + const wgl_swap_interval_func wglSwapIntervalEXT = | |
209 | + (wgl_swap_interval_func)wglGetProcAddress( | |
210 | + "wglSwapIntervalEXT"); | |
211 | + | |
212 | + assert(wglSwapIntervalEXT); | |
213 | + | |
214 | + /* Try to use control_tear if requested. */ | |
215 | + if(window->adaptive_vsync && | |
216 | + strstr(ext, "WGL_EXT_extensions_string") != NULL){ | |
217 | + | |
218 | + typedef const char*(*wgl_extension_strings_func)(void); | |
219 | + | |
220 | + const wgl_extension_strings_func wglGetExtensionsStringEXT = | |
221 | + (wgl_extension_strings_func)wglGetProcAddress( | |
222 | + "wglGetExtensionsStringEXT"); | |
223 | + | |
224 | + assert(wglGetExtensionsStringEXT); | |
225 | + | |
226 | + if(wglGetExtensionsStringEXT){ | |
227 | + const char *const wgl_ext = wglGetExtensionsStringEXT(); | |
228 | + if(strstr(wgl_ext, "WGL_EXT_swap_control_tear") != NULL){ | |
229 | + interval = -1; | |
230 | + } | |
231 | + } | |
232 | + } | |
233 | + | |
234 | + /* Set the interval if either adaptive VSync or regular VSync was | |
235 | + * requested. | |
236 | + */ | |
237 | + if(((window->adaptive_vsync && interval == -1) || window->vsync) && | |
238 | + wglSwapIntervalEXT != NULL){ | |
239 | + | |
240 | + wglSwapIntervalEXT(interval); | |
241 | + } | |
242 | + } | |
243 | + | |
189 | 244 | glClearColor(0.75f, 0.333f, 0.0f, 1.0f); |
190 | 245 | SetFocus(wnd); |
191 | 246 | return 0; |
@@ -313,7 +368,15 @@ void Glow_CreateWindow(struct Glow_Window *out, | ||
313 | 368 | size.bottom += (GetSystemMetrics(SM_CYFRAME) + |
314 | 369 | GetSystemMetrics(SM_CYCAPTION) + |
315 | 370 | GetSystemMetrics(SM_CXPADDEDBORDER)); |
316 | - out->win = CreateWindow(GLOW_CLASS_NAME, title, style, 64, 64, size.right, size.bottom, NULL, NULL, glow_app, out); | |
371 | + out->win = CreateWindow(GLOW_CLASS_NAME, | |
372 | + title, | |
373 | + style, | |
374 | + 64, 64, size.right, size.bottom, | |
375 | + NULL, NULL, | |
376 | + glow_app, | |
377 | + out); | |
378 | + out->adaptive_vsync = (flags & GLOW_ADAPTIVE_VSYNC) != 0; | |
379 | + out->vsync = (flags & GLOW_VSYNC) != 0; | |
317 | 380 | } |
318 | 381 | } |
319 | 382 |