如何绘制像素化形状(LIBGDX 概念)
How to draw pixelized shapes (LIBGDX conceptional)
我想画出像素化风格的形状。
我的圈子目前使用 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);
}
}
好吧,无聊了。给你。
备注:
绿色框只是为了显示帧缓冲区纹理被绘制到哪里,只需在 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();
}
}
我想画出像素化风格的形状。 我的圈子目前使用 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);
}
}
好吧,无聊了。给你。
备注:
绿色框只是为了显示帧缓冲区纹理被绘制到哪里,只需在 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();
}
}