Hola
Estoy usando DirectX 8 para dibujar un mapa a base de tiles. De momento estoy llenando toda la pantalla con una sola casilla. Como todas las casillas las tengo en una textura al crear los vertices tengo q indicar en que coordenadas de la textura esta la casilla a pintar.
Ocurre una cosa muy extraña. Segun ponga unas coordenadas de la textura u otra a los vertices consigo 85 frames por segundo o 43. ¿alguien sabe a q se debe? Os pongo debajo las coordenadas q pongo. Con las q estan comentadas consigo 85fps y con las otras 43. Es muy raro ¿no? :(
textX1 = 0.375
textY1 = 0
textX2 = 0.5
textY2 = 0.0625
'textX1 = 0.125
'textY1 = 0.03125
'textX2 = 0.25
'textY2 = 0.0625
85/43? me huele a v. sync
¿que es lo del v. sync?
85 podría ser, pero el 43 no me suena a vsync. Seguro que lo tiene activado, pero el 43 a saber.
El vsync es el vertical sync o sincronización vertical, que consiste en que la tarjeta gráfica rasterize un frame en cada pasada del monitor. De esta forma, si tienes el refresco vertical del monitor a 85 Hz, la tarjeta mostrará 85 frames por segundo.
Saludos.
¿conviene tener activado el vsync?
Lo raro es q la disminucion de los fps se produzca al cambiar las coordenadas de la textura que le paso a los vertices a la hora de crearlos. Con unos valores tiene unos fps y con otros otros direntes y ademas es casi la mitad.
Normalmente siempre tengo unos fps de 85.
Si normalmente tienes unos 85 fps, esta claro que tienes activado el vsync.
Hay gente que le gusta jugar con vsync porque dicen que se ve más fluido el juego. Lo ideal sería dar la opción al usuario de elegir lo que más le guste. Aunque creo que la mayoría de juegos desactivan el vsync :?:
Saludos.
Las coord. de textura no tienen nada que ver. Creo que deberías replantearte el problema. Quizás el problema venga a la hora de calcular en tu programa qué coordenadas le toca a cada uno.
Otra cosa..¿estás utilizando DX8 con DDraw o directamente con D3D? ¿Y estás utilizando hard o soft rasterizer?
Antes de nada muchas gracias a todos por echarme una mano :)
¿como se activa o desactiva el vsync?
Estoy usando D3D.
Las coordenadas las calculo dividiendo 1 entre el numero de tiles que tiene la textura y multiplicando todo por la posicion q ocupa la tile q quiero dibujar en textura.
En las lineas de codigo q puse antes si simplemente pongo comentarios en las lineas q no lo tenian y los quito de las que lo tenian ya, consigo los 85 fps. Por eso pienso q es ahi donde esta el problema, pero como estoy empezando todavia no las DirectX y no tengo mucha idea quiza haya hecho algo mal en algun otro punto.
Cuando inicializas Direct3D, la estructura D3DPRESENT_PARAMETERS tiene un miembro llamado PresentationInterval de tipo UINT. Si lo estableces a D3DPRESENT_INTERVAL_ONE tendrás activado el vsync.
Saludos.
He probado a cambiar su valor a D3DPRESENT_INTERVAL_ONE y se me mantienen los fps (a 85 y 43 dependiendo de las coordenadas q de a la textura)
He probado a ponerlo a D3DPRESENT_INTERVAL_IMMEDIATE y han aumentado los fps a 95 y 82 (segun las coordenadas q pase a la textura)
Lógico. Con INMEDIATE se muestran tantos FPS como tu aplicación pueda calcular y crear, de manera que INMEDIATE siempre dará más FPS que ONE. COn ONE, como ya dije, se sincroniza la muestra de frames con el refresco del monitor. Apostaría a que el refresco actual de tu monitor es 85 Hz :P
Saludos.
¿Immediate puede causar problemas al visualizarse? Lei hace tiempo q si no esperabas al refresco vertical se podian producier parpadeos al mostrarl las imagenes.
¿donde puedo mirar le frecuencia de refresco? He buscado en propiedades de pantalla y no lo he encontrado. ¿Que frecuencia es mejor poner?
No se mucho de DX pero creo q os habeis desviado del tema, no creo q el vsync tenga nada q ver, eso solo fue un comentario q se hizo acerca de q la tasa de 85 fps posiblemente fuera debido al vsync pero nada mas.
Yo pienso q mas bien es lo q ha dicho Haddd ;)
saludos
El calculo de las coordenadas de la textura creo q esta bien porque me dibuja justo la tile que quiero de todas las que tiene la textura. ¿donde podria estar el fallo?
¿no se os ocurre porque puede ser?
Puedo postear el codigo a ver si alguno veis donde esta el fallo.
Postealo, creo q sera la mejor solucion, si es mucho te recomiendo q pegues solo una parte o lo subas a un sitio web y pongas el link
saludos
Ahi va, espero q sea legible. Solo copio los procedimientos que pueden tener algo q ver (inicializarD3D, cargarTextura, dibujarCasilla, crearVertice, render)
Utilizo el mismo cuadrado (2 triangulos, 4 vertices) para dibujar todas las casillas. Voy cambiando la posicion de los vertices y la parte de la parte de la textura antes de dibujar la proxima casilla) Actualmente como estoy de pruebas siempre se dibuja la misma casilla por toda la pantalla.
Seguro q encontrais muchas cosas q no estan bien o son mejorables. Todas las criticas son bienvenidas :D
Y muchas gracias de antemano por leeros tantas lineas :)
Public Function inicializarD3D(hWnd As Long) As Boolean
On Error GoTo tratErr
Dim modo As D3DDISPLAYMODE 'describe nuestro modo de visualizacion
Dim D3DWindow As D3DPRESENT_PARAMETERS 'como se mostrara
Set DX = New DirectX8
Set D3D = DX.Direct3DCreate()
Set D3DX = New D3DX8
If D3D Is Nothing Then Exit Function
' capturamos el modo de visualizacion actual
D3D.GetAdapterDisplayMode D3DADAPTER_DEFAULT, modo
modo.Format = D3DFMT_R5G6B5 'If this mode doesn't work try the commented one above...
modo.Width = 800
modo.Height = 600
D3DWindow.SwapEffect = D3DSWAPEFFECT_FLIP
D3DWindow.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE 'D3DPRESENT_INTERVAL_ONE
D3DWindow.BackBufferCount = 1 '//1 backbuffer only
D3DWindow.BackBufferFormat = modo.Format 'What we specified earlier
D3DWindow.BackBufferWidth = 800
D3DWindow.BackBufferHeight = 600
D3DWindow.hDeviceWindow = hWnd
Set D3DDevice = D3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, _
D3DCREATE_SOFTWARE_VERTEXPROCESSING, D3DWindow)
If D3DDevice Is Nothing Then Exit Function
'//Set the vertex shader to use our vertex format
D3DDevice.SetVertexShader FVF
'//Transformed and lit vertices dont need lighting
' so we disable it...
D3DDevice.SetRenderState D3DRS_LIGHTING, False
D3DDevice.SetRenderState D3DRS_SRCBLEND, D3DBLEND_SRCALPHA
D3DDevice.SetRenderState D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA
D3DDevice.SetRenderState D3DRS_ALPHABLENDENABLE, True
'ColorKeyVal = &HFFFF00FF '//Magenta 256 colores
ColorKeyVal = &HFFFF00FA '//Magenta 16 bits
' Set textura = D3DX.CreateTextureFromFile(D3DDevice, App.Path & "protaRPG.bmp")
fnt.Name = "Verdana"
fnt.Size = 10
Set MainFontDesc = fnt
Set MainFont = D3DX.CreateFont(D3DDevice, MainFontDesc.hFont)
inicializarD3D = True
Exit Function
tratErr:
cerrarDD
inicializarD3D = False
End Function
Public Sub cargarTextura(textura As Direct3DTexture8, fichero As String)
Set textura = D3DX.CreateTextureFromFileEx(D3DDevice, App.Path & "" & fichero, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_FILTER_POINT, D3DX_FILTER_POINT, ColorKeyVal, ByVal 0, ByVal 0)
End Sub
Public Sub dibujarCasilla(x As Integer, y As Integer, casilla As Integer, textura As Integer)
Dim xx As Single
Dim yy As Single
Dim textX1 As Single 'coordenadas de la textura q se van a dibujar
Dim textY1 As Single
Dim textX2 As Single
Dim textY2 As Single
xx = CSng(x)
yy = CSng(y)
textX1 = 0.375 '(1 / tileSet(textura).ancho) * desplazamientoX
textY1 = 0 '(1 / tileSet(textura).alto) * desplazamientoY
textX2 = 0.5 '(1 / tileSet(textura).ancho) * (desplazamientoX + 1)
textY2 = 0.0625 '(1 / tileSet(textura).alto) * (desplazamientoY + 1)
' textX1 = 0.125 '(1 / tileSet(textura).ancho) * desplazamientoX
' textY1 = 0.03125 '(1 / tileSet(textura).alto) * desplazamientoY
' textX2 = 0.25 '(1 / tileSet(textura).ancho) * (desplazamientoX + 1)
' textY2 = 0.0625 '(1 / tileSet(textura).alto) * (desplazamientoY + 1)
verticesX(0) = crearVertice(xx, yy, 0, 1, RGB(255, 255, 255), 0, textX1, textY1)
verticesX(1) = crearVertice(xx + TAM_CASILLA, yy, 0, 1, RGB(255, 255, 255), 0, textX2, textY1)
verticesX(2) = crearVertice(xx, yy + TAM_CASILLA, 0, 1, RGB(255, 255, 255), 0, textX1, textY2)
verticesX(3) = crearVertice(xx + TAM_CASILLA, yy + TAM_CASILLA, 0, 1, RGB(255, 255, 255), 0, textX2, textY2)
' D3DDevice.SetTexture 0, tileSet(textura).textura
D3DDevice.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, verticesX(0), Len(verticesX(0))
End Sub
Public Function crearVertice(x As Single, y As Single, Z As Single, rhw As Single, color As Long, specular As Long, tu As Single, tv As Single) As D3DTLVERTEX
crearVertice.sx = x
crearVertice.sy = y
crearVertice.sz = Z
crearVertice.rhw = rhw
crearVertice.color = color
crearVertice.specular = specular
crearVertice.tu = tu
crearVertice.tv = tv
End Function
Public Sub Render()
Dim x As Integer
Dim y As Integer
On Error GoTo tratError
D3DDevice.Clear 0, ByVal 0, D3DCLEAR_TARGET, RGB(255, 150, 150), 1#, 0 '//Clear the screen black
D3DDevice.BeginScene
D3DDevice.SetTexture 0, tileSet(1).textura
y = 0
While y < RESOLUCIONY
x = 0
While x < RESOLUCIONX
Call dibujarCasilla2(x, y, 3, 1)
x = x + TAM_CASILLA
Wend
y = y + TAM_CASILLA
Wend
D3DDevice.EndScene
D3DDevice.Present ByVal 0, ByVal 0, 0, ByVal 0
Exit Sub
tratError:
cerrarDD
Unload frmPrincipal
End
End Sub
No tengo ni la mas remota idea de q puede ser, podria ser algo del calculo del filtrado de la textura o quizas sea cosa del calculo en punto flotante (a saber como trabaja vb con esas cosas).
saludos
¿q es el calculo del filtrado de la textura? ¿es lo mismo q las coordenadas de la textura?
lo mas extraño es que las coordenadas de la textura no las calculo en tiempo de ejecucion si no que las escribo directamente en el cudigo, y con unas coordenadas va a 43 (con las q no tengo comentadas) y con otras va a 83 (con las q tengo comentadas) .
cuando le das una textura de 32x32 pixeles y tiene q dibujarla de 400x400 en pantalla eso requiere calculo para agrandarla, a eso me referia, pero en realdiad no se muy bien si es eso, solo lo he dicho por si suena la flauta xDD.
saludos
No agrando las imagenes. Tengo un fichero .bmp con todas las casillas y cada una ocupa 32x32 pixels. Luego dibujo una de ellas en pantalla para lo cual tomo solo una parte de la textura en la que cargue el bmp. Esta casilla q dibujo la dibujo muchas veces hasta dibujar la pantalla entera con ella, pero cada vez la dibujo en un cuadrado de 32x32 pixels
Es muy raro lo que te pasa :(
Lo siguiente son pruebas o cambios que yo haria... algunos de ellos tienen mas que ver con el Voodoo y los Ovnis que con la informatica :loco:
- Pq usas Alpha Blending para dibujar un mapa ?
- Esto creo q esta mal:
ColorKeyVal = &HFFFF00FA '//Magenta 16 bits
para D3DFMT_R5G6B5 (16 bit) seria:
&HF81F
- Prueba a NO usar las fuentes de DirectX (al menos para probar hasta que te funcione bien)
- Al cargar la textura no le digas D3DFMT_UNKNOWN, prueba a decirle D3DFMT_R5G6B5.
- El segundo textY1 = 0.03125 prueba a ponerle menos decimales; textY1 = 0.0312 o textY1 = 0.031
- El valor specular de tu formato de vertice creo q no lo usas para nada.
- Prueba a borrar el z-buffer (por probar... :))
- Prueba a usar el mismo grafico en ambos casos (es decir dibuja el mismo dibujo), a ver que pasa...
Voy a probar lo q me dices a ver si funciona
El alpha Blending lo estaba usando para dibujar al personaje q se mueve por el mapa y q tiene partes que no han de verse.
El tipo de vertice que utilizo es el D3DTLVERTEX, no es un tipo propio sino uno que ya viene declarado. No sabia muy bien que tipo de vertice utilizar. ¿cual me recomendais q use? ¿para q sirve el valor specular?
¿como borro el z-buffer? ¿para q vale?
Si no me equivoco, el specular se refiere al color que mostrará como "reflejo" de la luz incidente en él. Es decir, una manzana, por ejemplo, tiene un color especular rojo porque al incidir la luz en él, se producen degradados de rojo en el entorno del rayo de luz. Normalmente el specular suele ser el mismo color que el difuso (aunque con varianzas en la luminosidad) y si lo cambias a otro color será para conseguir efectos visuales un tanto extraños.
Que alguien me corrija si me equivoco o si en este contexto no tiene nada que ver.
Lo del z-buffer olvidalo. Me acabo de dar cuenta de que no lo creas, y no creo q tenga nada q ver, solo lo decia por probar :)
El z-buffer sirve (asin a groso modo) para dibujar bien los objetos 3D. Es como un backbuffer, pero en lugar de pintar colores se pintan profundidades (un valor de 0 a 1 por cada pixel). Si quieres me enrollo mas y te lo explico con pelos y señales, pero esto es solo necesario para 3D ;)
En cuanto al tipo de vertice, pues lo mismo que usas pero sin el specular. Como estas trabajando en 2D y con vertices ya transformados e iluminados, lo del specular sobra (no hay luz, y aunque la hubiera no hay angulo con respecto a la luz)
Lo del alpha blending.... no tiene mucho sentido que lo estes usando para dibujar todo el mapa; deberias de hacer esto:
- Desactivar alpha blending
- Dibujar mapa
- Activar alpha blending
- Dibujar personajes
o bien:
- Dibujar mapa
- Activar alpha blending
- Dibujar personajes
- Desactivar alpha blending
la cuestion es que cuando dibujes el mapa no tengas el alpha blending. Ah, y para la textura del monigote tendras que usar un formato que tenga canal alpha :) como por ejemplo A4R4G4B4. (16 bit)
PD: yo en una manzana creo q usaria el specular blanco :P
Citar
PD: yo en una manzana creo q usaria el specular blanco :P
Pero un blanco rosáceo, ¿no?
Valeeee, un blanco con ligeros toques rosaceooos xD
Lo que habeis comentado del filtrado puede tener sentido, ya que parece un poco sospechoso que al pintar un trozo de textura del doble de tamaño, los FPS bajen a la mitad. Porque según esas coordenadas se dibuja el doble de textura ¿no?, lo que pasa que encogida en los 32x32 pixels...
En el caso de 85FPS la textura es de 0.125 x 0.03125, y en el caso de 43FPS la textura es de 0.125 x 0.0625
Podria ser que al dibujar la textura pequeña no se active el MINIFICATION_FILTER (no sé como son los nombres en dx8.1) y por eso el render sea más rápido.
saludos
Modificare el tipo de vertice, es tonteria declarar algo q no utilizo.
Tambien descactivare/activare el alpha blending a ver si aumento los fps.
Antes conseguia pintar al presonaje con sus partes transparentes usando un bmp ¿es necesario utilizar otro formato para las imagenes?
Sobre lo q me comentabas de poner menos decimales a las coordenadas de la textura lo curioso es q me funciona bien con el que tiene mas decimales (el 2º conjunto de coordenadas) y mal con el otro.
Citar
Antes conseguia pintar al presonaje con sus partes transparentes usando un bmp ¿es necesario utilizar otro formato para las imagenes?
Nop, siempre y cuando le digas al cargar la textura que quieres un formato con canal Alpha. Otra cosa seria que quisieras un personaje con zonas de transparencia variable, en ese caso tendrias que usar un formato de imagen con canal alpha como por ej. TGA o PNG.
Citar
Sobre lo q me comentabas de poner menos decimales a las coordenadas de la textura lo curioso es q me funciona bien con el que tiene mas decimales (el 2º conjunto de coordenadas) y mal con el otro.
Has leido lo que dice fiero?,... es mucho mas sensato que todo lo que yo he dicho :)
Ya esta solucionado!!! Muchisimas gracias a todos :D
Ambos teniais razon. Por un lado estaba el hecho de q se dublicaba el tamaño a dibujar por lo q se bajaban los fps.
Y si actibaba y desactivaba el alpha-blending tambien he conseguido q aumenten los fps
Y si en vez de al cargar las texturas indicando formato desconocido le pongo formato de 16 bits como me indicastes aumenta tambien los fps.
Lo unico es q ahora el personaje no se me dibuja con zonas transparentes. Al cambiar el formato con el que cargo la textura las zonas transparentes del prota dejan de serlo.
La imagen la tengo en un bmp de 24 bits (el paint solo me deja guardar como 8bits o 24) y supongo q al cargarlo como si fuera de 16 bits perdera informacion.
¿como puedo saber cual es el valor del nuevo magenta en 16 bits? En 24 bits era 255 0 y 250 (FF00FA en hexadecimal)
¿Hay alguna forma de capturar el color de un pixel determinado de una textura? Si fuera asi podria capturar el color del primer pixel de la textura q es magenta y ver su valor.
Felicidades, unos detalles:
No se como cargaras con vb el bmp pero supong q tendra ya una funcion para ello. Precisamente esto es lo malo q tiene vb q si q te quieres salir un poco de lo q te dan la tienes clara.
El blending por lo general es caro, hazlo como te ha dicho lord trancos antes, solo poniendo blend cuando dibujes el monigote ;)
saludos
Si, en VB hay una funcion para cargar el bmp en la textura (CreateTextureFromFileEx) y hay otra un poco mas sencilla menos configurable (tiene menos parametros)
Me gustaria aprender C (algo se) en profundidad ya que sin duda alguna es mucho mas potente que el VB. Lo malo es la falta de tiempo. Son tantas las cosas que quiero hacer y aprender y tan poco el tiempo del q dispongo :(
Estoy haciendo lo del blending como dice Lord Trancos, pero no consigo q el personaje me salga transparente. :(
No se como ira el blending en D3d pero deberia poner un modo de tal manera q el alfa origen se multiplicara por el color origen para eliminar las partes q no quieres del muñeco. en opengl seria glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); eso si, siempre q el jugador tenga el alfa a 0 en las zonas no visibles.
Por cierto, bmp creo q no soporta canal alfa, png y tga si, por si te sirve de algo ;)
saludos
Para cargar graficos sin transparencias:
D3DX.CreateTextureFromFileEx(D3DDevice, App.Path & "" & fichero, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_R5G6B5, D3DPOOL_MANAGED, D3DX_FILTER_POINT, D3DX_FILTER_POINT, ByVal 0, ByVal 0, ByVal 0)
Para graficos con transparencias:
D3DX.CreateTextureFromFileEx(D3DDevice, App.Path & "" & fichero, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_A1R5G5B5, D3DPOOL_MANAGED, D3DX_FILTER_POINT, D3DX_FILTER_POINT, ColorKeyVal, ByVal 0, ByVal 0)
Siendo ColorKeyVal = &HFC1F '// Magenta para el formato D3DFMT_A1R5G5B5
Si no te va, para los graficos con transparencias prueba esto:
D3DX.CreateTextureFromFileEx(D3DDevice, App.Path & "" & fichero, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_A4R4G4B4, D3DPOOL_MANAGED, D3DX_FILTER_POINT, D3DX_FILTER_POINT, ColorKeyVal, ByVal 0, ByVal 0)
Siendo ColorKeyVal = &HFF0F '// Magenta para el formato D3DFMT_A4R4G4B4
Conseguido!!!! :D
Muchas gracias a todos. Sois unas maquinas!!!
Efectivamente habia que poner D3DFMT_A1R5G5B5 al cargar la textura.
Luego en el colorkey no habia q poner el color en formato de 16bits sino siempre en formato 32 bits (lo dice la ayuda del SDK de DirectX) asi q el color key es FFFF00FF
Gracias de nuevo!
Citar
Luego en el colorkey no habia q poner el color en formato de 16bits sino siempre en formato 32 bits (lo dice la ayuda del SDK de DirectX) asi q el color key es FFFF00FF
Bueno es saberlo ;)