Java libgdx使用pixmap从覆盖创建纹理
我正在尝试创建一个方法,该方法返回使用libgdx和PixMap的覆盖修改的纹理 假设我有两张图片: FileHandle textureInput中的基础图像 以及文件句柄覆盖中的覆盖图像 它应该产生这种纹理: 因此,它应该使用来自textureInput的RGB值和来自叠加的alpha值,并创建最终图像。我相信我可以使用Pixmap类来实现这一点,但我似乎无法找到确切的方法 以下是我收集的方法结构:Java libgdx使用pixmap从覆盖创建纹理,java,libgdx,pixmap,Java,Libgdx,Pixmap,我正在尝试创建一个方法,该方法返回使用libgdx和PixMap的覆盖修改的纹理 假设我有两张图片: FileHandle textureInput中的基础图像 以及文件句柄覆盖中的覆盖图像 它应该产生这种纹理: 因此,它应该使用来自textureInput的RGB值和来自叠加的alpha值,并创建最终图像。我相信我可以使用Pixmap类来实现这一点,但我似乎无法找到确切的方法 以下是我收集的方法结构: public Texture getOverlayTexture(FileHandle
public Texture getOverlayTexture(FileHandle overLay, FileHandle textureInput){
Pixmap inputPix = new Pixmap(textureInput);
Pixmap overlayPix = new Pixmap(overLay);
Pixmap outputPix = new Pixmap(inputPix.getWidth(), inputPix.getHeight(), Format.RGBA8888);
// go over the inputPix and add each byte to the outputPix
// but only where the same byte is not alpha in the overlayPix
Texture outputTexture = new Texture(outputPix, Format.RGBA8888, false);
inputPix.dispose();
outputPix.dispose();
overlayPix.dispose();
return outputTexture;
}
我只是在寻找一点方向,从这里到哪里去。非常感谢您的帮助。如果这个问题太模糊或者我的方法完全不正确,我道歉
谢谢 我终于找到了这样做的方法 我的游戏是如何设置的是,每个项目画自己。他们得到一个雪碧棒,可以用它做一些事情。我这样做是出于各种原因。有一个包含项目列表的项目管理器。每个项目都有不同的属性。每个项目都有自己的渲染方法以及其他独立的方法。以下是最终奏效的方法: 不使用任何alpha遮罩的正常项目的渲染方法:
public void render(SpriteBatch batch, int renderLayer) {
if(renderLayer == Integer.parseInt(render_layer)){ // be in the correct render layer
batch.draw(item.region,
item.position.x, // position.x
item.position.y, // position.y
0, //origin x
0, //origin y
item.region.getRegionWidth() , //w
item.region.getRegionHeight(), //h
item.t_scale, //scale x
item.t_scale, //scale y
item.manager.radiansToDegrees(item.rotation)); //angle
}
}
public void render(SpriteBatch batch, int renderLayer) {
if(renderLayer == Integer.parseInt(render_layer)){
batch.enableBlending();
//draw the alpha mask
drawAlphaMask(batch, item.position.x, item.position.y, item.region.getRegionWidth(), item.region.getRegionHeight());
//draw our foreground elements
drawForeground(batch, item.position.x, item.position.y, item.region.getRegionWidth(), item.region.getRegionHeight());
batch.disableBlending();
}
}
所以它被交给一个spritebatch,它用正确的图像、位置、比例和旋转来绘制,就是这样
在玩过我在这里发现的东西之后:有一段时间,这终于对一个需要使用alpha掩蔽的物品起到了作用:
public void render(SpriteBatch batch, int renderLayer) {
if(renderLayer == Integer.parseInt(render_layer)){ // be in the correct render layer
batch.draw(item.region,
item.position.x, // position.x
item.position.y, // position.y
0, //origin x
0, //origin y
item.region.getRegionWidth() , //w
item.region.getRegionHeight(), //h
item.t_scale, //scale x
item.t_scale, //scale y
item.manager.radiansToDegrees(item.rotation)); //angle
}
}
public void render(SpriteBatch batch, int renderLayer) {
if(renderLayer == Integer.parseInt(render_layer)){
batch.enableBlending();
//draw the alpha mask
drawAlphaMask(batch, item.position.x, item.position.y, item.region.getRegionWidth(), item.region.getRegionHeight());
//draw our foreground elements
drawForeground(batch, item.position.x, item.position.y, item.region.getRegionWidth(), item.region.getRegionHeight());
batch.disableBlending();
}
}
有一个名为alphaMask的纹理区域,其中包含一个黑色形状。
它可以是任何图像,但在本例中,假设它是此形状/图像:
下面是使用该图像的上面调用的函数:
private void drawAlphaMask(SpriteBatch batch, float x, float y, float width, float height) {
//disable RGB color, only enable ALPHA to the frame buffer
Gdx.gl.glColorMask(false, false, false, true);
// Get these values so I can be sure I set them back to how it was
dst = batch.getBlendDstFunc();
src = batch.getBlendSrcFunc();
//change the blending function for our alpha map
batch.setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ZERO);
//draw alpha mask sprite
batch.draw(alphaRegion,
x, // position.x
y, // position.y
0, // origin x
0, // origin y
alphaRegion.getRegionWidth(), // w
alphaRegion.getRegionHeight(), // h
item.t_scale, // scale x
item.t_scale, // scale y
item.manager.radiansToDegrees(item.rotation)); // angle
//flush the batch to the GPU
batch.flush();
}
有多种“材料”适用于任何形状。在任何情况下,都会将其中一个指定给spriteRegion变量。让我们现在就这么说:
因此,上面调用的drawForeground方法使用该图像,如下所示:
private void drawForeground(SpriteBatch batch, float clipX, float clipY, float clipWidth, float clipHeight) {
//now that the buffer has our alpha, we simply draw the sprite with the mask applied
Gdx.gl.glColorMask(true, true, true, true);
batch.setBlendFunction(GL10.GL_DST_ALPHA, GL10.GL_ONE_MINUS_DST_ALPHA);
batch.draw(spriteRegion,
clipX, // corrected center position.x
clipY, // corrected center position.y
0, //origin x
0, //origin y
spriteRegion.getRegionWidth() , //w
spriteRegion.getRegionHeight(), //h
item.t_scale, //scale x
item.t_scale, //scale y
item.manager.radiansToDegrees(item.rotation)); //angle
//remember to flush before changing GL states again
batch.flush();
// set it back to however it was before
batch.setBlendFunction(src, dst);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();
cfg.useGL20 = false;
cfg.r = 8;
cfg.g = 8;
cfg.b = 8;
cfg.a = 8;
initialize(new SuperContraption("android"), cfg);
if (graphics.getView() instanceof SurfaceView) {
SurfaceView glView = (SurfaceView) graphics.getView();
// force alpha channel - I'm not sure we need this as the GL surface
// is already using alpha channel
glView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
}
}
这一切都可以在桌面构建中立即实现,并且可以在游戏中很好地生成“砖梁”(或任何东西):
然而,在Android和GWT构建中(因为毕竟我使用的是libgdx),它没有包含alpha掩码,而是渲染了完整的方块
环顾四周后,我发现:
为了在Android中解决这个问题,我修改了MainActivity.java onCreate方法,如下所示:
private void drawForeground(SpriteBatch batch, float clipX, float clipY, float clipWidth, float clipHeight) {
//now that the buffer has our alpha, we simply draw the sprite with the mask applied
Gdx.gl.glColorMask(true, true, true, true);
batch.setBlendFunction(GL10.GL_DST_ALPHA, GL10.GL_ONE_MINUS_DST_ALPHA);
batch.draw(spriteRegion,
clipX, // corrected center position.x
clipY, // corrected center position.y
0, //origin x
0, //origin y
spriteRegion.getRegionWidth() , //w
spriteRegion.getRegionHeight(), //h
item.t_scale, //scale x
item.t_scale, //scale y
item.manager.radiansToDegrees(item.rotation)); //angle
//remember to flush before changing GL states again
batch.flush();
// set it back to however it was before
batch.setBlendFunction(src, dst);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();
cfg.useGL20 = false;
cfg.r = 8;
cfg.g = 8;
cfg.b = 8;
cfg.a = 8;
initialize(new SuperContraption("android"), cfg);
if (graphics.getView() instanceof SurfaceView) {
SurfaceView glView = (SurfaceView) graphics.getView();
// force alpha channel - I'm not sure we need this as the GL surface
// is already using alpha channel
glView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
}
}
这就为安卓系统解决了这个问题
我仍然不知道如何使它在gwt中正常工作,因为我不知道如何告诉libgdx让gwt让webGl继续并注意alpha通道。我对如何以更简单或更便宜的方式做类似的事情很感兴趣(尽管这似乎很好)
如果有人知道如何使用GWT实现这一点,请作为另一个答案发布
如果您想查看纹理问题,以下是不工作的GWT构建:
您不能使用alpha频道来实现这一点吗?非常感谢,帮了我很多忙!以下是我基于您的代码片段的解决方案。它渲染了一个小地图背景,之后它只在我的小地图纹理中绘制像素:唯一不适合我的是正确的混合,所以我使用了
GL_ONE_减号SRC_ALPHA
而不是GL_ONE_减号DST_ALPHA