Frage

Ich bin derzeit ein kleines OpenGL-Spiel für die Android-Plattform zu entwickeln, und ich frage mich, ob es ein einfacher Weg, Text auf dem gerenderten Frame zu machen (wie ein HUD mit dem Spieler etc Score). Der Text müßte auch eine eigene Schriftart verwenden.

Ich habe ein Beispiel mit einem Blick als Overlay gesehen, aber ich weiß nicht, ob ich das tun will, da ich später das Spiel Portierung auf andere Plattformen wollen könnte.

Irgendwelche Ideen?

War es hilfreich?

Lösung

Das Android SDK kommt nicht mit jeder einfachen Möglichkeit, Text auf OpenGL Ansichten zu zeichnen. So dass Sie mit den folgenden Optionen.

  1. Legen Sie eine Textview über Ihre Surface. Dies ist langsam und schlecht, aber der direkteste Ansatz.
  2. Render gemeinsame Strings Texturen und einfach diese Texturen zeichnen. Dies ist bei weitem die einfachste und schnellste, aber die am wenigsten flexibel.
  3. Roll-your-own Text-Rendering-Code auf einem Sprite basiert. Wahrscheinlich zweitbeste Wahl, wenn 2 ist keine Option. Ein guter Weg, um Ihre Füße nass, aber zur Kenntnis zu bringen, dass es zwar einfach zu sein scheint (und grundlegende Funktionen sind), es ist schwieriger zu bekommen und mehr herausfordernd, wie Sie mehr Funktionen (Textur-Ausrichtung hinzufügen, die sich mit Zeilenumbrüchen, variabler Breite Schriftart usw. ) - wenn Sie diesen weg nehmen, macht es so einfach, wie Sie mit wegkommen können
  4. !
  5. Verwenden Sie ein Off-the-shelf / Open-Source-Bibliothek. Es gibt ein paar um, wenn Sie auf Google jagen, der schwierige Bit ist, sie integriert und ausgeführt wird. Aber zumindest, wenn Sie das tun, werden Sie alle haben die Flexibilität und Reife, die sie bieten.

Andere Tipps

Rendern von Text in eine Textur ist einfacher als das, was die Sprite Text Demo macht es sieht so aus, die Grundidee ist es, die Canvas-Klasse zu verwenden, um ein Bitmap zu machen und dann die Bitmap zu einer OpenGL-Textur übergeben:

// Create an empty, mutable bitmap
Bitmap bitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.ARGB_4444);
// get a canvas to paint over the bitmap
Canvas canvas = new Canvas(bitmap);
bitmap.eraseColor(0);

// get a background image from resources
// note the image format must match the bitmap format
Drawable background = context.getResources().getDrawable(R.drawable.background);
background.setBounds(0, 0, 256, 256);
background.draw(canvas); // draw the background to our bitmap

// Draw the text
Paint textPaint = new Paint();
textPaint.setTextSize(32);
textPaint.setAntiAlias(true);
textPaint.setARGB(0xff, 0x00, 0x00, 0x00);
// draw the text centered
canvas.drawText("Hello World", 16,112, textPaint);

//Generate one texture pointer...
gl.glGenTextures(1, textures, 0);
//...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

//Create Nearest Filtered Texture
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

//Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);

//Use the Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

//Clean up
bitmap.recycle();

Ich habe eine schriftliche Tutorial , die sich ausdehnt auf den entsandten Antwort von JVitela . Im Grunde ist es verwendet die gleiche Idee, aber anstatt jede Zeichenfolge in eine Textur-Rendering, macht es alle Zeichen aus einer Font-Datei auf eine Textur und Anwendungen, die für die volle dynamische Textdarstellung ohne weitere Verlangsamungen (sobald die Initialisierung abgeschlossen ist) zu ermöglichen .

Der Hauptvorteil meiner Methode, im Vergleich zu dem verschiedenen Schriftatlas Generatoren ist, dass Sie kleine Schriftdateien versenden können (.ttf OTF) mit Ihrem Projekt statt mit großen Bitmaps für jede Schriftart Variation und Größe zu versenden. Es kann bei jeder Auflösung perfekte Qualität Fonts erzeugt nur eine Schriftdatei:)

Die Tutorial enthält vollständiger Code, der in jedem Projekt verwendet werden kann:)

Nach diesem Link:

http: //code.neenbedankt .com / how-to-machen-ein-android-view-to-a-Bitmap

