• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ
未設定

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Cross-Platform OpenGL Windowing Library


コミットメタ情報

リビジョン2cbe4e6af63e182d33f1a0974b0c01fa5e60361f (tree)
日時2020-01-04 17:57:28
作者AlaskanEmily <emily@alas...>
コミッターAlaskanEmily

ログメッセージ

Add VSync and Adaptive VSync flags to Glow_CreateWindow

変更サマリ

差分

--- a/glow.h
+++ b/glow.h
@@ -28,6 +28,14 @@ extern "C" {
2828 /* Flags for Glow_CreateWindow */
2929 #define GLOW_RESIZABLE (1<<0)
3030 #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)
3139
3240 /******************************************************************************/
3341
--- a/glow_sdl2.c
+++ b/glow_sdl2.c
@@ -21,6 +21,7 @@ struct Glow_Context{
2121 struct Glow_Window{
2222 SDL_Window *win;
2323 struct Glow_Context ctx;
24+ SDL_bool vsync, adaptive_vsync;
2425 };
2526
2627 /******************************************************************************/
@@ -120,6 +121,9 @@ void Glow_CreateWindow(struct Glow_Window *out,
120121 out->ctx.win = out->win = SDL_CreateWindow(title,
121122 SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, sdl_flags);
122123 out->ctx.ctx = NULL;
124+
125+ out->vsync = (flags & GLOW_VSYNC) != 0;
126+ out->adaptive_vsync = (flags & GLOW_ADAPTIVE_VSYNC) != 0;
123127 }
124128
125129 /******************************************************************************/
@@ -295,6 +299,18 @@ int Glow_CreateContext(struct Glow_Window *win,
295299 SDL_GL_CONTEXT_PROFILE_CORE);
296300 out->ctx = SDL_GL_CreateContext(win->win);
297301 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+
298314 return 0;
299315 }
300316
--- a/glow_win32.c
+++ b/glow_win32.c
@@ -31,6 +31,7 @@ struct Glow_Window {
3131 HDC dc;
3232 HWND win;
3333 struct Glow_Context ctx;
34+ BOOL vsync, adaptive_vsync;
3435 };
3536
3637 /******************************************************************************/
@@ -178,14 +179,68 @@ static const PIXELFORMATDESCRIPTOR glow_pixel_format = {
178179
179180 /******************************************************************************/
180181
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+
182187 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+
185197 SetPixelFormat(window->dc, let, &glow_pixel_format);
186198 window->ctx.ctx = wglCreateContext(window->dc);
187199 window->ctx.dc = window->dc;
188200 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+
189244 glClearColor(0.75f, 0.333f, 0.0f, 1.0f);
190245 SetFocus(wnd);
191246 return 0;
@@ -313,7 +368,15 @@ void Glow_CreateWindow(struct Glow_Window *out,
313368 size.bottom += (GetSystemMetrics(SM_CYFRAME) +
314369 GetSystemMetrics(SM_CYCAPTION) +
315370 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;
317380 }
318381 }
319382