Java libgdx 1.20版本纹理bug

时间:2014-07-23 11:18:09

标签: libgdx textures

在我的游戏中,我一直试图修复有关fickering和distored纹理的bug。我在互联网上搜索,我尝试了一些像使用scene2d的解决方案,但它没有工作。我该怎么办?

此屏幕截图显示了问题:当角色移动时,一只眼睛有时比另一只眼睛大:

Screenshot

修改

当我使用sprite.setPosition((int)sprite.getX(),(int)sprite.getY())时,我仍然遇到问题widthdistored eye;每次我渲染我的角色之前。

当我从答案中使用自定义视口时,我在游戏窗口中看不到我做错了什么?

package com.mygdx.redHoodie;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.utils.viewport.StretchViewport;

public class GameScreen implements Screen {
    public static final int GAME_WIDTH = 800;
    public static final int GAME_HEIGHT= 480 ;

    SpriteBatch batch;
    Background background;
    public Hoodie hoodie;

    public PixelMultipleViewport viewport;
       OrthographicCamera camera;
    public int gameMode; // 0 normalna gra, 1 level up, 2 end game

    public GameScreen(){
         camera= new OrthographicCamera(GAME_WIDTH,GAME_HEIGHT);


         viewport = new PixelMultipleViewport(GAME_WIDTH, GAME_HEIGHT, camera);
         viewport.update();
         camera.setToOrtho(false, GAME_WIDTH, GAME_HEIGHT);
        batch = new SpriteBatch();

        //klasy wyswietlane
        background= new Background(this);
        hoodie = new Hoodie(this);

        startNewGame();
    }

    @Override
    public void render(float delta) {
        // TODO Auto-generated method stu

         Gdx.gl.glClearColor(1, 1, 0, 1);

         Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
         batch.setProjectionMatrix(camera.projection);
            batch.setTransformMatrix(camera.view);

         camera.update();
         //batch.setProjectionMatrix(camera.combined);
         this.update(delta);
         this.batch.begin();
            toRender(delta);
         this.batch.end();



    }

    public void update(float delta){
        hoodie.update(delta);
    }

    public void toRender(float delta){
        background.render();
        hoodie.render();

    }

    public void startNewGame(){

    }
    public void startNevLevel(){

    }

    @Override
    public void resize(int width, int height) {
        // TODO Auto-generated method stub
        viewport.update(width, height,false);
    }

    @Override
    public void show() {
        // TODO Auto-generated method stub

    }

    @Override
    public void hide() {
        // TODO Auto-generated method stub

    }

    @Override
    public void pause() {
        // TODO Auto-generated method stub

    }

    @Override
    public void resume() {
        // TODO Auto-generated method stub

    }

    @Override
    public void dispose() {
        // TODO Auto-generated method stub

    }

}

3 个答案:

答案 0 :(得分:2)

加载纹理时,请使用线性过滤和mip-mapping。默认过滤器是最近/最近,这将导致您看到的问题。

Texture myTexture = new Texture("textureFilename", true); //must enable mip-mapping in constructor
myTexture.setFilter(TextureFilter.MipMapLinearNearest, TextureFilter.Linear);

修改

我现在意识到,你看截图,你在一个更大的窗口中做像素化图形。为了做到这一点,是的,您需要保留最近/最近的过滤,而不是我建议的过滤。

为避免某些像素的大小不同,您必须将角色移动和相机移动四舍五入到最近的世界单位。当你的角色位于像素之间时,精灵像素的大小会有所不同,因为它们不会与屏幕像素对齐。

你的世界已缩放,因此一个单位等于你的一个大像素。因此,无论何时绘制任何东西,都需要先将其位置四舍五入到x和y中最接近的整数,以及相机位置。所以移动相机或精灵后,你必须做这样的事情:

sprite.position.set((int)sprite.position.x,(int)sprite.position.y,sprite.position.z);

就你的视口而言,如果你不想要任何黑条,你可能需要一个自定义的视口类,试图尽可能地匹配你想要的分辨率,然后向外扩展以避免失真。 ExtendViewport做了类似的事情,但与像素化图形的不同之处在于,您需要将世界分辨率设置为屏幕分辨率的整数倍,这样像素的边缘看起来就像是清晰而不是模糊。

我认为这会做你想要的。它采用您所需的屏幕分辨率并将其缩小到适合屏幕像素中每个像素大小为整数的位置。然后它将视图扩展到所需的分辨率以避免失真和黑条。这个类假设所有屏幕尺寸总是4的倍数。我认为是真的。如果你想获得花哨,你可以使用OpenGL剪裁将视口大小向下舍入到最接近的4的倍数,这是安全的。最多你会有2个像素的黑条,我认为这不会引人注意。

public class PixelMultipleViewport extends Viewport {

    private int minWorldWidth, minWorldHeight;

    public PixelMultipleViewport (int minWorldWidth, int minWorldHeight, Camera camera) {
        this.minWorldHeight = minWorldHeight;
        this.minWorldWidth = minWorldWidth;
        this.camera = camera;
    }

    @Override
    public void update (int screenWidth, int screenHeight, boolean centerCamera) {

        viewportWidth = screenWidth;
        viewportHeight = screenHeight;

        int maxHorizontalMultiple = screenWidth / minWorldWidth;
        int maxVerticalMultiple = screenHeight / minWorldHeight;

        int pixelSize = Math.min(maxHorizontalMultiple, maxVerticalMultiple);

        worldWidth = (float)screenWidth/(float)pixelSize;
        worldHeight = (float)screenHeight/(float)pixelSize;

        super.update(screenWidth, screenHeight, centerCamera);
    }
}

答案 1 :(得分:0)

这是我遇到的另一种选择。这是一种以任何分辨率在没有黑条的情况下以您喜欢的比例绘制场景的方法。

视觉质量会比我的其他答案(您以所需场景比例的整数倍绘制)略差,但明显优于使用截图中的直接最近过滤。

基本思想是以所需的比例将所有内容绘制到一个小的FrameBuffer,然后使用一个升级着色器(与线性过滤不同)将FrameBuffer的颜色纹理绘制到屏幕上。精灵像素的边缘。

解释is here。我没有把它移植到Libgdx或测试它。而且我不确定这个着色器在移动设备上的效果如何。它涉及每个屏幕片段运行四个相关的纹理查找。

答案 2 :(得分:0)

我知道这个话题很老,但是由于我的搜索将我带到了这里,将来可能会有更多的人关注。我曾遇到相同的像素撕裂问题,但仅在我的iOS 9 iPhone 4S上。在我的Android 9 Pixel 2上,它的渲染效果很好。尝试了许多操作(尤其是四舍五入为全像素),但即使使用了未缩放的全屏正交摄影机,也会受到伪影的影响。

强制将我的纹理设为POT(2的幂)可解决此问题!