El Guru Programador
Usuario DESCONOCIDO | Registrate Gratis | Usuarios Registrados
DirectX Graphics - Preparando un Framework (I)
- Webmaster de Open Tutor
 

Introduccion

Bienvenidos al primer tutorial de la serie DirectX Graphics en donde intentare mostrarles como preparar un contenedor para mas adelante ir generando aplicaciones mas complicadas. Si vienes del mundo de OpenGL como yo notaras que hay mucha diferencia, te parecera un poco mas complicado pero solo es cuestion de acostumbrarnos. Usaremos Visual Basic 6.0, si bien posiblemente funcione igual con VB5 supondre que todos tienen VB6. Sin mas rodeos, empecemos.

Como siempre abres VB y selecciona estandar EXE. Ve al menu Proyecto y selecciona Referencia, en la lista busca "DirectX 8 for Visual Basic Type Library", marca el check box, pulsa OK y ya esta. Este proyecto esta apto para usar DirectX! Me supongo que no tendras problemas hasta ahora, siempre y cuando hayas bajado e instalado los paquetes necesarios (de otro modo que estas haciendo aqui? :)

Declaraciones

Las siguientes declaraciones deben ir en un modulo (me supongo que todos saben como agregar un modulo al proyecto!), tambien pueden ir en la parte de declaraciones del formulario pero mejor hagamos bien "modular". Escribe lo sgte.:

Option Explicit
Public objDX As DirectX8 'El objeto principal de donde se derivan los demas
Public objD3D As Direct3D8 'El objeto que controla las operaciones de graficos
Public objDevice As Direct3DDevice8 'El responsable de dibujar todas las imagenes
Public bInit As Boolean 'Nos dira si DirectX se inicializo con exito
Public bFin As Boolean 'Para saber si debemos terminar o no

objDX es el objeto principal de todos los comandos DirectX8 y no puede existir un proyecto DirectX sin este objeto!
objD3D es el objeto que controla la operacion de DirectGraphics, sera responsable de crear un dispositivo mas adelante.
objDevice
es un dispositivo DirectGraphics (device) responsable de dibujar cualquier imagen en la pantalla.
bInit simplemente nos dira si DirectX se inicializo con exito o no.
bFin Nos indica si el usuario cerro la aplicacion para poder salir del loop.

Bien, hasta ahora nada de otro mundo verdad? solo declaramos algunas variables. Ahora vayamos al evento Form_Load del formulario y esribamos lo siguiente...

Private Sub Form_Load()
Me.Show
Me.Caption = "OpenTutor - Inicializando DirectX..."
'Creamos una nueva instancia del objeto DirectX8 para la variable
Set objDX = New DirectX8


Las dos primeras lineas todos conocemos, lo llamativo esta en la cuarta linea. Simplemente creamos una instancia de DirectX8 para la variable objDX; a partir de ahora tenemos acceso a todos los comandos a travez de objDX.

La Inicializacion

Dejemos el Form_Load por un momento y hagamos algo mas interesante, la funcion de inicializacion, debe ir en el modulo debajo de las declaraciones.

La funcion empieza con dos declaraciones y el manejador de errores...

'La funcion de inicializacion, aca empieza todo el proceso
Public Function DXInit()
'Relativo a la informacion del modo de presentacion como color, tamaño de la pantalla,etc
Dim m_D3DDisplayMode As D3DDISPLAYMODE
'Aca iran las opciones que elegimos para que DirectX despliegue el grafico
Dim m_D3DPresentParameters As D3DPRESENT_PARAMETERS
On Error GoTo errorhandler


La variable m_D3DDisplayMode describira el modo de presentacion (display mode) como el alto, ancho, formato, etc. La otra variable m_D3DPresentParameters contendra los parametros de presentacion como por ej: si va a ser pantalla completa o no. Y por ultimo el manejador de errores.

'Creamos una instancia del objeto Direct3D
Set objD3D = objDX.Direct3DCreate
'Obtiene el modo de presentacion del adaptador actual y lo guarda en m_D3DDisplayMode
Call objD3D.GetAdapterDisplayMode(D3DADAPTER_DEFAULT, m_D3DDisplayMode)
'Especificamos los parametros de presentacion
With m_D3DPresentParameters
.Windowed = 1
.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC
.BackBufferFormat = m_D3DDisplayMode.Format
End With
'Crea un dispositivo para el adaptador especificado
Set objDevice = objD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Form1.hWnd, _
D3DCREATE_SOFTWARE_VERTEXPROCESSING, m_D3DPresentParameters)
'Si no se creo el dispositivo generamos un error
If objDevice Is Nothing Then GoTo errorhandler
DXInit = True
Exit Function
errorhandler:
DXInit = False
End Function


