Aula Macedonia


Introducción a las DirectX


Artículo realizado por
Joan Teruel Planas.





Capítulo 1. Introducción a las APIs DirectX.

Las DirectX consisten en diferentes APIS dentro de ella, aquí tienes una lista de ellas:

De momento vamos a tocar la DirectDraw (para los amigos DDraw). Con las DDraw podremos controlar el vídeo, funciones gráficas de todo tipo, funciones de bliteaje, scrolles y fundidos, entre otras cosas.

Tenemos diferentes objetos, os daré una pequeña explicación sobre estos objetos, de momento los más básicos y más importantes.

El objeto DIRECTDRAW:

Interfaz: IDirectDraw. Este objeto sirve para iniciar las DirectX, con este objeto, hasta podremos saber que modos de vídeo soporta nuestra tarjeta, entre muchas cosas más, que ya iremos explicando y ampliando.

El objeto DIRECTDRAWSURFACE:

Interfaz: IDirectDrawSurface. Este objeto (que lo más normal es llamarle Surface) nos permite almacenar datos (como imágenes) y después ser visualizados en pantalla. Necesitamos tener el Surface Primario y el Secundario (más conocido como BACK) para poder enviar los datos de los otros Surfaces a estos, para poder sacarlos en pantalla.

El objeto DIRECTDRAWPALETTE:

Interfaz: IDirectDrawPalette. Este objeto representa una paleta de 256 colores en DirectX, se puede utilizar solamente, en los modos de 8 bits o inferiores.

Ahora crearemos un pequeño programa para saber como iniciar las DirectX, el modo de vídeo y como crear el Surface primario y el Surface secundario y después os explicaré un poco todo lo que hacemos en este ejemplo. El tutorial que he hecho y lo tenéis a vuestra disposición para bajarlo desde esta misma página, el código esta un poco más ampliado, mirarlo os irá muy bien.

#define NAME "MDEjemplo1"

/* El nombre de la ventana */

#define TITLE "Ejemplo de DirecDraw by Metasoft Entertainemnt"

#define WIN32_LEAN_AND_MEAN

#include <windows.h>

#include <windowsx.h>

#include <stdlib.h>

#include <stdarg.h>

/* Definiciones del DDRaw */

#include <ddraw.h>

#include <ddutil.h>

LPDIRECTDRAW MD_lpDD; /* Objeto DirectDraw */

LPDIRECTDRAWSURFACE MD_Primary; /* Surface Primario */

LPDIRECTDRAWSURFACE MD_Back; /* Surface Secundario o Back */

LPDIRECTDRAWSURFACE MD_Imagen; /* Surface para almacenar la imagen */

DDSURFACEDESC MD_ddsd; /* Acceso directo a la memoria del Surface*/

/*

* MD_InitDDraw - Aqui tenemos todo lo necesario para empezar a trabajar * con las DirectX.

*

*/

BOOL MD_InitDDraw(HWND hwnd)

{

HRESULT error;

HBITMAP Imagen;

/*

* Creamos el objeto DirectDraw

*/

DirectDrawCreate( NULL, &MD_lpDD, NULL );

/* Niveles de cooperatividad */

MD_lpDD->SetCooperativeLevel( hwnd,

DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );

/* Iniciamos el modo de video (640x480x8bpp) */

MD_lpDD->SetDisplayMode( 640, 480, 8 );

/* Creamos el Surface Primario y apartir de este el 1 Surface Secundario o Back */

MD_ddsd.dwSize = sizeof( MD_ddsd );

MD_ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;

MD_ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |

DDSCAPS_FLIP |

DDSCAPS_COMPLEX;

MD_ddsd.dwBackBufferCount = 1;

MD_lpDD->CreateSurface( &MD_ddsd, &MD_Primary,NULL);

/* Creamos el Surface Secundario o Back atacando al Primario */

ddscaps.dwCaps = DDSCAPS_BACKBUFFER;

MD_Primary->GetAttachedSurface(&ddscaps,

&MD_Back);

} /* Fin de la funcion MD_InitDDraw*/

DirectDrawCreate

Bien, después de un poco de código, siempre viene bien un poco de explicación. Mirar, tenemos al principio del código la función DirectDrawCreate esa función permite iniciar todo, desde el modo de vídeo hasta crear los Surfaces y un sin fin de cosas. El objeto DirectDraw es el interfaz principal, de el depende todo.

SetCooperativeLevel

Después tenemos la función SetCooperativeLevel, los niveles de cooperatividad indican cómo el DirectDraw se debe comportar con el dispositivo de vídeo o elementos que lo hagan cambiar, por ejemplo, si nuestro programa puede maximizarse o minimizarse, cambiar de tarea, etc... Como lo indicamos ahora en nuestro programa la aplicación se ejecuta en FULL SCREEN, los parámetros son estos:

MD_lpDD->SetCooperativeLevel( hwnd,

DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );

