No tengo opciones para usar que no sean métodos opengl (es decir, métodos glxxx()()). Necesito dibujar texto usando solo métodos gl. Después de leer el libro rojo entiendo que solo es posible a través del método glBitmap(). Si esta es la única forma posible, entonces ¿alguien me puede ayudar con la información de la matriz de píxeles para todos los personajes? ¿Hay alguna otra forma de dibujar texto?¿Cómo dibujar texto usando solo métodos OpenGL?
Respuesta
This article describe cómo representar texto en OpenGL utilizando diversas técnicas.
Con solamente usando OpenGL, hay varias maneras:
- utilizando glBitmap
- utilizando texturas
- usando listas de visualización
Dibujo texto en OpenGL llano no es un straigth- tarea de reenvío Probablemente debería echar un vistazo a las bibliotecas para hacer esto (ya sea mediante el uso de una biblioteca o como una implementación de ejemplo).
Algunos buenos puntos de partida podrían ser GLFont, OpenGL Font Survey y NeHe Tutorial for Bitmap Fonts (Windows).
Tenga en cuenta que los mapas de bits no son la única forma de lograr texto en OpenGL como se menciona en la encuesta de la fuente.
creo que la mejor solución para dibujar texto en OpenGL es fuentes textura, trabajo con ellos durante mucho tiempo. Son flexibles, rápidos y bonitos (con algunas excepciones posteriores). Utilizo un programa especial para convertir archivos de fuentes (.ttf por ejemplo) en texturas, que se guardan en archivos de algún formato interno de "fuente" (he desarrollado formatos y programas basados en http://content.gpwiki.org/index.php/OpenGL:Tutorials:Font_System aunque mi versión fue bastante lejos del soporte original Unicode, etc.). Al iniciar la aplicación principal, las fuentes se cargan desde este formato "interno". Mire el enlace de arriba para más información.
Con tal enfoque principal de la aplicación no utiliza ninguna bibliotecas especiales como FreeType, que no es deseable para mí también. El texto se dibuja utilizando las funciones estándar de OpenGL.
Si puedo agregar algo a esto alrea De buena respuesta, preste atención a la optmización de cualquier sistema de representación de fuentes, ya que puede afectar el rendimiento de su motor en recursos HW muy limitados, como los dispositivos móviles. –
Uso glutStrokeCharacter(GLUT_STROKE_ROMAN, myCharString)
.
Un ejemplo: A STAR WARS SCROLLER.
#include <windows.h>
#include <string.h>
#include <GL\glut.h>
#include <iostream.h>
#include <fstream.h>
GLfloat UpwardsScrollVelocity = -10.0;
float view=20.0;
char quote[6][80];
int numberOfQuotes=0,i;
//*********************************************
//* glutIdleFunc(timeTick); *
//*********************************************
void timeTick(void)
{
if (UpwardsScrollVelocity< -600)
view-=0.000011;
if(view < 0) {view=20; UpwardsScrollVelocity = -10.0;}
// exit(0);
UpwardsScrollVelocity -= 0.015;
glutPostRedisplay();
}
//*********************************************
//* printToConsoleWindow() *
//*********************************************
void printToConsoleWindow()
{
int l,lenghOfQuote, i;
for( l=0;l<numberOfQuotes;l++)
{
lenghOfQuote = (int)strlen(quote[l]);
for (i = 0; i < lenghOfQuote; i++)
{
//cout<<quote[l][i];
}
//out<<endl;
}
}
//*********************************************
//* RenderToDisplay() *
//*********************************************
void RenderToDisplay()
{
int l,lenghOfQuote, i;
glTranslatef(0.0, -100, UpwardsScrollVelocity);
glRotatef(-20, 1.0, 0.0, 0.0);
glScalef(0.1, 0.1, 0.1);
for( l=0;l<numberOfQuotes;l++)
{
lenghOfQuote = (int)strlen(quote[l]);
glPushMatrix();
glTranslatef(-(lenghOfQuote*37), -(l*200), 0.0);
for (i = 0; i < lenghOfQuote; i++)
{
glColor3f((UpwardsScrollVelocity/10)+300+(l*10),(UpwardsScrollVelocity/10)+300+(l*10),0.0);
glutStrokeCharacter(GLUT_STROKE_ROMAN, quote[l][i]);
}
glPopMatrix();
}
}
//*********************************************
//* glutDisplayFunc(myDisplayFunction); *
//*********************************************
void myDisplayFunction(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0, 30.0, 100.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
RenderToDisplay();
glutSwapBuffers();
}
//*********************************************
//* glutReshapeFunc(reshape); *
//*********************************************
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, 1.0, 1.0, 3200);
glMatrixMode(GL_MODELVIEW);
}
//*********************************************
//* int main() *
//*********************************************
int main()
{
strcpy(quote[0],"Luke, I am your father!.");
strcpy(quote[1],"Obi-Wan has taught you well. ");
strcpy(quote[2],"The force is strong with this one. ");
strcpy(quote[3],"Alert all commands. Calculate every possible destination along their last known trajectory. ");
strcpy(quote[4],"The force is with you, young Skywalker, but you are not a Jedi yet.");
numberOfQuotes=5;
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 400);
glutCreateWindow("StarWars scroller");
glClearColor(0.0, 0.0, 0.0, 1.0);
glLineWidth(3);
glutDisplayFunc(myDisplayFunction);
glutReshapeFunc(reshape);
glutIdleFunc(timeTick);
glutMainLoop();
return 0;
}
glutStrokeCharacter no es una función opengl –
cabe en glxxx() Requisito OP aunque :) – AndroidGecko
Aquí está el código modificado para trabajar en Ubuntu (glutInit, incluye): https://gist.github.com/tgandor/3963f112324030a2c833 –
Cargue una imagen con caracteres como textura y dibuje la parte de esa textura según el carácter que desee. Puede crear esa textura usando un programa de pintura, codificarlo o usar un componente de ventana para dibujar una imagen y recuperar esa imagen para obtener una copia exacta de las fuentes del sistema.
No necesita utilizar Glut o cualquier otra extensión, solo la operatividad básica de OpenGL. Hace el trabajo, sin mencionar que ha sido hecho así durante décadas por programadores profesionales en juegos exitosos y otras aplicaciones.
Incluso hay programas que puede usar para generar la textura de la imagen para usted. – fintelia
Teoría
por qué es difícil
formatos de fuentes populares como TrueType y OpenType son formatos del vector esquema: utilizan las curvas de Bézier para definir el límite de la carta.
La transformación de esos formatos en matrices de píxeles (rasterización) es demasiado específica y fuera del alcance de OpenGL, especialmente porque OpenGL no tiene primitivas no rectas (por ejemplo, ver Why is there no circle or ellipse primitive in OpenGL?)
El método más sencillo consiste en fuentes primeras de trama nosotros mismos en la CPU, y luego dar la matriz de píxeles a OpenGL como una textura.
OpenGL entonces sabe cómo hacer frente a las matrices de píxeles a través de texturas muy bien.
atlas textura
Podríamos Raster caracteres para cada cuadro y volver a crear las texturas, pero eso no es muy eficiente, especialmente si los personajes tienen un tamaño fijo.
El enfoque más eficiente es a raster todos los caracteres que desee usar y meter ellos en una sola textura.
y luego transferir a la GPU que una vez, y lo utilizan con textura UV encargo coordina para elegir el carácter correcto.
Este enfoque se denomina https://en.wikipedia.org/wiki/Texture_atlas y puede ser utilizado no sólo para las texturas, sino también otras texturas utilizadas en varias ocasiones, como las tejas en un juego o la interfaz de usuario web de iconos 2D.
La imagen de Wikipedia de la textura completa, que a su vez se ha tomado de freetype-gl, ilustra esto muy bien:
sospecho que la optimización de la colocación de caracteres al problema de textura más pequeño es un NP-duro problema, consulte: What algorithm can be used for packing rectangles of different sizes into the smallest rectangle possible in a fairly optimal way?
La misma técnica se utiliza en el desarrollo web para transmitir varias imágenes pequeñas (como iconos) a la vez, pero allí se llama "CSS Sprites": https://css-tricks.com/css-sprites/ y se utilizan para ocultar la latencia de la red en lugar de la de la Comunicación CPU/GPU.
métodos de mapa de bits sin CPU
También existen métodos que no utilizan la trama de la CPU a las texturas.
CPU Barrido de es simple, ya que utiliza la GPU lo menos posible, pero también empezar a pensar si sería posible utilizar la eficiencia de GPU más.
Este vídeo FOSDEM 2014 https://youtu.be/LZis03DXWjE?t=886 explica otras técnicas existentes:
- tesselation: convertir la fuente a pequeños triángulos. La GPU es realmente buena para dibujar triángulos.Desventajas:
- genera un manojo de triángulos
- O (n log n) Cálculo de CPU de los triángulos
- curvas Calcular al shaders. Un documento de 2005 de Blinn-Loop puso este método en el mapa. Desventaja: complejo. Ver: Resolution independent cubic bezier drawing on GPU (Blinn/Loop)
- implementaciones directas de hardware como OpenVG https://en.wikipedia.org/wiki/OpenVG. Desventaja: no muy implementada por alguna razón. Ver:
Fuentes dentro de la geometría 3D con perspectiva
Rendering fuentes dentro de la geometría 3D con perspectiva (en comparación con un sistema HUD ortogonal) es mucho más complicado, porque la perspectiva podría hacer que una parte del personaje esté mucho más cerca de la pantalla y la más rápido que el otro, haciendo una discretización uniforme de CPU (p. raster, tesselación) se ven mal en la parte más cercana. Esto es en realidad un tema de investigación activa:
- What is state-of-the-art for text rendering in OpenGL as of version 4.1?
- http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf
campos de distancia son una de las técnicas populares ahora.
Implementaciones
Los ejemplos que siguen fueron todos probados en Ubuntu 15.10.
Debido a que este es un problema complejo como se discutió anteriormente, la mayoría de los ejemplos son grandes y explotarían el límite de 30k de esta respuesta, así que simplemente clone los repositorios Git respectivos para compilar.
Sin embargo, todos son de código abierto, por lo que solo puede RTFS.
soluciones FreeType
FreeType se parece a la biblioteca de rasterización de fuente de código abierto dominante, por lo que nos permitirá utilizar las fuentes TrueType y OpenType, por lo que es la solución más elegante.
https://github.com/rougier/freetype-gl
era un conjunto de ejemplos de OpenGL y freetype, pero es más o menos convirtiendo en una biblioteca que lo hace y expone una API decente.
En cualquier caso, ya debería ser posible integrarlo en su proyecto copiando pegando algún código fuente.
Proporciona atlas de textura y técnicas de campo de distancia de fábrica.
Demos en: https://github.com/rougier/freetype-gl/tree/master/demos
No tiene un paquete Debian, y es un dolor para compilar en Ubuntu 15.10: https://github.com/rougier/freetype-gl/issues/82#issuecomment-216025527 (problemas de embalaje, algunas aguas arriba), pero mejoraron a partir de 16.10.
no tiene un buen método de instalación: https://github.com/rougier/freetype-gl/issues/115
Genera hermosas salidas de este tipo de demostración:
libdgx https://github.com/libgdx/libgdx/tree/1.9.2/extensions/gdx-freetype
Ejemplos/tutoriales:
- un tutorial NEHE: http://nehe.gamedev.net/tutorial/freetype_fonts_in_opengl/24001/
- http://learnopengl.com/#!In-Practice/Text-Rendering lo menciona, pero no pudo encontrar el código fuente ejecutable
- SO preguntas:
Otros rasterizadores fuente
Aquellos parecen menos buena que FreeType, pero pueden ser más liviano:
- https://github.com/nothings/stb/blob/master/stb_truetype.h
- http://www.angelcode.com/products/bmfont/
OpenGL 4 Tutoriales ejemplo 26 "fuentes de mapa de bits" de Anton
- tutorial: http://antongerdelan.net/opengl/)
- fuente: https://github.com/capnramses/antons_opengl_tutorials_book/blob/9a117a649ae4d21d68d2b75af5232021f5957aac/26_bitmap_fonts/main.cpp
La fuente fue creado por el autor de forma manual y se almacena en un solo archivo .png
. Las letras se almacenan en forma de matriz dentro de la imagen.
Este método, por supuesto, no es muy general, y tendría dificultades con la internacionalización.
Construir con:
make -f Makefile.linux64
vista previa de salida:
OpenGL-tutorial Capítulo 11 "2D" fuentes
- tutorial: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-11-2d-text/
- fuente: https://github.com/opengl-tutorials/ogl/blob/71cad106cefef671907ba7791b28b19fa2cc034d/tutorial11_2d_fonts/tutorial11.cpp
texturas se genera a partir de DDS files.
El tutorial explica cómo se crearon los archivos DDS, utilizando CBFG y Paint.Net.
vista previa de salida:
Por alguna razón Suzanne falta para mí, pero el contador de tiempo funciona bien: https://github.com/opengl-tutorials/ogl/issues/15
freeglut
GLUT tiene glutStrokeCharacter
y freeglut es código abierto ... https://github.com/dcnieho/FreeGLUT/blob/FG_3_0_0/src/fg_font.c#L255
OpenGLText
https://github.com/tlorach/OpenGLText
trama TrueType. Por empleado de NVIDIA. Tiene como objetivo la reutilización. No lo he intentado todavía
ARM Mali GLES SDK Muestra
http://malideveloper.arm.com/resources/sample-code/simple-text-rendering/ parece codificar todos los caracteres en un PNG, y se cortan a partir de ahí.
SDL_ttf
Fuente: https://github.com/cirosantilli/cpp-cheat/blob/d36527fe4977bb9ef4b885b1ec92bd0cd3444a98/sdl/ttf.c
vive en un árbol separado a SDL, y se integra fácilmente.
no proporciona una aplicación atlas textura sin embargo, lo que el rendimiento se limitará: Rendering fonts and text with SDL2 efficiently
las discusiones relacionadas
- 1. ¿Cómo puedo dibujar texto usando Libgdx/Java?
- 2. Dibujar texto multilingüe usando PIL
- 3. Cómo dibujar fondo en openGL
- 4. Cómo dibujar un mapa de bits en Android usando OpenGL
- 5. ¿Cómo dibujar un texto (escribir en la pantalla) usando las funciones estándar de OpenGL?
- 6. La forma correcta de dibujar texto en OpenGL ES 2
- 7. Cómo dibujar múltiples cubos en OpenGL
- 8. OpenGL: Dibujar líneas con VBO
- 9. ¿La mejor manera de dibujar texto con OpenGL y Cocoa?
- 10. Manera eficiente de dibujar en OpenGL ES
- 11. cómo dibujar un polígono transparente en openGL
- 12. OpenGL - Cómo dibujar píxel cuadrado con GL_POINTS
- 13. dibujar texto usando CGContextShowTextAtPoint pero el texto mostrado es invertida,
- 14. Cómo dibujar texto con fondo transparente usando C++/WinAPI?
- 15. cómo dibujar texto con color de fondo usando la lona
- 16. Dibujar texto en ángulo
- 17. ¿Cómo dibujar texto en lienzo?
- 18. ¿Cómo dibujo texto usando OpenGL, SDL y C++?
- 19. Dibujar líneas punteadas con OpenGL-ES
- 20. OpenGL - Dibujar un cuadrado con glDrawArrays()
- 21. ¿Cómo dibujar solo esta parte del arco?
- 22. iPhone OpenGl render texto
- 23. qt dibujar texto colorido
- 24. iPhone: ¿Dibujar texto girado?
- 25. Cómo dibujar la línea "brillante" en OpenGL ES
- 26. ¿Cómo dibujar algo con OpenGL ES en Linux?
- 27. OpenGL: ¿Cómo borrar solo una parte de la pantalla?
- 28. iPhone: cómo dibujar texto en una ventana?
- 29. ¿Cómo dibujar texto en cuadro de imagen?
- 30. Dibujar texto con gráficos básicos
gracias por Nehe enlace tutorial – befzz