Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Fuentes bitmap en D3D/OpenGL

Iniciado por senior wapo, 11 de Septiembre de 2006, 06:24:06 PM

« anterior - próximo »

senior wapo

Voy a implementar un sistema de fuentes que permita dibujar texto en cualquier idioma usando quads y texturas (mi API encapsula D3D y OGL). Como tendré mas símbolos de los que caben en una textura necesitaré gestionarlas de alguna manera para evitar al máximo los cambios de textura al dibujar el texto.

Me gustaría conocer experiencias de gente que ya lo haya hecho y haya comprobado por si mismos las diferencias de velocidad de un método a otro (conozco distintos métodos pero quiero ahorrarme probarlos todos y medir tiempos). NO usare VB sino que volcaré todo como un array.

Los dos candidatos más probables por el momento son, en orden de preferencia:
1. Dibujar las letras en orden añadiendo sus simbolos a una textura hasta llenarla (sin repetir simbolos) y entonces subir esa textura y el batch de quads.
2. Tener las texturas organizadas por frecuencia del caracter en ese lenguaje e ir cambiando de textura según necesite, ordenando por textura en lugar de quad siempre que sea posible (dentro de un mismo párrafo con mismo color y tipo de letra).

Gracias.

Pogacha

Si lo que quieres es velocidad lo mejor que puedes hacer es tomar el texto y renderizarlo a una textura, y de ahí uses la textura.

Sino otra idea es tener una funcion tipo Iniciar_Modo_Texto();
y luego de esto ir acumulando las entradas de texto, ya que pueden ser multirenglon.
Cuando ponga Terminar_Modo_texto(), te barres una a una las texturas y dibujas los caracteres correspondientes a tal y en una sola llamada por textura le pasas todo el arreglo de quads que lo utilizan.

Saludos.

senior wapo

Cita de: "Pogacha"Si lo que quieres es velocidad lo mejor que puedes hacer es tomar el texto y renderizarlo a una textura, y de ahí uses la textura.

El problema de imprimir todo en un solo quad es que subes muchos pixeles a la tarjeta. La palabra "Patata" subiria los pixeles de la imagen de la A 3 veces y la T 2 veces, en lugar de una. No es precisamente la opción más rápida.

Cita de: "Pogacha"Sino otra idea es tener una funcion tipo Iniciar_Modo_Texto();
y luego de esto ir acumulando las entradas de texto, ya que pueden ser multirenglon.
Cuando ponga Terminar_Modo_texto(), te barres una a una las texturas y dibujas los caracteres correspondientes a tal y en una sola llamada por textura le pasas todo el arreglo de quads que lo utilizan.
.

Ese es el procedimiento que describo en el punto 1. Imagino que es más rápido que el anterior y cuando he mirado las texturas en juegos comerciales (con trazadores tipo OGLE/3D Ripper DX) hacen algo parecido o eso deduzco mirando las texturas.

Si nadie me cuenta nada, acabaré haciendo algo asi...

Pogacha

Que no nos hemos entendido ...

Tienes que tener paginas con los caracteres ya previamente renderizados, usalmente la primera pagina con el ascii y luego diferentes codepages latin-1, windows-1251 (sin importar que uses unicode, es para que tengas la gamma ).
Ahora si tu intension es ir a los lenguajes asiaticos no alcanza lo que hagas, tan solo renderiza por GDI o lo que sea y subelo una vez mientras se repita en reiterados frames subsequentes ... (pudes tirar otro hilo para que renderize el texto)
Generalmente el texto es estatico y dura miles de frames!
Usas un solo quad y tienes la maxima velocidad de dibujo!

Saludos.

senior wapo

Si te entiendo, lo que pasa es que tu supones que la textura seguirá en memoria entre frames y yo asumo que habrá texture trashing por haber menos memoria de video que la ocupada por todas las texturas que uso en un frame.
Mi target son máquinas de escasa VRAM, por ejemplo 4-8MB, y si, quiero soportar lenguajes asiáticos con múltiples páginas de caracteres ya prerenderizados.

