exe*_*nza 8 opengl blending libgdx
我实际尝试实现的目标: 我想用渐变垂直颜色绘制文本。我找到了这个解决方案,但它不太适合我,因为在我的例子中它的渐变字体周围有黑色方块 - 不知道如何摆脱它,所以我开始了简单的(不相关的部分)问题更好地理解 opengl 和 libgdx 中混合和帧缓冲的物理原理
我试图理解的,与我的目标无关: 我有一个纹理,上面有一个白色方块,我把它画在红色背景上。我试图在白色方块的顶部绘制一个绿色方块,绿色方块部分覆盖白色方块,部分覆盖红色背景(见下图)。
我的意图是:绿色方块后面的白色区域应该涂成绿色,但所有红色背景不应该受到影响并保持不变(红色原样)。
我怎样才能做到这一点?
package com.mygdx.game;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
public class Game extends ApplicationAdapter {
SpriteBatch batch;
Texture img;
private int height;
private int width;
private ShapeRenderer shapeRenderer;
@Override
public void create() {
batch = new SpriteBatch();
img = new Texture("white.png");
width = Gdx.graphics.getWidth();
height = Gdx.graphics.getHeight();
shapeRenderer = new ShapeRenderer();
shapeRenderer.setAutoShapeType(true);
}
@Override
public void render() {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(img, width / 7, height / 4);
batch.end();
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_ONE, GL20.GL_SRC_COLOR);
shapeRenderer.begin();
shapeRenderer.set(ShapeRenderer.ShapeType.Filled);
shapeRenderer.setColor(Color.GREEN);
shapeRenderer.rect(width / 2 - 100, height / 4 - 50, 200, 200);
shapeRenderer.end();
Gdx.gl.glDisable(GL20.GL_BLEND);
}
@Override
public void dispose() {
batch.dispose();
img.dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,绿色方块无论如何都不应该是透明的,而应该在隐藏白色区域的地方挡住白色。
更新:我将@Xoppa 的答案标记为正确,因为它解决了我原来的问题,结果如下:
您确实可以使用某种蒙版来使用正方形混合它。为此,您可以首先使用自定义着色器将文本渲染到模板缓冲区,该着色器会丢弃 alpha 值低于特定阈值的片段。之后,您可以使用模板功能渲染正方形以仅影响文本“触摸”的片段。请注意,这确实涉及多个渲染调用,因此也会增加调用代码的复杂性。
但是,您说您实际上只想使用渐变呈现文本。为此,您不需要这种复杂的方法,只需在同一个渲染调用中应用渐变即可。
当你绘制文本时,你实际上渲染了许多小方块,对于文本中的每个字符一个方块。每个方块都应用了一个纹理区域,其中包含透明背景上的角色。如果您打开字体图像(例如,这是默认设置),那么您将看到此源图像。
就像您可以对普通正方形应用渐变一样,您也可以对构成文本的每个单独正方形应用渐变。有多种方法可以做到这一点。哪种最适合取决于用例。例如,如果您需要水平渐变或多行文本,则需要一些额外的步骤。由于您没有指定这一点,我将假设您想在单行文本上应用垂直渐变:
public class MyGdxGame extends ApplicationAdapter {
public static class GradientFont extends BitmapFont {
public static void applyGradient(float[] vertices, int vertexCount, float color1, float color2, float color3, float color4) {
for (int index = 0; index < vertexCount; index += 20) {
vertices[index + SpriteBatch.C1] = color1;
vertices[index + SpriteBatch.C2] = color2;
vertices[index + SpriteBatch.C3] = color3;
vertices[index + SpriteBatch.C4] = color4;
}
}
public GlyphLayout drawGradient(Batch batch, CharSequence str, float x, float y, Color topColor, Color bottomColor) {
BitmapFontCache cache = getCache();
float tc = topColor.toFloatBits();
float bc = bottomColor.toFloatBits();
cache.clear();
GlyphLayout layout = cache.addText(str, x, y);
for (int page = 0; page < cache.getFont().getRegions().size; page++) {
applyGradient(cache.getVertices(page), cache.getVertexCount(page), bc, tc, tc, bc);
}
cache.draw(batch);
return layout;
}
}
SpriteBatch batch;
GradientFont font;
float topColor;
float bottomColor;
@Override
public void create () {
batch = new SpriteBatch();
font = new GradientFont();
}
@Override
public void render () {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
font.drawGradient(batch, "Hello world", 0, 100, Color.GREEN, Color.BLUE);
batch.end();
}
@Override
public void dispose () {
batch.dispose();
font.dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,为了获得更好的答案,您应该包括您试图解决的实际问题,而不是专注于您认为的解决方案。另请参阅:https : //stackoverflow.com/help/asking。
归档时间: |
|
查看次数: |
347 次 |
最近记录: |