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,

<< capitulo anterior siguiente capitulo >>
0 comentarios :
Publicar un comentario