I want to render a BitmapFont within a libgdx ModelBatch. I've only found samples with "SpriteBatch". Of course I can move the SpriteBatch around in 3D space, but it is either rendered before or after the "ModelBatched" objects. But I'd like to have it rendered in the correct z position.
E.g.
Render modelInstanceA (z=20)
Render Font (z=30)
Render modelInstanceB (z=40)
Then modelInstanceB should cover Render Font should cover modelInstanceB.
In other words I'd like to render a font within a ModelBatch context.
modelBatch.begin(camera);
modelBatch.render(modelInstanceA);
modelBatch.render(font);
modelBatch.render(modelInstanceB);
modelBatch.end();
Is there a built in way to achieve this?
If the models are opaque, you could draw your text with SpriteBatch after the modelBatch.end() call, but you'd need to call Gdx.gl.glEnable(GL20.GL_DEPTH_TEST); before spriteBatch.begin(). Then disable it after spriteBatch.end() to clean up (libgdx classes by default expect it to be off).
Related
Is there a way to let the player save a high-resolution image of the game, while still maintaining all effects? For example, I have glow filters set to 2px. When I use the regular drawBitmap, everything is pixellated and the filters don't look great. So I've started enlarging the movieclip to double the size, then creating a bitmap that's twice the size and saving that. But the problem is that the filter effects get scaled down. For example, if the image went from 400 to 800 px tall, the 2px filter effect now looks half the size and warps everything.
I know this must be possible because, for example, using a fullscreen function does this already... it enlarges everything to a beautiful high resolution, while maintaining all effects relative to each other. How can I capture this effect in an image-saving capacity? (currently using jpegencoder)
Sounds like you have some aliasing so you'll need a re-sampling (blend) function to fix those jagged edges.
A good one is : Lanczos Resampler by Jozef Chúťka.
The important part from that demo code is the LanczosBitmapDataResizer class code about halfway scrolling down the page.
import flash.display.BitmapData;
import flash.utils.Dictionary;
class LanczosBitmapDataResizer
{ ...etc etc...
and it's accessed by updating a BitmapData
new_smooth_BMD = LanczosBitmapDataResizer.resize( old_pixelated_BMD, 227, 227 );
I've some problem for render Box2D Debug with Box2DDebugRenderer.
I've 2 OrthographicCamera, one for render the world (named Cam) and one for the HUD (healthBar, Armor, ...) (named hudCam).
I've tried to render :
b2dr.render(world, cam.combined); -> I can't see the Box2D
b2dr.render(world, cam.projection);
b2dr.render(world, hudCam.combined);
b2dr.render(world, hudCam.projection);
b2dr.render(world, new OrthographicCamera().combined); and b2dr.render(world, new OrthographicCamera().projection)
I can't find a way to render the Box2D exactly like cam, to see the edge of all bodies.
If somebody understand my problem, please help me !
Thx.
Unfortunately some tutorial out there suggest to use a meter-to-pixel-conversion when using Box2D. This is not neccessary (at least with Libgdx), as this conversion can be done by using a camera.
The problem in your case is, that you are using a meter-to-pixel-conversion when rendering the Sprites, while the Box2DDebugRenderer renders everything 1:1.
To solve this problem you have to get rid of the meter-to-pixel conversion and use the camera or the viewport to "scale" the things.
THis way, the Box2DDebugRenderer and your SpriteBatch can (and should) use the same camera to render.
For the camera/viewport:
The constructor has the params width and height. Those params are often set as Gdx.graphics.getWidth() and Gdx.graphics.getHeight(), which in my optinion is not right, the game should be resolution-independent.
You should instead select those values depending on how big your player (or any other visible entity) is in real life and how big it should be on screen.
Let's say you have a little characte, like in your game. It is 1m tall in real live and should take 1/13 of the screen height (more or less like in your first picture, where the screen is about 13 times as high as the character).
So your cameras height should be 13, your characters height (also it's Box2Ds Body height) should be 1m. Next you need to define the width. For that i like to think about my desired aspect ratio. Lets assume the game should focus on 16/9 devices, the width is then (13/9)*16=23.
Now your camera should be created like this:
camera = new OrthographicCamera(23, 13);
I am painting on a Panel by overriding the paintComponent -method.
class Canvas extends Panel ...
...
override def paintComponent(g: Graphics2D) {
super.paintComponent(g)
for (cmd <- commands.get) cmd.execute(g, this)
}
Okay. Inside one of the commands is this one.
case class TestCommand() {
def execute(g: java.awt.Graphics2D, c: Canvas) = {
val img = new BufferedImage(c.width, c.height, BufferedImage.TYPE_INT_RGB)
g.drawImage(img, null, 0, 0)
}
What im trying to do there is create a BufferedImage from the Graphics2D -object, so i can read the value of some pixel at location x, y.
However when this command is executed, i notice that the drawImage -method causes my panel to turn completely black, wiping everything i've drawn on it so far. I want the command to simply create a BufferedImage of what i've drawn on the panel, instead of somehow affecting the Graphics2D -object itself. What am i doing wrong here?
A Graphics2D is connected to some canvas or image. You might think of it like a brush or a pen. In this case, the graphics object you have is tied to your panel. Calling drawImage draws the image on to the panel.
If you want to draw the panel on to the image, you need a Graphics for the BufferedImage:
Graphics2D ig = img.createGraphics();
Then you need to paint the panel to the graphics. java.awt.Component provides a number of convenience methods for this type of thing, for example printAll:
c.printAll(ig);
ig.dispose(); // don't forget to dispose Graphics you've created
(Sorry, I don't really know Scala syntax, if it's different.)
Without being too presumptuous, there may be better ways to approach what you're doing. E.g. if you're doing painting to the panel, as mentioned in the comments, it's usually a good idea to do your painting on an image to begin with, then paint the image to the panel. Then you always have the image.
How can I draw text (font) on top of my static box2d body?
Background: Im able to draw sprites on top of bodies correctly.
I do this by having a box2dSpriteBatch which is projected on box2dCamera like so box2dSpriteBatch.setProjectionMatrix(box2dCamera.combined); And then simply rendering the sprite in the correct spot using getPosition of the body.
But if i try the same way for fonts, unfortunately it scales incredibly large, and if i try to scale the font down it doesn't appear. So im assuming I need to draw the text in window coordinates instead of box2d.
My attempt:
in show():
windowCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
in my Render method i call
windowSpriteBatch.setProjectionMatrix(windowCamera.combined);
also in Render i render the font
whiteFont.setScale(0.7f, 0.7f);
sb.begin();
whiteFont.draw(sb, "2", body.getPosition().x, (questionLineBody.getPosition().y)*PPM);
sb.end();
The solution was to Basically * my x position by PPM.
ie.
Add these lines to the Render method:
windowCamera.position.y = box2dCamera.position.y * PPM;
windowCamera.update();
windowSpriteBatch.setProjectionMatrix(windowCamera.combined);
And Render the font like so:
whiteFont.draw (sb,"2", body.getPosition().x * PPM, body.getPosition().y * PPM);
I have a spritesheet (packed by the wonderful TexturePacker) that looks like so:
and the animation as an animation works well using the current code.
However, when the animation moves to a frame where the bounding box is smaller (e.g. when the legs are closer, when the figure is kneeling, etc.), the image distorts so that the smaller bounding box fills the bounding box of the sprite.
How can I fix this?
The spritesheet above is a frame-extraction from a sample Adobe flash animation.
Easier way:
You can make all the textureregions the same size.
Hard way:
Keep it like this, but you need to save and calculate the size and position of every textureregion to draw.
I personally recommend you the first option, just make all the image the same size.
cant give you a link but here is what i do for these situations
while making the texture packer strip the white space
make a array of AtlasSprite for images
then in my render method
public void render(float delta) {
atlasSprite = animation.getKeyFrame(statetime, Animation.LOOPING);
atlasSprite.draw(batcher)
};
in my update method, which gives exact rectangular bounds of the current image displayed. Since you have stripped the whitespace and used AtlasSprite so bounds will be without blank whitespace.
public void update(float delta) {
bounds = sprite.getBoundingRectangle();
}
P.S. this is just a pseudo code and many syntatical error could be there its just to give you a idea