Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Problemillas con refresco, nitidez y líneas

Iniciado por RobiHm, 08 de Abril de 2007, 09:39:01 PM

« anterior - próximo »

RobiHm

Saludos cordiales, antes de nada felicitarte por el currele que has realizado con la librería y sobre todo con la documentación.
Decir que creo haber encontrado un pequeño fallo en la doc.
CitarY
Long. Coordenada vertical de dibujo. Para saber como funciona este parámetro leer información acerca del ZBuffer.
Z
Long. Coordenada de profundidad de dibujo.


Bueno os expongo mis dudillas/problemillas xD

Tengo un formulario a 1280x1024 en el que genero todo el tinglao.
Un mapa y el menú de usuario. Antes lo hacia en un MDI porque el juego dispone de más menús y demás, pero era imposible implementarlo con la librería.

Bueno los problemas son los siguientes.

Yo tengo controles y demás sobre el formulario para aprovechar sus eventos y ejecutar procesos concretos. Luego un par de timers, los de efectos y el de gráficos, mi problema surje cuando el de gráficos se ejecuta puesto que a veces actualiza (supongo que el form) y se nota el refresco de los otros controles. Tampoco me dibuja las líneas. Y los dibujos salen borrosos, he probado todos los filtros al cargar y en el que mejor se ve es sin filtro pero sigue borrososillo.

Mi duda es si los eventos de interfaz es recomendable hacerlo por controles o sin controles. Si es sin controles pordríais orientarme cómo hacerlo?.

Os pego el código, yo utilizo mysql como base de datos asi que quito las sentencias para ahorrar code.


Private Sub tmrdibuja_Timer()
   actualiza_graficos   'interval a 50
End Sub


'REFRESCA LOS GRÁFICOS
Private Sub actualiza_graficos()
   Dim X As Long, Y As Long
   Dim i As Integer
   
   'creamos los gráficos
   'generamos el fondo
   Call m_gfx.DRAW_Map(GRA_MIS("fondo"), 0, 0, 0, Me.Width, Me.Height)
   
'
   'dibujamos las casillas
   'creamos las casillas a lo ancho
   If optvercasillas(0).Value = True Then
       i = 0
       Do While i < NANCASILLAS
           m_gfx.DRAW_Line 0, i * TCASILLAS, NANCASILLAS * TCASILLAS, i * TCASILLAS, 0, m_gfx.ARGB_Set(0, 255, 255, 255)
           i = i + 1
       Loop
       'creamos las casillas a lo largo
       i = 0
       Do While i < NALCASILLAS
           m_gfx.DRAW_Line i * TCASILLAS, 0, i * TCASILLAS, NANCASILLAS * TCASILLAS, 0, m_gfx.ARGB_Set(0, 255, 255, 255)
           i = i + 1
       Loop
   End If
   
   'dibujamos los castillos
   Do While Not tdib.EOF
       'dibujamos
       dibujame "castillo", tdib!nx, tdib!ny + 200, 3
       tdib.MoveNext
   Loop
   
   'dibujamos los poblados
   Do While Not tdib.EOF
       'dibujamos
       dibujame "poblado", tdib!nx, tdib!ny + 200, 3
       tdib.MoveNext
   Loop
   
       
   'dibujamos las unidades
       'las recorremos
       Do While Not tdib.EOF
           'las dibujamos
           dibujame tdib!imagen & "-" & tdib!nombre & tdib!numframe, CLng(tdib!nx - 100), CLng(tdib!ny + 100), 1
           tdib.MoveNext
       Loop
       
   'dibujamos las banderas
       'las recorremos
       Do While Not tdib.EOF
           'las dibujamos
           X = tdib!nx - 50: Y = tdib!ny + 100
           For i = 0 To tdib!total
               dibujame "b" & tdib!jugador, X + i * 10, Y, 3
           Next i
           tdib.MoveNext
       Loop
   'sin tropas
       'las recorremos
       Do While Not tdib.EOF
           'las dibujamos
           If tdib!jugador = 0 Then
               dibujame "libre", tdib!nx - 50, tdib!ny + 100, 3
           Else
               dibujame "b" & tdib!jugador, tdib!nx - 50, tdib!ny + 100, 3
           End If
           tdib.MoveNext
       Loop
   
   'dibujamos los efectos
       'los recorremos
       Do While Not tdib.EOF
           'los dibujamos
           dibujame tdib!ngrafico & tdib!numframe, tdib!X, tdib!Y, 2
           tdib.MoveNext
       Loop
   
   'Ejecutamos las llamadas de la clase grafica:
   Call m_gfx.Frame(m_gfx.ARGB_Set(0, 255, 255, 255), 60)
End Sub


'DIBUJA EN EL FORMULARIO EN LAS COORDENADAS x , y
Private Sub dibujame(ruta As String, X As Long, Y As Long, tipo As Integer, Optional borro As Boolean = False)
   Dim carga As Long
   If tipo = 1 Then
       carga = GRA_UNIDADES(ruta)
   ElseIf tipo = 2 Then
       carga = GRA_EFECTOS(ruta)
   ElseIf tipo = 3 Then
       carga = GRA_MIS(ruta)
   End If
   Call m_gfx.DRAW_MapEx(carga, CLng(X / Screen.TwipsPerPixelX), CLng(Y / Screen.TwipsPerPixelY), 0, 0, 0, 0, Blendop_Color, &HFFFFFFFF, Mirror_None, Filter_None, False)
   
End Sub
Web : Indómita
Blog : MiBlog
Evobas : Evobas
Kobox : Kobox

[EX3]

Wenas.

Cita de: "RobiHm"Decir que creo haber encontrado un pequeño fallo en la doc.
CitarY
Long. Coordenada vertical de dibujo. Para saber como funciona este parámetro leer información acerca del ZBuffer.
Z
Long. Coordenada de profundidad de dibujo.
Solo te falta decirme en que funcion esta la errata o es en todas donde aparece la descripcion de las coordenadas Z e Y?

Cita de: "RobiHm"Mi duda es si los eventos de interfaz es recomendable hacerlo por controles o sin controles. Si es sin controles pordríais orientarme cómo hacerlo?.
Yo no recomiendo usar renderizado por DirectX y controles de interfaz de Windows ya que estos se renderizan por el GDI y no puedes hacer una presentacion grafica correcta usando ambos ya que cada uno se refresca en tiempos diferentes, de ahi el molesto parpadeo. Lo ideal y que yo recomendaria seria al igual que en los tutoriales, un formulario vacio sin controles, con borde fijo no escalable (para evitar ciertos problemas) con el comando de maximizar desactivado y con barra de titulo como mucho (en modo pantalla completa dx_lib32 retira automaticamente la barra de titulo). Luego para programar los eventos de entrada de teclado o raton deberias usar las funciones de la clase dx_Input y para mostrar controles visuales podrias hacerlo mediante primitvas y texto o bien usando imagenes. Para detectar colision del raton con los controles graficos tienes las funciones de colision de cajas y punto de dx_System y dx_Input para detectar las pulsaciones del raton. Luego, yo prefiero no instanciar controles de ninguna clase, lo digo por los Timers. dx_lib32 como veras tambien implementa sus propias rutinas para programar cronometros y asociarles un procedimiento Sub a modo de evento, pero vamos, no hay mucha diferencia de usar un Timer de Visual Basic a usar el cronometro de dx_lib32, esto ya es cuestion de gustos.

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

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

RobiHm

Ante todo muchisimas gracias por responderme [EX3] .

Por ahora solo me lo tope en el DRAW_MapEx al mirar si era en pixeles o twist las coords, como no lo pone he supuesto que es en pixeles (lógico xD)

Citardx_GFX_class: DRAW_MapEx
DRAW_MapEx


buf hacer todo con el dx_Input va a ser bastante duro, más que nada porque tendré que hacerme unas cuantas imágenes y programar cientos de eventos manuales xD, pero asi aprendo a utilizar el input xD

Lo de la nitidez es lo que más me preocupa adjunto un ejemplo.



Si eso lo hace con el decorado con los muñecajos ni te cuento.
Todas las imágenes las tengo en png, y con otras clases/controles logro verlas correctamente, al cargarlas con la librería se ven borrosillas.
Web : Indómita
Blog : MiBlog
Evobas : Evobas
Kobox : Kobox

[EX3]

Las imagenes que estas usando me supongo que seran de tamaños irregulares, dicho de otra forma, no son de tamaño potencia de 2 (16x16, 32x32, 128x128, 512x32, 256x1024 y combinaciones similares de potencia de 2...). Direct3D, API en el que se apoya dx_lib32, trabaja con texturas y estas en la memoria de la tarjeta siempre son de tamaño de potencia de 2. dx_lib32 te permite cargar cualquier imagen del tamaño que sea pero luego en memoria la tarjeta lo redimensiona a tamaño potencia de 2, por lo que una imagen de 131x185 pasaria a ser 256x256, y al redimensionar suaviza los pixeles, por lo que en imagenes muy pequeñas o de tamaños muy irregulares da ese aspecto tan borroso. Hay formas de que dx_lib32 intente respetar lo maximo posible la presentacion original de las imagenes, una es mediante los filtros a la hora de dibujar escalados con DRAW_MapEx() desactivando el filtrado de pixeles mediante la constante Blit_Filter.Filter_None en el parametro Filter. Otra forma tambien es cargar la imagen con MAP_Load(), o sus variantes, sin aplicar suavizado de pixeles cambiando el parametro opcional Smooth a False. Prueba con estos pasos que te comento y me cuentas, en la documentacion tienes algo mas de informacion sobre esto en las respectivas funciones.

Sobre dx_Input, no se exactamente que buscas hacer pero si tengo un hueco en el trabajo te ilustro con un pequeño ejemplo de menu grafico usando clases para crear objetos boton y demas.

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

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

RobiHm

Te subo una imágen de los gráficos con los que hago las pruebas, 72x72 (he probado anchando el mapa de pixels a 128x128 y se ve igual), es del Wesnoth. Por si quieres probarla.

[img=http://www.imaxenes.com/imagenes/piquero1mu64k8.png]

He probado lo que comentabas de los filtros y nada de nada sigue mostrandolo igual de borrosillo.

Respecto a lo del input quiero hacer una interfaz parecida a la del starcraft, nose si sabras como es, acciones de unidad, estado, caracteristicas y tal. Lo del ejemplo sería fabuloso.

Gracias por la ayuda, estoy aprendiendo bastante.
Web : Indómita
Blog : MiBlog
Evobas : Evobas
Kobox : Kobox

[EX3]

No me carga la imagen. Coloca bien los tags de imagen para se muestre la imagen en los mensajes del foro y utiliza ImageShack para subir las fotos al web, que este al menos no suele fallar.

Sobre lo de que te sigue mostrando borrosas las imagenes, mira a ver si puedes subir el proyecto para que lo pueda descargar y en un rato libre en casa echarle un vistazo o muestrame el codigo de inicializacion, carga de texturas y dibujo de las mismas a traves de una respuesta.

En principio con el filtro desactivado y cargando las imagenes sin suavizado no deberia emborronar las texturas.

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

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

[EX3]

Cita de: "[EX3"]En principio con el filtro desactivado y cargando las imagenes sin suavizado no deberia emborronar las texturas.
Rectifico, a mi tampoco me esta respetando el aspecto de los pixeles cuando reescalo. Esto recuerdo que cuando lo implemente fue para usos en los que la imagen se presentaba en su tamaño real, sin escalar, y se pretendia que diera la impresion de no estar suavizado, a tamaño real si se aprecia:

La captura esta escalada para apreciar algo mejor los detalles. Fijate que la primera esta cargada con Smooth = False y dibujada sin filtro mientras que la segunda esta cargada con suavizado y dibujada con filtro bilinear. Observa que se aprecia mas borrosa la segunda que la primera. Es los reescalados seguramente tambien lo este aplicando pero al ser escalas tan grandes no se debe apreciar a simple vista. En verdad esto esta pensado para trabajar en resoluciones bajas como 320x240 en caso de querer hacer un remake de un juego por ejemplo donde se busca ese aspecto pixelado (esto ahora que me acuerdo esta comentado en la documentacion)

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

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

RobiHm

Te coloco mi código


Imágen


definición de clase blablbal

Const MODO_VIDEO_ANCHO = 1280   'propiedades de pantalla
Const MODO_VIDEO_ALTO = 1024    '
Const MODO_BITS_COLOR = 32      '
Const MODO2_VIDEO_ANCHO = 800   'propiedades de pantalla
Const MODO2_VIDEO_ALTO = 600    '
Const MODO2_BITS_COLOR = 16      '

'Variable objeto que apunta a la clase dx_GFX:
Public m_gfx As dx_GFX_Class

' InicializarDX
Public Function InicializarDX(frm As Form, modo As Integer) As Boolean
On Error GoTo ErrHandler

   'Creamos la instancia de la clase dx_GFX:
   Set m_gfx = New dx_GFX_Class
   
   If modo = 2 Then
       'Inicializamos la clase y el modo de video a 640x480 en modo ventana:
       Call m_gfx.Init(frm.hWnd, MODO_VIDEO_ANCHO, MODO_VIDEO_ALTO, MODO2_BITS_COLOR, True)
   ElseIf modo = 1 Then
       Call m_gfx.Init(frm.hWnd, MODO_VIDEO_ANCHO, MODO_VIDEO_ALTO, MODO2_BITS_COLOR, False)
   End If
   Exit Function
ErrHandler:
   MsgBox Err.Description, , "Codigo de error: " & Err.Number
   Debug.Print "Codigo de error: " & Err.Number, Err.Description
   InicializarDX = False
End Function



Public GRA_UNIDADES As New Collection   'gráficos de unidades

carga (un procedimiento llamado carga todo que carga todo)

'cargamos los gráficos
   InicializarDX frmmapanormal, 2
  'unidades
   Cmd.CommandText = "select imagen from z_unidades"
   Set rs = Cmd.Execute
   While Not rs.EOF
           GRA_UNIDADES.Add m_gfx.MAP_Load(App.Path & "\images\unidades\" & rs!imagen & "-normal1" & ".png", 0, False), rs!imagen & "-normal1"
       rs.MoveNext
   Wend


visualización

 
   'generamos el fondo
   Call m_gfx.DRAW_Map(GRA_MIS("fondo"), 0, 0, 0, Me.Width, Me.Height)


'dibujamos las unidades
Cmd.CommandText = "select m.nx,m.ny,a.nombre,u.numframe,z.imagen " & _
    " from mapa m,u_unidades u,z_acciones a,z_unidades z" & _
    " where m.id=u.posicion and u.uaccion=a.id and z.uniid=u.uniid order by prioridad asc"
   Set tdib = Cmd.Execute
       'las recorremos
       Do While Not tdib.EOF
           'las dibujamos
           dibujame tdib!imagen & "-" & tdib!nombre & tdib!numframe, CLng(tdib!nx - 100), CLng(tdib!ny + 100), 1
           tdib.MoveNext
       Loop

'Ejecutamos las llamadas de la clase grafica:
   Call m_gfx.Frame(m_gfx.ARGB_Set(0, 255, 255, 255), 60)



procedimiento dibujame

'DIBUJA EN EL FORMULARIO EN LAS COORDENADAS x , y, se le envia con la ruta y true=borra anterior,false no borra
Private Sub dibujame(ruta As String, X As Long, Y As Long, tipo As Integer)
   Dim carga As Long
   If tipo = 1 Then
       carga = GRA_UNIDADES(ruta)
   ElseIf tipo = 2 Then
       carga = GRA_EFECTOS(ruta)
   ElseIf tipo = 3 Then
       carga = GRA_MIS(ruta)
   End If

   Call m_gfx.DRAW_MapEx(carga, CLng(X / Screen.TwipsPerPixelX), CLng(Y / Screen.TwipsPerPixelY), 0, 0, 0, 0, Blendop_Color, &HFFFFFFFF, Mirror_None, Blit_Filter.Filter_None, False)
 
End Sub



¿Existe alguna forma de solventarlo?
Web : Indómita
Blog : MiBlog
Evobas : Evobas
Kobox : Kobox

[EX3]

En principio, trabajando con las escalas correctas deberia verse bien y tu imagen no tiene un tamaño potencia de 2 (72x72) por lo que siempre se vera suavizada aun siendo minimamente desactivando el suavizado en la carga, que es lo que sucede en el ejemplo que ilustro antes (la imagen de la nave es de 26x39). Tendras que redimensionar tus imagenes (no reescalar por que perderias el aspecto original de las mismas) si no quieres que se suavicen los pixeles y el reescalado o redimensionado no me refiero hacerlo en tiempo de ejecucion con dx_lib32 si no con un programa de edicion grafico previamente de usar las imagenes en tu programa. La imagen debe ser originalmente de tamaño potencia 2.

Por otro lado veo algunas cosas mal en tu codigo:
'Ejecutamos las llamadas de la clase grafica:
   Call m_gfx.Frame(m_gfx.ARGB_Set(0, 255, 255, 255), 60)

Tener cuidado al definir colores con el primero parametro de ARGB_Set(). Recuerda que trabajas con colores de 32 bits y 4 canales: alpha, rojo, verde y azul. Si alpha vale 0 el color resultante es totalmente transparente y en este caso pintaria negro y no blanco como has definido. Los colores solidos siempre tiene alpha = 255.

Call m_gfx.DRAW_MapEx(carga, CLng(X / Screen.TwipsPerPixelX), CLng(Y / Screen.TwipsPerPixelY), 0, 0, 0, 0, Blendop_Color, &HFFFFFFFF, Mirror_None, Blit_Filter.Filter_None, False)
No pierdas tiempo realizando conversiones de twips a pixel con las funciones de Visual Basic. La clase dx_GFX ofrece su propio objeto Screen con las propiedades del modo de video que has establecido que se corresponde con area donde trabajas en la ventana, osea, el area cliente y no toda la ventana como tal (bordes internos y externos, barra de titulo, etc...) y estos valores ya estan en pixeles.

Prueba a redimensionar correctamente tus imagenes y vuelve a probar con los parametros de suavizado y filtrado desactivados. Yo he redimensionado a 64x64 y he probado a dibujarlos a diferentes escalas, todas ellas potencia de 2, y se ven totalmente pixeladas y sin desactivar los filtros o el suavizado al cargar:



Tu sprite redimensionado a 64x64



Una captura del programa con los resultados

Y el codigo de la prueba (el tutorial 2 modificado)
Option Explicit

'Variable objeto que apunta a la clase dx_GFX:
Dim m_gfx As dx_GFX_Class

'Alamcena el valor del grafico en memoria:
Dim Sprite As Long

'Controla el bucle principal:
Dim Looping As Boolean

Private Sub Form_Load()
'Mostramos la ventana:
Me.Show

'Creamos la instancia de la clase dx_GFX:
Set m_gfx = New dx_GFX_Class

'Inicializamos la clase y el modo de video a 640x480 en modo ventana:
Call m_gfx.Init(Me.hWnd, 640, 480, , True)

'Cargamos un grafico en memoria:
Sprite = m_gfx.MAP_Load(App.Path & "\Texture.png", 0)

Looping = True

Do While Looping
   Call m_gfx.DRAW_Map(Sprite, 0, 0, 0, 16, 16)
   
   Call m_gfx.DRAW_Map(Sprite, 16, 0, 0, 32, 32)
   
   Call m_gfx.DRAW_Map(Sprite, 48, 0, 0, 0, 0) ' Toma los valores por defecto de tamaño de la textura en memoria, 64x64 en este caso.
   
   Call m_gfx.DRAW_Map(Sprite, 112, 0, 0, 128, 128)
   
   Call m_gfx.DRAW_Map(Sprite, -32, 128, 0, 256, 256)
   
   Call m_gfx.DRAW_Map(Sprite, 128, 0, 0, 512, 512)
   
   'Ejecutamos las llamadas de la clase grafica:
   Call m_gfx.Frame

Loop

'Descargamos el grafico de la memoria:
Call m_gfx.MAP_Unload(Sprite)

'Terminamos la ejecucion de la clase:
Call m_gfx.Terminate

'Destruimos la instancia de la clase:
Set m_gfx = Nothing

End

End Sub

Private Sub Form_Unload(Cancel As Integer)
Looping = False

End Sub


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

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

RobiHm

Gracias por la ayuda redimensionaré/recortaré todas las imágenes a 64x64 y listo.

Lo de los colores lo queria transparente, solamente estaba trasteando con el ARGB xD

Las conversiones de twist y pixeles es debido a que yo usaba directamente direc 8 sin tu librería y declarabá las medidas en twist, lo puse de este modo como apaño, pero no lo dejaré asi xD
Ante todo gracias por las observaciones.

Respecto a los menús no he visto ningún ejemplo en los tutos. Pero supongo que será con clicks y coordenadas en el input.

Lo dicho muchas gracias xD
Web : Indómita
Blog : MiBlog
Evobas : Evobas
Kobox : Kobox

[EX3]

Cita de: "RobiHm"Respecto a los menús no he visto ningún ejemplo en los tutos. Pero supongo que será con clicks y coordenadas en el input.
No hay tutoriales sobre implementaciones de GUI con dx_lib32 y ahora mismo tampoco me sobra mucho tiempo para escribir uno me temo. Lo tendre en cuenta para cuando pueda cerrar la proxima distribucion de dx_lib32 en lo de meter algun ejemplo sencillo de menu y elementos muy basicos de GUI.

Salu2...
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.