O que eu realmente tento alcançar: eu gostaria de desenhar texto com uma cor vertical degradê. Encontrei essa solução, mas ela não se encaixa bem, pois possui um quadrado preto em torno da fonte gradiente no meu caso - não sei como me livrar dela, então comecei uma pergunta simples (a parte irrelevante) a entender melhor a física da mistura e do buffer de quadros no opengl e libgdx
O que eu estava tentando entender, irrelevante para o meu objetivo: tenho uma textura com um quadrado branco, desenho em cima de fundo vermelho. Estou tentando desenhar um quadrado verde em cima do branco, o quadrado verde cobre parcialmente o branco e parcialmente em cima do fundo vermelho (veja a figura abaixo).
Minha intenção é: a área branca que fica atrás do quadrado verde deve ser pintada em verde, mas todo o fundo vermelho não deve ser afetado e permanecer inalterado (vermelho como é).
Como posso fazer isso?
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();
}
}
Idealmente, o quadrado verde não deve ser transparente, apenas deve bloquear o branco onde oculta a área branca.
Atualização : Marque a resposta do @Xoppa como correta, pois resolve minha pergunta original com o seguinte resultado:
Respostas:
Você poderia realmente usar algum tipo de máscara para misturá-lo usando um quadrado. Para isso, você pode primeiro renderizar o texto no buffer de estêncil usando um sombreador personalizado que descarta fragmentos com um valor alfa abaixo de um determinado limite. Depois disso, você pode renderizar o quadrado usando a função stencil para afetar apenas os fragmentos "tocados" pelo texto. Observe que isso envolve várias chamadas de renderização e, portanto, adiciona complexidade ao seu código de chamada.
No entanto, você diz que realmente deseja renderizar texto usando gradiente. Para isso, você não precisa de uma abordagem tão complexa e pode simplesmente aplicar o gradiente na mesma chamada de renderização.
Quando você desenha texto, na verdade você renderiza muitos pequenos quadrados, para cada caractere no texto, um quadrado. Cada um desses quadrados possui uma região de texturização aplicada que contém o caractere em um plano de fundo transparente. Se você abrir a imagem da fonte (por exemplo, esse é o padrão ), verá a imagem de origem.
Assim como você pode aplicar um gradiente a um quadrado normal, também pode aplicar um gradiente a cada um dos quadrados individuais que compõem o texto. Existem várias maneiras de fazer isso. Qual a melhor opção depende do caso de uso. Por exemplo, se você precisar de um gradiente horizontal ou possuir texto com várias linhas, precisará de algumas etapas adicionais. Como você não especificou isso, vou assumir que você deseja aplicar um gradiente vertical em uma única linha de texto:
Aliás, para obter melhores respostas, você deve incluir o problema real que está tentando resolver, em vez de se concentrar no que você acha que é a solução. Consulte também: https://stackoverflow.com/help/asking .
fonte
applyGradient
. Suponho que é aí que você define o gradiente (você está certo que eu queria vertical), mas não tenho muita certeza de como isso funciona em relação ao número mágicoindex +=20
(por exemplo, esse valor é específico da fonte ou por que é 20?) e constantesSpriteBatch.CX
(são os cantos da textura?). É a coloração dos vértices padrão do OpenGL?drawGradient
para o construtor de classe interna, para que ele não seja chamado em todas as etapas de renderização (o construtor seria chamado de algum lugar docreate()
método) e deixodrawGradient
apenascache.draw(batch)
ereturn layout
linhas?Você pode falsificar a mistura fazendo algumas contas, eis o que eu vim:
E os resultados são:
E com:
fonte