How to draw text in world coordinate space?
I'm creating a game in libGDX. I want to create some UI elements (buttons and stuff), because of my app design, I would like to draw them in the world space, as other game objects.
I'm using Freetype generator that generates a bitmap font from true type font files(.ttf). The problem is that the dimension of the font is in pixels.
Orthographic camera that I use to to render the world, has viewport size of approximately 10x10, so when I generate a font at the size of 10, it covers almost whole screen(too big) and also looks very ugly because generated bitmap for the font is too small (too few pixels).
What I want is to create sprite, draw it at same size(world space) and draw text over it, and basicly create a button.
Is there some well established way how to deal with this?
java fonts libgdx bitmap-fonts
add a comment |
I'm creating a game in libGDX. I want to create some UI elements (buttons and stuff), because of my app design, I would like to draw them in the world space, as other game objects.
I'm using Freetype generator that generates a bitmap font from true type font files(.ttf). The problem is that the dimension of the font is in pixels.
Orthographic camera that I use to to render the world, has viewport size of approximately 10x10, so when I generate a font at the size of 10, it covers almost whole screen(too big) and also looks very ugly because generated bitmap for the font is too small (too few pixels).
What I want is to create sprite, draw it at same size(world space) and draw text over it, and basicly create a button.
Is there some well established way how to deal with this?
java fonts libgdx bitmap-fonts
I've had this exact same problem and I found it much easier to use a separate stage for something like this. There probably is a way to map the coordinates from your game stage to another stage if you choose to go that route. But trust me, trying to draw a font onto a stage with dimensions of something as small as 10x10 does not work out without some hacky solution. In my game, I kept the UI stage and game stage completely separate. However I never had to draw text in world coordinates so I can't help much there.
– retodaredevil
Jan 2 at 3:36
setUseIntegerPositions(false) on the font and set a smaller scale than 1. But it might be cleaner/easier to use a separate camera for your text that uses a ScreenViewport. You'd have to use your game's Viewport to project to screen coordinates and then unproject to the text layer's Viewport to figure out where to draw it. But beware of a LibGDX gotcha: one of those two methods (project/unproject) flips Y coordinates and the other doesn't so you will have to manually flip the Y of your screen coordinates before projecting to the text layer.
– Tenfour04
Jan 2 at 5:24
@Tenfour04 Using separate viewport seems to work. But how to determine correct size? Example: if the desired with of entire text is 100px, string is "HelloWorld", how to calculate the font size that will make rendered text exactly 100px wide?
– Jerry Lundegaard
Jan 2 at 15:29
I don't know of a way to do that exactly. But if approximately 100 px is okay, I would calculate ahead of time average character width for this particular font in units of pixels per font point size. Then simple arithmetic at runtime will give you the point size to use.
– Tenfour04
Jan 2 at 15:54
add a comment |
I'm creating a game in libGDX. I want to create some UI elements (buttons and stuff), because of my app design, I would like to draw them in the world space, as other game objects.
I'm using Freetype generator that generates a bitmap font from true type font files(.ttf). The problem is that the dimension of the font is in pixels.
Orthographic camera that I use to to render the world, has viewport size of approximately 10x10, so when I generate a font at the size of 10, it covers almost whole screen(too big) and also looks very ugly because generated bitmap for the font is too small (too few pixels).
What I want is to create sprite, draw it at same size(world space) and draw text over it, and basicly create a button.
Is there some well established way how to deal with this?
java fonts libgdx bitmap-fonts
I'm creating a game in libGDX. I want to create some UI elements (buttons and stuff), because of my app design, I would like to draw them in the world space, as other game objects.
I'm using Freetype generator that generates a bitmap font from true type font files(.ttf). The problem is that the dimension of the font is in pixels.
Orthographic camera that I use to to render the world, has viewport size of approximately 10x10, so when I generate a font at the size of 10, it covers almost whole screen(too big) and also looks very ugly because generated bitmap for the font is too small (too few pixels).
What I want is to create sprite, draw it at same size(world space) and draw text over it, and basicly create a button.
Is there some well established way how to deal with this?
java fonts libgdx bitmap-fonts
java fonts libgdx bitmap-fonts
asked Jan 1 at 23:11
Jerry LundegaardJerry Lundegaard
286
286
I've had this exact same problem and I found it much easier to use a separate stage for something like this. There probably is a way to map the coordinates from your game stage to another stage if you choose to go that route. But trust me, trying to draw a font onto a stage with dimensions of something as small as 10x10 does not work out without some hacky solution. In my game, I kept the UI stage and game stage completely separate. However I never had to draw text in world coordinates so I can't help much there.
– retodaredevil
Jan 2 at 3:36
setUseIntegerPositions(false) on the font and set a smaller scale than 1. But it might be cleaner/easier to use a separate camera for your text that uses a ScreenViewport. You'd have to use your game's Viewport to project to screen coordinates and then unproject to the text layer's Viewport to figure out where to draw it. But beware of a LibGDX gotcha: one of those two methods (project/unproject) flips Y coordinates and the other doesn't so you will have to manually flip the Y of your screen coordinates before projecting to the text layer.
– Tenfour04
Jan 2 at 5:24
@Tenfour04 Using separate viewport seems to work. But how to determine correct size? Example: if the desired with of entire text is 100px, string is "HelloWorld", how to calculate the font size that will make rendered text exactly 100px wide?
– Jerry Lundegaard
Jan 2 at 15:29
I don't know of a way to do that exactly. But if approximately 100 px is okay, I would calculate ahead of time average character width for this particular font in units of pixels per font point size. Then simple arithmetic at runtime will give you the point size to use.
– Tenfour04
Jan 2 at 15:54
add a comment |
I've had this exact same problem and I found it much easier to use a separate stage for something like this. There probably is a way to map the coordinates from your game stage to another stage if you choose to go that route. But trust me, trying to draw a font onto a stage with dimensions of something as small as 10x10 does not work out without some hacky solution. In my game, I kept the UI stage and game stage completely separate. However I never had to draw text in world coordinates so I can't help much there.
– retodaredevil
Jan 2 at 3:36
setUseIntegerPositions(false) on the font and set a smaller scale than 1. But it might be cleaner/easier to use a separate camera for your text that uses a ScreenViewport. You'd have to use your game's Viewport to project to screen coordinates and then unproject to the text layer's Viewport to figure out where to draw it. But beware of a LibGDX gotcha: one of those two methods (project/unproject) flips Y coordinates and the other doesn't so you will have to manually flip the Y of your screen coordinates before projecting to the text layer.
– Tenfour04
Jan 2 at 5:24
@Tenfour04 Using separate viewport seems to work. But how to determine correct size? Example: if the desired with of entire text is 100px, string is "HelloWorld", how to calculate the font size that will make rendered text exactly 100px wide?
– Jerry Lundegaard
Jan 2 at 15:29
I don't know of a way to do that exactly. But if approximately 100 px is okay, I would calculate ahead of time average character width for this particular font in units of pixels per font point size. Then simple arithmetic at runtime will give you the point size to use.
– Tenfour04
Jan 2 at 15:54
I've had this exact same problem and I found it much easier to use a separate stage for something like this. There probably is a way to map the coordinates from your game stage to another stage if you choose to go that route. But trust me, trying to draw a font onto a stage with dimensions of something as small as 10x10 does not work out without some hacky solution. In my game, I kept the UI stage and game stage completely separate. However I never had to draw text in world coordinates so I can't help much there.
– retodaredevil
Jan 2 at 3:36
I've had this exact same problem and I found it much easier to use a separate stage for something like this. There probably is a way to map the coordinates from your game stage to another stage if you choose to go that route. But trust me, trying to draw a font onto a stage with dimensions of something as small as 10x10 does not work out without some hacky solution. In my game, I kept the UI stage and game stage completely separate. However I never had to draw text in world coordinates so I can't help much there.
– retodaredevil
Jan 2 at 3:36
setUseIntegerPositions(false) on the font and set a smaller scale than 1. But it might be cleaner/easier to use a separate camera for your text that uses a ScreenViewport. You'd have to use your game's Viewport to project to screen coordinates and then unproject to the text layer's Viewport to figure out where to draw it. But beware of a LibGDX gotcha: one of those two methods (project/unproject) flips Y coordinates and the other doesn't so you will have to manually flip the Y of your screen coordinates before projecting to the text layer.
– Tenfour04
Jan 2 at 5:24
setUseIntegerPositions(false) on the font and set a smaller scale than 1. But it might be cleaner/easier to use a separate camera for your text that uses a ScreenViewport. You'd have to use your game's Viewport to project to screen coordinates and then unproject to the text layer's Viewport to figure out where to draw it. But beware of a LibGDX gotcha: one of those two methods (project/unproject) flips Y coordinates and the other doesn't so you will have to manually flip the Y of your screen coordinates before projecting to the text layer.
– Tenfour04
Jan 2 at 5:24
@Tenfour04 Using separate viewport seems to work. But how to determine correct size? Example: if the desired with of entire text is 100px, string is "HelloWorld", how to calculate the font size that will make rendered text exactly 100px wide?
– Jerry Lundegaard
Jan 2 at 15:29
@Tenfour04 Using separate viewport seems to work. But how to determine correct size? Example: if the desired with of entire text is 100px, string is "HelloWorld", how to calculate the font size that will make rendered text exactly 100px wide?
– Jerry Lundegaard
Jan 2 at 15:29
I don't know of a way to do that exactly. But if approximately 100 px is okay, I would calculate ahead of time average character width for this particular font in units of pixels per font point size. Then simple arithmetic at runtime will give you the point size to use.
– Tenfour04
Jan 2 at 15:54
I don't know of a way to do that exactly. But if approximately 100 px is okay, I would calculate ahead of time average character width for this particular font in units of pixels per font point size. Then simple arithmetic at runtime will give you the point size to use.
– Tenfour04
Jan 2 at 15:54
add a comment |
1 Answer
1
active
oldest
votes
Thanks to clarifying comments, I've came up with the solution.
I took a point at which I wanted to draw the text, projected it to the screen space by my world camera. Then I flipped y axis by:
point.y = viewportHeight - point.y;
Then I unprojected it with ScreenViewport (separate viewport for drawing the text, is uses camera of the size of the screen so 1unit == 1pixel).
Now I can draw text in projection where 1unit = 1pixel, on the point that is at the same place on the screen as previously chosen point in world space.
I also wanted to be able to draw text inside rectangular boundaries. For this I chose another point. At this point text should end. Did the same procedure as with start point, and then calculated width
targetWidth = endpoint.x - startpoint.x;
Then I used GlypthLayout class to get actual width of my text at some(generated) font size.
actualWidth = glyphLayout.width;
And when I scaled font like this
font.getData().setScale(targetWidth / actualWidth);
my font get scaled so drawed text is wide as target width.
But be aware of another problem! When I generate bimap font via FreetypeGenerator with size bigger when approximately 300, some letters don't draw, and are missing. (probably bug).
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53999659%2fhow-to-draw-text-in-world-coordinate-space%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks to clarifying comments, I've came up with the solution.
I took a point at which I wanted to draw the text, projected it to the screen space by my world camera. Then I flipped y axis by:
point.y = viewportHeight - point.y;
Then I unprojected it with ScreenViewport (separate viewport for drawing the text, is uses camera of the size of the screen so 1unit == 1pixel).
Now I can draw text in projection where 1unit = 1pixel, on the point that is at the same place on the screen as previously chosen point in world space.
I also wanted to be able to draw text inside rectangular boundaries. For this I chose another point. At this point text should end. Did the same procedure as with start point, and then calculated width
targetWidth = endpoint.x - startpoint.x;
Then I used GlypthLayout class to get actual width of my text at some(generated) font size.
actualWidth = glyphLayout.width;
And when I scaled font like this
font.getData().setScale(targetWidth / actualWidth);
my font get scaled so drawed text is wide as target width.
But be aware of another problem! When I generate bimap font via FreetypeGenerator with size bigger when approximately 300, some letters don't draw, and are missing. (probably bug).
add a comment |
Thanks to clarifying comments, I've came up with the solution.
I took a point at which I wanted to draw the text, projected it to the screen space by my world camera. Then I flipped y axis by:
point.y = viewportHeight - point.y;
Then I unprojected it with ScreenViewport (separate viewport for drawing the text, is uses camera of the size of the screen so 1unit == 1pixel).
Now I can draw text in projection where 1unit = 1pixel, on the point that is at the same place on the screen as previously chosen point in world space.
I also wanted to be able to draw text inside rectangular boundaries. For this I chose another point. At this point text should end. Did the same procedure as with start point, and then calculated width
targetWidth = endpoint.x - startpoint.x;
Then I used GlypthLayout class to get actual width of my text at some(generated) font size.
actualWidth = glyphLayout.width;
And when I scaled font like this
font.getData().setScale(targetWidth / actualWidth);
my font get scaled so drawed text is wide as target width.
But be aware of another problem! When I generate bimap font via FreetypeGenerator with size bigger when approximately 300, some letters don't draw, and are missing. (probably bug).
add a comment |
Thanks to clarifying comments, I've came up with the solution.
I took a point at which I wanted to draw the text, projected it to the screen space by my world camera. Then I flipped y axis by:
point.y = viewportHeight - point.y;
Then I unprojected it with ScreenViewport (separate viewport for drawing the text, is uses camera of the size of the screen so 1unit == 1pixel).
Now I can draw text in projection where 1unit = 1pixel, on the point that is at the same place on the screen as previously chosen point in world space.
I also wanted to be able to draw text inside rectangular boundaries. For this I chose another point. At this point text should end. Did the same procedure as with start point, and then calculated width
targetWidth = endpoint.x - startpoint.x;
Then I used GlypthLayout class to get actual width of my text at some(generated) font size.
actualWidth = glyphLayout.width;
And when I scaled font like this
font.getData().setScale(targetWidth / actualWidth);
my font get scaled so drawed text is wide as target width.
But be aware of another problem! When I generate bimap font via FreetypeGenerator with size bigger when approximately 300, some letters don't draw, and are missing. (probably bug).
Thanks to clarifying comments, I've came up with the solution.
I took a point at which I wanted to draw the text, projected it to the screen space by my world camera. Then I flipped y axis by:
point.y = viewportHeight - point.y;
Then I unprojected it with ScreenViewport (separate viewport for drawing the text, is uses camera of the size of the screen so 1unit == 1pixel).
Now I can draw text in projection where 1unit = 1pixel, on the point that is at the same place on the screen as previously chosen point in world space.
I also wanted to be able to draw text inside rectangular boundaries. For this I chose another point. At this point text should end. Did the same procedure as with start point, and then calculated width
targetWidth = endpoint.x - startpoint.x;
Then I used GlypthLayout class to get actual width of my text at some(generated) font size.
actualWidth = glyphLayout.width;
And when I scaled font like this
font.getData().setScale(targetWidth / actualWidth);
my font get scaled so drawed text is wide as target width.
But be aware of another problem! When I generate bimap font via FreetypeGenerator with size bigger when approximately 300, some letters don't draw, and are missing. (probably bug).
answered Jan 2 at 20:44
Jerry LundegaardJerry Lundegaard
286
286
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53999659%2fhow-to-draw-text-in-world-coordinate-space%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I've had this exact same problem and I found it much easier to use a separate stage for something like this. There probably is a way to map the coordinates from your game stage to another stage if you choose to go that route. But trust me, trying to draw a font onto a stage with dimensions of something as small as 10x10 does not work out without some hacky solution. In my game, I kept the UI stage and game stage completely separate. However I never had to draw text in world coordinates so I can't help much there.
– retodaredevil
Jan 2 at 3:36
setUseIntegerPositions(false) on the font and set a smaller scale than 1. But it might be cleaner/easier to use a separate camera for your text that uses a ScreenViewport. You'd have to use your game's Viewport to project to screen coordinates and then unproject to the text layer's Viewport to figure out where to draw it. But beware of a LibGDX gotcha: one of those two methods (project/unproject) flips Y coordinates and the other doesn't so you will have to manually flip the Y of your screen coordinates before projecting to the text layer.
– Tenfour04
Jan 2 at 5:24
@Tenfour04 Using separate viewport seems to work. But how to determine correct size? Example: if the desired with of entire text is 100px, string is "HelloWorld", how to calculate the font size that will make rendered text exactly 100px wide?
– Jerry Lundegaard
Jan 2 at 15:29
I don't know of a way to do that exactly. But if approximately 100 px is okay, I would calculate ahead of time average character width for this particular font in units of pixels per font point size. Then simple arithmetic at runtime will give you the point size to use.
– Tenfour04
Jan 2 at 15:54