26 */ |
26 */ |
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 "ascension/2d/sprite.h" |
|
32 |
31 #include <GL/glew.h> |
33 #include <GL/glew.h> |
32 #include <cx/array_list.h> |
34 #include <cx/array_list.h> |
33 |
35 |
34 static void asc_gl_debug_callback( |
36 static void asc_gl_debug_callback( |
35 GLenum source, GLenum type, GLuint id, GLenum severity, |
37 GLenum source, GLenum type, GLuint id, GLenum severity, |
44 source, id, type, severity, length, message); |
46 source, id, type, severity, length, message); |
45 } |
47 } |
46 } |
48 } |
47 |
49 |
48 static int asc_shader_initialize_predefined(AscGLContext *ctx) { |
50 static int asc_shader_initialize_predefined(AscGLContext *ctx) { |
|
51 // TODO: check if we can replace that by lazy loading shaders just like fonts |
49 int ret = 0; |
52 int ret = 0; |
50 ret |= asc_shader_sprite_init(&ctx->shader.sprite); |
53 ret |= asc_shader_sprite_init(&ctx->shader.sprite_uv, false); |
|
54 ret |= asc_shader_sprite_init(&ctx->shader.sprite_rect, true); |
51 ret |= asc_error_catch_all_gl(); |
55 ret |= asc_error_catch_all_gl(); |
52 return ret; |
56 return ret; |
53 } |
57 } |
54 |
58 |
55 static void asc_shader_destroy_predefined(AscGLContext *ctx) { |
59 static void asc_shader_destroy_predefined(AscGLContext *ctx) { |
56 asc_shader_program_destroy(&ctx->shader.sprite.program); |
60 asc_shader_program_destroy(&ctx->shader.sprite_uv.program); |
57 } |
61 asc_shader_program_destroy(&ctx->shader.sprite_rect.program); |
58 |
|
59 static int asc_texture_initialize_predefined(AscGLContext *ctx) { |
|
60 asc_texture_init_rectangle(ctx->textures_rect, ASC_TEXTURE_RECT_COUNT); |
|
61 asc_texture_init_2d(ctx->textures_2d, ASC_TEXTURE_2D_COUNT); |
|
62 |
|
63 // Create a 1x1 surface with 32-bit RGBA format |
|
64 SDL_Surface* white1x1 = SDL_CreateRGBSurface( |
|
65 0, 1, 1, 32, |
|
66 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF); |
|
67 if (white1x1 == NULL) { |
|
68 asc_error("Failed to create surface: %s", SDL_GetError()); |
|
69 return 1; |
|
70 } |
|
71 SDL_FillRect(white1x1, NULL, 0xFFFFFFFF); |
|
72 |
|
73 // Initialize the empty textures with the white surface |
|
74 asc_texture_from_surface(&ctx->textures_rect[ASC_TEXTURE_RECT_EMPTY_1X1_IDX], white1x1); |
|
75 asc_texture_from_surface(&ctx->textures_2d[ASC_TEXTURE_2D_EMPTY_1X1_IDX], white1x1); |
|
76 |
|
77 return asc_error_catch_all_gl(); |
|
78 } |
|
79 |
|
80 static void asc_texture_destroy_predefined(AscGLContext *ctx) { |
|
81 asc_texture_destroy(ctx->textures_rect, ASC_TEXTURE_RECT_COUNT); |
|
82 asc_texture_destroy(ctx->textures_2d, ASC_TEXTURE_2D_COUNT); |
|
83 } |
62 } |
84 |
63 |
85 struct asc_gl_context_cleanup_data { |
64 struct asc_gl_context_cleanup_data { |
86 int type; |
65 int type; |
87 union { |
66 union { |
134 asc_error("Initializing predefined shaders failed"); |
113 asc_error("Initializing predefined shaders failed"); |
135 SDL_GL_DeleteContext(ctx->glctx); |
114 SDL_GL_DeleteContext(ctx->glctx); |
136 return false; |
115 return false; |
137 } |
116 } |
138 |
117 |
139 if (asc_texture_initialize_predefined(ctx)) { |
|
140 asc_error("Initializing predefined textures failed"); |
|
141 return false; |
|
142 } |
|
143 |
|
144 ctx->cleanup_funcs = cxArrayListCreateSimple(sizeof(struct asc_gl_context_cleanup_data), 8); |
118 ctx->cleanup_funcs = cxArrayListCreateSimple(sizeof(struct asc_gl_context_cleanup_data), 8); |
145 cxDefineDestructor(ctx->cleanup_funcs, asc_gl_context_cleanup); |
119 cxDefineDestructor(ctx->cleanup_funcs, asc_gl_context_cleanup); |
146 |
120 |
147 return true; |
121 return true; |
148 } else { |
122 } else { |
155 void asc_gl_context_destroy(AscGLContext *ctx) { |
129 void asc_gl_context_destroy(AscGLContext *ctx) { |
156 if (ctx->glctx == NULL) return; |
130 if (ctx->glctx == NULL) return; |
157 SDL_GL_MakeCurrent(ctx->window, ctx->glctx); |
131 SDL_GL_MakeCurrent(ctx->window, ctx->glctx); |
158 |
132 |
159 cxListFree(ctx->cleanup_funcs); |
133 cxListFree(ctx->cleanup_funcs); |
160 asc_texture_destroy_predefined(ctx); |
|
161 asc_shader_destroy_predefined(ctx); |
134 asc_shader_destroy_predefined(ctx); |
162 |
135 |
163 // destroy the GL context and the window |
136 // destroy the GL context and the window |
164 SDL_GL_DeleteContext(ctx->glctx); |
137 SDL_GL_DeleteContext(ctx->glctx); |
165 ctx->glctx = NULL; |
138 ctx->glctx = NULL; |