Was ich eigentlich versuche zu erreichen: Ich möchte Text mit einer vertikalen Farbverlaufsfarbe zeichnen. Ich habe diese Lösung gefunden, aber sie passt nicht ganz zu mir, da sie in meinem Fall ein schwarzes Quadrat um die Verlaufsschrift hat - ich weiß nicht, wie ich sie loswerden soll, also habe ich eine einfache Frage (den irrelevanten Teil) gestellt Verstehe die Physik von Blending und Frame Buffer in opengl und libgdx besser
Was ich zu verstehen versuchte, ist für mein Ziel irrelevant: Ich habe eine Textur mit einem weißen Quadrat darauf, ich zeichne sie auf einen roten Hintergrund. Ich versuche, ein grünes Quadrat über das weiße zu zeichnen, das grüne Quadrat bedeckt teilweise das weiße und teilweise den roten Hintergrund (siehe Bild unten).
Meine Absicht ist: Der weiße Bereich, der sich hinter dem grünen Quadrat befindet, sollte in grüner Farbe gestrichen werden, aber der gesamte rote Hintergrund sollte nicht beeinträchtigt werden und unverändert bleiben (rot wie er ist).
Wie kann ich das machen?
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();
}
}
Idealerweise sollte das grüne Quadrat sowieso nicht transparent sein, sondern nur Weiß blockieren, wo es den weißen Bereich verbirgt.
Update : Ich markiere die Antwort von @Xoppa als richtig, da sie meine ursprüngliche Frage mit folgendem Ergebnis löst:
Antworten:
Sie könnten tatsächlich eine Art Maske verwenden, um sie mit einem Quadrat zu mischen. Dazu können Sie den Text zunächst mit einem benutzerdefinierten Shader in den Schablonenpuffer rendern, der Fragmente mit einem Alpha-Wert unterhalb eines bestimmten Schwellenwerts verwirft. Danach können Sie das Quadrat mit der Schablonenfunktion rendern, um nur die vom Text "berührten" Fragmente zu beeinflussen. Beachten Sie, dass dies jedoch mehrere Renderaufrufe umfasst und daher auch Ihren Aufrufcode komplexer macht.
Sie sagen jedoch, dass Sie eigentlich nur Text mit Farbverlauf rendern möchten. Dafür benötigen Sie keinen so komplexen Ansatz und können den Verlauf einfach innerhalb desselben Renderaufrufs anwenden.
Wenn Sie Text zeichnen, rendern Sie tatsächlich viele kleine Quadrate, für jedes Zeichen im Text ein Quadrat. Auf jedes dieser Quadrate wird eine Texturregion angewendet, die das Zeichen auf einem transparenten Hintergrund enthält. Wenn Sie das Schriftbild öffnen (z. B. dies ist die Standardeinstellung ), wird dieses Quellbild angezeigt .
So wie Sie einem normalen Quadrat einen Farbverlauf zuweisen können, können Sie auch jedem einzelnen Quadrat, aus dem der Text besteht, einen Farbverlauf zuweisen. Dafür gibt es mehrere Möglichkeiten. Welche am besten passt, hängt vom Anwendungsfall ab. Wenn Sie beispielsweise einen horizontalen Farbverlauf oder mehrzeiligen Text benötigen, benötigen Sie einige zusätzliche Schritte. Da Sie dies nicht angegeben haben, gehe ich davon aus, dass Sie einen vertikalen Farbverlauf auf eine einzelne Textzeile anwenden möchten:
Übrigens, um bessere Antworten zu erhalten, sollten Sie das eigentliche Problem angeben, das Sie lösen möchten, anstatt sich auf das zu konzentrieren, was Sie für die Lösung halten. Siehe auch: https://stackoverflow.com/help/asking .
quelle
applyGradient
. Ich nehme an, hier haben Sie den Farbverlauf eingestellt (Sie haben Recht, ich wollte vertikal), aber ich bin mir nicht ganz sicher, wie es in Bezug auf die magische Zahl funktioniertindex +=20
(z. B. ist dieser Wert schriftspezifisch oder warum ist er 20?). und KonstantenSpriteBatch.CX
(sind sie die Textur-Ecken?). Ist es Opengl Standard Vertices Färbung?drawGradient
Konstruktor der inneren Klasse verschiebe, damit es nicht bei jedem Rendering-Schritt aufgerufen wird (der Konstruktor würde irgendwo in dercreate()
Methode als solche bezeichnet) unddrawGradient
nur incache.draw(batch)
undreturn layout
Zeilen belassen?Sie können das Mischen vortäuschen, indem Sie ein bisschen rechnen. Hier ist, was ich mir ausgedacht habe:
Und die Ergebnisse sind:
Und mit:
quelle