Sie können machen jede Ansicht in eine Bitmap. Es ist wahrscheinlich wert davon aus, dass Sie eine Ansicht Layout können, wie Sie benötigen (einschließlich Text, Bilder etc.) und macht es dann zu einer Bitmap.

Mit JVitela Code oben sollten Sie in der Lage sein, verwenden Sie diese Bitmap als OpenGL Textur.

Hier finden Sie aktuelle CBFG und den Android-Port des Lade- / Rendering-Code. Sie sollten den Code in das Projekt fallen können, und es sofort verwenden.

CBFG - http://www.codehead.co.uk/cbfg

Android loader - http://www.codehead.co.uk/cbfg/TexFont.java

schaute ich auf die Sprite-Text Beispiel und es sieht schrecklich für eine solche Aufgabe kompliziert, ich als zu auf eine Textur-Rendering, aber ich mache mir Sorgen um die Leistung, die verursachen könnten getroffen. Ich könnte nur mit Blick gehen muß, statt und Sorgen über die Portierung, wenn es an der Zeit, dass die Brücke zu überqueren:)

Sehen Sie sich die "Sprite Text" Probe in den GLSurfaceView Proben .

IMHO gibt es drei Gründe OpenGL ES in einem Spiel zu verwenden:

  1. Vermeiden Sie Unterschiede zwischen mobilen Plattformen durch einen offenen Standard verwendet wird;
  2. Um mehr Kontrolle über den Renderprozess;
  3. profitieren von GPU parallele Verarbeitung;

Text Zeichnung ist immer ein Problem in Game Design, weil man die Dinge zeichnen, so dass Sie nicht das Aussehen haben können und das Gefühl einer gemeinsamen Aktivität, mit Widgets und so weiter.

Sie können einen Rahmen verwenden, um Bitmap-Fonts von Truetype-Schriften zu erzeugen und sie zu machen. Alle Frameworks ich gesehen habe, die gleiche Art und Weise: erzeugen die Vertex- und Texturkoordinaten für den Text in Einzeichnungszeit. Dies ist nicht die effizienteste Verwendung von OpenGL.

Der beste Weg ist, entfernten Puffer (Vertex Buffer Objects - VBOs) zuzuordnen. Für die Ecken und Texturen in Code früh, um die faulen Speichertransferoperationen in Einzeichnungszeit vermeiden

Beachten Sie, dass Game-Spieler weiß nicht, wie Text zu lesen, so dass Sie einen lange dynamisch generierte Text nicht schreiben. Für Etiketten, können Sie statische Texturen verwenden, dynamischen Text für Zeit und Kerbe lassend, und beide sind numerisch mit ein paar Zeichen lang sein.

Also, meine Lösung ist einfach:

  1. Erstellen Textur für gemeinsame Etiketten und Warnungen;
  2. Erstellen Textur für die Zahlen 0-9, ":", "+" und "-". Eine Textur für jedes Zeichen;
  3. Generieren Remote VBOs für alle Positionen auf dem Bildschirm. Ich kann statisch oder dynamisch Text, dass Positionen machen, aber die VBOs sind statisch;
  4. Generieren nur eine Textur VBO, als Text immer eine Möglichkeit, wiedergegeben wird;
  5. In Einzeichnungszeit, mache ich den statischen Text;
  6. Für dynamischen Text, kann ich an der Position VBO späht, den Charakter Textur bekommen und ziehen Sie es, um ein Zeichen zu einem Zeitpunkt.

Zeichnen Operationen sind schnell, wenn Sie die Fern statische Puffer verwenden.

Ich erstelle eine XML-Datei mit Bildschirmpositionen (basierend auf dem Bildschirm Diagonal Prozent) und Texturen (statisch und Zeichen), und dann lade ich diese XML vor Rendering.

Um eine hohe FPS-Rate erhalten, die Sie vermeiden sollten VBOs bei Einzeichnungszeit zu erzeugen.

Wenn Sie sich mit GL bestehen, können Sie den Text auf Texturen machen. Unter der Annahme, dass die meisten der HUD relativ statisch sind, sollten Sie nicht zu oft die Texturen auf Texturspeicher zu laden.

Hier finden Sie aktuelle CBFG und die Android-Port des Lade- / Rendering Code. Sie sollten den Code in das Projekt fallen können, und es verwenden, sofort.

  1. CBFG

  2. Android loader

