Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Render Target

Iniciado por AUTOMATEC, 12 de Mayo de 2010, 05:11:53 AM

« anterior - próximo »

AUTOMATEC

Hola,
Mi nombre es Julio Calvo, Ing. Electrónico de profesión y actualmente soy Director Técnico y socio de AUTOMATEC S.R.L., empresa boliviana dedicada al desarrollo de máquinas vending.
Regularmente mi trabajo se enmarca en trabajar con PCB desarrolladas por nosotros mismos con microcontroladores PIC como elementos de control pero esta vez me ha tocado afrontar un proyecto basado en un sistema KT16-AD32 desarrollado por E-Way Technology System Corp. Éste no es más que una placa madre similar a las usadas en las PC de escritorio pero con ciertas características pensadas para su uso específico en ciertos sistemas.
En fin, ahora me ha tocado dejar de lado por un momento el Visual Basic para microcontroladores (Mikropic) y retornar a mis años de universidad cuando tenía cierta destreza con el VB6 para PC. Sin embargo los años no pasan en vano y cuando uno deja de practicar pierde la habilidad.
Dado que el desarrollo que encaramos ahora requiere una interfaz hombre-máquina bastante gráfica, me di a la tarea de investigar sobre la programación de entornos gráficos, algo había escuchado sobre el GDI y el GDI+ y grata fué mi sorpresa al encontrame con tu proyecto "dx_lib32". Luego de probar algunas funciones y procedimientos del mismo puedo dar por sentado que es exactamente lo que estaba buscando, los tutoriales están bastante bien, son entendibles y su implementación es muy intuitiva, sin embargo aún hay ciertas cosas que no entiendo justamente porque mi manejo del Visual Basic es bastante básico ahora.
Particularmente me refiero a las funciones de Render Target. El concepto lo entendí bastante bien por eso me interesa profundizar en ello. En realidad lo que no puedo (y puede parecer una tontería) es realizar  las declaraciones, qué variables pasar, asignar a quién?, etc. Lamentablemente no hay ningún ejemplo de cómo hacerlo y quería pedirte encarecidamente que me pudieras enviar un pequeño ejemplo de cómo crear, cómo abrir, dibujar una línea o cubo y luego cerrar y destruir. Para mi los ejemplos son como las imágenes... valen más que mil palabras.
Espero que puedas leer pronto este mensaje y por favor ayudarme a la brevedad posible, no puedo seguir avanzando si no tengo claro com trabajar con esta función. Si queres enviarme una respuesta directa a mi correo electrónico corporativo la dirección es jcalvo@automatec.com.bo
Te estaré enormemente agradecido y nuevamente... tu proyecto es excelente, felicidades!
Saludos cordiales.

Julio Calvo

[EX3]

Hola, Juan. Gracias por los comentarios :)

Cita de: AUTOMATEC en 12 de Mayo de 2010, 05:11:53 AM
Particularmente me refiero a las funciones de Render Target. El concepto lo entendí bastante bien por eso me interesa profundizar en ello. En realidad lo que no puedo (y puede parecer una tontería) es realizar  las declaraciones, qué variables pasar, asignar a quién?, etc. Lamentablemente no hay ningún ejemplo de cómo hacerlo y quería pedirte encarecidamente que me pudieras enviar un pequeño ejemplo de cómo crear, cómo abrir, dibujar una línea o cubo y luego cerrar y destruir. Para mi los ejemplos son como las imágenes... valen más que mil palabras.
Pues vamos a ello. El mecanismo de los RenderTarget es muy sencillo a la vez que basico ya que se trabaja de igual manera que si dibujaras normalmente como se hace en los ejemplos que has visto. Un pequeño ejemplo de como funciona el sistema. El codigo esta basado en el del tutorial 2, por lo que podrias abrir el tutorial y reemplazar el codigo por este para verlo funcionar:
Option Explicit

Private Graphics As dx_GFX_Class ' Instancia del objeto grafico de dx_lib32.
Private Render As Boolean ' Controla el bucle de renderizado.
Private Texture As Long ' Identificador de la textura.

