Lo que realmente intento lograr: me gustaría dibujar texto con un color vertical degradado. Encontré esta solución, pero no me queda del todo, ya que en mi caso tiene un cuadrado negro alrededor de la fuente de degradado; no sé cómo deshacerme de ella, así que comencé una pregunta simple (la parte irrelevante) para Comprender mejor la física de la mezcla y el búfer de trama en opengl y libgdx
Lo que estaba tratando de entender, irrelevante para mi objetivo: tengo una textura con un cuadrado blanco, lo dibujo sobre un fondo rojo. Estoy tratando de dibujar un cuadrado verde sobre el blanco, el cuadrado verde cubre parcialmente el blanco y parcialmente sobre el fondo rojo (vea la imagen a continuación).
Mi intención es: el área blanca, que está detrás del cuadrado verde, debe pintarse en color verde, pero todo el fondo rojo no debe verse afectado y permanecer sin cambios (rojo como está).
¿Cómo puedo hacer esto?
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, el cuadrado verde no debería ser transparente de todos modos, solo debería bloquear el blanco donde oculta el área blanca.
La salida que estoy obteniendo:
Actualización : Marco la respuesta de @Xoppa como correcta, ya que resuelve mi pregunta original con el siguiente resultado:
Respuestas:
De hecho, podría usar algún tipo de máscara para mezclarla usando un cuadrado. Para eso, primero puede representar el texto en el búfer de la plantilla utilizando un sombreador personalizado que descarta los fragmentos con un valor alfa por debajo de un cierto umbral. Después de eso, puede renderizar el cuadrado utilizando la función de plantilla para afectar solo los fragmentos "tocados" por el texto. Tenga en cuenta que esto implica múltiples llamadas de renderizado y, por lo tanto, agrega complejidad a su código de llamada también.
Sin embargo, dices que en realidad solo quieres renderizar texto usando degradado. Para eso no necesita un enfoque tan complejo y simplemente puede aplicar el gradiente dentro de la misma llamada de renderizado.
Cuando dibuja texto, en realidad representa muchos cuadrados pequeños, para cada carácter en el texto un cuadrado. Cada uno de estos cuadrados tiene una región de textura aplicada que contiene el personaje en un fondo transparente. Si abre la imagen de la fuente (por ejemplo, esta es la predeterminada ), verá esta imagen de origen.
Al igual que puede aplicar un degradado a un cuadrado normal, también puede aplicar un degradado a cada uno de esos cuadrados individuales que conforman el texto. Hay múltiples formas de hacerlo. El mejor traje depende del caso de uso. Por ejemplo, si necesita un degradado horizontal o tiene texto de varias líneas, necesita algunos pasos adicionales. Como no especificó esto, voy a suponer que desea aplicar un degradado vertical en una sola línea de texto:
Por cierto, para obtener mejores respuestas, debe incluir el problema real que está tratando de resolver, en lugar de centrarse en lo que cree que es la solución. Ver también: https://stackoverflow.com/help/asking .
fuente
applyGradient
. Supongo que ahí es donde establece el gradiente (tiene razón, quería vertical), pero no estoy muy seguro de cómo funciona en relación con el número mágicoindex +=20
(por ejemplo, ¿es este valor fuente específica o por qué es 20?) y constantesSpriteBatch.CX
(¿son las esquinas de textura?). ¿Es el color estándar de vértices opengl?drawGradient
al constructor de la clase interna, por lo que no se llama en cada paso de representación (el constructor se llamaría unos en algún lugar delcreate()
método) y se dejadrawGradient
solocache.draw(batch)
yreturn layout
líneas?Puedes falsificar la mezcla haciendo algo de matemática. Esto es lo que se me ocurrió:
Y los resultados son:
Y con:
fuente