My goal is to draw all my visuals to a framebuffer which has a size that matches 1 by 1 with my pixel art assets. And then output the framebuffer texture to the current screen size. (A common solution for scaling pixel art).
The problem I am having while trying to achieve this is 2-fold
- The frameBuffer texture is drawn too small. I expect the texture to match the whole window.
- resizing the screen further distorts the proportions and position. I expect the frameBuffer texture to keep filling the screen after resizing it.
This is my trimmed down code.
public class BattleScreen extends GameScreen {
public static final int VISIBLE_WIDTH = 21;
public static final int VISIBLE_HEIGHT = 21;
private static OrthographicCamera mapCamera = null;
private SpriteBatch spriteBatch;
private OrthographicCamera hudCamera;
private Hud hud;
private EntityStage entityStage;
private FrameBuffer fbo;
private void initializeVariables(UnitOwner enemy, MapManager mapMgr) {
mapCamera = new OrthographicCamera();
mapCamera.setToOrtho(false, VISIBLE_WIDTH, VISIBLE_HEIGHT);
fbo = new FrameBuffer(Pixmap.Format.RGBA8888, 672, 672, false);
spriteBatch = new SpriteBatch(900);
entityStage = new EntityStage();
hudCamera = new OrthographicCamera();
hudCamera.setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
}
@Override
public void show() {
resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
mapCamera.position.set(currentMap.getMapWidth() * 0.5f, currentMap.getMapHeight() * 0.5f, 0f);
mapRenderer = new OrthogonalTiledMapRenderer(mapMgr.getCurrentTiledMap(), Map.UNIT_SCALE, spriteBatch);
mapRenderer.setView(mapCamera);
final FitViewport vp = new FitViewport(VISIBLE_WIDTH, VISIBLE_HEIGHT, mapCamera);
currentMap.getTiledMapStage().setViewport(vp);
entityStage.setViewport(vp);
}
private void update(final float delta) {
mapCamera.position.x = Utility.clamp(mapCamera.position.x, currentMap.getTilemapWidthInTiles() - (mapCamera.viewportWidth * 0.5f), 0 + (mapCamera.viewportWidth * 0.5f));
mapCamera.position.y = Utility.clamp(mapCamera.position.y, currentMap.getTilemapHeightInTiles() - (mapCamera.viewportHeight * 0.5f), 0 + (mapCamera.viewportHeight * 0.5f));
mapCamera.update();
hudCamera.update();
}
private void renderElements(final float delta) {
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
fbo.begin();
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderMap();
renderUnits();
renderHUD(delta);
fbo.end();
spriteBatch.begin();
Texture texture = fbo.getColorBufferTexture();
TextureRegion textureRegion = new TextureRegion(texture);
textureRegion.flip(false, true);
spriteBatch.draw(textureRegion, 0, 0, fbo.getWidth(), fbo.getHeight());
spriteBatch.end();
}
private void renderMap() {
spriteBatch.setProjectionMatrix(mapCamera.combined);
mapRenderer.setView(mapCamera);
currentMap.getTiledMapStage().getViewport().apply();
mapRenderer.render();
}
private void renderUnits() {
spriteBatch.begin();
entityStage.getViewport().apply();
for (Entity unit : units) {
final Color temp = spriteBatch.getColor();
spriteBatch.setColor(new Color(temp.r, temp.g, temp.b, unit.getEntityactor().getColor().a));
spriteBatch.draw(getFrame(), getEntityactor().getX(), unit.getEntityactor().getY(), 1.0f, 1.0f);
spriteBatch.setColor(temp);
}
}
private void renderHUD(final float delta) {
spriteBatch.setProjectionMatrix(hud.getStage().getCamera().combined);
hud.getStage().getViewport().apply();
hud.render(delta);
}
@Override
public void resize(final int width, final int height) {
currentMap.getTiledMapStage().getViewport().update(width, height, false);
entityStage.getViewport().update(width, height, false);
hud.resize(width, height);
pauseMenu.resize(width, height);
}
}
What I tried is changing the width and height on this line in the render method
spriteBatch.draw(textureRegion, 0, 0, 1000, 1000);
And then it does fill up the whole screen nicely
Which is weird because the screen is 672 x 672 in size.