Muy bien, ahora lo primero que debemos hacer es crear un objeto Direct3D8 como en la segunda linea Nota que para esto usamos el objeto creado en el form_load objDX y su metodo Direct3DCreate.

Despues llamamos al metodo GetAdapterDisplayMode para obtener informacion sobre el modo de presentacion del adaptador actual. Tiene la estructura:

object.GetAdapterDisplayMode(Adapter As Long, Mode As D3DDISPLAYMODE)

-object es un objeto relacionado al objeto Direct3D8, en este caso objD3D
-Adapter es un valor de tipo long que identifica la tarjeta de video a analizar,generalmente usaras D3DADAPTER_DEFAULT que se refiere al adaptador primario, a no ser que tengas una configuracion de dos monitores.
-Mode una variable de tipo D3DDISPLAYMODE que sera llenado con informacion del adaptador actual, en este caso m_D3DDisplayMode.

Las siguientes cinco lineas llenan la variable m_D3DPresentParameters con la informacion requerida para graficar...

-Windowed: 1 significa modo de ventana y 0 pantalla completa
-SwapEffect: La forma en que se mostrara la informacion. Puede ser D3DSWAPEFFECT_COPY que copia la informacion desde el buffer secundario (backbuffer) al area cliente de la ventana destino inmediatamente, no se intenta sincronizar la copia con el periodo de trazo vertical del adaptador por lo que la imagen puede no ser la mejor; D3DSWAPEFFECT_COPY_VSYNC que copia y lo mantiene sincronizado con la tarjeta de video para evitar parpadeos en la pantalla; D3DSWAPEFFECT_FLIP y D3DSWAPEFFECT_DISCARD no los analice en profundidad y todavia tengo dudas sobre su uso.
-BackBufferFormat el tipo de backbuffer que se creara, debe tener el mismo formato que el adaptador actual por eso usamos m_D3DDisplayMode.Format que contiene esta informacion.

La siguiente linea crea el dispositivo encargado de dibujar la informacion y tiene la definicion...

object.CreateDevice(Adapter As Long, DeviceType As CONST_D3DDEVTYPE, hFocusWindow As Long, BehaviorFlags As Long, _
PresentationParameters As D3DPRESENT_PARAMETERS) As Direct3DDevice8


-object objeto relacionado a Direct3D8, en este caso objD3D.
-Adapter es un valor de tipo long que identifica la tarjeta de video a analizar,generalmente usaras D3DADAPTER_DEFAULT que se refiere al adaptador primario, a no ser que tengas una configuracion de dos monitores.
-DeviceType especifica el dispositivo que quieres, si el que elegis no esta disponible el metodo fallara. Pueden ser: D3DDEVTYPE_HAL, aceleracion de hardware, usara tu tarjeta de video para hacer todo lo posible, lo que no puede hacer tu tarjeta en hardware lo hara con emulacion de software; D3DDEVTYPE_REF, el Reference Rasterizer soporta todo, y por eso es lentisimo se recomienda su uso solo para probar algo que tu hardware no soporta y quieres saber como se vera. Esta implementado en software; y D3DDEVTYPE_SW, el Software Rendering Device, un dispositivo de software que tiene que ser registrado con el metodo Direct3D8.RegisterSoftwareDevice, dificilmente hagamos uso de esta opcion.
-hFocusWindow el manejador de la ventana que mostrara el grafico, generalmente de un form o picturebox.
-BehaviorFlags controla el comportamiento del dispositivo de Direct3D. Pueden ser: 3DCREATE_SOFTWARE_VERTEXPROCESSING, hara todos los calculos de vertices en software; 3DCREATE_HARDWARE_VERTEXPROCESSING, hara todos los calculos de vertices en hardware (por lo
tanto mas rapido); D3DCREATE_MIXED_VERTEXPROCESSING, combinacion de software y hardware.
-PresentationParameters los parametros de presentacion que llenaste un poco mas arriba en la variable m_D3DPresentParameters.

Uffff!, eso fue terrible, o no? Tomemos un respiro despues de esa larga explicacion... Ahhh.... un poco mejor :). La sgte. linea simplemente verifica que se haya creado el dispositivo, de lo contrario saltara un mensaje de error que no nos dira mucho en realidad.

Si hubo un error llegamos a errorhandler que pone la funcion a False y ya esta, termino la inicializacion.

El Loop

Ahora volvamos al Form_Load. Donde nos quedamos? Ah en Set objDX = New DirectX8. Lo primero que hacemos es llamar la funcion de inicializacion y poner el resultado en bInit, si bInit es False entonces fallo la inicializacion y quitamos un mensaje no muy esclarecedor y terminamos el programa.