Private TextureTarget As Long  ' Identificador de la textura que usaremos como destino de las operaciones de dibujo del render target.
Private RenderTarget As Long ' Identificador de la instancia del render target.

' La idea general del render target es crear una composicion permamente sobre una textura para evitar, por ejemplo, tener que
' redibujarlas continuamente de forma independiente. Definimos pues una bandera para controlar que generamos el contenido
' render target una sola vez:
Private SetContent As Boolean

Private Sub Form_Load()
    Me.Show ' Forzamos al formulario a mostrarse.
    Set Graphics = New dx_GFX_Class ' Creamos la instancia del objeto grafico.
    Render = Graphics.Init(Me.hWnd, 640, 480, 32, True) ' Inicializamos el objeto grafico y el modo de video.
    Texture = Graphics.MAP_Load(App.Path & "\texture.png", 0) ' Cargamos la textura para el sprite.
   
    TextureTarget = Graphics.MAP_Create(512, 512, True) ' Creamos la textura destino del render target.
    ' Al crearla con MAP_Create le indicamos en el 3º parametro que se usara para tal fin.
    ' Como se explica en la documentacion, los mapas o texturas trabajan internamente en tamaños o dimensiones de potencia 2
    ' por lo que no se le podria aplicar un tamaño irregular como 640x480 u 800x600 ya que al crearla se redimensionara
    ' automaticamente al siguiente tamaño o dimension que sea potencia 2 (640x480 -> 1024x512, 800x600 = 1024x1024).
   
    RenderTarget = Graphics.TARGET_Create(TextureTarget) ' Creamos la instancia del render target asignando la textura de destino que hemos creado.
       
    Do While Render
        If Not SetContent Then
            Graphics.TARGET_Open RenderTarget ' Abrimos el render target para capturar operaciones de dibujo.
            ' Solo se puede tener un render target abierto al mismo tiempo.
           
            ' Dibujamos unas cuantas cosas:
            Graphics.DRAW_Map Texture, 0, 0, 0, 0, 0
            Graphics.DRAW_Box 100, 100, 300, 300, 0, &HFFFF0000
            Graphics.DRAW_Line 0, 0, 512, 512, 0, &HFF00FF00
           
            Graphics.TARGET_Close ' Cerramos el render target.
           
            SetContent = True
        End If
       
        ' Dibujamos la textura del render target aplicando transformaciones (dibujamos a mitad de tamaño y rotado unos 26º):
        Graphics.DRAW_MapEx TextureTarget, Graphics.Screen.Width \ 2, Graphics.Screen.Height \ 2, 0, 256, 256, 26, Blendop_Color, &HFFFFFFFF, Mirror_None, Filter_Bilinear, True
        ' Una de las ventajas del render target es que se puede aplicar transformaciones a toda la composicion creada de la misma forma
        ' que una textura normal y corriente, que de hecho, el resultado es ese.
       
        Graphics.Frame ' Renderizamos la escena.
    Loop
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Graphics.MAP_Unload Texture ' Descargamos la textura de memoria.
    Render = False ' Termina el bucle de renderizado.
    Graphics.Terminate ' Terminamos la ejecucion de la clase grafica y liberamos los recursos utilizados.
    Set Graphics = Nothing ' Destruimos la instancia del objeto grafico.
End Sub

El unico problema a tener en cuenta con los render target es que mi implementacion, la de dx_lib32, es muy lenta en ciertos casos, para crear composiciones continuamente en tiempo real. En el ejemplo creamos la composicion una sola vez y en una textura de 512x512, a 1024x1024 quizas seria mas lento todavia, por lo que siempre he desaconsejado su uso salvo necesidad. Al menos es el sistema has visto que es sencillo de utilizar por lo que puedes experimentar para tus necesidades y adaptarlo de forma que no reduzca severamente el rendimiento de tu aplicacion.

Pues nada, espero que el tutorial y las explicaciones te sean de ayuda ;)

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

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

AUTOMATEC

Estimado José,

Te quiero agradecer profundamente por tu ayuda con el tema del Render Targer. Me ha funcionado a las mil maravillas y es justo como lo quería.
Te comento a grandes rasgos que se trata de una máquina de video bingo que debe generar aleatoriamente los números de 4 cartones que se ponen en juego al mismo tiempo, pero una vez visualizados no hacia falta modificarlos ni nada por el estilo así que la filosofía del Render Target de dibujarlo una sola vez y luego asociarlo a un gráfico cayó como anillo al dedo, no se nota en lo más mínimo ratardo alguno.
Cuando lo tenga un poco más avanzado te pasaré el código para que le eches un vistazo y me digas tu opinión.
Nuevamente te felicito por ese proyecto y te agradezco infinitamente por brindarnos esta herramienta tan útil.

Saludos cordiales.

Julio Calvo

[EX3]

#3
Gracias, me alegro de que te haya servido de ayuda :)

Salu2...

P.D.: No se si es por modificaciones de la version con la que estoy trabajando actualmente o de la que esta publicada en la web pero haciendo pruebas tambien he notado que el render target en tiempo real (renderizando una escena de 800x600 en cada frame sobre una textura de 1024x1024) rinde mejor (muchisimo mejor de lo que esperaba) que las pruebas que hice hace años atras (en la version 2.1.186 mas o menos), de hecho lo estoy implementando en mi juego y no he notado severos problemas (mantengo una tasa de actualizacion de entre 38 y 45 fps frente a los 5 o 7 fps que lograba antaño, teniendo en cuenta que 30fps minimo es aceptable), lo cual es una buena noticia si alguien precisa utilizarlo en sus proyectos (para realizar efectos sobre la composicion de la escena como zooms, rotaciones, efectos de post-proceso o lo que se le ocurra a cada uno :))
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

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

Hechelion

Tal vez sea porque desde que comenzó el proyecto hasta ahora los PC han evolucionado y ya no usan carbón :P

En todo caso, una excelente noticia, aunque por lo que entiendo el colega sólo precisa crear el contenido una vez por partida y no de forma general en cada frame, a todo esto suerte con el proyecto y una agradable noticia ver que se está haciendo el desarrollo porque he visto que muchas máquina similares las arman en latinoamericana, pero toda la electrónica la compran lista en china.

[EX3]

Cita de: Hechelion en 13 de Mayo de 2010, 12:50:03 PM
Tal vez sea porque desde que comenzó el proyecto hasta ahora los PC han evolucionado y ya no usan carbón :P
Si no fuera por que llevo casi 10 desarrollando y manteniendo otros tantos la libreria (que empece en su dia con un Pentium II 400mhz sin grafica 3D y con 64mb RAM) hasta te diria que es eso jajajaja... :P

Cita de: Hechelion en 13 de Mayo de 2010, 12:50:03 PM
En todo caso, una excelente noticia, aunque por lo que entiendo el colega sólo precisa crear el contenido una vez por partida y no de forma general en cada frame.
Ya ya, si eso lo entendi en su pregunta y asi lo ha hecho por lo que comenta. El asunto es que cuando yo decidi implementar en su dia el mecanismo de render target era con la intencion de usarlo para poder renderizar toda la escena a una textura y poder, de forma unica, aplicar transformaciones y demas efectos a la escena, por ejemplo, rotar ligeramente toda la escena para simular inclinacion de la camara (si jugastes al Super Metroid de SNES veras este efecto al finalizar el primer nivel de juego), aplicar espejejados (en prince of persia, cuando tomabas la pocima trampa que invertia la pantalla, menuda "broma" xDD) o crear pequeños efectos post-proceso ya sea alterando la coloracion de la escena uniformemente (o renderizarla en escala de grises para una escena, que por ejemplo, sea un flashback) o hacer algun efecto de vision doble (por ejemplo, conjuntandolo con un resalte en blanco aditivo, como si fuera el efecto despues de que te cegaran) o hasta hacer un juego a pantalla partida (dos render targets, uno para el jugador 1 y otro para el jugador 2). En fin, que se me acaba de abrir la opcion de implementar viejas ideas que ya di por perdidas en mi proyecto del juego :D

Salu2...

P.D.: Ahora falta ver que con toda la carga grafica no baje por debajo de 35fps como minimo, si no tocara nuevamente descartar :P
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

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






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.