Skip to content

Commit 7c6537a

Browse files
authored
Merge pull request #4907 from ZeanKey/master
[example] Closes #4901, Fix Problems in 'text_draw_3d.c'
2 parents 688a81d + 12bf30c commit 7c6537a

File tree

1 file changed

+53
-111
lines changed

1 file changed

+53
-111
lines changed

examples/text/text_draw_3d.c

+53-111
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,6 @@ typedef struct WaveTextConfig {
6565
static void DrawTextCodepoint3D(Font font, int codepoint, Vector3 position, float fontSize, bool backface, Color tint);
6666
// Draw a 2D text in 3D space
6767
static void DrawText3D(Font font, const char *text, Vector3 position, float fontSize, float fontSpacing, float lineSpacing, bool backface, Color tint);
68-
// Measure a text in 3D. For some reason `MeasureTextEx()` just doesn't seem to work so i had to use this instead.
69-
static Vector3 MeasureText3D(Font font, const char *text, float fontSize, float fontSpacing, float lineSpacing);
7068

7169
// Draw a 2D text in 3D space and wave the parts that start with `~~` and end with `~~`.
7270
// This is a modified version of the original code by @Nighten found here https://github.com/NightenDushi/Raylib_DrawTextStyle
@@ -107,9 +105,9 @@ int main(void)
107105

108106
// Use the default font
109107
Font font = GetFontDefault();
110-
float fontSize = 8.0f;
111-
float fontSpacing = 0.5f;
112-
float lineSpacing = -1.0f;
108+
float fontSize = 0.8f;
109+
float fontSpacing = 0.05f;
110+
float lineSpacing = -0.1f;
113111

114112
// Set the text (using markdown!)
115113
char text[64] = "Hello ~~World~~ in 3D!";
@@ -317,89 +315,89 @@ int main(void)
317315
rlRotatef(180.0f, 0.0f, 1.0f, 0.0f);
318316
char *opt = (char *)TextFormat("< SIZE: %2.1f >", fontSize);
319317
quads += TextLength(opt);
320-
Vector3 m = MeasureText3D(GetFontDefault(), opt, 8.0f, 1.0f, 0.0f);
318+
Vector2 m = MeasureTextEx(GetFontDefault(), opt, 0.8f, 0.1f);
321319
Vector3 pos = { -m.x/2.0f, 0.01f, 2.0f};
322-
DrawText3D(GetFontDefault(), opt, pos, 8.0f, 1.0f, 0.0f, false, BLUE);
323-
pos.z += 0.5f + m.z;
320+
DrawText3D(GetFontDefault(), opt, pos, 0.8f, 0.1f, 0.0f, false, BLUE);
321+
pos.z += 0.5f + m.y;
324322

325323
opt = (char *)TextFormat("< SPACING: %2.1f >", fontSpacing);
326324
quads += TextLength(opt);
327-
m = MeasureText3D(GetFontDefault(), opt, 8.0f, 1.0f, 0.0f);
325+
m = MeasureTextEx(GetFontDefault(), opt, 0.8f, 0.1f);
328326
pos.x = -m.x/2.0f;
329-
DrawText3D(GetFontDefault(), opt, pos, 8.0f, 1.0f, 0.0f, false, BLUE);
330-
pos.z += 0.5f + m.z;
327+
DrawText3D(GetFontDefault(), opt, pos, 0.8f, 0.1f, 0.0f, false, BLUE);
328+
pos.z += 0.5f + m.y;
331329

332330
opt = (char *)TextFormat("< LINE: %2.1f >", lineSpacing);
333331
quads += TextLength(opt);
334-
m = MeasureText3D(GetFontDefault(), opt, 8.0f, 1.0f, 0.0f);
332+
m = MeasureTextEx(GetFontDefault(), opt, 0.8f, 0.1f);
335333
pos.x = -m.x/2.0f;
336-
DrawText3D(GetFontDefault(), opt, pos, 8.0f, 1.0f, 0.0f, false, BLUE);
337-
pos.z += 1.0f + m.z;
334+
DrawText3D(GetFontDefault(), opt, pos, 0.8f, 0.1f, 0.0f, false, BLUE);
335+
pos.z += 0.5f + m.y;
338336

339337
opt = (char *)TextFormat("< LBOX: %3s >", slb? "ON" : "OFF");
340338
quads += TextLength(opt);
341-
m = MeasureText3D(GetFontDefault(), opt, 8.0f, 1.0f, 0.0f);
339+
m = MeasureTextEx(GetFontDefault(), opt, 0.8f, 0.1f);
342340
pos.x = -m.x/2.0f;
343-
DrawText3D(GetFontDefault(), opt, pos, 8.0f, 1.0f, 0.0f, false, RED);
344-
pos.z += 0.5f + m.z;
341+
DrawText3D(GetFontDefault(), opt, pos, 0.8f, 0.1f, 0.0f, false, RED);
342+
pos.z += 0.5f + m.y;
345343

346344
opt = (char *)TextFormat("< TBOX: %3s >", SHOW_TEXT_BOUNDRY? "ON" : "OFF");
347345
quads += TextLength(opt);
348-
m = MeasureText3D(GetFontDefault(), opt, 8.0f, 1.0f, 0.0f);
346+
m = MeasureTextEx(GetFontDefault(), opt, 0.8f, 0.1f);
349347
pos.x = -m.x/2.0f;
350-
DrawText3D(GetFontDefault(), opt, pos, 8.0f, 1.0f, 0.0f, false, RED);
351-
pos.z += 0.5f + m.z;
348+
DrawText3D(GetFontDefault(), opt, pos, 0.8f, 0.1f, 0.0f, false, RED);
349+
pos.z += 0.5f + m.y;
352350

353351
opt = (char *)TextFormat("< LAYER DISTANCE: %.3f >", layerDistance);
354352
quads += TextLength(opt);
355-
m = MeasureText3D(GetFontDefault(), opt, 8.0f, 1.0f, 0.0f);
353+
m = MeasureTextEx(GetFontDefault(), opt, 0.8f, 0.1f);
356354
pos.x = -m.x/2.0f;
357-
DrawText3D(GetFontDefault(), opt, pos, 8.0f, 1.0f, 0.0f, false, DARKPURPLE);
355+
DrawText3D(GetFontDefault(), opt, pos, 0.8f, 0.1f, 0.0f, false, DARKPURPLE);
358356
rlPopMatrix();
359357
//-------------------------------------------------------------------------
360358

361359
// Draw 3D info text (use default font)
362360
//-------------------------------------------------------------------------
363361
opt = "All the text displayed here is in 3D";
364362
quads += 36;
365-
m = MeasureText3D(GetFontDefault(), opt, 10.0f, 0.5f, 0.0f);
363+
m = MeasureTextEx(GetFontDefault(), opt, 1.0f, 0.05f);
366364
pos = (Vector3){-m.x/2.0f, 0.01f, 2.0f};
367-
DrawText3D(GetFontDefault(), opt, pos, 10.0f, 0.5f, 0.0f, false, DARKBLUE);
368-
pos.z += 1.5f + m.z;
365+
DrawText3D(GetFontDefault(), opt, pos, 1.0f, 0.05f, 0.0f, false, DARKBLUE);
366+
pos.z += 1.5f + m.y;
369367

370368
opt = "press [Left]/[Right] to change the font size";
371369
quads += 44;
372-
m = MeasureText3D(GetFontDefault(), opt, 6.0f, 0.5f, 0.0f);
370+
m = MeasureTextEx(GetFontDefault(), opt, 0.6f, 0.05f);
373371
pos.x = -m.x/2.0f;
374-
DrawText3D(GetFontDefault(), opt, pos, 6.0f, 0.5f, 0.0f, false, DARKBLUE);
375-
pos.z += 0.5f + m.z;
372+
DrawText3D(GetFontDefault(), opt, pos, 0.6f, 0.05f, 0.0f, false, DARKBLUE);
373+
pos.z += 0.5f + m.y;
376374

377375
opt = "press [Up]/[Down] to change the font spacing";
378376
quads += 44;
379-
m = MeasureText3D(GetFontDefault(), opt, 6.0f, 0.5f, 0.0f);
377+
m = MeasureTextEx(GetFontDefault(), opt, 0.6f, 0.05f);
380378
pos.x = -m.x/2.0f;
381-
DrawText3D(GetFontDefault(), opt, pos, 6.0f, 0.5f, 0.0f, false, DARKBLUE);
382-
pos.z += 0.5f + m.z;
379+
DrawText3D(GetFontDefault(), opt, pos, 0.6f, 0.05f, 0.0f, false, DARKBLUE);
380+
pos.z += 0.5f + m.y;
383381

384382
opt = "press [PgUp]/[PgDown] to change the line spacing";
385383
quads += 48;
386-
m = MeasureText3D(GetFontDefault(), opt, 6.0f, 0.5f, 0.0f);
384+
m = MeasureTextEx(GetFontDefault(), opt, 0.6f, 0.05f);
387385
pos.x = -m.x/2.0f;
388-
DrawText3D(GetFontDefault(), opt, pos, 6.0f, 0.5f, 0.0f, false, DARKBLUE);
389-
pos.z += 0.5f + m.z;
386+
DrawText3D(GetFontDefault(), opt, pos, 0.6f, 0.05f, 0.0f, false, DARKBLUE);
387+
pos.z += 0.5f + m.y;
390388

391389
opt = "press [F1] to toggle the letter boundry";
392390
quads += 39;
393-
m = MeasureText3D(GetFontDefault(), opt, 6.0f, 0.5f, 0.0f);
391+
m = MeasureTextEx(GetFontDefault(), opt, 0.6f, 0.05f);
394392
pos.x = -m.x/2.0f;
395-
DrawText3D(GetFontDefault(), opt, pos, 6.0f, 0.5f, 0.0f, false, DARKBLUE);
396-
pos.z += 0.5f + m.z;
393+
DrawText3D(GetFontDefault(), opt, pos, 0.6f, 0.05f, 0.0f, false, DARKBLUE);
394+
pos.z += 0.5f + m.y;
397395

398396
opt = "press [F2] to toggle the text boundry";
399397
quads += 37;
400-
m = MeasureText3D(GetFontDefault(), opt, 6.0f, 0.5f, 0.0f);
398+
m = MeasureTextEx(GetFontDefault(), opt, 0.6f, 0.05f);
401399
pos.x = -m.x/2.0f;
402-
DrawText3D(GetFontDefault(), opt, pos, 6.0f, 0.5f, 0.0f, false, DARKBLUE);
400+
DrawText3D(GetFontDefault(), opt, pos, 0.6f, 0.05f, 0.0f, false, DARKBLUE);
403401
//-------------------------------------------------------------------------
404402

405403
SHOW_LETTER_BOUNDRY = slb;
@@ -462,16 +460,16 @@ static void DrawTextCodepoint3D(Font font, int codepoint, Vector3 position, floa
462460

463461
// Character destination rectangle on screen
464462
// NOTE: We consider charsPadding on drawing
465-
position.x += (float)(font.glyphs[index].offsetX - font.glyphPadding)/(float)font.baseSize*scale;
466-
position.z += (float)(font.glyphs[index].offsetY - font.glyphPadding)/(float)font.baseSize*scale;
463+
position.x += (float)(font.glyphs[index].offsetX - font.glyphPadding)*scale;
464+
position.z += (float)(font.glyphs[index].offsetY - font.glyphPadding)*scale;
467465

468466
// Character source rectangle from font texture atlas
469467
// NOTE: We consider chars padding when drawing, it could be required for outline/glow shader effects
470468
Rectangle srcRec = { font.recs[index].x - (float)font.glyphPadding, font.recs[index].y - (float)font.glyphPadding,
471469
font.recs[index].width + 2.0f*font.glyphPadding, font.recs[index].height + 2.0f*font.glyphPadding };
472470

473-
float width = (float)(font.recs[index].width + 2.0f*font.glyphPadding)/(float)font.baseSize*scale;
474-
float height = (float)(font.recs[index].height + 2.0f*font.glyphPadding)/(float)font.baseSize*scale;
471+
float width = (float)(font.recs[index].width + 2.0f*font.glyphPadding)*scale;
472+
float height = (float)(font.recs[index].height + 2.0f*font.glyphPadding)*scale;
475473

476474
if (font.texture.id > 0)
477475
{
@@ -544,7 +542,7 @@ static void DrawText3D(Font font, const char *text, Vector3 position, float font
544542
{
545543
// NOTE: Fixed line spacing of 1.5 line-height
546544
// TODO: Support custom line spacing defined by user
547-
textOffsetY += scale + lineSpacing/(float)font.baseSize*scale;
545+
textOffsetY += fontSize + lineSpacing;
548546
textOffsetX = 0.0f;
549547
}
550548
else
@@ -554,69 +552,14 @@ static void DrawText3D(Font font, const char *text, Vector3 position, float font
554552
DrawTextCodepoint3D(font, codepoint, (Vector3){ position.x + textOffsetX, position.y, position.z + textOffsetY }, fontSize, backface, tint);
555553
}
556554

557-
if (font.glyphs[index].advanceX == 0) textOffsetX += (float)(font.recs[index].width + fontSpacing)/(float)font.baseSize*scale;
558-
else textOffsetX += (float)(font.glyphs[index].advanceX + fontSpacing)/(float)font.baseSize*scale;
555+
if (font.glyphs[index].advanceX == 0) textOffsetX += (float)font.recs[index].width*scale + fontSpacing;
556+
else textOffsetX += (float)font.glyphs[index].advanceX*scale + fontSpacing;
559557
}
560558

561559
i += codepointByteCount; // Move text bytes counter to next codepoint
562560
}
563561
}
564562

565-
// Measure a text in 3D. For some reason `MeasureTextEx()` just doesn't seem to work so i had to use this instead.
566-
static Vector3 MeasureText3D(Font font, const char* text, float fontSize, float fontSpacing, float lineSpacing)
567-
{
568-
int len = TextLength(text);
569-
int tempLen = 0; // Used to count longer text line num chars
570-
int lenCounter = 0;
571-
572-
float tempTextWidth = 0.0f; // Used to count longer text line width
573-
574-
float scale = fontSize/(float)font.baseSize;
575-
float textHeight = scale;
576-
float textWidth = 0.0f;
577-
578-
int letter = 0; // Current character
579-
int index = 0; // Index position in sprite font
580-
581-
for (int i = 0; i < len; i++)
582-
{
583-
lenCounter++;
584-
585-
int next = 0;
586-
letter = GetCodepoint(&text[i], &next);
587-
index = GetGlyphIndex(font, letter);
588-
589-
// NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
590-
// but we need to draw all of the bad bytes using the '?' symbol so to not skip any we set next = 1
591-
if (letter == 0x3f) next = 1;
592-
i += next - 1;
593-
594-
if (letter != '\n')
595-
{
596-
if (font.glyphs[index].advanceX != 0) textWidth += (font.glyphs[index].advanceX+fontSpacing)/(float)font.baseSize*scale;
597-
else textWidth += (font.recs[index].width + font.glyphs[index].offsetX)/(float)font.baseSize*scale;
598-
}
599-
else
600-
{
601-
if (tempTextWidth < textWidth) tempTextWidth = textWidth;
602-
lenCounter = 0;
603-
textWidth = 0.0f;
604-
textHeight += scale + lineSpacing/(float)font.baseSize*scale;
605-
}
606-
607-
if (tempLen < lenCounter) tempLen = lenCounter;
608-
}
609-
610-
if (tempTextWidth < textWidth) tempTextWidth = textWidth;
611-
612-
Vector3 vec = { 0 };
613-
vec.x = tempTextWidth + (float)((tempLen - 1)*fontSpacing/(float)font.baseSize*scale); // Adds chars spacing to measure
614-
vec.y = 0.25f;
615-
vec.z = textHeight;
616-
617-
return vec;
618-
}
619-
620563
// Draw a 2D text in 3D space and wave the parts that start with `~~` and end with `~~`.
621564
// This is a modified version of the original code by @Nighten found here https://github.com/NightenDushi/Raylib_DrawTextStyle
622565
static void DrawTextWave3D(Font font, const char *text, Vector3 position, float fontSize, float fontSpacing, float lineSpacing, bool backface, WaveTextConfig* config, float time, Color tint)
@@ -645,7 +588,7 @@ static void DrawTextWave3D(Font font, const char *text, Vector3 position, float
645588
{
646589
// NOTE: Fixed line spacing of 1.5 line-height
647590
// TODO: Support custom line spacing defined by user
648-
textOffsetY += scale + lineSpacing/(float)font.baseSize*scale;
591+
textOffsetY += fontSize + lineSpacing;
649592
textOffsetX = 0.0f;
650593
k = 0;
651594
}
@@ -672,8 +615,8 @@ static void DrawTextWave3D(Font font, const char *text, Vector3 position, float
672615
DrawTextCodepoint3D(font, codepoint, (Vector3){ pos.x + textOffsetX, pos.y, pos.z + textOffsetY }, fontSize, backface, tint);
673616
}
674617

675-
if (font.glyphs[index].advanceX == 0) textOffsetX += (float)(font.recs[index].width + fontSpacing)/(float)font.baseSize*scale;
676-
else textOffsetX += (float)(font.glyphs[index].advanceX + fontSpacing)/(float)font.baseSize*scale;
618+
if (font.glyphs[index].advanceX == 0) textOffsetX += (float)font.recs[index].width*scale + fontSpacing;
619+
else textOffsetX += (float)font.glyphs[index].advanceX*scale + fontSpacing;
677620
}
678621

679622
i += codepointByteCount; // Move text bytes counter to next codepoint
@@ -698,8 +641,6 @@ static Vector3 MeasureTextWave3D(Font font, const char* text, float fontSize, fl
698641

699642
for (int i = 0; i < len; i++)
700643
{
701-
lenCounter++;
702-
703644
int next = 0;
704645
letter = GetCodepoint(&text[i], &next);
705646
index = GetGlyphIndex(font, letter);
@@ -717,16 +658,17 @@ static Vector3 MeasureTextWave3D(Font font, const char* text, float fontSize, fl
717658
}
718659
else
719660
{
720-
if (font.glyphs[index].advanceX != 0) textWidth += (font.glyphs[index].advanceX+fontSpacing)/(float)font.baseSize*scale;
721-
else textWidth += (font.recs[index].width + font.glyphs[index].offsetX)/(float)font.baseSize*scale;
661+
lenCounter++;
662+
if (font.glyphs[index].advanceX != 0) textWidth += font.glyphs[index].advanceX*scale;
663+
else textWidth += (font.recs[index].width + font.glyphs[index].offsetX)*scale;
722664
}
723665
}
724666
else
725667
{
726668
if (tempTextWidth < textWidth) tempTextWidth = textWidth;
727669
lenCounter = 0;
728670
textWidth = 0.0f;
729-
textHeight += scale + lineSpacing/(float)font.baseSize*scale;
671+
textHeight += fontSize + lineSpacing;
730672
}
731673

732674
if (tempLen < lenCounter) tempLen = lenCounter;
@@ -735,7 +677,7 @@ static Vector3 MeasureTextWave3D(Font font, const char* text, float fontSize, fl
735677
if (tempTextWidth < textWidth) tempTextWidth = textWidth;
736678

737679
Vector3 vec = { 0 };
738-
vec.x = tempTextWidth + (float)((tempLen - 1)*fontSpacing/(float)font.baseSize*scale); // Adds chars spacing to measure
680+
vec.x = tempTextWidth + (float)((tempLen - 1)*fontSpacing); // Adds chars spacing to measure
739681
vec.y = 0.25f;
740682
vec.z = textHeight;
741683

@@ -749,4 +691,4 @@ static Color GenerateRandomColor(float s, float v)
749691
float h = (float)GetRandomValue(0, 360);
750692
h = fmodf((h + h*Phi), 360.0f);
751693
return ColorFromHSV(h, s, v);
752-
}
694+
}

0 commit comments

Comments
 (0)