【问题标题】:How to draw pixelized shapes (LIBGDX conceptional)如何绘制像素化形状(LIBGDX 概念)
【发布时间】:2021-06-11 04:16:56
【问题描述】:

我想以像素化风格绘制形状。 我目前使用 shaperenderer 绘制的圆圈以真实像素呈现。

但我更喜欢像素化。

我尝试使用相机和视口来获得效果,但没有成功。我更喜欢使用 FillViewport。

我们是否需要创建自己的 drawLine 函数并沿着一条线绘制小方块? 或者这可以通过保持纵横比的视口来完成吗?

是否有任何小型示例项目展示了如何创建像素化的简单形状。

我知道我可以自己编码,但我想避免在使用框架时。

在skretch中你可以画一条线,只需要指定像素大小,很简单。

有什么提示吗?

public class SimpleCirleActor extends Actor {
        ShapeRenderer renderer;
        float radius;
        public SimpleCirleActor(int x , int y, float radius) {
            setBounds(0,0, Constants.pixelsPerSector(),Constants.pixelsPerSector());
            this.radius = radius;
            setX(x);setY(y);
            renderer = new ShapeRenderer();
        }

        @Override
        public void draw(Batch batch, float parentAlpha) {
            super.draw(batch, parentAlpha);
            renderer.setProjectionMatrix(getStage().getCamera().combined);
            renderer.begin(ShapeRenderer.ShapeType.Line);
            renderer.setColor(Color.CYAN);
            float x = getX();
            renderer.circle(x, getY(), radius);
            renderer.end();
        }

    @Override
    public void act(float delta) {
        super.act(delta);
    }

}

【问题讨论】:

  • 您可以绘制到一个小的帧缓冲区,然后将其绘制到屏幕上,根据需要放大。只需确保将帧缓冲区纹理过滤设置为最近的像素,以便保持硬边缘。
  • 这是唯一的方法吗?
  • 我试过了,效果很好。但它有一个很大的缺点,我们将只通过一个帧缓冲区到屏幕,这将覆盖之前绘制的所有内容。而且我不知道如何在帧缓冲区中绘制演员。我想必须有一个更简单的解决方案。我的意思是这是一个游戏框架,我希望我们可以防止任何黑客攻击。
  • 你可以用 FrameBuffers 做任何你想做的事,除了 Libgdx 的支持并不像我记得的那样好。当您绘制到帧缓冲区时,您会创建一个纹理。这种纹理可以像任何其他纹理一样使用,即。就像 libgdx 用来将精灵绘制到屏幕上的纹理一样。我可以向您保证,您可以使用帧缓冲区做您想做的事情,但不能保证它不会变得比您想要的更混乱。也许您应该发布到目前为止您对帧缓冲区所做的工作,我可以尝试帮助您将其绘制到屏幕上,而不会过度绘制其他所有内容。
  • 太棒了。谢谢。将准备一个小项目尽快展示。

标签: java libgdx


【解决方案1】:

好吧,无聊了。给你。

注意事项:

绿色框只是为了显示帧缓冲区纹理被绘制到的位置,只需在 fbo.begin() 语句后将填充颜色更改为零 alpha 以使其清晰。

BINDING_DEPTH_FRAMEBUFFER,BINDING_DEFAULT 变量来自我的代码。你可能不需要担心这些,除非你在切换纹理和使用定制着色器方面搞砸了。

绘制fbo,batch.draw(fbo.getColorBufferTexture(), 20, 20, 200, 200, 0, 0, 1, 1);希望这对你来说没问题。如果你想旋转 fbo,你应该能够从你的相机创建一个旋转的投影矩阵。如果您想使用定制着色器,您只需小心将 fbo 作为纹理链接到着色器。

package com.funferret.pixelshapes;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.utils.ScreenUtils;

public class MyGdxGame extends ApplicationAdapter {
    ShapeRenderer shapeBatch;
    SpriteBatch batch;
    Texture img;
    FrameBuffer fbo;
    public OrthographicCamera fboCamera;

    int fboWidth=40;
    int fboHeight=40;
    int BINDING_DEPTH_FRAMEBUFFER=3;
    int BINDING_DEFAULT=0;

    void createFrameBuffer()
    {
        if (fbo!=null)
        {
            fbo.dispose();
        }
        fbo = new FrameBuffer(Pixmap.Format.RGBA8888, fboWidth, fboHeight, false);
        fbo.getColorBufferTexture().setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest);
        fbo.getColorBufferTexture().bind(BINDING_DEPTH_FRAMEBUFFER);
        Gdx.graphics.getGL20().glActiveTexture(GL20.GL_TEXTURE0 + BINDING_DEFAULT); //make sure this is set to 0 for batch draws
        fboCamera=new OrthographicCamera();
        fboCamera.setToOrtho(false, fboWidth, fboHeight);
        fboCamera.update();
    }

    @Override
    public void create () {
        batch = new SpriteBatch();
        shapeBatch=new ShapeRenderer();
        img = new Texture("badlogic.jpg");
    }

    @Override
    public void render ()
    {
    //I had some initialisation problems with the fbo when trying to create a framebuffer. Need to be absolutely certain
        //size is correct and opengl context is set up before creating the framebuffer (as far as I remember). This if statement and the
        //createFrameBuffer function works for me and will allow you to change the size of fboWidth/fboHeight on the fly (though will cause stutters if you do)
        if ((fbo==null) || (fbo.getWidth()!=fboWidth) || (fbo.getHeight()!=fboHeight))
        {
            createFrameBuffer();
        }

        //start drawing to a small framebuffer, that we will then scale up to create a pixelated effect
        fbo.begin();
        ScreenUtils.clear(0, 1, 0, 0.5f);
        shapeBatch.begin(ShapeRenderer.ShapeType.Line);
        shapeBatch.setProjectionMatrix(fboCamera.combined);
        Gdx.gl.glDisable(GL20.GL_BLEND);
        shapeBatch.setColor(1f, 0f, 1f, 1);
        shapeBatch.circle(20,20,15,10);
        shapeBatch.end();
        fbo.end();


        ScreenUtils.clear(1, 0, 0, 1);
        batch.begin();
        batch.draw(img, 0, 0);
        batch.draw(fbo.getColorBufferTexture(), 20, 20, 200, 200, 0, 0, 1, 1);
        batch.end();
    }
    
    @Override
    public void dispose () {
        batch.dispose();
        img.dispose();
        shapeBatch.dispose();
        fbo.dispose();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多