Set objDX = New DirectX8 --> Aca nos quedamos!
bInit = DXInit()
If bInit = False Then
MsgBox "Error critico en DirectX Graphics", vbExclamation + vbOKOnly, "Error"
End
End If

Si bInit es True saltamos a esta parte:

Me.Caption = "OpenTutor - FrameWork Basico"
Do
'Limpia el viewport(area de visualizacion)
Call objDevice.Clear(0, ByVal 0, D3DCLEAR_TARGET, &H44AA&, 1#, 0)
objDevice.BeginScene
objDevice.EndScene

Call objDevice.Present(ByVal 0, ByVal 0, 0, ByVal 0)
DoEvents 'Le damos un respiro a windows para que haga sus cosas :)
Loop Until bFin = True
End
End Sub

Cambiamos el titulo pues ya termino la inicializacion, y entramos al loop y lo primero que hacemos es limpiar el viewport, el area de visualizacion, para esto usamos el metodo Clear del objDevice y tiene la definicion:

object.Clear(Count As Long, ClearD3DRect As Any, Flags As CONST_D3DCLEARFLAGS, Color As Long, Z As Single, Stencil As Long)

-Object Objeto que se refiere al objeto Direct3DDevice8
-Count Numero de rectangulos en el array especificado en ClearD3DRect. Si pones ClearD3DRect a Byval 0, entonces este parametro debe ser 0
-ClearD3DRect El primer elemento de un array de tipo D3DRect que describe los rectangulos a limpiar. Si se pone Byval 0 a este parametro, entonces todo el viewport se limpiara.
-Flags Indica que superficie (surface) va a ser limpiado, pueden ser: D3DCLEAR_TARGET, limpiara el area de visualizacion; D3DCLEAR_ZBUFFER limpiara el buffer de profundidad (Depth Buffer); y D3DCLEAR_STENCIL limpiara el buffer de stencil (Stencil Buffer). Es importante decir que no debes limpiar un buffer que no tienes, si no tienes un buffer stencil no lo limpies o generaras un error.
-Color Un color de 32 bits, Alfa, Rojo, Verde y Azul. Debes usarlo en forma hexadecimal parecido a los colores en HTML en esta forma &HAARRGGBB por ejemplo &HFFFFFFFF.
-Z Es el valor z que este metodo almacena en el Buffer de Profundidad. Puede estar en el rango de 0.0 a 1.0 Un valor de 0.0 representa la distancia mas cercana al observador, y el 1.0 la distancia mas larga.
-Stencil Un valor integer para almacenar en cada entrada en el Stencil Buffer. Este parametro puede ir desde 0 hasta (2 a la n) -1, donde n es el bit de profundidad del Stencil Buffer.

Las dos lineas despues de esto indican el principio y final de la escena respectivamente, todos los dibujos deben estar entre estos metodos, no pueden estar otro lado o se generara un error. Como en este tutorial no dibujamos ningun poligono simplemente estan ahi de adorno :)

OK, casi terminamos, lo ultimo que debemos hacer es presentar la informacion al usuario con el metodo objDevice.Present.

object.Present(SourceRect As Any, DestRect As Any, DestWindowOverride As Long, DirtyRegion As Any)

-Object Objeto que se refiere al objeto Direct3DDevice8
-SourceRect Es un tipo de datos que contiene un rectangulo de origen Si es Byval 0 toda la superfice es presentada.
-DestRect Es un tipo de datos que contiene el rectangulo de destino. Si es Byval 0 todo el area cliente es llenado.
-DestWindowOverride LA ventana destino en donde se hara la presentacion . Debes poner 0 si quieres usar el hWnd especificado en m_D3DPresentParameters.
-DirtyRegion Este parametro no se usa y debe ser Byval 0.

Algo que me olvide de decir mas atras es que todo ese rollo de Byval 0 es porque el parametro es de tipo Any y si se pasa simplemente 0 se genera un error.


Lo unico que queda por hacer es liberar los objetos cuando el usuario cierra la ventana, esto hacemos en el Form_Unload:

Private Sub Form_Unload(Cancel As Integer)
Set objD3D = Nothing
Set objDevice = Nothing
bFin = True
End Sub

Simplemente destruimos los dos objetos y ponemos bFin a True para salir del ciclo y terminar.

Bien, fin! Trata de entender esto lo mas bien posible y si tienes la documentacion de DirectX revisa los temas tratados aqui, estan en ingles pero bueno.... que se le va a hacer. Si crees que no explique algo o si piensas que puedes explicarlo mejor no dudes en escribirme . Haciendo click aqui te bajas el codigo fuente

 
Suscribite al boletin y recibi las novedades del sito en tu Email!
Tu Email

 

Contactos myStudio Network