Skip to content

[examples] BaseSize is divided twice in example 'draw 3d' in 'text' #4901

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ZeanKey opened this issue Apr 17, 2025 · 4 comments
Closed

[examples] BaseSize is divided twice in example 'draw 3d' in 'text' #4901

ZeanKey opened this issue Apr 17, 2025 · 4 comments

Comments

@ZeanKey
Copy link
Contributor

ZeanKey commented Apr 17, 2025

I was trying to use code of DrawText3D() and MeasureText3D() in 'draw 3d' example in 'text' part like following and notice that the size of the text is significantly smaller then DrawText(). Also, the X, Z value as return value in MeasureText3D() was different to MeasureTextEx().

This is the native code in example copied from DrawTextCodepoint3D():

int index = GetGlyphIndex(font, codepoint);
float scale = fontSize/(float)font.baseSize;

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

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

float width = (float)(font.recs[index].width + 2.0f*font.glyphPadding)/(float)font.baseSize*scale;
float height = (float)(font.recs[index].height + 2.0f*font.glyphPadding)/(float)font.baseSize*scale;

Notice that value added in position X and Z, it's OringinalSize / BaseSize * ScaleFactor, aka OringinalSize / BaseSize * FontSize / BaseSize since ScaleFactor defined in line two is FontSize / BaseSize, therefore the basesize is not supposed to be divided again I guess.

The result became normal on my test case after removing the second division.

@raysan5
Copy link
Owner

raysan5 commented Apr 18, 2025

@ZeanKey I'm not sure about this change, I did not create the example so I don't know the intention of the original creator but my guess is that font size in pixels is translated into 3d units, so the baseSize must be considered. Default raylib font has a baseSize of 10px, so, it is mapped to 10 units in 3d. Considering the baseSize maps that mapping correct.

Have you tried using another font, for example of 16px, with your change, would it be mapped to 16 units in 3d?

@ZeanKey
Copy link
Contributor Author

ZeanKey commented Apr 18, 2025

I just loaded the same font in two different size like following:

Font fontSimSun16 = LoadFontEx("text/resources/simsun.ttf", 16, NULL, -1);
Font fontSimSun32 = LoadFontEx("text/resources/simsun.ttf", 32, NULL, -1);

and here's the code I used to draw it:

char *opt = (char *)TextFormat("SAMPLE", fontSize);
// Basesize 16, Target size 16
quads += TextLength(opt);
Vector3 m = MeasureText3D(fontSimSun16, opt, 16.0f, 1.0f, 0.0f);
Vector3 pos = { -m.x/2.0f, 0.01f, 2.0f};
DrawText3D(fontSimSun16, opt, pos, 16.0f, 1.0f, 0.0f, false, BLUE);
pos.z += 0.5f + m.z;

// Basesize 32, Target size 32
quads += TextLength(opt);
m = MeasureText3D(fontSimSun32, opt, 32.0f, 1.0f, 0.0f);
pos.x = -m.x/2.0f;
DrawText3D(fontSimSun32, opt, pos, 32.0f, 1.0f, 0.0f, false, BLUE);
pos.z += 0.5f + m.z;

I used the original version of Text3D functions in example in sample and this is the outcome:

Image

It's seenable that both text is resized to about 1px according to the grid behind(2px gap).
I'm not sure if its effect supposed to be.

It seems that the example version cannot show these font in units corresponding to different size. Both are shown in about 1 px size 'cause for the dup div.

@ZeanKey
Copy link
Contributor Author

ZeanKey commented Apr 18, 2025

Here's how it works in my version:

Image

Noted that I used the MeasureTextEx() instead of the version from my PR here since I noticed that I didn't fully fixed the part of textHeight, its still directly returning the value of scale factor. Due to its not completely fixed I've closed that PR.

rlRotatef(180.0f, 0.0f, 1.0f, 0.0f);
char *opt = (char *)TextFormat("SAMPLE", fontSize);
quads += TextLength(opt);
Vector2 m = MeasureTextEx(fontSimSun16, opt, 16.0f, 1.0f);
Vector3 pos = { -m.x/2.0f, 0.01f, 2.0f};
DrawText3D(fontSimSun16, opt, pos, 16.0f, 1.0f, 0.0f, false, BLUE);
pos.z += 0.5f + m.y;

quads += TextLength(opt);
m = MeasureTextEx(fontSimSun32, opt, 32.0f, 1.0f);
pos.x = -m.x/2.0f;
DrawText3D(fontSimSun32, opt, pos, 32.0f, 1.0f, 0.0f, false, BLUE);
pos.z += 0.5f + m.y;

I think this version rightly, at least properly present the size argument user given which the former one cannot due to the dup div.

@ZeanKey
Copy link
Contributor Author

ZeanKey commented Apr 18, 2025

Just also note that I noticed that the space calculation in MeasureText3D() (and its wave version) didn't seem to be right in 3 points:

if (font.glyphs[index].advanceX != 0) textWidth += (font.glyphs[index].advanceX+fontSpacing)/(float)font.baseSize*scale;

this appear in MeasureTextWave3D() line 720, however in line 738 it has:

vec.x = tempTextWidth + (float)((tempLen - 1)*fontSpacing/(float)font.baseSize*scale); // Adds chars spacing to measure

it seems like if font has advanceX not 0 the space would be dupelicated counted, in MeasureTextEx() in core its like:

if (font.glyphs[index].advanceX > 0) textWidth += font.glyphs[index].advanceX;

which didn't count twice so I think example version is not right, since I'm not certain about how advanceX will be defined I didn't write test case.

Secondly, for MeasureTextWave3D() only, consider this line for evaluating the width:

vec.x = tempTextWidth + (float)((tempLen - 1)*fontSpacing/(float)font.baseSize*scale); // Adds chars spacing to measure

The MeasureTextWave3D() use tempLen to calculate the space which take the maximum lenCounter in each line, however, the lenCounter wasn't accumulated through the char to skip the '~~' commend, instead it just take the length of the line. So the spacing for '~~' is also counted which it shouldn't:

Image

which is very clear when space is adjusted to 20.0f.

Thridly, for the same code:

vec.x = tempTextWidth + (float)((tempLen - 1)*fontSpacing/(float)font.baseSize*scale); // Adds chars spacing to measure

I think space is also scaled by scale factor, which it shouldn't according to the MeasureTextEx(), but it perhaps was not a very serious problem:

textSize.x = tempTextWidth*scaleFactor + (float)((tempByteCounter - 1)*spacing);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants