Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





ayuda predibujando texto

Iniciado por Hechelion, 05 de Noviembre de 2008, 07:05:19 AM

« anterior - próximo »

Hechelion

Buenas.

Para cerrar mi proyecto estoy creando algunas clases para reemplazar algunos objetos de VB que utilice en su momento (cuando las tenga terminadas las posteare por si a alguien le sirven ), específicamente estoy creando una clase que reemplace al MesageBox y de paso sirva como una ListBox. Mi duda, surge a la hora de maximizar el rendimiento, pues la librería pierde rendimiento con los draw_text (en mi equipo no he tenido problema, pero no quiero poner rendimiento un intel core 2 duo para mostrar 10 línea seguidas de texto), así que pase muchos cálculos a una función que sólo se invoca cuando cambia el contenido del string a dibujar, pero quería saber si existe alguna forma de hacer lo mismo con el dibujo de los textos.

Había pensado en usar el buffer secundario, pero luego de leer la recomendación de José Miguel lo descarte de plano, pero me ha quedado dando vuelta el bichito a ver si es posible dibujar los textos en algún lugar y luego invocar esa imagen de forma cíclica ahorrando esos valiosos draw_text.

[EX3]

Hombre, mi recomendacion de los RenderTarget es que no se usen de forma continua en lo que a dibujar sobre ellos se refiere tal y como se hace en otros lenguajes o motores o frameworks como XNA donde no penaliza igual su uso (en caso de dx_lib32 es mas problema de que nunca supe implementarlos correctamente  :-\). Vamos, que puedes usarlo en una precarga del programa o de nivel o de lo que sea, algo puntual, y luego utilizar esa textura resultante tantas veces como quieras igual que cualquier otra textura que hubieras cargado. Aun asi, un par de cosillas: 10 lineas de texto o 20, si fuesen todas un mismo bloque (un parrafo) las puedes concatenar todas en una misma string mediante saltos de linea y tan solo hacer una llamada a DRAW_Text. Por otro lado, tanto texto supongo que sera para una GUI (los menus y pantallas de configuracion del juego) y no para el HUD del juego. En la GUI yo no me preocuparia demasiado por el framerate mientras no baje de 30fps. En una GUI no precisas la misma potencia que por ejemplo en mitad de un juego procesando varios enemigos, items, fisica y efectos varios, por lo que yo no me comeria mucho la cabeza y tiraria directamente con DRAW_Text, agrupando en parrafos dentro de lo posible como comentaba antes, en vez de ir precacheando con los RenderTargets. Yo al menos esto si lo suelo hacer asi pero claro, tambien depende que estes tratando de hacer exactamente.

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

Hechelion

Si fuera una pantalla de menú con texto estático no me haría problema. a ver.... Creo que me conviene explicar para qué necesito esos textos.
Mi proyecto es juego basado en turnos, cada vez que se termina un turno se actualizan los movimientos de flotas, que básicamente se dividen en dos tipos, conquista de un planeta enemigo o refuerzo de un planeta aliado, cada evento se transforma en una línea de texto que debo informar al jugador, además, en la esquina inferior derecha hay un log histórico con todos los mensajes del juego, de momento lo tengo resuelto con un listbox común y silvestre, pero quería reemplazarlo utilizando la librería y una clase, así que como veras ese log tendría que estar metido en el bucle principal de dibujo.

con esto me ha surgido otra duda. ¿sigo utilizando el listbox o lo cambio?

[EX3]

Vale, entiendo que serian bloques de lineas (en plan consola de texto). Yo creo que metiendo a capon todas las lineas en un string para enchufarselo directamente en una sola llamada a DRAW_Text te seria mas comodo y rapido. El texto lo mantienes en un array o coleccion de forma que puedas coger las n lineas que necesites mostrar (siendo un historico supongo que se podra navegar toda la lista de mensajes) y dichas lineas concatenarlas en un solo string. Eso de seguro va a ser mas rapido y limpio que ir actualizando un RenderTarget con dx_lib32. Luego, en vez de barra de desplazamiento lo que podrias poner serian dos botones, uno para subir linea y otro para bajar. No es tan practico como una barra de progreso pero te sera facil de implementar. Algo si tenia en su dia hecho con una consola tipo Quake me hice con la antigua version 1.3 de la libreria y linea a linea (lo tenia asi para poder intercarlar graficos para representar lineas de separacion y algun elemento similar entre lineas) y no petaba demasiado el rendimiento, vamos, se notaba cuando se renderizaba la consola pero tampoco tumbaba el framerate, por lo que una sola llamada a DRAW_Text con un parrafo de n lineas en un solo string tendria que ir con diferencia mucho mejor.

Si el ListBox te funciona y no te destroza la estetica ni interfiere con el renderizado del juego sigue usandolo. Yo es que no suelo utilizarr controles de Windows sobre el renderizado de DirectX por que a veces hace cosas raras (al menos cuando lo probe en su dia) pero si te funciona pues no te compliques sin mas :) Lo interesante de hacerlo con dx_lib32 es que puedes hacer que dicho historial de mensajes sea traslucido mientras no este el cursor encima del texto dejando mas visibilidad al area que oculta del juego y que se haga opaco cuando pases el cursor por encima. No se, efectos y alguna ventaja mas podrias sacarle.

Salu2...

P.D.: A ver si enseñas alguna captura, que me gustaria ver como avanza tu creacion ;)
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

Hechelion

Interesante lo del uso de CRLF en una llamada a DRAW_Text, no sabía que se podía hacer, sin embargo no creo que me sirva, pues por desgracia uso 3 colores diferentes para las lineas. De momento tengo un bucle que llena cada línea con un llamado a la función.
Con respecto a la clase, aunque ésta esta bastante verde tiene un verticalscroll en todas las de la ley.

Con respecto al juego, estéticamente le hecho muy pocos cambios, la mayoría son a nivel de código, como reemplazar objetos de VB por clases, etc.

Hechelion

Buenas.

Al final he optado por dejar el texto del control de un único color con una única llamada a DrawText y estoy penando en publicar el código de la clase por si a alguien más le sirve, pero antes de eso me gustaría saber que técnicas o funciones existen para redondear los bordes, pues de momento el fondo del control es un cuadrado con esquinas de 90º.

[EX3]

Cita de: Hechelion en 12 de Noviembre de 2008, 06:03:58 PM
pero antes de eso me gustaría saber que técnicas o funciones existen para redondear los bordes, pues de momento el fondo del control es un cuadrado con esquinas de 90º.
En dx_lib32 me temo que ninguna :P Las funciones de primitivas son primitivas hasta en su complejidad ya que son primitivas basicas xDD (no tengo ni funcion para dibujar elipses...)

Lo mas que puedes hacer es que el control permita asociarle dos graficos, uno que haga de esquina redondeada y otro para los bordes (aplicando espejados podrias hacer un marco completo y escalable) y el interior del control ser una primitiva caja o bien otro grafico. Es lo unico que se me ocurre pero seria viable y ademas te daria mas libertad para darle calidad y transparencias al marco del control mediante transparencias o texturas, mejor que un simple marco de lineas :)

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

Hechelion

#7
No quería meter gráficos para no complicar más la clase, pero lo veo como la mejor opción.

Te comento que en estos días que he estado creado 4 clases básicas con la idea de utilizarlas y compartirlas me he dado un atisbo del dolor de cabeza que debió ser programar la librería.

y de ahí surge una duda, en cada clase he tenido que crear unas enumeraciones publicas, el problema es que cuando cargo 2 o más clases en un proyecto VB me detecta dichas enum publicas como redundantes y se niega a correr ¿sabes como solucionar eso?

[EX3]

No he tenido dicho problema ya que cada clase en dx_lib32 tiene su propio codigo sin repetirse en las otras clases. Lo mas enrevesado que tengo es que la clase sistema, en las funciones de colision, utiliza una estructura de datos que esta declarada en la clase grafica, GFX_RECT, es una estructura que usan tanto una como otra clase. Aqui por ejemplo tuve el mismo problema ya que al principio lo que hacia era declarar la estructura en las dos clases con el consiguiente error de duplicado.

Lo idoneo, es que te hagas un modulo bas donde metas las declaraciones, estructuras y enumeraciones que vayas a usar en varias clases, de esta forma daria igual que cargaras una o varias clases ya que no dependerian unas de otras si no que todas apuntarian al modulo bas. Yo esto en dx_lib32 no podia hacerlo ya que en una Dll ActiveX como en un OCX los modulos bas no son visibles fuera de la Dll, son publicos solo dentro del contexto del componente.

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

Hechelion

#9
Lo he arreglado agregando el nombre de la clase a la enumeración


Public Enum EnumTransparenciaCMsgList
    Msg_none = 0
    Msg_Only_Cursor = 1
    Msg_Only_Focus = 2
    Msg_Focus_OR_Cursor = 3
End Enum

Public Enum EnumTransparenciaCSroll
    Scroll_none = 0
    Scroll_Only_Cursor = 1
    Scroll_Only_Focus = 2
    Scroll_Focus_OR_Cursor = 3
End Enum


De esa forma cada clase muestra la misma enumeración cuando se llena el valor y no me produce problemas de nombres, de seguro no es lo más elegante pero funciona sin complicar al usuarios final, las clases están casi listas, son 4, una para crear botones, otra crear texto, otra para crear Scroll (vertical y horizontal) y la última que es la de la lista que además puede funcionar como un frame padre de las otras clases.

actualemte las clases poseen 2 transparencias con lo cual es sumamente fácil programar que el objeto sea transparente hasta que el cursor pase por encima o si se queda con el foco


Set MsgPrincipal = New CMsgList
....
....
MsgPrincipal.UseTransparency2 = Msg_Focus_OR_Cursor '<- indica que use el valor de transparencia2 si tiene el cursor o si tiene le foco
MsgPrincipal.Transparency = 50 '<- transparencia utilizada por defecto
MsgPrincipal.Transparency2 = 0 '<- transparencia utilizada si se pasa el cursor por encima o si se queda con el foco según se especifique con UseTransparency2
MsgPrincipal.Map_Corner = Esquina1 '<-- paso de referencias para mapas que definen las esquinas y el borde, además se puede utilizar una imagen que contenga el fondo
MsgPrincipal.Map_BorderH = BordeH
MsgPrincipal.Map_BorderV = BordeV '<-- esto queda por el error al rotar y deformar una imagen
....
....

'Si dimencionamos con WithEvetens podemos programas algunos eventos comunes del control como click
Private Sub MsgPrincipal_Click()
MsgBox "funciona"
End Sub


Además como pueden ver en la última línea es posible programar eventos individuales para cada objeto creado sin necesidad de manipular la clase.






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.