• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

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

Cross-Platform OpenGL Windowing Library


Commit MetaInfo

Revisionae2115beca5eef14279ba02fa7c5c4842a825332 (tree)
Time2019-04-13 15:10:10
AuthorAlaskanEmily <emily@alas...>
CommiterAlaskanEmily

Log Message

Add SDL2 backend

Change Summary

Incremental Difference

--- a/gcc.mk
+++ b/gcc.mk
@@ -17,7 +17,13 @@ glow_x11.o: glow_x11.c glow.h
1717 $(CC) $(CFLAGS) $(X11INCLUDE) -c glow_x11.c -o glow_x11.o
1818
1919 glow_x11.os: glow_x11.c glow.h
20- $(CC) $(CFLAGS)$(FPICFLAGS) $(X11INCLUDE) -c glow_x11.c -o glow_x11.os
20+ $(CC) $(CFLAGS) $(FPICFLAGS) $(X11INCLUDE) -c glow_x11.c -o glow_x11.os
21+
22+glow_sdl2.o: glow_sdl2.c glow.h
23+ $(CC) $(CFLAGS) -c glow_sdl2.c -o glow_sdl2.o
24+
25+glow_sdl2.os: glow_sdl2.c glow.h
26+ $(CC) $(CFLAGS) $(FPICFLAGS) -c glow_sdl2.c -o glow_sdl2.os
2127
2228 libglow.so: glow_$(GLOWTARGET).os
2329 $(LINKER) $(SHAREDFLAGS) glow_$(GLOWTARGET).os -o libglow.so
--- /dev/null
+++ b/glow_sdl2.c
@@ -0,0 +1,332 @@
1+/* Copyright (C) 2019 Alaskan Emily, Transnat Games
2+ *
3+ * This Source Code Form is subject to the terms of the Mozilla Public
4+ * License, v. 2.0. If a copy of the MPL was not distributed with this
5+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6+
7+#include "glow.h"
8+#include "SDL.h"
9+#include "SDL_video.h"
10+#include "SDL_syswm.h"
11+
12+/******************************************************************************/
13+
14+struct Glow_Context{
15+ SDL_Window *win;
16+ SDL_GLContext ctx;
17+};
18+
19+/******************************************************************************/
20+
21+struct Glow_Window{
22+ SDL_Window *win;
23+ struct Glow_Context ctx;
24+};
25+
26+/******************************************************************************/
27+
28+void Glow_ViewportSize(unsigned w, unsigned h,
29+ unsigned *out_w, unsigned *out_h){
30+ out_w[0] = w;
31+ out_h[0] = h;
32+}
33+
34+/******************************************************************************/
35+
36+void *Glow_GetSystemWindow(struct Glow_Window *window){
37+ SDL_SysWMinfo info;
38+ if(!SDL_GetWindowWMInfo(window->win, &info))
39+ return NULL;
40+ switch(info.subsystem){
41+#ifdef SDL_VIDEO_DRIVER_WINDOWS
42+ case SDL_SYSWM_WINDOWS:
43+ return (void*)info.info.win.window;
44+#endif
45+
46+#ifdef SDL_VIDEO_DRIVER_WINRT
47+ case SDL_SYSWM_WINRT:
48+ return info.info.winrt.window;
49+#endif
50+
51+#ifdef SDL_VIDEO_DRIVER_MIR
52+ case SDL_SYSWM_MIR:
53+ return info.info.mir.surface;
54+#endif
55+
56+#ifdef SDL_VIDEO_DRIVER_WAYLAND
57+ case SDL_SYSWM_WAYLAND:
58+ return info.info.wl.surface;
59+#endif
60+
61+#ifdef SDL_VIDEO_DRIVER_X11
62+ case SDL_SYSWM_X11:
63+ return (void*)info.info.x11.window;
64+#endif
65+
66+#ifdef SDL_VIDEO_DRIVER_DIRECTFB
67+ case SDL_SYSWM_DIRECTFB:
68+ return info.info.dfb.window;
69+#endif
70+
71+#ifdef SDL_VIDEO_DRIVER_COCOA
72+ case SDL_SYSWM_COCOA:
73+ return info.info.cocoa.window;
74+#endif
75+
76+#ifdef SDL_VIDEO_DRIVER_UIKIT
77+ case SDL_SYSWM_UIKIT:
78+ return info.info.uikit.window;
79+#endif
80+ case SDL_SYSWM_UNKNOWN: /* FALLTHROUGH */
81+ default:
82+ return NULL;
83+ }
84+}
85+
86+/******************************************************************************/
87+
88+void *Glow_GetProcAddress(const char *name){
89+ return SDL_GL_GetProcAddress(name);
90+}
91+
92+/******************************************************************************/
93+
94+unsigned Glow_WindowStructSize(void){
95+ return sizeof(struct Glow_Window);
96+}
97+
98+/******************************************************************************/
99+
100+void Glow_CreateWindow(struct Glow_Window *out,
101+ unsigned w, unsigned h, const char *title, int flags){
102+
103+ int sdl_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN;
104+
105+#ifdef SDL_WINDOW_ALLOW_HIGHDPI
106+ sdl_flags |= SDL_WINDOW_ALLOW_HIGHDPI;
107+#endif
108+
109+ if((flags & GLOW_RESIZABLE) != 0)
110+ sdl_flags |= SDL_WINDOW_RESIZABLE;
111+ if((flags & GLOW_UNDECORATED) != 0)
112+ sdl_flags |= SDL_WINDOW_BORDERLESS;
113+
114+ /* This is used every time a window is created. SDL2 ref-counts this, so
115+ * it is OK to use this on window construction and a matched quit occurs on
116+ * window destruction.
117+ */
118+ SDL_InitSubSystem(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK|SDL_INIT_EVENTS);
119+
120+ out->ctx.win = out->win = SDL_CreateWindow(title,
121+ SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, sdl_flags);
122+ out->ctx.ctx = NULL;
123+}
124+
125+/******************************************************************************/
126+
127+void Glow_DestroyWindow(struct Glow_Window *win){
128+ SDL_DestroyWindow(win->win);
129+ if(win->ctx.ctx != NULL)
130+ SDL_GL_DeleteContext(win->ctx.ctx);
131+ SDL_QuitSubSystem(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK|SDL_INIT_EVENTS);
132+}
133+
134+/******************************************************************************/
135+
136+void Glow_SetTitle(struct Glow_Window *win, const char *title){
137+ SDL_SetWindowTitle(win->win, title);
138+}
139+
140+/******************************************************************************/
141+
142+void Glow_ShowWindow(struct Glow_Window *win){
143+ SDL_ShowWindow(win->win);
144+ SDL_RaiseWindow(win->win);
145+}
146+
147+/******************************************************************************/
148+
149+void Glow_HideWindow(struct Glow_Window *win){
150+ SDL_HideWindow(win->win);
151+}
152+
153+/******************************************************************************/
154+
155+void Glow_GetWindowSize(const struct Glow_Window *win,
156+ unsigned *out_w, unsigned *out_h){
157+
158+ int w, h;
159+ SDL_GetWindowSize(win->win, &w, &h);
160+ out_w[0] = w;
161+ out_h[0] = h;
162+}
163+
164+/******************************************************************************/
165+
166+void Glow_FlipScreen(struct Glow_Window *win){
167+ SDL_GL_SwapWindow(win->win);
168+}
169+
170+/******************************************************************************/
171+
172+static int glow_write_keyname(const SDL_Event *in, struct Glow_Event *out){
173+ const char *const name = SDL_GetKeyName(in->key.keysym.sym);
174+#if defined _WIN32 || defined __CYGWIN__ || defined WIN32
175+ strncpy(out->value.key, name, GLOW_MAX_KEY_NAME_SIZE-2);
176+ out->value.key[GLOW_MAX_KEY_NAME_SIZE-1] = 0;
177+#else
178+ strlcpy(out->value.key, name, GLOW_MAX_KEY_NAME_SIZE-1);
179+#endif
180+ return 1;
181+}
182+
183+/******************************************************************************/
184+
185+static enum Glow_MouseButton glow_translate_button(unsigned s){
186+ if((s & SDL_BUTTON_LMASK) != 0)
187+ return eGlowLeft;
188+ if((s & SDL_BUTTON_RMASK) != 0)
189+ return eGlowRight;
190+ if((s & SDL_BUTTON_MMASK) != 0)
191+ return eGlowMiddle;
192+ return eGlow_NUM_BUTTONS;
193+}
194+
195+/******************************************************************************/
196+
197+static int glow_convert_sdl2_event(const SDL_Event *in,
198+ struct Glow_Event *out){
199+
200+ switch(in->type){
201+ case SDL_QUIT:
202+ case SDL_APP_TERMINATING:
203+ out->type = eGlowQuit;
204+ return 1;
205+ case SDL_KEYDOWN:
206+ out->type = eGlowKeyboardPressed;
207+ return glow_write_keyname(in, out);
208+ case SDL_KEYUP:
209+ out->type = eGlowKeyboardReleased;
210+ return glow_write_keyname(in, out);
211+ case SDL_MOUSEMOTION:
212+ out->type = eGlowMouseMoved;
213+ out->value.mouse.xy[0] = in->motion.x;
214+ out->value.mouse.xy[1] = in->motion.y;
215+ out->value.mouse.button = glow_translate_button(in->motion.state);
216+ return 1;
217+ case SDL_MOUSEBUTTONDOWN:
218+ out->type = eGlowMousePressed;
219+ out->value.mouse.xy[0] = in->button.x;
220+ out->value.mouse.xy[1] = in->button.y;
221+ out->value.mouse.button = glow_translate_button(in->button.state);
222+ return 1;
223+ case SDL_MOUSEBUTTONUP:
224+ out->type = eGlowMouseReleased;
225+ out->value.mouse.xy[0] = in->button.x;
226+ out->value.mouse.xy[1] = in->button.y;
227+ out->value.mouse.button = glow_translate_button(in->button.state);
228+ return 1;
229+ case SDL_WINDOWEVENT:
230+ switch(in->window.event){
231+ case SDL_WINDOWEVENT_SIZE_CHANGED: /* FALLTHROUGH */
232+ case SDL_WINDOWEVENT_RESIZED:
233+ out->type = eGlowResized;
234+ out->value.resize[0] = in->window.data1;
235+ out->value.resize[1] = in->window.data2;
236+ return 1;
237+ }
238+ break;
239+ }
240+
241+ return 0;
242+}
243+
244+/******************************************************************************/
245+
246+unsigned Glow_GetEvent(struct Glow_Window *win, struct Glow_Event *out_event){
247+
248+ SDL_Event ev;
249+ (void)win;
250+
251+ while(SDL_PollEvent(&ev)){
252+ if(glow_convert_sdl2_event(&ev, out_event))
253+ return 1;
254+ }
255+
256+ return 0;
257+}
258+
259+/******************************************************************************/
260+
261+void Glow_WaitEvent(struct Glow_Window *win, struct Glow_Event *out_event){
262+
263+ SDL_Event ev;
264+ (void)win;
265+
266+ do{
267+ SDL_WaitEvent(&ev);
268+ }while(!glow_convert_sdl2_event(&ev, out_event));
269+}
270+
271+/******************************************************************************/
272+
273+unsigned Glow_ContextStructSize(void){
274+ return sizeof(struct Glow_Context);
275+}
276+
277+/******************************************************************************/
278+
279+int Glow_CreateContext(struct Glow_Window *win,
280+ struct Glow_Context *opt_share,
281+ unsigned major, unsigned minor,
282+ struct Glow_Context *out){
283+
284+ if(opt_share != NULL){
285+ SDL_GL_MakeCurrent(win->win, opt_share->ctx);
286+ SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
287+ }
288+ else{
289+ SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 0);
290+ }
291+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major);
292+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor);
293+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
294+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
295+ SDL_GL_CONTEXT_PROFILE_CORE);
296+ out->ctx = SDL_GL_CreateContext(win->win);
297+ out->win = win->win;
298+ return 0;
299+}
300+
301+/******************************************************************************/
302+
303+void Glow_CreateLegacyContext(struct Glow_Window *win,
304+ struct Glow_Context *out){
305+
306+ SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 0);
307+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
308+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
309+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
310+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
311+ SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
312+ win->ctx.ctx = SDL_GL_CreateContext(win->win);
313+ if(out)
314+ out->ctx = win->ctx.ctx;
315+}
316+
317+/******************************************************************************/
318+
319+void Glow_MakeCurrent(struct Glow_Context *ctx){
320+ SDL_GL_MakeCurrent(ctx->win, ctx->win);
321+}
322+
323+/******************************************************************************/
324+
325+struct Glow_Window *Glow_CreateLegacyWindow(
326+ unsigned w, unsigned h, const char *title){
327+
328+ struct Glow_Window *const win = malloc(sizeof(struct Glow_Window));
329+ Glow_CreateWindow(win, w, h, title, 0);
330+ Glow_CreateLegacyContext(win, NULL);
331+ return win;
332+}
--- a/nmakefile
+++ b/nmakefile
@@ -12,6 +12,12 @@ glow.lib: glow_win32.obj
1212 glow.dll: glow_win32.obj
1313 link /nologo /dll /out:glow.dll /implib:glow.lib OpenGL32.lib gdi32.lib user32.lib glow_win32.obj
1414
15+glow_sdl2.obj: glow_sdl2.c glow.h
16+ cl /I"$(MAKEDIR)\include" /DGLOW_EXPORTS /DGLOW_DLL /c glow_sdl2.c /nologo
17+
18+sdl2: glow_sdl2.obj
19+ link /nologo /dll /out:glow.dll /implib:glow.lib sdl2.lib glow_sdl2.obj /LIBPATH:"$(MAKEDIR)\lib"
20+
1521 clean:
1622 del glow.dll > nul || echo > nul
1723 del glow.lib > nul || echo > nul