Ich habe Probleme mit dieser Implementierung. Es zeigt nur ein Zeichen, wenn ich ändert Größe der Bitmap Schriftart versuchen zu tun (ich brauche Sonderzeichen) ganzes Unentschieden fehlschlägt: (

Ich habe für diese für ein paar Stunden suchen, ist dies der erste Artikel war ich kam accross und obwohl es die beste Antwort hat, die beliebtesten Antworten, die ich denke, sind abwegig. Sicherlich für das, was ich brauchte. weichsel ist und Antworten des shakazed waren direkt auf den Button, aber ein wenig in den Artikeln verdeckt. Setzen Sie sich für das Projekt. Hier: Erstellen Sie einfach ein neues Android-Projekt auf Basis vorhandener Probe. Wählen Sie ApiDemos:

Sehen Sie unter dem Quellordner

ApiDemos/src/com/example/android/apis/graphics/spritetext

Und Sie werden alles finden, was Sie brauchen.

statischer Text :

  • Generieren Sie ein Bild mit allen Wörtern auf Ihrem PC verwendet werden (zum Beispiel mit GIMP).
  • Laden Sie diese als Textur und verwenden Sie es als Material für eine Ebene.

Langtext , dass einmal aktualisiert werden muss, in einer Zeit lang:

  • Let android zeichnet auf einer Bitmap-Leinwand (JVitela-Lösung).
  • Laden Sie das als Material für ein Flugzeug.
  • Verwenden Sie unterschiedliche Texturkoordinaten für jedes Wort.

eine Zahl (formatiert 00.0):

  • Generieren Sie ein Bild mit allen Zahlen und einem Punkt.
  • Laden Sie das als Material für ein Flugzeug.
  • Verwenden Sie den folgenden Shader.
  • In Ihrem OnDraw Ereignis nur den Wert Variable auf den Shader gesendet aktualisieren.

    precision highp float;
    precision highp sampler2D;
    
    uniform float uTime;
    uniform float uValue;
    uniform vec3 iResolution;
    
    varying vec4 v_Color;
    varying vec2 vTextureCoord;
    uniform sampler2D s_texture;
    
    void main() {
    
    vec4 fragColor = vec4(1.0, 0.5, 0.2, 0.5);
    vec2 uv = vTextureCoord;
    
    float devisor = 10.75;
    float digit;
    float i;
    float uCol;
    float uRow;
    
    if (uv.y < 0.45) {
        if (uv.x > 0.75) {
            digit = floor(uValue*10.0);
            digit = digit - floor(digit/10.0)*10.0;
            i = 48.0 - 32.0 + digit;
            uRow = floor(i / 10.0);
            uCol = i - 10.0 * uRow;
            fragColor = texture2D( s_texture, uv / devisor * 2.0 + vec2((uCol-1.5) / devisor, uRow / devisor) );
        } else if (uv.x > 0.5) {
            uCol = 4.0;
            uRow = 1.0;
            fragColor = texture2D( s_texture, uv / devisor * 2.0 + vec2((uCol-1.0) / devisor, uRow / devisor) );
        } else if (uv.x > 0.25) {
            digit = floor(uValue);
            digit = digit - floor(digit/10.0)*10.0;
            i = 48.0 - 32.0 + digit;
            uRow = floor(i / 10.0);
            uCol = i - 10.0 * uRow;
            fragColor = texture2D( s_texture, uv / devisor * 2.0 + vec2((uCol-0.5) / devisor, uRow / devisor) );
        } else if (uValue >= 10.0) {
            digit = floor(uValue/10.0);
            digit = digit - floor(digit/10.0)*10.0;
            i = 48.0 - 32.0 + digit;
            uRow = floor(i / 10.0);
            uCol = i - 10.0 * uRow;
            fragColor = texture2D( s_texture, uv / devisor * 2.0 + vec2((uCol-0.0) / devisor, uRow / devisor) );
        } else {
            fragColor = vec4(0.0, 0.0, 0.0, 0.0);
        }
    } else {
        fragColor = vec4(0.0, 0.0, 0.0, 0.0);
    }
    gl_FragColor = fragColor;
    
    }
    

über Code arbeitet für eine Texturatlas wo Zahlen von 0 auf der 7. Spalte der zweiten Reihe der Schriftart Atlas starten (Textur).

Siehe

https://www.shadertoy.com/view/Xl23Dw Demonstration ( mit falscher Textur obwohl)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top