Растягивание текстур при использовании фреймбуфера и СпрайтБэтча

#java #android #libgdx

#java #Android #libgdx

Вопрос:

Я работаю над этим уже 2 дня и до сих пор не могу понять, что происходит. Я работаю над игровым фреймворком, и я перешел с Slick2D на LibGDX и хотел бы один раз отобразить текстуру, чтобы сэкономить циклы CPU / GPU и повысить производительность. Я создал класс с именем DrawSurface , и его основная цель — позволить мне рисовать текстуру вне экрана, а затем просто рисовать ее, используя LibGDXs, встроенный в класс Image.

 public final class DrawSurface {

    public static interface DrawCall{
        void draw(SpriteBatch b, int width, int height);
    }

    public static Texture offscreenDraw(DrawCall c, int canvasWidth, int canvasHeight){
        FrameBuffer fbo = new FrameBuffer(Pixmap.Format.RGBA8888,(canvasWidth),(canvasHeight),true);
        SpriteBatch batch = new SpriteBatch();
                batch.setProjectionMatrix(new Matrix4().setToOrtho2D(0,0,fbo.getWidth(),fbo.getHeight()));
        fbo.begin();
        batch.begin();
        c.draw(batch,fbo.getWidth(),fbo.getHeight());
        batch.end();
        Pixmap map = ScreenUtils.getFrameBufferPixmap(0,0,fbo.getWidth(),fbo.getHeight());
        fbo.end();
        Texture t = new Texture(map);
        map.dispose();
        return t;
    }

}
  

Что дает мне этот результат при рисовании изображений:
Глючный рендеринг

«DrawCall», который используется для получения этого изображения, является:

  Texture t = DrawSurface.offscreenDraw(new DrawSurface.DrawCall() {
            @Override
            public void draw(SpriteBatch b, int w, int h) {
                Image img = new Image(0x0000FF,w,h);
                img.setLocation(0,0);
                img.draw(b);
                for(int i = 0; i < w; i  = 64){
                    for(int j = 0; j < h; j  = 64){
                        Blocks.GRASS_BLOCK.setLocation(i,j);
                        Blocks.GRASS_BLOCK.draw(b);
                    }
                }
            }
        },512,512);
  

Изображение должно отображаться в виде синего квадрата размером 512×512 пикселей с небольшими изображениями блоков «Трава», которые также должны быть квадратными. Размер 16×16. К сожалению, я получаю искаженный результат, и я не понимаю, почему. Поскольку Большая белая вещь (программный джойстик, который я создал) не растягивается, пока «DrawsSurface» есть. Если вы хотите взглянуть на мой код камеры:

         // Constructor Above.
        this.gameWidth = gameWidth;
        this.gameHeight = gameHeight;
        this.camera = new OrthographicCamera();
        FlatPixelGame.gameCamera = this.camera;
        this.viewport = new StretchViewport(gameWidth,gameHeight,camera);
        this.viewport.apply();
        LogBot.log("Game Instance Created Size [%s,%s]",gameWidth,gameHeight);
        InputManager.getInstance().addListener(this);

        this.camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);
  

Буду признателен за любую помощь, я просмотрел форумы, документацию StackOverflow и LibGDX и, похоже, до сих пор не могу решить эту проблему.

Опять же, заранее благодарю вас 🙂

Комментарии:

1. Чтобы отметить, что после некоторой работы это, похоже, проблема с Pixmap классом. Я могу рисовать и масштабировать изображения как обычно, но изображения, созданные из растровых изображений, вызывают деформацию при рисовании в этом буфере.

Ответ №1:

После небольшой работы под капотом с исходным кодом LibGDX от BadLogic, а также чтения потоков ошибок, кажется, возникает проблема при преобразовании a PixMap в текстуру. Рендеринг изображения, полученного из файла, работает нормально, но сгенерированные изображения, полученные из Pixmap файла, могут показывать деформацию из-за того, что порт просмотра вне экрана не совпадает с текущим портом просмотра рендеринга.

Быстрый способ обойти это — использовать TextureRegion s и спрайты.

 public static Image offscreenDraw(DrawCall c, int canvasWidth, int canvasHeight){
        FrameBuffer fbo = new FrameBuffer(Pixmap.Format.RGBA8888,canvasWidth,canvasHeight,true);
        SpriteBatch batch = new SpriteBatch();
        Matrix4 matrix = new Matrix4();
        matrix.setToOrtho2D(0, 0, canvasWidth,canvasHeight);
        batch.setProjectionMatrix(matrix);
        fbo.begin();
        batch.begin();
        c.draw(batch,canvasWidth,canvasHeight);
        batch.end();

        Texture t = fbo.getColorBufferTexture();
        t.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest);
        if(!t.getTextureData().isPrepared()){
            t.getTextureData().prepare();
        }
        fbo.end();

        TextureRegion r = new TextureRegion(t,0,0,canvasWidth,canvasHeight);
        return new Image(new com.badlogic.gdx.scenes.scene2d.ui.Image(new Sprite(r)));
    }