28 votes

Rendu de texte en direct OpenGL

Je me suis mise en œuvre d'une interface graphique construite sur le toit d'OpenGL. Je suis venu pour le problème que chaque GUI ont -- rendu de texte. Je connais plusieurs méthodes de rendu de texte en OpenGL, cependant, je suis wonderin lequel d'entre eux serait le mieux adapté pour une interface graphique.

Généralement dans une interface graphique, nous avons deux types de texte -- statiques et en direct. Statique est assez facile, nous pouvons rendre une TTF à une texture et l'oublier. C'est le "live" de texte qui est plus à me tracasser ... imaginez la console, ou un chat en direct dans un jeu multi-joueurs.

J'ai pensé à plusieurs options:

  • pas de cas particuliers -- rendu et de charger une texture à chaque fois que le texte change, tout en gardant à l'esprit alors rendre à nouveau quand de nouveau, le texte apparaît, et en essayant de diviser le texte plus grand dans les petites pièces (comme par chat en ligne). Cependant ce serait encore nous laisser suspendus dans les cas comme une ligne de score qui change tout le temps, ou un texte d'introduction qui rend "par le caractère" (machine à écrire de style vu dans certains de sci-fi jeux)
  • quad-par caractère, elle semble également une solution populaire, vous préparez une texture avec la table ASCII, et de rendre une texture quad caractère. Cependant, j'ai de sérieux doutes sur l'efficacité d'une telle solution. Conseils sur la manière de faire que le plus rapide serait également la bienvenue.
  • les solutions hybrides -- cependant je n'ai aucune idée de comment le mettre en œuvre que proprement

La question est donc: comment rendre le texte en OpenGL efficacement?

(si cela aide, je code en STL/Boost-lourds C++ et visant à GForce 6 et, plus tard, les cartes graphiques)

Toutes les suggestions de bienvenue.

24voto

Gregory Pakosz Points 35546

EDIT2: Sean Barrett vient de sortir polices Bitmap pour le C/C++ 3D programmeurs.

EDIT: un autre code joyau qui vaut un coup d'oeil est la Police Cachette , qui tire profit de Sean Barrett stb_truetype.h.


Vous pouvez créer une texture dans laquelle vous rendre tous les personnages de votre police. Alors que vous venez de dessiner texturé quads avec la projection orthographique et bon de coordonnées de texture: cette approche fonctionne lorsque votre texte est dans une langue qui ne contient pas beaucoup de symboles: comme l'anglais. La texture de police est créé une seule fois au début de l'application et le rendu des quads est vraiment rapide.

C'est ce que j'utilise et je crois que c'est le moyen le plus rapide pour rendre le texte en OpenGL. Au début, j'ai utilisé Angelcode de Police Bitmap Générateur de l' outil, puis j'ai intégré FreeType directement et a construit une grande texture contenant tous les glyphes au lancement de l'application. Comme pour les conseils pour améliorer les quads la vitesse de rendu, j'ai simplement utilisé VBO comme pour le reste de la géométrie dans mon application.

Je suis surpris que vous avez des doutes à propos de quad rendu alors que vous ne semblez pas à vous soucier de la performance de la génération d'une texture sur le cpu, puis de le télécharger, puis de liaison pour enfin rendre un rectangle avec elle, que pour chaque image. Évolution des états OpenGL est le goulot d'étranglement, pas le 500 - 1000 quads vous allez utiliser pour le texte.

Aussi, avoir un regard sur les bibliothèques comme la FTGL bibliothèque qui convertit la totalité de la police dans les polygones (géométrique des polices).

6voto

luke Points 16255

Essayez de lire ceci: http://dmedia.dprogramming.com/?n=Tutorials.TextRendering1.

L'approche décrite est la méthode habituelle pour un rendu de texte avec des Api graphiques. Un personnage par quad, et toutes les données d'image pour le texte dans une seule texture. Si vous pouvez ajuster l'ensemble de votre jeu de caractères en une seule texture (en fait, en fonction de la taille de la texture, vous pourriez être en mesure de s'adapter à différentes) le rendu est extrêmement rapide.

La clé est que la texture de liaison est l'opération que vous souhaitez minimiser. Si vous pouvez rendre l'ensemble de votre texte avec une texture unique, il n'a pas d'importance la façon dont beaucoup de texte, vous devez mettre sur l'écran. Même si vous devez passer des textures d'une poignée de fois (les différentes polices de caractères, les différents attributs de police [le gras, le soulignement, etc]) performance doit encore être bonne. Texte de la performance pourrait être plus critique pour une PALETTE, mais il est moins important dans le GUI.

1voto

rombust Points 11

C'est délicat à faire, surtout si vous souhaitez utiliser des techniques de rendu de police sous-pixel. Jetez un œil au SDK ClanLib . Il utilise un rendu par lots pour restituer un écran entier de texte en un seul appel OpenGL. Puisqu'il a une licence basée sur zlib, vous pouvez extraire son code si vous ne souhaitez pas utiliser le SDK lui-même

0voto

fa. Points 2117

Par quad personnage manipulé la pensée d'une liste d'affichage (mis à jour uniquement lorsque des modifications de texte) est tout à fait suffisant pour la plupart des cas.

Je l'ai utilisé avec X11 polices à l'aide de la XLoadQueryFont, glGenLists, glXUseXFont, glCallLists vous avez un tableau d'affichage des listes décrivant chaque personnage.

le glCallLists fonction accepte un char * argument pour votre texte et il peut être incorporé à l'intérieur d'une liste d'affichage.

Donc, vous vous retrouvez avec un seul appel à l'affichage des blocs de texte.

La texture de police proposé par G. Pakosz est similaire, mais vous calculer votre propre "par le caractère" afficher les listes.

Votre première options seront plus lent qu'il faudra processeur rendu à chaque changement de texte.

0voto

Ned Points 1796

pouvez simplement utiliser ces deux fonctions:

void renderstring2d(char string[], float r, float g, float b, float x, float y)
{
    glColor3f(r, g, b);

    glRasterPos2f(x, y);
    for(unsigned int i = 0; i &lt strlen(string); i++)
        glutBitmapCharacter(GLUT_BITMAP_9_BY_15, string[i]);
}

void renderstring3d(char string[], float r, float g, float b, float x, float y, float z)
{
    glDisable(GL_LIGHTING);
    glColor3f(r, g, b);

    glRasterPos3f(x, y, z);
    for(unsigned int i = 0; i &lt strlen(string); i++)
        glutBitmapCharacter(GLUT_BITMAP_9_BY_15, string[i]);
}

ensuite, lorsque vous effectuez le rendu 2D texte, n'oubliez pas de remettre le modelview et les matrices de projection.

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();

// Render text and quads

glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();

Vous n'avez pas besoin de rendre à un quad à l'aide de ces fonctions, car ces fonctions rendre directement à la mémoire de trame.

Et si cela ne fonctionne pas pour vous, vérifier cela. http://www.opengl.org/resources/faq/technical/fonts.htm

Il parle de rendu de texte à l'aide de glBitmap, glDrawPixels, et alpha blending.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X