30 #include "ascension/error.h" |
30 #include "ascension/error.h" |
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) { |
|
36 if (node->color.alpha == 0 || node->hidden || node->internal.tex_id == 0) { |
|
37 return; |
|
38 } |
|
39 |
|
40 glUseProgram(ASC_SHADER_FONT.base.id); |
|
41 |
|
42 // Upload projection |
|
43 // TODO: when we group UI draw calls, we don't need this |
|
44 glUniformMatrix4fv(ASC_SHADER_FONT.base.projection, 1, |
|
45 GL_FALSE, asc_context.active_window->projection); |
|
46 |
|
47 // Upload model matrix |
|
48 asc_mat4f model = {0}; |
|
49 model[asc_mat4_index(0, 0)] = node->internal.dimension.width; |
|
50 model[asc_mat4_index(1, 1)] = node->internal.dimension.height; |
|
51 model[asc_mat4_index(3, 0)] = node->position.x; |
|
52 model[asc_mat4_index(3, 1)] = node->position.y; |
|
53 model[asc_mat4_index(3, 3)] = 1; |
|
54 glUniformMatrix4fv(ASC_SHADER_FONT.base.model, 1, GL_FALSE, model); |
|
55 |
|
56 // Upload surface |
|
57 glActiveTexture(GL_TEXTURE0); |
|
58 glBindTexture(GL_TEXTURE_RECTANGLE, node->internal.tex_id); |
|
59 glUniform1i(ASC_SHADER_FONT.surface, 0); |
|
60 |
|
61 // Draw mesh |
|
62 asc_primitives_draw_plane(); |
|
63 } |
|
64 |
35 AscText *asc_text(int x, int y, char const *text) { |
65 AscText *asc_text(int x, int y, char const *text) { |
36 AscText *node = calloc(1, sizeof(AscText)); |
66 AscText *node = calloc(1, sizeof(AscText)); |
37 if (node == NULL) { |
67 if (node == NULL) { |
38 asc_error("Out of memory."); |
68 asc_error("Out of memory."); |
39 return NULL; |
69 return NULL; |
40 } |
70 } |
|
71 |
|
72 node->node.free_func = (asc_scene_free_func) asc_text_free; |
|
73 node->node.draw_func = (asc_scene_draw_func) asc_text_draw; |
41 |
74 |
42 node->position = (asc_vec2i) {x, y}; |
75 node->position = (asc_vec2i) {x, y}; |
43 node->font = asc_context.active_font; |
76 node->font = asc_context.active_font; |
44 node->color = asc_context.ink; |
77 node->color = asc_context.ink; |
45 if (text != NULL) { |
78 if (text != NULL) { |
91 |
124 |
92 // Free the surface |
125 // Free the surface |
93 SDL_FreeSurface(surface); |
126 SDL_FreeSurface(surface); |
94 } |
127 } |
95 |
128 |
96 void asc_text_draw(AscText const *node) { |
|
97 if (node->color.alpha == 0 || node->hidden) { |
|
98 return; |
|
99 } |
|
100 |
|
101 if (node->internal.tex_id == 0) { |
|
102 asc_error("Tried to redraw text node after destruction"); |
|
103 return; |
|
104 } |
|
105 |
|
106 glUseProgram(ASC_SHADER_FONT.base.id); |
|
107 |
|
108 // Upload projection |
|
109 // TODO: when we group UI draw calls, we don't need this |
|
110 glUniformMatrix4fv(ASC_SHADER_FONT.base.projection, 1, |
|
111 GL_FALSE, asc_context.active_window->projection); |
|
112 |
|
113 // Upload model matrix |
|
114 asc_mat4f model = {0}; |
|
115 model[asc_mat4_index(0, 0)] = node->internal.dimension.width; |
|
116 model[asc_mat4_index(1, 1)] = node->internal.dimension.height; |
|
117 model[asc_mat4_index(3, 0)] = node->position.x; |
|
118 model[asc_mat4_index(3, 1)] = node->position.y; |
|
119 model[asc_mat4_index(3, 3)] = 1; |
|
120 glUniformMatrix4fv(ASC_SHADER_FONT.base.model, 1, GL_FALSE, model); |
|
121 |
|
122 // Upload surface |
|
123 glActiveTexture(GL_TEXTURE0); |
|
124 glBindTexture(GL_TEXTURE_RECTANGLE, node->internal.tex_id); |
|
125 glUniform1i(ASC_SHADER_FONT.surface, 0); |
|
126 |
|
127 // Draw mesh |
|
128 asc_primitives_draw_plane(); |
|
129 } |
|
130 |
|
131 void asc_text_free(AscText *node) { |
129 void asc_text_free(AscText *node) { |
132 asc_dprintf("Release text node texture: %u", node->internal.tex_id); |
130 asc_dprintf("Release text node texture: %u", node->internal.tex_id); |
133 glDeleteTextures(1, &node->internal.tex_id); |
131 glDeleteTextures(1, &node->internal.tex_id); |
134 free(node->text); |
132 free(node->text); |
135 free(node); |
133 free(node); |