| 303 | } |
| 304 | |
| 305 | void Gui::text_3d(const Matrix4x4 &local_pose, const Vector3 &pos, u32 font_size, const char *str, StringId64 font, StringId64 material, const Color4 &color, f32 depth) |
| 306 | { |
| 307 | const MaterialResource *mr = (MaterialResource *)_resource_manager->get(RESOURCE_TYPE_MATERIAL, material); |
| 308 | _material_manager->create_material(mr); |
| 309 | |
| 310 | const FontResource *fr = (FontResource *)_resource_manager->get(RESOURCE_TYPE_FONT, font); |
| 311 | const f32 scale = (f32)font_size / (f32)fr->font_size; |
| 312 | |
| 313 | VertexData *vd = (VertexData *)_buffer->vertex_buffer_end(); |
| 314 | u16 *id = (u16 *)_buffer->index_buffer_end(); |
| 315 | |
| 316 | u32 num_vertices = 0; |
| 317 | u32 num_indices = 0; |
| 318 | |
| 319 | u32 cp; |
| 320 | u32 state = 0; |
| 321 | f32 pen_x = 0.0f; |
| 322 | f32 pen_y = 0.0f; |
| 323 | const GlyphData deffault_glyph = {}; |
| 324 | |
| 325 | for (const u8 *ch = (u8 *)str; *ch; ++ch) { |
| 326 | if (utf8::decode(&state, &cp, *ch) != UTF8_ACCEPT) |
| 327 | continue; |
| 328 | |
| 329 | if (cp == '\n') { |
| 330 | pen_x = 0.0f; |
| 331 | pen_y -= scale*fr->font_size; |
| 332 | continue; |
| 333 | } else if (cp == '\t') { |
| 334 | pen_x += scale*font_size*4; |
| 335 | continue; |
| 336 | } |
| 337 | |
| 338 | const GlyphData *glyph = font_resource::glyph(fr, cp, &deffault_glyph); |
| 339 | const f32 baseline = glyph->height - glyph->y_offset; |
| 340 | const f32 x_offset = fsign(pen_x) * scale*glyph->x_offset; |
| 341 | |
| 342 | // Glyph position coords. |
| 343 | const f32 x0 = pen_x + pos.x + x_offset; |
| 344 | const f32 y0 = pen_y + pos.y - scale*baseline; |
| 345 | const f32 x1 = x0 + scale*glyph->width; |
| 346 | const f32 y1 = y0 + scale*glyph->height; |
| 347 | |
| 348 | pen_x += scale*glyph->x_advance; |
| 349 | |
| 350 | // Glyph atlas coords. |
| 351 | const f32 u0 = glyph->x / fr->texture_size; |
| 352 | const f32 v1 = glyph->y / fr->texture_size; // Upper-left char corner |
| 353 | const f32 u1 = glyph->width / fr->texture_size + u0; |
| 354 | const f32 v0 = glyph->height / fr->texture_size + v1; // Bottom-left char corner |
| 355 | |
| 356 | const u32 abgr = to_abgr(color); |
| 357 | |
| 358 | // Fill vertex buffer. |
| 359 | vd[0].pos.x = x0; |
| 360 | vd[0].pos.y = y0; |
| 361 | vd[0].pos.z = pos.z; |
| 362 | vd[0].uv.x = u0; |
no test coverage detected