31 #include "ascension/shader.h" |
31 #include "ascension/shader.h" |
32 |
32 |
33 #include <GL/glew.h> |
33 #include <GL/glew.h> |
34 |
34 |
35 static void asc_text_draw(AscText const *node) { |
35 static void asc_text_draw(AscText const *node) { |
36 if (node->color.alpha == 0 || node->hidden || node->tex_id == 0) { |
36 if (node->color.alpha == 0 || node->hidden) { |
37 return; |
37 return; |
38 } |
38 } |
39 |
39 |
40 // Obtain shader |
40 // Obtain shader |
41 AscShaderSprite *shader = &asc_context.active_window->glctx.shader.sprite; |
41 AscShaderSprite *shader = &asc_context.active_window->glctx.shader.sprite; |
42 |
42 |
43 // Upload model matrix |
43 // Upload model matrix |
44 glUniformMatrix4fv(shader->base.model, 1, |
44 glUniformMatrix4fv(shader->base.model, 1, |
45 GL_FALSE, node->base.world_transform); |
45 GL_FALSE, node->base.world_transform); |
46 |
46 |
47 // Upload surface |
47 // Bind texture |
48 glActiveTexture(GL_TEXTURE0); |
48 asc_texture_bind(&node->tex, shader->tex, 0); |
49 glBindTexture(GL_TEXTURE_RECTANGLE, node->tex_id); |
|
50 glUniform1i(shader->surface, 0); |
|
51 |
49 |
52 // Apply depth |
50 // Apply depth |
53 glUniform1f(shader->depth, (float)(node->base.depth)); |
51 glUniform1f(shader->depth, (float)(node->base.depth)); |
54 |
52 |
55 // Draw mesh |
53 // Draw mesh |
61 if (node->color.alpha == 0 || node->hidden) { |
59 if (node->color.alpha == 0 || node->hidden) { |
62 return; |
60 return; |
63 } |
61 } |
64 |
62 |
65 // Generate new texture, if required |
63 // Generate new texture, if required |
66 if (node->tex_id == 0) { |
64 if (asc_texture_uninitialized(&node->tex)) { |
67 glGenTextures(1, &node->tex_id); |
65 asc_texture_init_rectangle(&node->tex); |
68 glBindTexture(GL_TEXTURE_RECTANGLE, node->tex_id); |
|
69 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
|
70 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
|
71 asc_dprintf("Generated new texture for text node: %u", node->tex_id); |
|
72 } |
66 } |
73 |
67 |
74 // Render text onto a surface |
68 // Render text onto a surface |
75 SDL_Surface *surface = TTF_RenderUTF8_Blended_Wrapped( |
69 SDL_Surface *surface = TTF_RenderUTF8_Blended_Wrapped( |
76 asc_font_cache_validate(node->font)->ptr, |
70 asc_font_cache_validate(node->font)->ptr, |
85 node->base.scale.width = (float) surface->w; |
79 node->base.scale.width = (float) surface->w; |
86 node->base.scale.height = (float) surface->h; |
80 node->base.scale.height = (float) surface->h; |
87 asc_update_transform((AscSceneNode *) node); |
81 asc_update_transform((AscSceneNode *) node); |
88 |
82 |
89 // Transfer Image Data |
83 // Transfer Image Data |
90 // TODO: move the image data transfer to a separate function - we will need it more often |
84 asc_texture_from_surface(&node->tex, surface); |
91 glBindTexture(GL_TEXTURE_RECTANGLE, node->tex_id); |
|
92 glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch / surface->format->BytesPerPixel); |
|
93 glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, |
|
94 surface->w, surface->h, |
|
95 0, GL_BGRA, GL_UNSIGNED_BYTE, surface->pixels); |
|
96 |
85 |
97 // Free the surface |
86 // Free the surface |
98 SDL_FreeSurface(surface); |
87 SDL_FreeSurface(surface); |
99 } |
88 } |
100 |
89 |
101 AscSceneNode *asc_text(int x, int y, char const *text) { |
90 AscSceneNode *asc_text(int x, int y, char const *text) { |
102 AscText *node = calloc(1, sizeof(AscText)); |
91 AscText *node = calloc(1, sizeof(AscText)); |
103 if (node == NULL) { |
|
104 asc_error("Out of memory."); |
|
105 return NULL; |
|
106 } |
|
107 |
92 |
108 node->base.render_group = ASC_RENDER_GROUP_SPRITE_BLEND; |
93 node->base.render_group = ASC_RENDER_GROUP_SPRITE_BLEND; |
109 node->base.free_func = (asc_scene_free_func) asc_text_free; |
94 node->base.free_func = (asc_scene_free_func) asc_text_free; |
110 node->base.update_func = (asc_scene_update_func) asc_text_update; |
95 node->base.update_func = (asc_scene_update_func) asc_text_update; |
111 node->base.draw_func = (asc_scene_draw_func) asc_text_draw; |
96 node->base.draw_func = (asc_scene_draw_func) asc_text_draw; |