I have this approach which works and scales as expected on Windows Desktop:
public class MyGdxGame extends ApplicationAdapter {
SpriteBatch m_batch;
FitViewport m_viewport;
OrthographicCamera m_camera;
private Texture img;
private BitmapFont m_font;
#Override
public void create() {
Gdx.app.setLogLevel(Application.LOG_NONE);
m_batch = new SpriteBatch();
m_camera = new OrthographicCamera();
m_camera.position.set(640 / 2f, 400 / 2f, 0);
m_camera.update();
m_viewport = new FitViewport(640, 400, m_camera);
img = new Texture("badlogic.jpg");
m_font = new BitmapFont();
}
#Override
public void render() {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
m_batch.begin();
m_font.draw(m_batch, "X000000000000000000000000000000000000000000000000000000000000000000000000000000X", 0, m_camera.viewportHeight);
m_batch.draw(img, 0, 0);
m_batch.end();
}
#Override
public void resize(int width, int height) {
m_viewport.update(width, height);
}
}
Initial Window Size:
Bigger Window Size
But if I deploy to Android (in this case Nexus 7 2013) it seems not to scale properly:
Why does it not work? How to solve this?
You forgot to use the camera in your sprite batch. Call
spriteBatch.setProjectionMatrix(viewport.getCamera().combined);
before spriteBatch.begin();.
Related
I'had like to use a FrameBuffer and to set his size in world units instead of pixel.
When I set the FrameBuffer size in pixel, i have the expected result. But when I use another personal units. The result is messed up.
Here a snippet of the working code:
public class FBOTestLibGDX implements ApplicationListener {
public static void main(String[] args) {
LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
cfg.useGL30 = false;
cfg.width = 640;
cfg.height = 480;
cfg.resizable = false;
new LwjglApplication(new FBOTestLibGDX(), cfg);
}
Texture atlas;
FrameBuffer fbo;
TextureRegion fboRegion;
Matrix4 projection = new Matrix4();
SpriteBatch batch;
OrthographicCamera cam;
#Override
public void create() {
atlas = new Texture(Gdx.files.local("src/test/resources/fboData/testTexture.jpg"));
fbo = new FrameBuffer(Format.RGBA8888, atlas.getWidth(), atlas.getHeight(), false);
fboRegion = new TextureRegion(fbo.getColorBufferTexture(), atlas.getWidth(), atlas.getHeight());
fboRegion.flip(false, true); // FBO uses lower left, TextureRegion uses
projection.setToOrtho2D(0, 0, atlas.getWidth(), atlas.getHeight());
batch = new SpriteBatch();
batch.setProjectionMatrix(projection);
cam = new OrthographicCamera(5, 5);
cam.setToOrtho(false);
renderTextureInFBO();
}
protected void renderTextureInFBO() {
fbo.begin();
Gdx.gl.glClearColor(0f, 0f, 0f, 0f);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.setProjectionMatrix(projection);
batch.draw(atlas, 0, 0);
batch.end();
fbo.end();
}
#Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 0f);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(cam.combined);
batch.begin();
batch.draw(fboRegion, 0, 0, 5, 5);
batch.end();
}
#Override
public void resize(int width, int height) {
cam.setToOrtho(false, 5, 5);
//batch.setProjectionMatrix(cam.combined);
}
#Override
public void pause() {}
#Override
public void resume() {}
#Override
public void dispose() {}
}
Using pixel I obtain this result:
But if I use world units for FrameBuffer like this:
public void create() {
...
fbo = new FrameBuffer(Format.RGBA8888, 5, 5, false);
fboRegion = new TextureRegion(fbo.getColorBufferTexture(), 5, 5);
fboRegion.flip(false, true);
projection.setToOrtho2D(0, 0, 5, 5);
...
}
protected void renderTextureInFBO() {
...
batch.draw(atlas, 0, 0,5,5);
...
}
I obtain a low scaled result:
The question is, it is possible to set the FrameBuffer size in world unit as we do for batch and viewport or it is mandatory to set it in pixel?
As specified in the documentation, a FrameBuffer size have to be defined in pixel. cf:
FrameBuffer specification
FrameBuffer
public FrameBuffer(Pixmap.Format format,
int width,
int height,
boolean hasDepth,
boolean hasStencil)
Creates a new FrameBuffer having the given dimensions and potentially a depth and a stencil buffer attached.
Parameters:
format - the format of the color buffer; according to the OpenGL ES 2.0 spec, only RGB565, RGBA4444 and RGB5_A1 are color-renderable
width - the width of the framebuffer in pixels
height - the height of the framebuffer in pixels
hasDepth - whether to attach a depth buffer
Throws
GdxRuntimeException - in case the FrameBuffer could not be created
Can someone just give me a real quick answer on how i would implement a viewport so this sprite would fill the whole screen?
Thanks
Current code (not working):
public SplashScreen(Jump game)
{
this.game = game;
cam = new OrthographicCamera();
cam.setToOrtho(false, 1920, 1080);
sb = new SpriteBatch();
}
public void show()
{
}
public void render(float delta)
{
Gdx.gl20.glClearColor(0.2F, 0.6F, 1F, 1F);
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);
cam.update();
sb.setProjectionMatrix(cam.combined);
sb.begin();
sb.draw(Assets.splash_spr_background, 0, 0);
sb.end();
}
On
#Override
public void resize(int width, int height) {
stage.getViewport().update(Gdx.graphics.getWidth(),
Gdx.graphics.getHeight(), false);
}
as spritebatch does not have a viewport. You have to control this using stage or cam.
you can do that.
I have an image that I want to move to the right. To do this I increase its x position by 200f*Gdx.graphics.getDeltaTime(); every time render is called. I've read other posts where people had similar problems but were they were not multiplying by delta or Gdx.graphics.getDeltaTime(). Because I obviously do this why is my image flickering/vibrating when its moving???
My code:
public class gm extends Game{
OrthographicCamera cam;
SpriteBatch batch;
Texture img;
float x = 0;
#Override
public void create () {
batch = new SpriteBatch();
img = new Texture("badlogic.jpg");
cam = new OrthographicCamera();
cam.setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
}
#Override
public void render () {
super.render();
//x += 200f*Gdx.graphics.getDeltaTime();
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
cam.update();
batch.setProjectionMatrix(cam.combined);
batch.begin();
batch.draw(img, x += 100f*Gdx.graphics.getDeltaTime(), 0);
batch.end();
}
}
apologies in advance for the very newbie question, currently trying to learn libGDX, every tutorial suggests this should work, its correctly displaying the text button in the centre of the screen however it isnt showing the background image title.png.
ive played around with it quite a bit to try and get it to work with no luck, any help you can give me would be greatly appreciated!
public class MainMenu implements Screen {
ZebraGems game;
Stage stage;
BitmapFont font;
BitmapFont blackfont;
TextureAtlas atlas;
Skin skin;
SpriteBatch batch;
TextButton button;
Texture titleTexture;
Sprite titleSprite;
public MainMenu(ZebraGems game){
this.game = game;
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
stage.act(delta);
batch.begin();
titleSprite.draw(batch);
stage.draw();
batch.end();
}
#Override
public void resize(int width, int height) {
if (stage == null);
stage = new Stage (width, height, true);
stage.clear();
titleTexture = new Texture("data/title.png");
titleSprite = new Sprite(titleTexture);
titleSprite.setColor(1,1,1,0);
titleSprite.setSize(480, 800);
titleSprite.setPosition (0, 0);
Gdx.input.setInputProcessor(stage);
TextButtonStyle style = new TextButtonStyle();
style.up = skin.getDrawable("play");
style.down = skin.getDrawable("playpressed");
style.font = blackfont;
button = new TextButton("", style);
button.setWidth(213);
button.setHeight(94);
button.setX(Gdx.graphics.getWidth() /2 - button.getWidth() /2);
button.setY(Gdx.graphics.getHeight() /2 - button.getHeight() /2);
stage.addActor(button);
}
#Override
public void show() {
batch = new SpriteBatch();
atlas = new TextureAtlas("data/playButton.pack");
skin = new Skin();
skin.addRegions(atlas);
blackfont = new BitmapFont(Gdx.files.internal("data/blackfont.fnt"));
}
#Override
public void hide() {
dispose();
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
batch.dispose();
skin.dispose();
atlas.dispose();
stage.dispose();
blackfont.dispose();
}
}
Move stage.draw() out of the batch.begin() and batch.end().
Furthermore in case you are using the latest nighty build of libgdx, you should add stage.getViewport().update(width, height, true) to your resize(...) method.
Furthermore you are doing this titleSprite.setColor(1,1,1,0) which sets the alpha of the background sprite to 0 which means 100% transparent = invisible.
Do this instead: titleSprite.setColor(1,1,1,1).
In total your render should look like this:
batch.begin();
titleSprite.draw(batch);
batch.end();
stage.act(delta);
stage.draw();
I am testing out Libgdx and Scene2d. I expected this small program to display a logo, but it draws a black screen only. Any idea what am I missing?
public class MyGame implements ApplicationListener {
private Stage stage;
#Override
public void create() {
stage = new Stage(800, 800, false);
Gdx.input.setInputProcessor(stage);
MyActor actor = new MyActor();
stage.addActor(actor);
}
#Override
public void render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
#Override
public void dispose() {
stage.dispose();
}
#Override
public void resize(int width, int height) {
stage.setViewport(800, 800, false);
}
}
public class MyActor extends Actor {
Sprite sprite;
public MyActor() {
sprite = new Sprite();
sprite.setTexture(new Texture("data/libgdx.png"));
setWidth(sprite.getWidth());
setHeight(sprite.getHeight());
setBounds(0, 0, getWidth(), getHeight());
setTouchable(Touchable.enabled);
setX(0);
setY(0);
}
#Override
public void draw(SpriteBatch batch, float parentAlpha) {
Color color = getColor();
batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);
batch.draw(sprite, getX(), getY());
}
}
Construct the sprite with the texture and use Gdx.file.internal:
sprite = new Sprite(new Texture(Gdx.files.internal("data/libgdx.png")));
Anyway, if you just want to display and act on images, you might prefer to use Image class:
private Stage stage;
private Texture texture;
#Override
public void create() {
stage = new Stage();
Gdx.input.setInputProcessor(stage);
texture = new Texture(Gdx.files.internal("data/libgdx.png"));
TextureRegion region = new TextureRegion(texture, 0, 0, 512, 275);
com.badlogic.gdx.scenes.scene2d.ui.Image actor = new com.badlogic.gdx.scenes.scene2d.ui.Image(region);
stage.addActor(actor);
}
#Override
public void render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
I was getting a black screen too until I explicitly set Actor's height (setHeight(height)) and width (setWidth(width)) to the Sprite's values.
tex = new Texture(Gdx.files.internal("happy.png"));
Image happy = new Image(tex);
/* happy.setBounds(happy.getX(), happy.getY(), happy.getWidth(), happy.getHeight()); not needed if using full image */
stage.addActor(happy);
Your problem is most likely this line, in the draw method
batch.draw(sprite, getX(), getY());
The code I have seen when drawing sprites is
sprite.draw(batch);