| 27 |
27 |
| 28 #include "ascension/glcontext.h" |
28 #include "ascension/glcontext.h" |
| 29 #include "ascension/error.h" |
29 #include "ascension/error.h" |
| 30 |
30 |
| 31 #include <GL/glew.h> |
31 #include <GL/glew.h> |
| |
32 #include <cx/array_list.h> |
| 32 |
33 |
| 33 static void asc_gl_debug_callback( |
34 static void asc_gl_debug_callback( |
| 34 GLenum source, GLenum type, GLuint id, GLenum severity, |
35 GLenum source, GLenum type, GLuint id, GLenum severity, |
| 35 GLsizei length, const GLchar* message, |
36 GLsizei length, const GLchar* message, |
| 36 __attribute__((__unused__)) const void* userParam |
37 __attribute__((__unused__)) const void* userParam |
| 92 } |
93 } |
| 93 |
94 |
| 94 static void asc_texture_destroy_predefined(AscGLContext *ctx) { |
95 static void asc_texture_destroy_predefined(AscGLContext *ctx) { |
| 95 asc_texture_destroy(ctx->textures_rect, ASC_TEXTURE_RECT_COUNT); |
96 asc_texture_destroy(ctx->textures_rect, ASC_TEXTURE_RECT_COUNT); |
| 96 asc_texture_destroy(ctx->textures_2d, ASC_TEXTURE_2D_COUNT); |
97 asc_texture_destroy(ctx->textures_2d, ASC_TEXTURE_2D_COUNT); |
| |
98 } |
| |
99 |
| |
100 struct asc_gl_context_cleanup_data { |
| |
101 int type; |
| |
102 union { |
| |
103 void(*f1)(void); |
| |
104 void(*f2)(void*); |
| |
105 void(*f3)(void*, void*); |
| |
106 }; |
| |
107 void *memory; |
| |
108 void *additional_data; |
| |
109 }; |
| |
110 |
| |
111 static void asc_gl_context_cleanup(struct asc_gl_context_cleanup_data *data) { |
| |
112 switch (data->type) { |
| |
113 case 1: |
| |
114 data->f1(); |
| |
115 break; |
| |
116 case 2: |
| |
117 data->f2(data->memory); |
| |
118 break; |
| |
119 default: |
| |
120 data->f3(data->memory, data->additional_data); |
| |
121 break; |
| |
122 } |
| 97 } |
123 } |
| 98 |
124 |
| 99 bool asc_gl_context_initialize( |
125 bool asc_gl_context_initialize( |
| 100 AscGLContext *ctx, |
126 AscGLContext *ctx, |
| 101 SDL_Window *window, |
127 SDL_Window *window, |
| 134 if (asc_texture_initialize_predefined(ctx)) { |
160 if (asc_texture_initialize_predefined(ctx)) { |
| 135 asc_error("Initializing predefined textures failed"); |
161 asc_error("Initializing predefined textures failed"); |
| 136 return false; |
162 return false; |
| 137 } |
163 } |
| 138 |
164 |
| 139 ctx->mpool = cxMempoolCreateSimple(128); |
165 ctx->cleanup_funcs = cxArrayListCreateSimple(sizeof(struct asc_gl_context_cleanup_data), 8); |
| |
166 cxDefineDestructor(ctx->cleanup_funcs, asc_gl_context_cleanup); |
| 140 |
167 |
| 141 return true; |
168 return true; |
| 142 } else { |
169 } else { |
| 143 asc_error("glewInit failed: %s", glewGetErrorString(err)); |
170 asc_error("glewInit failed: %s", glewGetErrorString(err)); |
| 144 SDL_GL_DeleteContext(ctx->glctx); |
171 SDL_GL_DeleteContext(ctx->glctx); |
| 148 |
175 |
| 149 void asc_gl_context_destroy(AscGLContext *ctx) { |
176 void asc_gl_context_destroy(AscGLContext *ctx) { |
| 150 if (ctx->glctx == NULL) return; |
177 if (ctx->glctx == NULL) return; |
| 151 SDL_GL_MakeCurrent(ctx->window, ctx->glctx); |
178 SDL_GL_MakeCurrent(ctx->window, ctx->glctx); |
| 152 |
179 |
| 153 cxMempoolFree(ctx->mpool); |
180 cxListFree(ctx->cleanup_funcs); |
| 154 ctx->mpool = NULL; |
|
| 155 asc_texture_destroy_predefined(ctx); |
181 asc_texture_destroy_predefined(ctx); |
| 156 asc_shader_destroy_predefined(ctx); |
182 asc_shader_destroy_predefined(ctx); |
| 157 asc_primitives_destroy(ctx); |
183 asc_primitives_destroy(ctx); |
| 158 |
184 |
| 159 // destroy the GL context and the window |
185 // destroy the GL context and the window |
| 160 SDL_GL_DeleteContext(ctx->glctx); |
186 SDL_GL_DeleteContext(ctx->glctx); |
| 161 ctx->glctx = NULL; |
187 ctx->glctx = NULL; |
| 162 } |
188 } |
| |
189 |
| |
190 void asc_gl_context_add_cleanup_func(AscGLContext *ctx, void(*func)(void)) { |
| |
191 struct asc_gl_context_cleanup_data *data = cxListEmplace(ctx->cleanup_funcs); |
| |
192 data->type = 1; |
| |
193 data->f1 = func; |
| |
194 } |
| |
195 |
| |
196 void asc_gl_context_add_cleanup_func2(AscGLContext *ctx, void(*func)(void*), void *memory) { |
| |
197 struct asc_gl_context_cleanup_data *data = cxListEmplace(ctx->cleanup_funcs); |
| |
198 data->type = 2; |
| |
199 data->f2 = func; |
| |
200 data->memory = memory; |
| |
201 } |
| |
202 |
| |
203 void asc_gl_context_add_cleanup_func3(AscGLContext *ctx, void(*func)(void*,void*), void *memory, void *additional_data) { |
| |
204 struct asc_gl_context_cleanup_data *data = cxListEmplace(ctx->cleanup_funcs); |
| |
205 data->type = 3; |
| |
206 data->f3 = func; |
| |
207 data->memory = memory; |
| |
208 data->additional_data = additional_data; |
| |
209 } |