41 settings->glsettings.gl_major_version = 4; |
41 settings->glsettings.gl_major_version = 4; |
42 settings->glsettings.gl_minor_version = 0; |
42 settings->glsettings.gl_minor_version = 0; |
43 settings->title = "Ascended Window"; |
43 settings->title = "Ascended Window"; |
44 } |
44 } |
45 |
45 |
46 AscWindow *asc_window_initialize(unsigned int index, AscWindowSettings const *settings) { |
46 void asc_window_initialize(unsigned int index, AscWindowSettings const *settings) { |
47 if (index >= ASC_MAX_WINDOWS) { |
47 if (index >= ASC_MAX_WINDOWS) { |
48 asc_error("Maximum number of windows exceeded."); |
48 asc_error("Maximum number of windows exceeded."); |
49 return NULL; |
49 return; |
50 } |
50 } |
51 AscWindow *window = &asc_context.windows[index]; |
51 AscWindow *window = &asc_context.windows[index]; |
52 if (window->id > 0) { |
52 if (window->id > 0) { |
53 asc_error("Cannot create window - slot already occupied."); |
53 asc_error("Cannot create window - slot already occupied."); |
54 asc_dprintf("Tried to create window with index %u twice", index); |
54 asc_dprintf("Tried to create window with index %u twice", index); |
55 return NULL; |
55 return; |
56 } |
56 } |
57 if (window->ui != NULL) { |
57 if (window->ui != NULL) { |
58 asc_dprintf("Window with index %u has a dangling UI pointer", index); |
58 asc_dprintf("Window with index %u has a dangling UI pointer", index); |
59 asc_scene_node_free(window->ui); |
59 asc_scene_node_free(window->ui); |
60 } |
60 } |
70 settings->dimensions.height, |
70 settings->dimensions.height, |
71 flags |
71 flags |
72 ); |
72 ); |
73 if (window->window == NULL) { |
73 if (window->window == NULL) { |
74 asc_error(SDL_GetError()); |
74 asc_error(SDL_GetError()); |
75 return NULL; |
75 return; |
76 } |
76 } |
77 |
77 |
78 window->id = SDL_GetWindowID(window->window); |
78 window->id = SDL_GetWindowID(window->window); |
79 SDL_GetWindowSize(window->window, |
79 SDL_GetWindowSize(window->window, |
80 &window->dimensions.width, |
80 &window->dimensions.width, |
83 window->resized = true; // count initial sizing as resize |
83 window->resized = true; // count initial sizing as resize |
84 |
84 |
85 if (asc_gl_context_initialize(&window->glctx, window->window, &settings->glsettings)) { |
85 if (asc_gl_context_initialize(&window->glctx, window->window, &settings->glsettings)) { |
86 window->ui = asc_scene_node_empty(); |
86 window->ui = asc_scene_node_empty(); |
87 asc_dprintf("Window %u initialized", window->id); |
87 asc_dprintf("Window %u initialized", window->id); |
88 asc_window_active = window; |
88 asc_context.active_window = index; |
89 return window; |
|
90 } else { |
89 } else { |
91 asc_dprintf("Creating GL context failed for window %u", window->id); |
90 asc_dprintf("Creating GL context failed for window %u", window->id); |
92 // cleanup on error |
91 // cleanup on error |
93 SDL_DestroyWindow(window->window); |
92 SDL_DestroyWindow(window->window); |
94 window->window = NULL; |
93 window->window = NULL; |
95 window->id = 0; |
94 window->id = 0; |
96 return NULL; |
|
97 } |
95 } |
98 } |
96 } |
99 |
97 |
100 void asc_window_destroy(AscWindow* window) { |
98 void asc_window_destroy(unsigned int index) { |
101 // safeguard |
99 // safeguard |
102 if (window->id == 0) return; |
100 if (asc_context.windows[index].id == 0) return; |
103 |
101 |
104 // this window cannot be active anymore |
102 // this window cannot be active anymore |
105 if (asc_window_active == window) { |
103 if (asc_context.active_window == index) { |
106 asc_window_active = NULL; |
104 asc_context.active_window = ASC_MAX_WINDOWS; |
107 } |
105 } |
|
106 |
|
107 // pointer to the window |
|
108 AscWindow *window = &asc_context.windows[index]; |
|
109 |
|
110 // for releasing OpenGL resources, we need to make the context current |
|
111 asc_gl_context_activate(&window->glctx); |
108 |
112 |
109 // destroy all scenes |
113 // destroy all scenes |
110 asc_scene_node_free(window->ui); |
114 asc_scene_node_free(window->ui); |
111 window->ui = NULL; |
115 window->ui = NULL; |
112 |
116 |
117 if (window->window != NULL) { |
121 if (window->window != NULL) { |
118 SDL_DestroyWindow(window->window); |
122 SDL_DestroyWindow(window->window); |
119 } |
123 } |
120 |
124 |
121 // if another window was active, make the other context current again |
125 // if another window was active, make the other context current again |
122 if (asc_window_active != NULL) { |
126 if (asc_context.active_window < ASC_MAX_WINDOWS) { |
123 asc_gl_context_activate(&asc_window_active->glctx); |
127 asc_gl_context_activate(&asc_active_window->glctx); |
124 } |
128 } |
125 |
129 |
126 // clean the data |
130 // clean the data |
127 asc_dprintf("Window %u and its OpenGL context destroyed.", window->id); |
131 asc_dprintf("Window %u and its OpenGL context destroyed.", window->id); |
128 memset(window, 0, sizeof(AscWindow)); |
132 memset(window, 0, sizeof(AscWindow)); |
129 } |
133 } |
130 |
134 |
131 void asc_window_sync(AscWindow* window) { |
135 void asc_window_sync(unsigned int index) { |
132 AscWindow *active_window = asc_window_active; |
136 // necessary safeguard |
133 if (window != active_window) { |
137 if (asc_context.windows[index].id == 0) return; |
134 asc_window_activate(window); |
138 |
|
139 // active the window that shall be synced temporarily |
|
140 unsigned int active_index = asc_context.active_window; |
|
141 if (index != active_index) { |
|
142 asc_window_activate(index); |
135 } |
143 } |
136 |
144 |
137 // Clear the color buffer for the window frame |
145 // Clear the color buffer for the window frame |
138 int window_width = window->dimensions.width; |
146 int window_width = asc_active_window->dimensions.width; |
139 int window_height = window->dimensions.height; |
147 int window_height = asc_active_window->dimensions.height; |
140 glViewport(0, 0, window_width, window_height); |
148 glViewport(0, 0, window_width, window_height); |
141 glClear(GL_COLOR_BUFFER_BIT); |
149 glClear(GL_COLOR_BUFFER_BIT); |
142 asc_recti viewport = {0, 0, window_width, window_height}; |
150 asc_recti viewport = {0, 0, window_width, window_height}; |
143 |
151 |
144 // Draw the UI |
152 // Draw the UI |
145 AscCamera ui_camera; |
153 AscCamera ui_camera; |
146 asc_camera_ortho(&ui_camera, viewport); |
154 asc_camera_ortho(&ui_camera, viewport); |
147 asc_scene_draw(window->ui, viewport, &ui_camera); |
155 asc_scene_draw(asc_active_window->ui, viewport, &ui_camera); |
148 |
156 |
149 // Swap Buffers |
157 // Swap Buffers |
150 SDL_GL_SwapWindow(window->window); |
158 SDL_GL_SwapWindow(asc_active_window->window); |
151 |
159 |
152 // Clear Flags |
160 // Clear Flags |
153 window->resized = false; |
161 asc_active_window->resized = false; |
154 |
162 |
155 if (window != active_window) { |
163 if (index != active_index) { |
156 asc_window_activate(active_window); |
164 asc_window_activate(active_index); |
157 } |
165 } |
158 } |
166 } |
159 |
167 |
160 void asc_window_activate(AscWindow *window) { |
168 void asc_window_activate(unsigned int index) { |
161 asc_gl_context_activate(&window->glctx); |
169 asc_context.active_window = index; |
162 asc_window_active = (AscWindow *)window; |
170 asc_gl_context_activate(&asc_active_window->glctx); |
163 } |
171 } |