src/text.c

changeset 37
8a8cc6725b48
parent 36
e26b4ac1661c
child 38
6e5629ea4c5c
equal deleted inserted replaced
36:e26b4ac1661c 37:8a8cc6725b48
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->internal.tex_id == 0) { 36 if (node->color.alpha == 0 || node->hidden || node->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 // Upload model matrix
41 glUseProgram(ASC_SHADER_FONT.base.id);
42
43 // TODO: when we group UI draw calls, we don't need to upload matrices here
44 // Upload matrices
45 glUniformMatrix4fv(ASC_SHADER_FONT.base.projection, 1,
46 GL_FALSE, asc_context.active_window->projection);
47 glUniformMatrix4fv(ASC_SHADER_FONT.base.model, 1, 41 glUniformMatrix4fv(ASC_SHADER_FONT.base.model, 1,
48 GL_FALSE, node->base.transform); 42 GL_FALSE, node->base.transform);
49 43
50 // Upload surface 44 // Upload surface
51 glActiveTexture(GL_TEXTURE0); 45 glActiveTexture(GL_TEXTURE0);
52 glBindTexture(GL_TEXTURE_RECTANGLE, node->internal.tex_id); 46 glBindTexture(GL_TEXTURE_RECTANGLE, node->tex_id);
53 glUniform1i(ASC_SHADER_FONT.surface, 0); 47 glUniform1i(ASC_SHADER_FONT.surface, 0);
54 48
55 // Draw mesh 49 // Draw mesh
56 asc_primitives_draw_plane(); 50 asc_primitives_draw_plane();
51 }
52
53 static void asc_text_update_transform(AscText *node) {
54 asc_transform_scale(node->base.transform, (float) node->dimension.width, (float) node->dimension.height, 0);
55 asc_transform_translate2i(node->base.transform, node->position);
57 } 56 }
58 57
59 static void asc_text_update(AscText *node) { 58 static void asc_text_update(AscText *node) {
60 // short circuit if fully transparent or hidden, we don't need anything 59 // short circuit if fully transparent or hidden, we don't need anything
61 if (node->color.alpha == 0 || node->hidden) { 60 if (node->color.alpha == 0 || node->hidden) {
62 return; 61 return;
63 } 62 }
64 63
65 // Generate new texture, if required 64 // Generate new texture, if required
66 if (node->internal.tex_id == 0) { 65 if (node->tex_id == 0) {
67 glGenTextures(1, &node->internal.tex_id); 66 glGenTextures(1, &node->tex_id);
68 glBindTexture(GL_TEXTURE_RECTANGLE, node->internal.tex_id); 67 glBindTexture(GL_TEXTURE_RECTANGLE, node->tex_id);
69 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 68 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
70 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 69 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
71 asc_dprintf("Generated new texture for text node: %u", node->internal.tex_id); 70 asc_dprintf("Generated new texture for text node: %u", node->tex_id);
72 } 71 }
73 72
74 // Render text onto a surface 73 // Render text onto a surface
75 SDL_Surface *surface = TTF_RenderUTF8_Blended_Wrapped( 74 SDL_Surface *surface = TTF_RenderUTF8_Blended_Wrapped(
76 asc_font_cache_validate(node->font)->ptr, 75 asc_font_cache_validate(node->font)->ptr,
80 ); 79 );
81 if (surface == NULL) { 80 if (surface == NULL) {
82 asc_error(SDL_GetError()); 81 asc_error(SDL_GetError());
83 return; 82 return;
84 } 83 }
85 84 node->dimension.width = surface->w;
86 // Transform 85 node->dimension.height = surface->h;
87 asc_transform_scale(node->base.transform, (float) surface->w, (float) surface->h, 0); 86 asc_node_update_transform(node);
88 asc_transform_translate2i(node->base.transform, node->position);
89 87
90 // Transfer Image Data 88 // Transfer Image Data
91 // TODO: move the image data transfer to a separate function - we will need it more often 89 // TODO: move the image data transfer to a separate function - we will need it more often
92 glBindTexture(GL_TEXTURE_RECTANGLE, node->internal.tex_id); 90 glBindTexture(GL_TEXTURE_RECTANGLE, node->tex_id);
93 glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch / surface->format->BytesPerPixel); 91 glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch / surface->format->BytesPerPixel);
94 glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, 92 glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA,
95 surface->w, surface->h, 93 surface->w, surface->h,
96 0, GL_BGRA, GL_UNSIGNED_BYTE, surface->pixels); 94 0, GL_BGRA, GL_UNSIGNED_BYTE, surface->pixels);
97 95
104 if (node == NULL) { 102 if (node == NULL) {
105 asc_error("Out of memory."); 103 asc_error("Out of memory.");
106 return NULL; 104 return NULL;
107 } 105 }
108 106
107 node->base.render_group = ASC_RENDER_GROUP_FONTS;
109 node->base.free_func = (asc_scene_free_func) asc_text_free; 108 node->base.free_func = (asc_scene_free_func) asc_text_free;
110 node->base.update_func = (asc_scene_update_func) asc_text_update; 109 node->base.update_func = (asc_scene_update_func) asc_text_update;
110 node->base.transform_update_func = (asc_scene_update_func) asc_text_update_transform;
111 node->base.draw_func = (asc_scene_draw_func) asc_text_draw; 111 node->base.draw_func = (asc_scene_draw_func) asc_text_draw;
112 112
113 node->position.x = x; 113 node->position.x = x;
114 node->position.y = y; 114 node->position.y = y;
115 node->font = asc_context.active_font; 115 node->font = asc_context.active_font;
116 node->color = asc_context.ink; 116 node->color = asc_context.ink;
117 if (text != NULL) { 117 if (text != NULL) {
118 node->text = strdup(text); 118 node->text = strdup(text);
119 } 119 }
120 120
121 // initialize
122 asc_text_update(node);
123 asc_text_update_transform(node);
124
121 return &node->base; 125 return &node->base;
122 } 126 }
123 127
124 void asc_text_free(AscText *node) { 128 void asc_text_free(AscText *node) {
125 asc_dprintf("Release text node texture: %u", node->internal.tex_id); 129 asc_dprintf("Release text node texture: %u", node->tex_id);
126 glDeleteTextures(1, &node->internal.tex_id); 130 glDeleteTextures(1, &node->tex_id);
127 free(node->text); 131 free(node->text);
128 free(node); 132 free(node);
129 } 133 }

mercurial