43 "source = %d, id = %u, type = %d, severity= %d, message = %.*s", |
43 "source = %d, id = %u, type = %d, severity= %d, message = %.*s", |
44 source, id, type, severity, length, message); |
44 source, id, type, severity, length, message); |
45 if (type == GL_DEBUG_TYPE_ERROR) { |
45 if (type == GL_DEBUG_TYPE_ERROR) { |
46 asc_error(buf.ptr); |
46 asc_error(buf.ptr); |
47 } else { |
47 } else { |
48 asc_dprintf("GL debug: %*.s", (int)buf.length, buf.ptr); |
48 asc_dprintf("GL debug: %.*s", (int)buf.length, buf.ptr); |
49 } |
49 } |
50 cx_strfree(&buf); |
50 cx_strfree(&buf); |
51 } |
|
52 |
|
53 |
|
54 static void asc_event_window_resized(Uint32 id, Sint32 width, Sint32 height) { |
|
55 for (unsigned int i = 0 ; i < ASC_MAX_WINDOWS ; i++) { |
|
56 if (asc_context.windows[i].id == id) { |
|
57 asc_context.windows[i].dimensions.width = width; |
|
58 asc_context.windows[i].dimensions.height = height; |
|
59 asc_mat4f_ortho(asc_context.windows[i].projection, 0, (float) width, (float) height, 0); |
|
60 return; |
|
61 } |
|
62 } |
|
63 } |
|
64 |
|
65 bool asc_loop_next(void) { |
|
66 // dispatch SDL events |
|
67 SDL_Event event; |
|
68 while (SDL_PollEvent(&event)) { |
|
69 switch (event.type) { |
|
70 case SDL_QUIT: |
|
71 asc_set_flag(&asc_context.flags, ASC_FLAG_QUIT); |
|
72 break; |
|
73 case SDL_WINDOWEVENT: { |
|
74 if (event.window.type == SDL_WINDOWEVENT_RESIZED) |
|
75 asc_event_window_resized( |
|
76 event.window.windowID, |
|
77 event.window.data1, |
|
78 event.window.data2 |
|
79 ); |
|
80 break; |
|
81 } |
|
82 case SDL_KEYDOWN: |
|
83 // TODO: remove this code and implement key press map instead |
|
84 if (event.key.keysym.sym == SDLK_ESCAPE) |
|
85 return false; |
|
86 break; |
|
87 case SDL_KEYUP: |
|
88 // TODO: implement key press map |
|
89 break; |
|
90 } |
|
91 } |
|
92 |
|
93 // sync the windows |
|
94 for (unsigned int i = 0 ; i < ASC_MAX_WINDOWS ; i++) { |
|
95 if (asc_context.windows[i].id > 0) { |
|
96 asc_window_sync(&asc_context.windows[i]); |
|
97 } |
|
98 } |
|
99 |
|
100 return !asc_test_flag(asc_context.flags, ASC_FLAG_QUIT); |
|
101 } |
51 } |
102 |
52 |
103 void asc_window_settings_init_defaults(AscWindowSettings* settings) { |
53 void asc_window_settings_init_defaults(AscWindowSettings* settings) { |
104 settings->depth_size = 24; |
54 settings->depth_size = 24; |
105 settings->vsync = 1; |
55 settings->vsync = 1; |
168 glEnable(GL_DEPTH_TEST); |
118 glEnable(GL_DEPTH_TEST); |
169 glEnable(GL_BLEND); |
119 glEnable(GL_BLEND); |
170 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
120 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
171 glEnable(GL_DEBUG_OUTPUT); |
121 glEnable(GL_DEBUG_OUTPUT); |
172 glDebugMessageCallback(asc_gl_debug_callback, NULL); |
122 glDebugMessageCallback(asc_gl_debug_callback, NULL); |
|
123 |
173 asc_dprintf("Window %u initialized", window->id); |
124 asc_dprintf("Window %u initialized", window->id); |
174 return window; |
125 if (asc_primitives_init(&window->primitives)) { |
|
126 asc_context.active_window = window; |
|
127 return window; |
|
128 } else { |
|
129 asc_dprintf("!!! Creating primitives for window %u failed !!!", window->id); |
|
130 } |
175 } else { |
131 } else { |
176 asc_error(glewGetErrorString(err)); |
132 asc_error(glewGetErrorString(err)); |
177 } |
133 } |
178 } |
134 } |
179 |
135 |
189 |
145 |
190 void asc_window_destroy(AscWindow* window) { |
146 void asc_window_destroy(AscWindow* window) { |
191 // safeguard |
147 // safeguard |
192 if (window->id == 0) return; |
148 if (window->id == 0) return; |
193 |
149 |
|
150 // this window cannot be active anymore |
|
151 if (asc_context.active_window == window) { |
|
152 asc_context.active_window = NULL; |
|
153 } |
|
154 |
|
155 // release context related data (we have to make the GL context current for this) |
|
156 SDL_GL_MakeCurrent(window->window, window->glctx); |
|
157 asc_primitives_destroy(&window->primitives); |
|
158 |
194 // destroy the GL context and the window |
159 // destroy the GL context and the window |
195 if (window->glctx != NULL) { |
160 if (window->glctx != NULL) { |
196 SDL_GL_DeleteContext(window->glctx); |
161 SDL_GL_DeleteContext(window->glctx); |
197 } |
162 } |
198 if (window->window != NULL) { |
163 if (window->window != NULL) { |
199 SDL_DestroyWindow(window->window); |
164 SDL_DestroyWindow(window->window); |
200 } |
165 } |
201 |
166 |
|
167 // if another window was active, make the other context current again |
|
168 if (asc_context.active_window != NULL) { |
|
169 AscWindow const *aw = asc_context.active_window; |
|
170 SDL_GL_MakeCurrent(aw->window, aw->glctx); |
|
171 } |
|
172 |
202 // clean the data |
173 // clean the data |
203 asc_dprintf("Window %u and its OpenGL context destroyed.", window->id); |
174 asc_dprintf("Window %u and its OpenGL context destroyed.", window->id); |
204 memset(window, 0, sizeof(AscWindow)); |
175 memset(window, 0, sizeof(AscWindow)); |
205 } |
176 } |
206 |
177 |
207 void asc_window_sync(AscWindow const* window) { |
178 void asc_window_sync(AscWindow const* window) { |
208 SDL_GL_MakeCurrent(window->window, window->glctx); |
179 AscWindow const *active_window = asc_context.active_window; |
|
180 if (window != active_window) { |
|
181 asc_window_activate(window); |
|
182 } |
209 SDL_GL_SwapWindow(window->window); |
183 SDL_GL_SwapWindow(window->window); |
210 glViewport(0, 0, window->dimensions.width, window->dimensions.height); |
184 glViewport(0, 0, window->dimensions.width, window->dimensions.height); |
211 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
185 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
212 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
186 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
|
187 if (window != active_window) { |
|
188 asc_window_activate(active_window); |
|
189 } |
213 } |
190 } |
|
191 |
|
192 void asc_window_activate(AscWindow const *window) { |
|
193 SDL_GL_MakeCurrent(window->window, window->glctx); |
|
194 asc_context.active_window = window; |
|
195 } |