domingo, 16 de diciembre de 2012

Poco a poco vamos progresando

Tras casi seis meses de desarrollo, el port del proyecto dx_lib32 a C++ va cogiendo forma.

Poco a poco la funcionalidad de la librería se va acercando a la de la original. Aunque por ahora solo estoy abarcando el tema de gráficos, éstos empiezan a tener unas características aceptables. Dibujo de sprites, polígonos, texto, líneas, etc. La última incorporación han sido splines y polylines, ambas no soportadas por la librería original. Realmente no estoy portando el código "tal cual", suelo implementar las cosas a mi manera; tendiendo en cuenta el diseño y funcionalidad originales por supuesto.

Un ejemplo de polyline


El rendimiento creo que empieza a ser también bastante aceptable. Normalmente hago test sobre un Asus Eee PC 1005PE, que cuenta con un Intel Atom a 1.2GHz y una Intel GMA 3150. Mi filosofía es que si algo funciona bien ahí, funcionará bien en cualquier lado. Y parece que por ahora la teoría se cumple: He conseguido mover cerca de 100 sprites + 100 strings + 100 polígonos (Entre pentágonos y decágonos) a unos 30FPS. En un sobremesa corriente ronda los 300FPS. Y todavía puedo hacer muchas más optimizaciones.

Captura de uno de los test de stress

Por otro lado, he reorganizado completamente la API. Ahora la librería se basa en el lanzamiento de excepciones para informar sobre errores. En un primer momento consideré implementar la API, sobretodo en la rama de matemáticas, de manera que no comprobara errores. Es decir, el usuario era responsable de introducir datos correctos. Pero ésto a la larga no es viable.
Por ejemplo, la clase dl32Matrix implementa una matriz de dimensión cualquiera. Las operaciones con matrices tienen ciertas restricciones. Cuando dichas restricciones no se cumplen, las funciones de dl32Matrix lanzan una excepción del tipo dl32InvalidMatrixOperationException:
 static dl32Matrix Add(dl32Matrix m1,dl32Matrix m2)throw(dl32InvalidMatrixOperationException);
 static dl32Matrix Sub(dl32Matrix m1,dl32Matrix m2)throw(dl32InvalidMatrixOperationException);
 static dl32Matrix Mul(dl32Matrix matrix,float mul)throw(dl32InvalidMatrixOperationException);
 static dl32Matrix Mul(dl32Matrix m1,dl32Matrix m2)throw(dl32InvalidMatrixOperationException);

 dl32Matrix operator+(dl32Matrix matrix)throw(dl32InvalidMatrixOperationException){return Add(*this,matrix);};
 dl32Matrix operator-(dl32Matrix matrix)throw(dl32InvalidMatrixOperationException){return Sub(*this,matrix);};
 dl32Matrix operator*(dl32Matrix matrix)throw(dl32InvalidMatrixOperationException){return Mul(*this,matrix);};
 dl32Matrix operator*(float factor)throw(dl32InvalidMatrixOperationException){return Mul(*this,factor);};

Además la librería cuenta con un sencillo sistema de ventanas que cuenta con lo básico necesario para implementar un juego: Una clase dl32Window que permite crear ventanas, redimensionarlas, cambiar el título, etc. Ëstas implementan un  sencillo sistema de eventos que hacen la programación del juego mucho más sencilla:

#include "dl32Window.h"
#include "dl32Graphics.h"
#include "dl32Math.h"

typedef struct Box
{
    dl32AABB2D area;
    dl32Color color;
};

void OnMouseMove(dl32MouseData mouseData);
void OnIdle();//Éste evento se ejecuta cuando no han llegado mensajes a la ventana

dl32Window* window;
dl32GraphicsClass* gfx;

Box box;

INT WINAPI wWinMain(HINSTANCE,HINSTANCE,LPWSTR,INT)
{
    window = new dl32Window("dx_lib32 example",0,0,800,600);//x,y,width,height
    gfx = new dl32GraphicsClass(Window);

    window->MouseMove.AddHandler(OnMouseMove);
    window->Idle.AddHandler(OnIdle);

    box.color = DL32COLOR_ORANGE;
    box.area = dl32AABB2D(0,0,100,100);//x,y,width,height

    dl32Window::Start();//Inicia el procesamiento de mensajes (Empieza el juego)

    delete gfx;
    //Las intancias de dl32Window son gestionadas internamente. No es necesario delete

    return 0;
}

void OnMouseMove(dl32MouseData mouseData)
{
    box.area.Position = mouseData.Location;
}

void OnIdle()
{
    gfx->DRAW_Box(box.area,box.color);
    gfx.Frame();
}

Todavía me queda mucho por recorrer. La parte de gráficos está casi completa, solo falta el tema de render-targets. Pero ésto solo es el principio. También hay sonido vídeo, e input. Pero no me faltan ganas. Todavía estoy a la espera de encontrar a un colaborador que esté a la altura. El tiempo me lo dará.

Si estáis interesados en los progresos del proyecto, visitad los foros de stratos que mencioné en el primer post, además de seguir mi cuenta de twitter, @Manu343726 , donde suelo escribir mientras programo.