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 } |