24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 * POSSIBILITY OF SUCH DAMAGE. |
25 * POSSIBILITY OF SUCH DAMAGE. |
26 */ |
26 */ |
27 |
27 |
28 #include "ascension/window.h" |
28 #include "ascension/window.h" |
|
29 #include "ascension/context.h" |
|
30 #include "ascension/error.h" |
29 |
31 |
30 #include <cx/linked_list.h> |
32 #include <cx/linked_list.h> |
31 #include <cx/printf.h> |
33 #include <cx/printf.h> |
32 |
34 |
33 #include <GL/glew.h> |
35 #include <GL/glew.h> |
48 cx_strfree(&buf); |
50 cx_strfree(&buf); |
49 } |
51 } |
50 |
52 |
51 |
53 |
52 static void asc_event_window_resized(Uint32 id, Sint32 width, Sint32 height) { |
54 static void asc_event_window_resized(Uint32 id, Sint32 width, Sint32 height) { |
53 CxIterator iter = cxListIterator(asc_context.windows); |
55 for (unsigned int i = 0 ; i < ASC_MAX_WINDOWS ; i++) { |
54 cx_foreach(AscWindow*, w, iter) { |
56 if (asc_context.windows[i].id == id) { |
55 if (w->id == id) { |
57 asc_context.windows[i].dimensions.width = width; |
56 w->dimensions.width = width; |
58 asc_context.windows[i].dimensions.height = height; |
57 w->dimensions.height = height; |
|
58 return; |
59 return; |
59 } |
60 } |
60 } |
61 } |
61 } |
62 } |
62 |
63 |
103 settings->gl_major_version = 3; |
105 settings->gl_major_version = 3; |
104 settings->gl_minor_version = 3; |
106 settings->gl_minor_version = 3; |
105 settings->title = "Ascended Window"; |
107 settings->title = "Ascended Window"; |
106 } |
108 } |
107 |
109 |
108 void asc_window_initialize(AscWindow* window, AscWindowSettings const* settings) { |
110 AscWindow *asc_window_initialize(unsigned int index, AscWindowSettings const *settings) { |
|
111 if (index >= ASC_MAX_WINDOWS) { |
|
112 asc_error("Maximum number of windows exceeded."); |
|
113 return NULL; |
|
114 } |
|
115 AscWindow *window = &asc_context.windows[index]; |
|
116 if (window->id > 0) { |
|
117 asc_error("Cannot create window - slot already occupied."); |
|
118 asc_dprintf("Tried to create window with index %u", index); |
|
119 return NULL; |
|
120 } |
|
121 |
109 Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN; |
122 Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN; |
110 flags |= settings->fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_RESIZABLE; |
123 flags |= settings->fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_RESIZABLE; |
111 |
124 |
112 window->window = SDL_CreateWindow( |
125 window->window = SDL_CreateWindow( |
113 settings->title, |
126 settings->title, |
117 settings->dimensions.height, |
130 settings->dimensions.height, |
118 flags |
131 flags |
119 ); |
132 ); |
120 if (window->window == NULL) { |
133 if (window->window == NULL) { |
121 asc_error(SDL_GetError()); |
134 asc_error(SDL_GetError()); |
122 return; |
135 return NULL; |
123 } |
136 } |
124 |
137 |
125 window->id = SDL_GetWindowID(window->window); |
138 window->id = SDL_GetWindowID(window->window); |
126 SDL_GetWindowSize(window->window, |
139 SDL_GetWindowSize(window->window, |
127 &window->dimensions.width, |
140 &window->dimensions.width, |
145 glEnable(GL_BLEND); |
158 glEnable(GL_BLEND); |
146 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
159 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
147 glEnable(GL_DEBUG_OUTPUT); |
160 glEnable(GL_DEBUG_OUTPUT); |
148 glDebugMessageCallback(asc_gl_debug_callback, NULL); |
161 glDebugMessageCallback(asc_gl_debug_callback, NULL); |
149 asc_dprintf("Window %u initialized", window->id); |
162 asc_dprintf("Window %u initialized", window->id); |
150 cxListAdd(asc_context.windows, window); |
163 return window; |
151 return; |
|
152 } else { |
164 } else { |
153 asc_error(glewGetErrorString(err)); |
165 asc_error(glewGetErrorString(err)); |
154 } |
166 } |
155 } |
167 } |
156 |
168 |
162 SDL_DestroyWindow(window->window); |
174 SDL_DestroyWindow(window->window); |
163 window->window = NULL; |
175 window->window = NULL; |
164 window->id = 0; |
176 window->id = 0; |
165 } |
177 } |
166 |
178 |
167 void asc_window_destroy_impl(AscWindow* window) { |
179 void asc_window_destroy(AscWindow* window) { |
168 // destory the GL context and the window |
180 // safeguard |
|
181 if (window->id == 0) return; |
|
182 |
|
183 // destroy the GL context and the window |
169 if (window->glctx != NULL) { |
184 if (window->glctx != NULL) { |
170 SDL_GL_DeleteContext(window->glctx); |
185 SDL_GL_DeleteContext(window->glctx); |
171 } |
186 } |
172 if (window->window != NULL) { |
187 if (window->window != NULL) { |
173 SDL_DestroyWindow(window->window); |
188 SDL_DestroyWindow(window->window); |
174 } |
189 } |
175 |
190 |
176 // clean the data |
191 // clean the data |
177 asc_dprintf("Window %u and its OpenGL context destroyed.", window->id); |
192 asc_dprintf("Window %u and its OpenGL context destroyed.", window->id); |
178 memset(window, 0, sizeof(AscWindow)); |
193 memset(window, 0, sizeof(AscWindow)); |
179 } |
|
180 |
|
181 void asc_window_destroy(AscWindow* window) { |
|
182 // find the window in the context and remove it |
|
183 bool found = false; |
|
184 CxMutIterator iter = cxListMutIterator(asc_context.windows); |
|
185 cx_foreach(AscWindow*, w, iter) { |
|
186 if (w == window) { |
|
187 found = true; |
|
188 cxIteratorFlagRemoval(iter); |
|
189 } |
|
190 } |
|
191 if (!found) asc_window_destroy_impl(window); |
|
192 } |
194 } |
193 |
195 |
194 void asc_window_sync(AscWindow const* window) { |
196 void asc_window_sync(AscWindow const* window) { |
195 SDL_GL_MakeCurrent(window->window, window->glctx); |
197 SDL_GL_MakeCurrent(window->window, window->glctx); |
196 SDL_GL_SwapWindow(window->window); |
198 SDL_GL_SwapWindow(window->window); |