Asumiendo que cada vez que usas una textura la tienes que subir (habrá caso en que tengas suerte y permanezca aún en VRAM desde el frame anterior, pero yo acoto al caso peor), te encuentras que subir todo el texto como una imagen ocupa más ancho de banda que subir solo la composición de los símbolos usados y 4 vertices por letra del texto.

ocupa mas ancho de banda (más tiempo de espera a que la suba) subir el texto como una imagen:


que asi:


Da igual si son letras latinas o simbolos coreanos o hebreos y si se sube una sola vez o una por frame.

Ambas texturas son composiciones en memoria a partir de diferentes paginas ya prerenderizadas con todos los caracteres. Parece que esa es la operativa más difundida.

Pogacha

Cita de: "senior wapo"Si te entiendo, lo que pasa es que tu supones que la textura seguirá en memoria entre frames y yo asumo que habrá texture trashing por haber menos memoria de video que la ocupada por todas las texturas que uso en un frame.
Mi target son máquinas de escasa VRAM, por ejemplo 4-8MB, y si, quiero soportar lenguajes asiáticos con múltiples páginas de caracteres ya prerenderizados.

Asumiendo que cada vez que usas una textura la tienes que subir (habrá caso en que tengas suerte y permanezca aún en VRAM desde el frame anterior, pero yo acoto al caso peor), te encuentras que subir todo el texto como una imagen ocupa más ancho de banda que subir solo la composición de los símbolos usados y 4 vertices por letra del texto.

ocupa mas ancho de banda (más tiempo de espera a que la suba) subir el texto como una imagen:


que asi:


Da igual si son letras latinas o simbolos coreanos o hebreos y si se sube una sola vez o una por frame.

Ambas texturas son composiciones en memoria a partir de diferentes paginas ya prerenderizadas con todos los caracteres. Parece que esa es la operativa más difundida.

Con que ahí veniamos.
No estoy seguro de cuanto puedas ahorrarte entre un sistema y otro.
¿Y vale la pena tanta complicación por una rama tan pequeña ?
Placas de menos de 8mb que no tienen problemas de compatibilidad con D3D supongo serán menos del uno por mil.
Por eso que para tales placas se usa render por software y san se acabo.

Saludos.

Saludos.

Prompt

senior wapo, se debe hacer como describes. no repetir caracteres te permitirá controlar el tamaño que ocupa la generación del texto en la tarjeta.

Luego solo tienes que repetir el pintado n veces en las posiciones x e y de cada letra.

H O L A

HOLA tiene un rect: left, top, right y bottom que definen el rectangulo ( si lo pintas como sprite ) sinó con x e y para esto valdrá perfectamente.

luego solo tienes que ir sumando, el tamaño de cada letra ( si no son del mismo tamaño cada letra ) e ir pintando... en fin lo puedes hacer de mil maneras.

O si ya tienes todo hecho y solo quieres ahorrarte letras pues apuntas a la misma textura anteriormente creada o ....

Me imagino que se te habran ocurrido mil cosas ya.

Es la solución más rápida para la GPU y un coste no muy grande de CPU guardar información por letra o un altgoritmo algo cambiado en la generación del texto. A demás las texturas en pantalla con el Alpha, chupan muchisimo! y es un ahorro importante.

tamat

Conoces el Bitmap Font Generator?

Yo lo utilizo para generar las texturas de las fonts en mi framework y va de puta madre. Te posiciona las letras de manera que quede la menor cantidad de espacio muerto en la textura, además puedes controlar el tamaño de las texturas, el padding, y si no cabe en una textura te genera varias.

Aparte genera un archivo XML con las coordenadas de cada letra, propiedades como el kerning y el identificador de la textura donde está.

Para mi es inmejorable. Otra cosa es cómo gestionaras luego el render, yo lo hago a lo bruto lanzando quads para cada letra.
Por un stratos menos tenso

Pogacha

Estube replanteandolo y si, es mejor tu sistema en varios puntos, pero definitivamente no creo que valga la pena. No creo que haya mucha repetición en los caracteres asiaticos, aun usando los silabonicos ...






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.