Showing
13 changed files
with
541 additions
and
33 deletions
This diff could not be displayed because it is too large.
... | ... | @@ -217,7 +217,7 @@ function _M:makeFrame(base, w, h, iw, ih) |
217 | 217 | return f |
218 | 218 | end |
219 | 219 | |
220 | -function _M:makeFrameDO(base, w, h, iw, ih) | |
220 | +function _M:makeFrameDO(base, w, h, iw, ih, center) | |
221 | 221 | local f = {} |
222 | 222 | f.container = core.renderer.container() |
223 | 223 | if base then |
... | ... | @@ -233,7 +233,8 @@ function _M:makeFrameDO(base, w, h, iw, ih) |
233 | 233 | if not w then w = iw + f.b4.w + f.b6.w end |
234 | 234 | if not h then h = ih + f.b8.h + f.b2.h end |
235 | 235 | |
236 | - local cx, cy = -math.floor(w / 2), -math.floor(h / 2) | |
236 | + local cx, cy = 0,0 | |
237 | + if center then cx, cy = -math.floor(w / 2), -math.floor(h / 2) end | |
237 | 238 | |
238 | 239 | f.container:add(core.renderer.fromTextureTable(f.b5, cx + f.b4.w, cy + f.b8.h, w - f.b6.w - f.b4.w, h - f.b8.h - f.b2.h, true)) |
239 | 240 | |
... | ... | @@ -251,6 +252,7 @@ function _M:makeFrameDO(base, w, h, iw, ih) |
251 | 252 | end |
252 | 253 | f.w = math.floor(w) |
253 | 254 | f.h = math.floor(h) |
255 | + | |
254 | 256 | return f |
255 | 257 | end |
256 | 258 | ... | ... |
... | ... | @@ -530,11 +530,11 @@ end |
530 | 530 | |
531 | 531 | local renderer = core.renderer.renderer() |
532 | 532 | local UIBase = require "engine.ui.Base" |
533 | -local f = UIBase:makeFrameDO("ui/dialogframe_", 400, 400) | |
533 | +local f = UIBase:makeFrameDO("ui/dialogframe_", 400, 400, nil, nil, true) | |
534 | 534 | f.container:translate(400, 400) |
535 | -local f2 = UIBase:makeFrameDO("ui/button", 100, 40) | |
535 | +local f2 = UIBase:makeFrameDO("ui/button", 100, 40, nil, nil, true) | |
536 | 536 | -- f2.container:translate(100, 150) |
537 | -local f3 = UIBase:makeFrameDO("ui/textbox", 25, 25) | |
537 | +local f3 = UIBase:makeFrameDO("ui/textbox", 25, 25, nil, nil, true) | |
538 | 538 | -- f3.container:translate(20, 10) |
539 | 539 | -- f3.container:rotate(0, 0, math.rad(45)) |
540 | 540 | -- f2.container:add(core.renderer.redPoint()) |
... | ... | @@ -546,15 +546,21 @@ f.container:add(f2.container) |
546 | 546 | f2.container:add(f3.container) |
547 | 547 | renderer:add(f.container) |
548 | 548 | |
549 | +local t = core.renderer.text(UIBase.font) | |
550 | +t:text("Coco l'asticot!") | |
551 | +t:translate(50, 50) | |
552 | +t:rotate(0, 0, math.rad(45)) | |
553 | +f.container:add(t) | |
549 | 554 | |
550 | 555 | function _M:display() |
551 | 556 | renderer:toScreen(0, 0, 1, 1, 1, 1) |
552 | 557 | -- f.container:scale(0.01, 0.01, 0, true) |
553 | - f.container:rotate(0, 0, math.rad(1), true) | |
554 | - f2.container:rotate(0, 0, math.rad(1), true) | |
555 | - f3.container:rotate(0, 0, -math.rad(2), true) | |
558 | + -- f.container:rotate(0, 0, math.rad(1), true) | |
559 | + -- f2.container:rotate(0, 0, math.rad(1), true) | |
560 | + -- f3.container:rotate(0, 0, -math.rad(2), true) | |
556 | 561 | -- f.container:translate(2, 1) |
557 | 562 | f3.container:scale(1, 2 + math.sin(core.game.getTime()/500), 1) |
563 | + t:rotate(0, math.rad(1.5), 0, true) | |
558 | 564 | end |
559 | 565 | |
560 | 566 | --- Ask if we really want to close, if so, save the game first | ... | ... |
... | ... | @@ -24,6 +24,7 @@ |
24 | 24 | extern "C" { |
25 | 25 | #include "tgl.h" |
26 | 26 | #include "useshader.h" |
27 | +#include "font.h" | |
27 | 28 | } |
28 | 29 | |
29 | 30 | #include <vector> |
... | ... | @@ -58,7 +59,9 @@ protected: |
58 | 59 | bool changed = false; |
59 | 60 | public: |
60 | 61 | DisplayObject() { model = mat4(); }; |
61 | - virtual ~DisplayObject() {}; | |
62 | + virtual ~DisplayObject() { | |
63 | + if (lua_ref != LUA_NOREF && L) luaL_unref(L, LUA_REGISTRYINDEX, lua_ref); | |
64 | + }; | |
62 | 65 | void setLuaState(lua_State *L) { this->L = L; }; |
63 | 66 | void setLuaRef(int ref) {lua_ref = ref; }; |
64 | 67 | int unsetLuaRef() { int ref = lua_ref; lua_ref = LUA_NOREF; return ref; }; |
... | ... | @@ -76,20 +79,19 @@ public: |
76 | 79 | |
77 | 80 | class DOVertexes : public DisplayObject{ |
78 | 81 | public: |
79 | - // static long next_id = 1; | |
80 | - vector<long> ids; | |
81 | 82 | vector<vertex> vertices; |
82 | 83 | int tex_lua_ref = LUA_NOREF; |
83 | 84 | GLuint tex; |
84 | 85 | shader_type *shader; |
85 | 86 | |
86 | 87 | DOVertexes() { |
87 | - ids.reserve(4); | |
88 | 88 | vertices.reserve(4); |
89 | 89 | tex = 0; |
90 | 90 | shader = default_shader; |
91 | 91 | }; |
92 | - virtual ~DOVertexes() {}; | |
92 | + virtual ~DOVertexes() { | |
93 | + if (tex_lua_ref != LUA_NOREF && L) luaL_unref(L, LUA_REGISTRYINDEX, tex_lua_ref); | |
94 | + }; | |
93 | 95 | |
94 | 96 | int addQuad( |
95 | 97 | float x1, float y1, float u1, float v1, | ... | ... |
src/displayobjects/TextObject.cpp
0 → 100644
1 | +/* | |
2 | + TE4 - T-Engine 4 | |
3 | + Copyright (C) 2009 - 2015 Nicolas Casalini | |
4 | + | |
5 | + This program is free software: you can redistribute it and/or modify | |
6 | + it under the terms of the GNU General Public License as published by | |
7 | + the Free Software Foundation, either version 3 of the License, or | |
8 | + (at your option) any later version. | |
9 | + | |
10 | + This program is distributed in the hope that it will be useful, | |
11 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | + GNU General Public License for more details. | |
14 | + | |
15 | + You should have received a copy of the GNU General Public License | |
16 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
17 | + | |
18 | + Nicolas Casalini "DarkGod" | |
19 | + darkgod@te4.org | |
20 | +*/ | |
21 | + | |
22 | +extern "C" { | |
23 | +#include "lua.h" | |
24 | +#include "lauxlib.h" | |
25 | +#include "display.h" | |
26 | +#include "types.h" | |
27 | +#include "physfs.h" | |
28 | +#include "physfsrwops.h" | |
29 | +#include "main.h" | |
30 | +} | |
31 | + | |
32 | +#include "displayobjects/TextObject.hpp" | |
33 | + | |
34 | +int DOText::addCharQuad(const char *str, size_t len, font_style style, int bx, int by, float r, float g, float b, float a) { | |
35 | + int x = 0, y = by; | |
36 | + ssize_t off = 1; | |
37 | + int32_t c; | |
38 | + float italic = 0; | |
39 | + if (style == FONT_STYLE_ITALIC) { style = FONT_STYLE_NORMAL; italic = 0.2; } | |
40 | + while (off > 0) { | |
41 | + off = utf8proc_iterate((const uint8_t*)str, len, &c); | |
42 | + str += off; | |
43 | + len -= off; | |
44 | + | |
45 | + if (c > 0 && c < MAX_ATLAS_DATA) { | |
46 | + font_atlas_data_style *d = &font->atlas_data[c].data[style]; | |
47 | + if (!d->w) font_add_atlas(font, c, style); | |
48 | + if (d->w) { | |
49 | + addQuad( | |
50 | + d->w * italic + bx + x, y, d->tx1, d->ty1, | |
51 | + d->w * italic + bx + x + d->w, y, d->tx2, d->ty1, | |
52 | + bx + x + d->w, y + d->h, d->tx2, d->ty2, | |
53 | + bx + x, y + d->h, d->tx1, d->ty2, | |
54 | + r, g, b, a | |
55 | + ); | |
56 | + x += d->w; | |
57 | + } | |
58 | + } | |
59 | + } | |
60 | + return x; | |
61 | +} | |
62 | + | |
63 | +int DOText::getTextChunkSize(const char *str, size_t len, font_style style) { | |
64 | + int x = 0, y = 0; | |
65 | + ssize_t off = 1; | |
66 | + int32_t c; | |
67 | + float italic = 0; | |
68 | + if (style == FONT_STYLE_ITALIC) { style = FONT_STYLE_NORMAL; italic = 0.2; } | |
69 | + while (off > 0) { | |
70 | + off = utf8proc_iterate((const uint8_t*)str, len, &c); | |
71 | + str += off; | |
72 | + len -= off; | |
73 | + | |
74 | + if (c > 0 && c < MAX_ATLAS_DATA) { | |
75 | + font_atlas_data_style *d = &font->atlas_data[c].data[style]; | |
76 | + if (!d->w) font_add_atlas(font, c, style); | |
77 | + if (d->w) { | |
78 | + x += d->w; | |
79 | + } | |
80 | + } | |
81 | + } | |
82 | + return x; | |
83 | +} | |
84 | + | |
85 | +void DOText::parseText() { | |
86 | + font_type *f = font; | |
87 | + if (!f) return; | |
88 | + if (!f->atlas) font_make_atlas(f, 0, 0); | |
89 | + size_t len = strlen(text); | |
90 | + if (!len) return; | |
91 | + const char *str = text; | |
92 | + float r = 1, g = 1, b = 1, a = 1; | |
93 | + float lr = 1, lg = 1, lb = 1, la = 1; | |
94 | + int max_width = line_max_width; | |
95 | + int bx = 0, by = 0; | |
96 | + bool no_linefeed = lua_toboolean(L, 11); | |
97 | + | |
98 | + setTexture(f->atlas_tex, LUA_NOREF); | |
99 | + | |
100 | + // Update VO size once, we are allocating a few more than neede in case of utf8 or control sequences, but we dont care | |
101 | + vertices.reserve(len * 4); | |
102 | + | |
103 | + int font_h = TTF_FontHeight(f->font); | |
104 | + int id_dduid = 1; | |
105 | + int nb_lines = 1; | |
106 | + int id_real_line = 1; | |
107 | + char *line_data = NULL; | |
108 | + int line_data_size = 0; | |
109 | + char *start = (char*)str, *stop = (char*)str, *next = (char*)str; | |
110 | + int max_size = 0; | |
111 | + int size = 0; | |
112 | + bool is_separator = false; | |
113 | + int i; | |
114 | + bool force_nl = false; | |
115 | + font_style style = FONT_STYLE_NORMAL; | |
116 | + while (true) | |
117 | + { | |
118 | + if ((*next == '\n') || (*next == ' ') || (*next == '\0') || (*next == '#')) | |
119 | + { | |
120 | + bool inced = false; | |
121 | + if (*next == ' ' && *(next+1)) | |
122 | + { | |
123 | + inced = true; | |
124 | + stop = next; | |
125 | + next++; | |
126 | + } | |
127 | + else stop = next - 1; | |
128 | + | |
129 | + // Make a surface for the word | |
130 | + int len = next - start; | |
131 | + int future_size = getTextChunkSize(start, len, style); | |
132 | + | |
133 | + // If we must do a newline, flush the previous word and the start the new line | |
134 | + if (!no_linefeed && (force_nl || (future_size && max_width && (size + future_size > max_width)))) | |
135 | + { | |
136 | + // Push it & reset the surface | |
137 | + id_dduid = 1; | |
138 | + is_separator = false; | |
139 | +// printf("Ending previous line at size %d\n", size); | |
140 | + if (size > max_size) max_size = size; | |
141 | + size = 0; | |
142 | + nb_lines++; | |
143 | + if (force_nl) | |
144 | + { | |
145 | + id_real_line++; | |
146 | + if (line_data) { line_data = NULL; } | |
147 | + } | |
148 | + force_nl = false; | |
149 | + } | |
150 | + | |
151 | + if (len) | |
152 | + { | |
153 | + // Detect separators | |
154 | + if ((*start == '-') && (*(start+1) == '-') && (*(start+2) == '-') && !(*(start+3))) is_separator = true; | |
155 | + | |
156 | +// printf("Drawing word '%s'\n", start); | |
157 | + size += addCharQuad(start, len, style, bx + size, by + (nb_lines-1) * font_h, r, g, b, a); | |
158 | + } | |
159 | + if (inced) next--; | |
160 | + start = next + 1; | |
161 | + | |
162 | + // Force a linefeed | |
163 | + if (*next == '\n') force_nl = true; | |
164 | + | |
165 | + // Handle special codes | |
166 | + else if (*next == '#') | |
167 | + { | |
168 | + char *codestop = next + 1; | |
169 | + while (*codestop && *codestop != '#') codestop++; | |
170 | + // Font style | |
171 | + if (*(next+1) == '{') { | |
172 | + if (*(next+2) == 'n') style = FONT_STYLE_NORMAL; | |
173 | + else if (*(next+2) == 'b') style = FONT_STYLE_BOLD; | |
174 | + else if (*(next+2) == 'i') style = FONT_STYLE_ITALIC; | |
175 | + else if (*(next+2) == 'u') style = FONT_STYLE_UNDERLINED; | |
176 | + } | |
177 | + // Entity UID | |
178 | + else if ((codestop - (next+1) > 4) && (*(next+1) == 'U') && (*(next+2) == 'I') && (*(next+3) == 'D') && (*(next+4) == ':')) { | |
179 | +// lua_getglobal(L, "__get_uid_entity"); | |
180 | +// char *colon = next + 5; | |
181 | +// while (*colon && *colon != ':') colon++; | |
182 | +// lua_pushlstring(L, next+5, colon - (next+5)); | |
183 | +// lua_call(L, 1, 1); | |
184 | +// if (lua_istable(L, -1)) | |
185 | +// { | |
186 | +// // printf("DirectDrawUID in font:draw %d : %d\n", size, h); | |
187 | +// lua_createtable(L, 0, 4); | |
188 | + | |
189 | +// lua_pushliteral(L, "e"); | |
190 | +// lua_pushvalue(L, -3); | |
191 | +// lua_rawset(L, -3); | |
192 | + | |
193 | +// lua_pushliteral(L, "x"); | |
194 | +// lua_pushnumber(L, size); | |
195 | +// lua_rawset(L, -3); | |
196 | + | |
197 | +// lua_pushliteral(L, "w"); | |
198 | +// lua_pushnumber(L, h); | |
199 | +// lua_rawset(L, -3); | |
200 | + | |
201 | +// lua_rawseti(L, -4, id_dduid++); // __dduids | |
202 | + | |
203 | +// size += h; | |
204 | +// } | |
205 | +// lua_pop(L, 1); | |
206 | + } | |
207 | + // Extra data | |
208 | + else if (*(next+1) == '&') { | |
209 | + line_data = next + 2; | |
210 | + line_data_size = codestop - (next+2); | |
211 | + } | |
212 | + // Color | |
213 | + else { | |
214 | + if ((codestop - (next+1) == 4) && (*(next+1) == 'L') && (*(next+2) == 'A') && (*(next+3) == 'S') && (*(next+4) == 'T')) | |
215 | + { | |
216 | + r = lr; | |
217 | + g = lg; | |
218 | + b = lb; | |
219 | + a = la; | |
220 | + } | |
221 | + | |
222 | + lua_getglobal(L, "colors"); | |
223 | + lua_pushlstring(L, next+1, codestop - (next+1)); | |
224 | + lua_rawget(L, -2); | |
225 | + if (lua_istable(L, -1)) { | |
226 | + lr = r; | |
227 | + lg = g; | |
228 | + lb = b; | |
229 | + la = a; | |
230 | + | |
231 | + lua_pushliteral(L, "r"); | |
232 | + lua_rawget(L, -2); | |
233 | + r = lua_tonumber(L, -1) / 255; | |
234 | + lua_pushliteral(L, "g"); | |
235 | + lua_rawget(L, -3); | |
236 | + g = lua_tonumber(L, -1) / 255; | |
237 | + lua_pushliteral(L, "b"); | |
238 | + lua_rawget(L, -4); | |
239 | + b = lua_tonumber(L, -1) / 255; | |
240 | + lua_pop(L, 3); | |
241 | + a = 1; | |
242 | + } | |
243 | + // Hexacolor | |
244 | + else if (codestop - (next+1) == 6) | |
245 | + { | |
246 | + lr = r; | |
247 | + lg = g; | |
248 | + lb = b; | |
249 | + la = a; | |
250 | + | |
251 | + int rh = 0, gh = 0, bh = 0; | |
252 | + | |
253 | + if ((*(next+1) >= '0') && (*(next+1) <= '9')) rh += 16 * (*(next+1) - '0'); | |
254 | + else if ((*(next+1) >= 'a') && (*(next+1) <= 'f')) rh += 16 * (10 + *(next+1) - 'a'); | |
255 | + else if ((*(next+1) >= 'A') && (*(next+1) <= 'F')) rh += 16 * (10 + *(next+1) - 'A'); | |
256 | + if ((*(next+2) >= '0') && (*(next+2) <= '9')) rh += (*(next+2) - '0'); | |
257 | + else if ((*(next+2) >= 'a') && (*(next+2) <= 'f')) rh += (10 + *(next+2) - 'a'); | |
258 | + else if ((*(next+2) >= 'A') && (*(next+2) <= 'F')) rh += (10 + *(next+2) - 'A'); | |
259 | + | |
260 | + if ((*(next+3) >= '0') && (*(next+3) <= '9')) gh += 16 * (*(next+3) - '0'); | |
261 | + else if ((*(next+3) >= 'a') && (*(next+3) <= 'f')) gh += 16 * (10 + *(next+3) - 'a'); | |
262 | + else if ((*(next+3) >= 'A') && (*(next+3) <= 'F')) gh += 16 * (10 + *(next+3) - 'A'); | |
263 | + if ((*(next+4) >= '0') && (*(next+4) <= '9')) gh += (*(next+4) - '0'); | |
264 | + else if ((*(next+4) >= 'a') && (*(next+4) <= 'f')) gh += (10 + *(next+4) - 'a'); | |
265 | + else if ((*(next+4) >= 'A') && (*(next+4) <= 'F')) gh += (10 + *(next+4) - 'A'); | |
266 | + | |
267 | + if ((*(next+5) >= '0') && (*(next+5) <= '9')) bh += 16 * (*(next+5) - '0'); | |
268 | + else if ((*(next+5) >= 'a') && (*(next+5) <= 'f')) bh += 16 * (10 + *(next+5) - 'a'); | |
269 | + else if ((*(next+5) >= 'A') && (*(next+5) <= 'F')) bh += 16 * (10 + *(next+5) - 'A'); | |
270 | + if ((*(next+6) >= '0') && (*(next+6) <= '9')) bh += (*(next+6) - '0'); | |
271 | + else if ((*(next+6) >= 'a') && (*(next+6) <= 'f')) bh += (10 + *(next+6) - 'a'); | |
272 | + else if ((*(next+6) >= 'A') && (*(next+6) <= 'F')) bh += (10 + *(next+6) - 'A'); | |
273 | + | |
274 | + r = (float)rh / 255; | |
275 | + g = (float)gh / 255; | |
276 | + b = (float)bh / 255; | |
277 | + a = 1; | |
278 | + } | |
279 | + lua_pop(L, 2); | |
280 | + } | |
281 | + | |
282 | + char old = *codestop; | |
283 | + *codestop = '\0'; | |
284 | +// printf("Found code: %s\n", next+1); | |
285 | + *codestop = old; | |
286 | + | |
287 | + start = codestop + 1; | |
288 | + next = codestop; // The while will increment it, so we dont so it here | |
289 | + } | |
290 | + } | |
291 | + if (*next == '\0') break; | |
292 | + next++; | |
293 | + } | |
294 | + | |
295 | + id_dduid = 1; | |
296 | + if (size > max_size) max_size = size; | |
297 | + | |
298 | + this->nb_lines = nb_lines; | |
299 | + this->w = max_size; | |
300 | + this->h = nb_lines * font_h; | |
301 | +} | |
302 | + | |
303 | +void DOText::setText(const char *text) { | |
304 | + free((void*)this->text); | |
305 | + this->text = strdup(text); | |
306 | + parseText(); | |
307 | +} | ... | ... |
src/displayobjects/TextObject.hpp
0 → 100644
1 | +/* | |
2 | + TE4 - T-Engine 4 | |
3 | + Copyright (C) 2009 - 2015 Nicolas Casalini | |
4 | + | |
5 | + This program is free software: you can redistribute it and/or modify | |
6 | + it under the terms of the GNU General Public License as published by | |
7 | + the Free Software Foundation, either version 3 of the License, or | |
8 | + (at your option) any later version. | |
9 | + | |
10 | + This program is distributed in the hope that it will be useful, | |
11 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | + GNU General Public License for more details. | |
14 | + | |
15 | + You should have received a copy of the GNU General Public License | |
16 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
17 | + | |
18 | + Nicolas Casalini "DarkGod" | |
19 | + darkgod@te4.org | |
20 | +*/ | |
21 | +#ifndef TEXTOBJECTS_H | |
22 | +#define TEXTOBJECTS_H | |
23 | + | |
24 | +#include "displayobjects/DisplayObject.hpp" | |
25 | +extern "C" { | |
26 | +#include "font.h" | |
27 | +#include "utf8proc/utf8proc.h" | |
28 | +} | |
29 | + | |
30 | +class DOText : public DOVertexes{ | |
31 | +private: | |
32 | + int font_lua_ref = LUA_NOREF; | |
33 | + font_type *font = NULL; | |
34 | + | |
35 | + char *text; | |
36 | + int line_max_width = 99999; | |
37 | + bool no_linefeed = false; | |
38 | + int nb_lines = 1; | |
39 | + int w = 0; | |
40 | + int h = 0; | |
41 | + | |
42 | +public: | |
43 | + | |
44 | + DOText() { | |
45 | + text = strdup(""); | |
46 | + }; | |
47 | + virtual ~DOText() { | |
48 | + free((void*)text); | |
49 | + if (font_lua_ref != LUA_NOREF && L) luaL_unref(L, LUA_REGISTRYINDEX, font_lua_ref); | |
50 | + }; | |
51 | + | |
52 | + void setFont(font_type *font, int lua_ref) { | |
53 | + if (font_lua_ref != LUA_NOREF && L) luaL_unref(L, LUA_REGISTRYINDEX, font_lua_ref); | |
54 | + this->font = font; | |
55 | + font_lua_ref = lua_ref; | |
56 | + }; | |
57 | + | |
58 | + void setNoLinefeed(bool no_linefeed) { this->no_linefeed = no_linefeed; parseText(); }; | |
59 | + void setMaxWidth(int width) { this->line_max_width = width; parseText(); }; | |
60 | + | |
61 | + void setText(const char *text); | |
62 | + | |
63 | +private: | |
64 | + void parseText(); | |
65 | + int getTextChunkSize(const char *str, size_t len, font_style style); | |
66 | + int addCharQuad(const char *str, size_t len, font_style style, int bx, int by, float r, float g, float b, float a); | |
67 | +}; | |
68 | + | |
69 | +#endif | ... | ... |
... | ... | @@ -55,7 +55,7 @@ static int set_default_atlas_chars(lua_State *L) { |
55 | 55 | |
56 | 56 | static int sdl_free_font(lua_State *L) |
57 | 57 | { |
58 | - lua_font *f = (lua_font*)auxiliar_checkclass(L, "sdl{font}", 1); | |
58 | + font_type *f = (font_type*)auxiliar_checkclass(L, "sdl{font}", 1); | |
59 | 59 | if (f->font) TTF_CloseFont(f->font); |
60 | 60 | if (f->atlas) { |
61 | 61 | SDL_FreeSurface(f->atlas); |
... | ... | @@ -73,7 +73,7 @@ static int sdl_new_font(lua_State *L) |
73 | 73 | const char *name = luaL_checkstring(L, 1); |
74 | 74 | int size = luaL_checknumber(L, 2); |
75 | 75 | |
76 | - lua_font *f = (lua_font*)lua_newuserdata(L, sizeof(lua_font)); | |
76 | + font_type *f = (font_type*)lua_newuserdata(L, sizeof(font_type)); | |
77 | 77 | auxiliar_setclass(L, "sdl{font}", -1); |
78 | 78 | |
79 | 79 | SDL_RWops *src = PHYSFSRWOPS_openRead(name); |
... | ... | @@ -95,7 +95,7 @@ static int sdl_new_font(lua_State *L) |
95 | 95 | return 1; |
96 | 96 | } |
97 | 97 | |
98 | -bool font_add_atlas(lua_font *f, int32_t c, font_style style) { | |
98 | +bool font_add_atlas(font_type *f, int32_t c, font_style style) { | |
99 | 99 | if (c < 1 || c >= MAX_ATLAS_DATA) return FALSE; |
100 | 100 | |
101 | 101 | SDL_Color color = {255, 255, 255}; |
... | ... | @@ -126,7 +126,15 @@ bool font_add_atlas(lua_font *f, int32_t c, font_style style) { |
126 | 126 | } |
127 | 127 | } |
128 | 128 | |
129 | -void font_make_atlas(lua_font *f, int w, int h) { | |
129 | +void font_update_atlas(font_type *f) { | |
130 | + if (f->atlas_changed) { | |
131 | + tfglBindTexture(GL_TEXTURE_2D, f->atlas_tex); | |
132 | + copy_surface_to_texture(f->atlas); | |
133 | + f->atlas_changed = FALSE; | |
134 | + } | |
135 | +} | |
136 | + | |
137 | +void font_make_atlas(font_type *f, int w, int h) { | |
130 | 138 | if (!w) w = DEFAULT_ATLAS_W; |
131 | 139 | if (!h) h = DEFAULT_ATLAS_H; |
132 | 140 | |
... | ... | @@ -183,14 +191,14 @@ void font_make_atlas(lua_font *f, int w, int h) { |
183 | 191 | |
184 | 192 | static int sdl_font_make_atlas(lua_State *L) |
185 | 193 | { |
186 | - lua_font *f = (lua_font*)auxiliar_checkclass(L, "sdl{font}", 1); | |
194 | + font_type *f = (font_type*)auxiliar_checkclass(L, "sdl{font}", 1); | |
187 | 195 | if (!f->atlas) font_make_atlas(f, lua_tonumber(L, 2), lua_tonumber(L, 3)); |
188 | 196 | return 0; |
189 | 197 | } |
190 | 198 | |
191 | 199 | static int sdl_font_get_atlas_size(lua_State *L) |
192 | 200 | { |
193 | - lua_font *f = (lua_font*)auxiliar_checkclass(L, "sdl{font}", 1); | |
201 | + font_type *f = (font_type*)auxiliar_checkclass(L, "sdl{font}", 1); | |
194 | 202 | if (!f->atlas) font_make_atlas(f, 0, 0); |
195 | 203 | lua_pushnumber(L, f->atlas_w); |
196 | 204 | lua_pushnumber(L, f->atlas_h); |
... | ... | @@ -199,7 +207,7 @@ static int sdl_font_get_atlas_size(lua_State *L) |
199 | 207 | |
200 | 208 | // static int sdl_font_atlas_debug(lua_State *L) |
201 | 209 | // { |
202 | -// lua_font *f = (lua_font*)auxiliar_checkclass(L, "sdl{font}", 1); | |
210 | +// font_type *f = (font_type*)auxiliar_checkclass(L, "sdl{font}", 1); | |
203 | 211 | // if (!f->atlas) font_make_atlas(f, 0, 0); |
204 | 212 | // int x = luaL_checknumber(L, 2); |
205 | 213 | // int y = luaL_checknumber(L, 3); |
... | ... | @@ -221,7 +229,7 @@ static int sdl_font_get_atlas_size(lua_State *L) |
221 | 229 | |
222 | 230 | static int sdl_font_size(lua_State *L) |
223 | 231 | { |
224 | - lua_font *f = (lua_font*)auxiliar_checkclass(L, "sdl{font}", 1); | |
232 | + font_type *f = (font_type*)auxiliar_checkclass(L, "sdl{font}", 1); | |
225 | 233 | const char *str = luaL_checkstring(L, 2); |
226 | 234 | int w, h; |
227 | 235 | |
... | ... | @@ -236,21 +244,21 @@ static int sdl_font_size(lua_State *L) |
236 | 244 | |
237 | 245 | static int sdl_font_height(lua_State *L) |
238 | 246 | { |
239 | - lua_font *f = (lua_font*)auxiliar_checkclass(L, "sdl{font}", 1); | |
247 | + font_type *f = (font_type*)auxiliar_checkclass(L, "sdl{font}", 1); | |
240 | 248 | lua_pushnumber(L, TTF_FontHeight(f->font)); |
241 | 249 | return 1; |
242 | 250 | } |
243 | 251 | |
244 | 252 | static int sdl_font_lineskip(lua_State *L) |
245 | 253 | { |
246 | - lua_font *f = (lua_font*)auxiliar_checkclass(L, "sdl{font}", 1); | |
254 | + font_type *f = (font_type*)auxiliar_checkclass(L, "sdl{font}", 1); | |
247 | 255 | lua_pushnumber(L, TTF_FontLineSkip(f->font)); |
248 | 256 | return 1; |
249 | 257 | } |
250 | 258 | |
251 | 259 | static int sdl_font_style_get(lua_State *L) |
252 | 260 | { |
253 | - lua_font *f = (lua_font*)auxiliar_checkclass(L, "sdl{font}", 1); | |
261 | + font_type *f = (font_type*)auxiliar_checkclass(L, "sdl{font}", 1); | |
254 | 262 | int style = TTF_GetFontStyle(f->font); |
255 | 263 | |
256 | 264 | if (style & TTF_STYLE_BOLD) lua_pushliteral(L, "bold"); |
... | ... | @@ -263,7 +271,7 @@ static int sdl_font_style_get(lua_State *L) |
263 | 271 | |
264 | 272 | static int sdl_font_style(lua_State *L) |
265 | 273 | { |
266 | - lua_font *f = (lua_font*)auxiliar_checkclass(L, "sdl{font}", 1); | |
274 | + font_type *f = (font_type*)auxiliar_checkclass(L, "sdl{font}", 1); | |
267 | 275 | const char *style = luaL_checkstring(L, 2); |
268 | 276 | |
269 | 277 | if (!strcmp(style, "normal")) TTF_SetFontStyle(f->font, 0); |
... | ... | @@ -276,7 +284,7 @@ static int sdl_font_style(lua_State *L) |
276 | 284 | int sdl_surface_drawstring(lua_State *L) |
277 | 285 | { |
278 | 286 | SDL_Surface **s = (SDL_Surface**)auxiliar_checkclass(L, "sdl{surface}", 1); |
279 | - lua_font *f = (lua_font*)auxiliar_checkclass(L, "sdl{font}", 2); | |
287 | + font_type *f = (font_type*)auxiliar_checkclass(L, "sdl{font}", 2); | |
280 | 288 | const char *str = luaL_checkstring(L, 3); |
281 | 289 | int x = luaL_checknumber(L, 4); |
282 | 290 | int y = luaL_checknumber(L, 5); |
... | ... | @@ -301,7 +309,7 @@ int sdl_surface_drawstring_aa(lua_State *L) |
301 | 309 | { |
302 | 310 | if (no_text_aa) return sdl_surface_drawstring(L); |
303 | 311 | SDL_Surface **s = (SDL_Surface**)auxiliar_checkclass(L, "sdl{surface}", 1); |
304 | - lua_font *f = (lua_font*)auxiliar_checkclass(L, "sdl{font}", 2); | |
312 | + font_type *f = (font_type*)auxiliar_checkclass(L, "sdl{font}", 2); | |
305 | 313 | const char *str = luaL_checkstring(L, 3); |
306 | 314 | int x = luaL_checknumber(L, 4); |
307 | 315 | int y = luaL_checknumber(L, 5); |
... | ... | @@ -324,7 +332,7 @@ int sdl_surface_drawstring_aa(lua_State *L) |
324 | 332 | |
325 | 333 | static int sdl_surface_drawstring_newsurface(lua_State *L) |
326 | 334 | { |
327 | - lua_font *f = (lua_font*)auxiliar_checkclass(L, "sdl{font}", 1); | |
335 | + font_type *f = (font_type*)auxiliar_checkclass(L, "sdl{font}", 1); | |
328 | 336 | const char *str = luaL_checkstring(L, 2); |
329 | 337 | int r = luaL_checknumber(L, 3); |
330 | 338 | int g = luaL_checknumber(L, 4); |
... | ... | @@ -349,7 +357,7 @@ static int sdl_surface_drawstring_newsurface(lua_State *L) |
349 | 357 | static int sdl_surface_drawstring_newsurface_aa(lua_State *L) |
350 | 358 | { |
351 | 359 | if (no_text_aa) return sdl_surface_drawstring_newsurface(L); |
352 | - lua_font *f = (lua_font*)auxiliar_checkclass(L, "sdl{font}", 1); | |
360 | + font_type *f = (font_type*)auxiliar_checkclass(L, "sdl{font}", 1); | |
353 | 361 | const char *str = luaL_checkstring(L, 2); |
354 | 362 | int r = luaL_checknumber(L, 3); |
355 | 363 | int g = luaL_checknumber(L, 4); |
... | ... | @@ -374,7 +382,7 @@ static int sdl_new_tile(lua_State *L) |
374 | 382 | { |
375 | 383 | int w = luaL_checknumber(L, 1); |
376 | 384 | int h = luaL_checknumber(L, 2); |
377 | - lua_font *f = (lua_font*)auxiliar_checkclass(L, "sdl{font}", 3); | |
385 | + font_type *f = (font_type*)auxiliar_checkclass(L, "sdl{font}", 3); | |
378 | 386 | const char *str = luaL_checkstring(L, 4); |
379 | 387 | int x = luaL_checknumber(L, 5); |
380 | 388 | int y = luaL_checknumber(L, 6); |
... | ... | @@ -494,7 +502,7 @@ static void font_make_texture_line(lua_State *L, SDL_Surface *s, int id, bool is |
494 | 502 | |
495 | 503 | static int sdl_font_draw(lua_State *L) |
496 | 504 | { |
497 | - lua_font *f = (lua_font*)auxiliar_checkclass(L, "sdl{font}", 1); | |
505 | + font_type *f = (font_type*)auxiliar_checkclass(L, "sdl{font}", 1); | |
498 | 506 | const char *str = luaL_checkstring(L, 2); |
499 | 507 | int max_width = luaL_checknumber(L, 3); |
500 | 508 | int r = luaL_checknumber(L, 4); | ... | ... |
... | ... | @@ -57,8 +57,13 @@ typedef struct |
57 | 57 | int atlas_x, atlas_y; |
58 | 58 | font_atlas_data *atlas_data; |
59 | 59 | bool atlas_changed; |
60 | -} lua_font; | |
60 | +} font_type; | |
61 | 61 | |
62 | 62 | extern int luaopen_font(lua_State *L); |
63 | 63 | |
64 | +extern bool font_add_atlas(font_type *f, int32_t c, font_style style); | |
65 | +extern void font_update_atlas(font_type *f); | |
66 | +extern void font_make_atlas(font_type *f, int w, int h); | |
67 | + | |
68 | + | |
64 | 69 | #endif | ... | ... |
... | ... | @@ -133,6 +133,26 @@ void DORVertexes::render(DORContainer *container, mat4 cur_model) { |
133 | 133 | resetChanged(); |
134 | 134 | } |
135 | 135 | |
136 | +void DORText::render(DORContainer *container, mat4 cur_model) { | |
137 | + cur_model *= model; | |
138 | + auto dl = getDisplayList(container, tex, shader); | |
139 | + | |
140 | + // Make sure we do not have to reallocate each step | |
141 | + int nb = vertices.size(); | |
142 | + int startat = dl->list.size(); | |
143 | + dl->list.reserve(startat + nb); | |
144 | + | |
145 | + // Copy & apply the model matrix | |
146 | + // DG: is it better to first copy it all and then alter it ? most likely not, change me | |
147 | + dl->list.insert(std::end(dl->list), std::begin(this->vertices), std::end(this->vertices)); | |
148 | + vertex *dest = dl->list.data(); | |
149 | + for (int di = startat; di < startat + nb; di++) { | |
150 | + dest[di].pos = cur_model * dest[di].pos; | |
151 | + } | |
152 | + | |
153 | + resetChanged(); | |
154 | +} | |
155 | + | |
136 | 156 | void DORContainer::render(DORContainer *container, mat4 cur_model) { |
137 | 157 | cur_model *= model; |
138 | 158 | for (auto it = dos.begin() ; it != dos.end(); ++it) { | ... | ... |
... | ... | @@ -70,6 +70,16 @@ public: |
70 | 70 | }; |
71 | 71 | |
72 | 72 | /**************************************************************************** |
73 | + ** GL DO for text | |
74 | + ****************************************************************************/ | |
75 | +class DORText : public DOText, public DisplayObjectGL { | |
76 | +public: | |
77 | + DORText() : DOText(), DisplayObjectGL() {}; | |
78 | + virtual ~DORText() {}; | |
79 | + virtual void render(DORContainer *container, mat4 cur_model); | |
80 | +}; | |
81 | + | |
82 | +/**************************************************************************** | |
73 | 83 | ** GL DO Container, the base of the rendering pyramid |
74 | 84 | ****************************************************************************/ |
75 | 85 | class DORContainer : public DOContainer, public DisplayObjectGL { |
... | ... | @@ -99,7 +109,7 @@ private: |
99 | 109 | public: |
100 | 110 | RendererGL(); |
101 | 111 | RendererGL(int w, int h); |
102 | - ~RendererGL(); | |
112 | + virtual ~RendererGL(); | |
103 | 113 | |
104 | 114 | virtual void update(); |
105 | 115 | virtual void toScreen(float x, float y, float r, float g, float b, float a); | ... | ... |
... | ... | @@ -218,6 +218,71 @@ static int gl_vertexes_scale(lua_State *L) |
218 | 218 | } |
219 | 219 | |
220 | 220 | /****************************************************************** |
221 | + ** Text | |
222 | + ******************************************************************/ | |
223 | +static int gl_text_new(lua_State *L) | |
224 | +{ | |
225 | + DORText **v = (DORText**)lua_newuserdata(L, sizeof(DORText*)); | |
226 | + auxiliar_setclass(L, "gl{text}", -1); | |
227 | + *v = new DORText(); | |
228 | + (*v)->setLuaState(L); | |
229 | + | |
230 | + font_type *f = (font_type*)auxiliar_checkclass(L, "sdl{font}", 1); | |
231 | + if (lua_isnumber(L, 2)) (*v)->setMaxWidth(lua_tonumber(L, 2)); | |
232 | + (*v)->setNoLinefeed(lua_toboolean(L, 3)); | |
233 | + | |
234 | + lua_pushvalue(L, 1); | |
235 | + (*v)->setFont(f, luaL_ref(L, LUA_REGISTRYINDEX)); | |
236 | + | |
237 | + return 1; | |
238 | +} | |
239 | + | |
240 | +static int gl_text_free(lua_State *L) | |
241 | +{ | |
242 | + DORText **v = (DORText**)auxiliar_checkclass(L, "gl{text}", 1); | |
243 | + delete(*v); | |
244 | + lua_pushnumber(L, 1); | |
245 | + return 1; | |
246 | +} | |
247 | + | |
248 | +static int gl_text_set(lua_State *L) | |
249 | +{ | |
250 | + DORText **v = (DORText**)auxiliar_checkclass(L, "gl{text}", 1); | |
251 | + (*v)->setText(lua_tostring(L, 2)); | |
252 | + | |
253 | + return 0; | |
254 | +} | |
255 | + | |
256 | +static int gl_text_shader(lua_State *L) | |
257 | +{ | |
258 | + DORText **v = (DORText**)auxiliar_checkclass(L, "gl{text}", 1); | |
259 | + shader_type *shader = (shader_type*)lua_touserdata(L, 2); | |
260 | + (*v)->setShader(shader); | |
261 | + return 0; | |
262 | +} | |
263 | + | |
264 | +static int gl_text_translate(lua_State *L) | |
265 | +{ | |
266 | + DORText **v = (DORText**)auxiliar_checkclass(L, "gl{text}", 1); | |
267 | + (*v)->translate(lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4), lua_toboolean(L, 5)); | |
268 | + return 0; | |
269 | +} | |
270 | + | |
271 | +static int gl_text_rotate(lua_State *L) | |
272 | +{ | |
273 | + DORText **v = (DORText**)auxiliar_checkclass(L, "gl{text}", 1); | |
274 | + (*v)->rotate(lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4), lua_toboolean(L, 5)); | |
275 | + return 0; | |
276 | +} | |
277 | + | |
278 | +static int gl_text_scale(lua_State *L) | |
279 | +{ | |
280 | + DORText **c = (DORText**)auxiliar_checkclass(L, "gl{text}", 1); | |
281 | + (*c)->scale(lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4), lua_toboolean(L, 5)); | |
282 | + return 0; | |
283 | +} | |
284 | + | |
285 | +/****************************************************************** | |
221 | 286 | ** Lua declarations |
222 | 287 | ******************************************************************/ |
223 | 288 | |
... | ... | @@ -253,9 +318,21 @@ static const struct luaL_Reg gl_vertexes_reg[] = |
253 | 318 | {NULL, NULL}, |
254 | 319 | }; |
255 | 320 | |
321 | +static const struct luaL_Reg gl_text_reg[] = | |
322 | +{ | |
323 | + {"__gc", gl_text_free}, | |
324 | + {"text", gl_text_set}, | |
325 | + {"shader", gl_text_shader}, | |
326 | + {"translate", gl_text_translate}, | |
327 | + {"rotate", gl_text_rotate}, | |
328 | + {"scale", gl_text_scale}, | |
329 | + {NULL, NULL}, | |
330 | +}; | |
331 | + | |
256 | 332 | const luaL_Reg rendererlib[] = { |
257 | 333 | {"renderer", gl_renderer_new}, |
258 | 334 | {"vertexes", gl_vertexes_new}, |
335 | + {"text", gl_text_new}, | |
259 | 336 | {"container", gl_container_new}, |
260 | 337 | {NULL, NULL} |
261 | 338 | }; |
... | ... | @@ -264,6 +341,7 @@ int luaopen_renderer(lua_State *L) |
264 | 341 | { |
265 | 342 | auxiliar_newclass(L, "gl{renderer}", gl_renderer_reg); |
266 | 343 | auxiliar_newclass(L, "gl{vertexes}", gl_vertexes_reg); |
344 | + auxiliar_newclass(L, "gl{text}", gl_text_reg); | |
267 | 345 | auxiliar_newclass(L, "gl{container}", gl_container_reg); |
268 | 346 | luaL_openlib(L, "core.renderer", rendererlib, 0); |
269 | 347 | return 1; | ... | ... |
-
Please register or login to post a comment