src/window.c

changeset 44
b3da4096c607
parent 41
df81d493716e
child 47
44457f6cb0a2
equal deleted inserted replaced
43:5a8c31904e44 44:b3da4096c607
28 #include "ascension/window.h" 28 #include "ascension/window.h"
29 #include "ascension/context.h" 29 #include "ascension/context.h"
30 #include "ascension/error.h" 30 #include "ascension/error.h"
31 #include "ascension/utils.h" 31 #include "ascension/utils.h"
32 32
33 #include <cx/printf.h>
34
35 #include <GL/glew.h> 33 #include <GL/glew.h>
36 34
37 static void asc_gl_debug_callback(
38 GLenum source, GLenum type, GLuint id, GLenum severity,
39 GLsizei length, const GLchar* message,
40 const void* userParam
41 ) {
42 cxmutstr buf = cx_asprintf(
43 "source = %d, id = %u, type = %d, severity= %d, message = %.*s",
44 source, id, type, severity, length, message);
45 if (type == GL_DEBUG_TYPE_ERROR) {
46 asc_error(buf.ptr);
47 } else {
48 asc_dprintf("GL debug: %.*s", (int)buf.length, buf.ptr);
49 }
50 cx_strfree(&buf);
51 }
52
53 void asc_window_settings_init_defaults(AscWindowSettings* settings) { 35 void asc_window_settings_init_defaults(AscWindowSettings* settings) {
54 settings->depth_size = 24;
55 settings->vsync = 1;
56 settings->dimensions.width = 800; 36 settings->dimensions.width = 800;
57 settings->dimensions.height = 600; 37 settings->dimensions.height = 600;
58 settings->fullscreen = 0; 38 settings->fullscreen = 0;
59 settings->gl_major_version = 4; 39 settings->glsettings.depth_size = 24;
60 settings->gl_minor_version = 0; 40 settings->glsettings.vsync = 1;
41 settings->glsettings.gl_major_version = 4;
42 settings->glsettings.gl_minor_version = 0;
61 settings->title = "Ascended Window"; 43 settings->title = "Ascended Window";
62 } 44 }
63 45
64 static void asc_window_init_scenes(AscWindow *window) { 46 static void asc_window_init_scenes(AscWindow *window) {
65 asc_scene_init(&window->ui); 47 asc_scene_init(&window->ui);
101 &window->dimensions.width, 83 &window->dimensions.width,
102 &window->dimensions.height 84 &window->dimensions.height
103 ); 85 );
104 window->resized = true; // count initial sizing as resize 86 window->resized = true; // count initial sizing as resize
105 87
106 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); 88 if (asc_gl_context_initialize(&window->glctx, window->window, &settings->glsettings)) {
107 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, settings->gl_major_version); 89 asc_dprintf("Window %u initialized", window->id);
108 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, settings->gl_minor_version); 90 asc_context.active_window = window;
109 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, settings->depth_size); 91 asc_window_init_scenes(window);
110 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 92 return window;
111 window->glctx = SDL_GL_CreateContext(window->window); 93 } else {
112 if (window->glctx == NULL) {
113 asc_dprintf("Creating GL context failed for window %u", window->id); 94 asc_dprintf("Creating GL context failed for window %u", window->id);
114 } else { 95 // cleanup on error
115 glewExperimental = GL_TRUE; 96 SDL_DestroyWindow(window->window);
116 GLenum err = glewInit(); 97 window->window = NULL;
117 if (err == GLEW_OK) { 98 window->id = 0;
118 SDL_GL_SetSwapInterval(settings->vsync); 99 return NULL;
119 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
120 glEnable(GL_DEBUG_OUTPUT);
121 glDebugMessageCallback(asc_gl_debug_callback, NULL);
122
123 asc_dprintf("Window %u initialized", window->id);
124 if (asc_primitives_init(&window->primitives)) {
125 asc_context.active_window = window;
126 asc_window_init_scenes(window);
127 return window;
128 } else {
129 asc_dprintf("!!! Creating primitives for window %u failed !!!", window->id);
130 }
131 } else {
132 asc_error(glewGetErrorString(err));
133 }
134 } 100 }
135
136 // cleanup on error
137 if (window->glctx != NULL) {
138 SDL_GL_DeleteContext(window->glctx);
139 }
140 window->glctx = NULL;
141 SDL_DestroyWindow(window->window);
142 window->window = NULL;
143 window->id = 0;
144 } 101 }
145 102
146 void asc_window_destroy(AscWindow* window) { 103 void asc_window_destroy(AscWindow* window) {
147 // safeguard 104 // safeguard
148 if (window->id == 0) return; 105 if (window->id == 0) return;
153 } 110 }
154 111
155 // destroy all scenes 112 // destroy all scenes
156 asc_scene_destroy(&window->ui); 113 asc_scene_destroy(&window->ui);
157 114
158 // release context related data (we have to make the GL context current for this) 115 // release context related data
159 SDL_GL_MakeCurrent(window->window, window->glctx); 116 asc_gl_context_destroy(&window->glctx);
160 asc_primitives_destroy(&window->primitives);
161 117
162 // destroy the GL context and the window 118 // destroy window
163 if (window->glctx != NULL) {
164 SDL_GL_DeleteContext(window->glctx);
165 }
166 if (window->window != NULL) { 119 if (window->window != NULL) {
167 SDL_DestroyWindow(window->window); 120 SDL_DestroyWindow(window->window);
168 } 121 }
169 122
170 // if another window was active, make the other context current again 123 // if another window was active, make the other context current again
171 if (asc_context.active_window != NULL) { 124 if (asc_context.active_window != NULL) {
172 AscWindow const *aw = asc_context.active_window; 125 asc_gl_context_activate(&asc_context.active_window->glctx);
173 SDL_GL_MakeCurrent(aw->window, aw->glctx);
174 } 126 }
175 127
176 // clean the data 128 // clean the data
177 asc_dprintf("Window %u and its OpenGL context destroyed.", window->id); 129 asc_dprintf("Window %u and its OpenGL context destroyed.", window->id);
178 memset(window, 0, sizeof(AscWindow)); 130 memset(window, 0, sizeof(AscWindow));
179 } 131 }
180 132
181 void asc_window_sync(AscWindow* window) { 133 void asc_window_sync(AscWindow* window) {
182 AscWindow const *active_window = asc_context.active_window; 134 AscWindow *active_window = asc_context.active_window;
183 if (window != active_window) { 135 if (window != active_window) {
184 asc_window_activate(window); 136 asc_window_activate(window);
185 } 137 }
186 138
187 // Draw the UI 139 // Draw the UI
196 if (window != active_window) { 148 if (window != active_window) {
197 asc_window_activate(active_window); 149 asc_window_activate(active_window);
198 } 150 }
199 } 151 }
200 152
201 void asc_window_activate(AscWindow const *window) { 153 void asc_window_activate(AscWindow *window) {
202 SDL_GL_MakeCurrent(window->window, window->glctx); 154 asc_gl_context_activate(&window->glctx);
203 asc_context.active_window = (AscWindow *)window; 155 asc_context.active_window = (AscWindow *)window;
204 } 156 }

mercurial