El flag DDSCL_EXCLUSIVE y el DDSCL_FULLSCREEN, indica que nuestra aplicación se ejecutará en modo EXCLUSIVO i en FULL SCREEN teniendo así, toda la capacidad del hardware (cambiar paletas, el modo de vídeo, etc...). De momento, para empezar, lo haremos en FULL SCREEN. En modo de ventana, tiene sus particularidades, pero veréis que es fácil.

SetDisplayMode

La siguiente función que viene es la SetDisplayMode, esta función nos permite iniciar el modo de vídeo en DirectX, naturalmente, en FULL SCREEN; en modo ventana, no se puede indicar el modo de vídeo que se quiere iniciar, ya que coge el modo de vídeo que tengas puesto en el Windows. Esta función tiene estos parámetros:

SetDisplayMode( SCREEN_W, SCREEN_H, BPP );

SCREEN_W es el Ancho de la pantalla.

SCREEN_H es el Alto de la pantalla.

BPP (Bits por píxel) formato de píxel.

Los modos de vídeo principales son estos:

320x200 VGA

320x240 VGA

512x384 SVGA

640x480 SVGA

800x600 SVGA

1024x768 SVGA

Y los principales y los más utilizados formatos de píxel son estos:

8 bpp (paleta).

16 bpp (sin paleta);

24 bpp (sin paleta);

CreateSurface

 

Esta función sirve para crear una zona para almacenar datos (por ejemplo una imagen).

Surfaces de Volcado:

Ahora tocaremos los surfaces para poder visualizar los datos almacenados en los otros surfaces, en pantalla. Tenemos el Surface Primario y el Surface Secundario o Back y estos surfaces, son los que utilizaremos para volcar los datos de los otros surfaces, que serán visualizados en pantalla.

MD_ddsd.dwSize = sizeof( MD_ddsd );

MD_ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;

MD_ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |

DDSCAPS_FLIP |

DDSCAPS_COMPLEX;

MD_ddsd.dwBackBufferCount = 1;

MD_lpDD->CreateSurface( &MD_ddsd, &MD_Primary,NULL);

Aquí le decimos que el Surface primario, será el que se encargue de volcar a la pantalla la información guardada en otros Surfaces, DDSCAPS_FLIP entre otras flags y después creamos el Surface Secundario o Back:

ddscaps.dwCaps = DDSCAPS_BACKBUFFER;

MD_Primary->GetAttachedSurface(&ddscaps, &MD_Back);

Para visualizar una imagen primero la tendremos que enviar al surface Secundario o Back con la función BLTFAST O BLT y después con la función FLIP automáticamente la enviará directamente al Surface primario y ya podremos ver la imagen visualizada en pantalla.

Surfaces de almacenamiento:

Estos Surfaces (por fin) son los encargados de guardar una imagen entre otras cosas, vamos a ver los pasos a seguir para crear uno:

MD_ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
MD_ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;

MD_ddsd.dwWidth = 640; /* Alto del Surface */

MD_ddsd.dwHeight = 480; /* Ancho del Surface */

MD_lpDD->CreateSurface( &MD_ddsd, &MD_Imagen, NULL );

Primero le ponemos unos flags, os explicaré los más importantes, el DDSD_HEIGHT y el DDSD_WIDTH sirve para decirle que el surface tendrá un tamaño determinado, que luego los definiremos más abajo en dw.width y dw.height.

Esto es lo principal sobre el tema de Surfaces, espero que lo entendáis. Es un tema muy importante sobre las DirectX.

Ahora solo, tendríamos que cargar una imagen y enviarla a este Surface, cada imagen necesita un Surface, pero en el próximo artículo, veremos como crear una buena función para automatizar el proceso.

Funciones de Bliteaje

En DirectX tenemos 2 funciones para dibujar en pantalla, son estas:

BltFast.

Blt.

Ahora os explicaré la BltFast, es la más fácil de utilizar.

Surfaces Secundario -> BltFast( x, y, Surfaces de la imagen, Rect de la imagen, flag);

Primero le decimos que la imagen la envíe al Surface Secundario.

X = La posición X en pantalla;

Y = La posición Y en pantalla;

Después tenemos el Surface donde se halla la imagen almacenada.

Después viene el RECT esta definición sirve para crear un cuadrado dónde le diremos el ancho y el alto de la imagen, para poder dibujarla (Mirar el código adjunto, en la función MD_draw).

Y después tenemos unos cuantos flags, explicaré los más utilizados:

DDBLTFAST_NOCOLORKEY dibuja la imagen sin transparencia.

DDBLTFAST_SRCCOLORKEY dibuja la imagen con transparencia.

Para dibujar la imagen con transparencia tendremos que hacer algunos pasos más, que ya veremos más adelante.

Bueno, yo ya me despido hasta el siguiente número, veremos cosas más avanzadas. Como puede ser dibujar imágenes transparentes y un sin fin de cosas, espero que os vaya bien este tutorial y a programar!.




Puedes obtener el código fuente de los ejemplos mostrados pulsando aquí



ÚLTIMA REVISIÓN EN FEBRERO DE 1999




AULA MACEDONIA
a
MACEDONIA Magazine