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->internal.tex_id == 0) { |
36 if (node->color.alpha == 0 || node->hidden || node->internal.tex_id == 0) { |
37 return; |
37 return; |
38 } |
38 } |
39 |
39 |
|
40 // TODO: when we group draw calls, we don't need to activate shader here |
40 glUseProgram(ASC_SHADER_FONT.base.id); |
41 glUseProgram(ASC_SHADER_FONT.base.id); |
41 |
42 |
42 // Upload projection |
43 // TODO: when we group UI draw calls, we don't need to upload matrices here |
43 // TODO: when we group UI draw calls, we don't need this |
44 // Upload matrices |
44 glUniformMatrix4fv(ASC_SHADER_FONT.base.projection, 1, |
45 glUniformMatrix4fv(ASC_SHADER_FONT.base.projection, 1, |
45 GL_FALSE, asc_context.active_window->projection); |
46 GL_FALSE, asc_context.active_window->projection); |
46 |
47 glUniformMatrix4fv(ASC_SHADER_FONT.base.model, 1, |
47 // Upload model matrix |
48 GL_FALSE, node->base.transform); |
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 |
49 |
56 // Upload surface |
50 // Upload surface |
57 glActiveTexture(GL_TEXTURE0); |
51 glActiveTexture(GL_TEXTURE0); |
58 glBindTexture(GL_TEXTURE_RECTANGLE, node->internal.tex_id); |
52 glBindTexture(GL_TEXTURE_RECTANGLE, node->internal.tex_id); |
59 glUniform1i(ASC_SHADER_FONT.surface, 0); |
53 glUniform1i(ASC_SHADER_FONT.surface, 0); |
60 |
54 |
61 // Draw mesh |
55 // Draw mesh |
62 asc_primitives_draw_plane(); |
56 asc_primitives_draw_plane(); |
63 } |
57 } |
64 |
58 |
65 AscText *asc_text(int x, int y, char const *text) { |
59 static void asc_text_update(AscText *node) { |
66 AscText *node = calloc(1, sizeof(AscText)); |
|
67 if (node == NULL) { |
|
68 asc_error("Out of memory."); |
|
69 return NULL; |
|
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; |
|
74 |
|
75 node->position = (asc_vec2i) {x, y}; |
|
76 node->font = asc_context.active_font; |
|
77 node->color = asc_context.ink; |
|
78 if (text != NULL) { |
|
79 node->text = strdup(text); |
|
80 } |
|
81 |
|
82 return node; |
|
83 } |
|
84 |
|
85 void asc_text_update(AscText *node) { |
|
86 // short circuit if fully transparent or hidden, we don't need anything |
60 // short circuit if fully transparent or hidden, we don't need anything |
87 if (node->color.alpha == 0 || node->hidden) { |
61 if (node->color.alpha == 0 || node->hidden) { |
88 return; |
62 return; |
89 } |
63 } |
90 |
64 |
107 if (surface == NULL) { |
81 if (surface == NULL) { |
108 asc_error(SDL_GetError()); |
82 asc_error(SDL_GetError()); |
109 return; |
83 return; |
110 } |
84 } |
111 |
85 |
112 // Store basic node information |
86 // Transform |
113 node->position = node->position; |
87 asc_transform_scale(node->base.transform, (float) surface->w, (float) surface->h, 0); |
114 node->internal.dimension.width = surface->w; |
88 asc_transform_translate2i(node->base.transform, node->position); |
115 node->internal.dimension.height = surface->h; |
|
116 |
89 |
117 // Transfer Image Data |
90 // Transfer Image Data |
118 // TODO: move the image data transfer to a separate function - we will need it more often |
91 // TODO: move the image data transfer to a separate function - we will need it more often |
119 glBindTexture(GL_TEXTURE_RECTANGLE, node->internal.tex_id); |
92 glBindTexture(GL_TEXTURE_RECTANGLE, node->internal.tex_id); |
120 glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch / surface->format->BytesPerPixel); |
93 glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch / surface->format->BytesPerPixel); |
124 |
97 |
125 // Free the surface |
98 // Free the surface |
126 SDL_FreeSurface(surface); |
99 SDL_FreeSurface(surface); |
127 } |
100 } |
128 |
101 |
|
102 AscText *asc_text(int x, int y, char const *text) { |
|
103 AscText *node = calloc(1, sizeof(AscText)); |
|
104 if (node == NULL) { |
|
105 asc_error("Out of memory."); |
|
106 return NULL; |
|
107 } |
|
108 |
|
109 node->base.free_func = (asc_scene_free_func) asc_text_free; |
|
110 node->base.update_func = (asc_scene_update_func) asc_text_update; |
|
111 node->base.draw_func = (asc_scene_draw_func) asc_text_draw; |
|
112 |
|
113 node->position.x = x; |
|
114 node->position.y = y; |
|
115 node->font = asc_context.active_font; |
|
116 node->color = asc_context.ink; |
|
117 if (text != NULL) { |
|
118 node->text = strdup(text); |
|
119 } |
|
120 |
|
121 return node; |
|
122 } |
|
123 |
129 void asc_text_free(AscText *node) { |
124 void asc_text_free(AscText *node) { |
130 asc_dprintf("Release text node texture: %u", node->internal.tex_id); |
125 asc_dprintf("Release text node texture: %u", node->internal.tex_id); |
131 glDeleteTextures(1, &node->internal.tex_id); |
126 glDeleteTextures(1, &node->internal.tex_id); |
132 free(node->text); |
127 free(node->text); |
133 free(node); |
128 free(node); |