miércoles, 13 de marzo de 2013

PakEngine. Capitulo 10. Refactorizando el Render

Artículo perteneciente a la sección del PakEngine

Hola a todos,

Hace poco estaba metido con el tema de ponerle el pintado de textos con z al motor, pero, "oh sorpresa!!!" la complejidad ciclomática se me disparaba y los test TDD me petaban sin parar. Así que he decidido hacer un miniparón y pensar bien la solución, para refactorizar el código y que sea más fácil introducir nuevas características de pintado.

La solución a la que he llegado es la siguiente:
- El render gestiona  un vector de punteros a objetos de la clase RenderObject
- La clase RenderObject solo contiene la x,y,z del objeto a renderizar (ya sea un gráfico,texto, animación,etc..) y una función virtual llamada Draw.
- Se implemena una nueva clase llamada DrawObject que hereda de RenderObject e implementa la funcionalidad de Draw, permitiendo introducir nuevas características sin aumentar la complejidad del sistema.

Está todo el código subido al svn.


class RenderObject
{
public:
int x, y ,z;

RenderObject(){};
~RenderObject(){};
virtual void Draw() = 0;
int GetZ(void){ return z; };
};



class DrawObject : public RenderObject
{
private:
int id;

public:
DrawObject(int tx,int ty, int tz, int tid);
~DrawObject(){};
void Draw(void);
};




DrawObject::DrawObject(int tx, int ty, int tz, int tid)
{
x = tx;
y = ty;
z = tz;
id = tid;
}

void DrawObject::Draw(void)
{
int tex,w,h;

tex = SPRITELIST_GetTexture(id);
w = SPRITELIST_GetWidth(id);
h = SPRITELIST_GetHeight(id);

glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

glBegin(GL_QUADS);
glTexCoord2f( 1.0f, 1.0f); glVertex2i( x + w , y + h );
glTexCoord2f( 0.0f, 1.0f); glVertex2i( x     , y + h );
glTexCoord2f( 0.0f, 0.0f); glVertex2i( x     , y  );
glTexCoord2f( 1.0f, 0.0f); glVertex2i( x + w    , y );
glEnd();
};

El código para introducir un nuevo gráfico queda tal que asi:

void SetElement(int index, int x, int y, int z, int id)
{
DrawList[index] = new DrawObject(x,y,z,id);
}

Y el render se reduce a..


void RENDER_Run(void)
{
RenderObject *elem = 0;

//Inspeccionamos todos los elementos a pintar
for( RENDERLIST_GetFirstElement(&elem) ; elem ; RENDERLIST_GetNextElement(&elem) )
elem->Draw();
[...]


Si os fijais, he usado C++ por primera vez en el proyecto . El motivo no es otro que por que hasta ahora no  me había encontrado con la necesidad de usarlo. Usar la herencia de clases y la sobrecarga de funciones virtuales me permite disminuir drásticamente la complejidad de la operación de render (si lo hiciera con C puro debería usar un switch que podría crecer de forma indefinida)

Gracias a esto, lo siguiente que haré será implementar el pintado de textos con z creando una nueva clase que herede de RenderObject y que tenga la función de Draw como a ella le interese, pero esto ya es tema del siguiente capítulo...

Nos vemos,
LordPakusBlog

<< capitulo anterior                                                                                         siguiente capitulo >>

0 comentarios :

Publicar un comentario

Entradas populares