Addons
------

	* load addons in sorted order

Scripting
---------

	* make event based input available
	* make font height available

SceneGraph
----------

	* create scene graph
	
* make ShaderProgram a class
* create RenderSet AND/OR RenderQueue
* RenderQueueVisitor
* reimport input class
* use vbos for meshes and tangents

 #if 0
	/*
	 void RenderDevice::renderShadowVolume(Mesh *mesh,
	 const Vector3Float &direction, const Vector3Float &extrude)
	 {
	 // Calculate visibility
	 unsigned int i, frontface_count = 0;
	 for (i=0; i < mesh->shadowfaces.count(); i++)
	 {
	 if (mesh->shadowfaces[i].plane.distance(extrude) < 0)
	 {
	 shadow_faces[i].backFace = false;
	 frontface_count++;
	 }
	 else
	 {
	 shadow_faces[i].backFace = true;
	 }
	 }

	 unsigned int max_edges = (frontface_count) * 3;
	 if (_extrudeVertexBuffer.count() < (max_edges * 4))
	 {
	 clog << ">>> increase shadow buffers to "<< max_edges << " Edges"<< endline;
	 _extrudeVertexBuffer.create( (max_edges + 100) * 4);
	 }

	 if (_extrudeIndexBuffer.count() < (max_edges * 6))
	 _extrudeIndexBuffer.create( (max_edges + 100) * 6);

	 // fill the buffer
	 unsigned int j, k;
	 extrude_quad_count = 0;
	 Vertex *face_vertices[3];
	 for (i=0; i<shadow_faces.count(); i++)
	 {
	 if (shadow_faces[i].backFace == false)
	 {
	 for (j=0; j<3; j++)
	 {
	 k = shadow_faces[i].neighbours[j];
	 if ( (k == 0) || (shadow_faces[k-1].backFace == true))
	 {
	 unsigned int src_index_offset = i * 3;
	 face_vertices[0]
	 = &mesh->vertex_buffer[ mesh->index_buffer[ src_index_offset ] ];
	 face_vertices[1]
	 = &mesh->vertex_buffer[ mesh->index_buffer[ src_index_offset + 1] ];
	 face_vertices[2]
	 = &mesh->vertex_buffer[ mesh->index_buffer[ src_index_offset + 2] ];

	 #ifdef DEBUG_SILHOUETTE
	 glBegin( GL_LINES );
	 glVertex3f( face_vertices[j]->point.x, face_vertices[j]->point.y, face_vertices[j]->point.z );
	 glVertex3f( face_vertices[(j+1)%3]->point.x, face_vertices[(j+1)%3]->point.y, face_vertices[(j+1)%3]->point.z );
	 glEnd();
	 #endif

	 unsigned int vertex_offset = extrude_quad_count*4;
	 _extrudeVertexBuffer[vertex_offset] = face_vertices[j]->point;
	 _extrudeVertexBuffer[vertex_offset+1] = face_vertices[(j+1)%3]->point;
	 _extrudeVertexBuffer[vertex_offset+2] = face_vertices[(j+1)%3]->point + extrude_vector;
	 _extrudeVertexBuffer[vertex_offset+3] = face_vertices[j]->point
	 + extrude_vector;

	 unsigned int index_offset = extrude_quad_count*6;
	 _extrudeIndexBuffer[index_offset] = vertex_offset;
	 _extrudeIndexBuffer[index_offset+1] = vertex_offset + 3;
	 _extrudeIndexBuffer[index_offset+2] = vertex_offset + 1;
	 _extrudeIndexBuffer[index_offset+3] = vertex_offset + 1;
	 _extrudeIndexBuffer[index_offset+4] = vertex_offset + 3;
	 _extrudeIndexBuffer[index_offset+5] = vertex_offset + 2;

	 extrude_quad_count++;
	 }
	 }
	 }

	 }

	 if (_capIndexBuffer.count() < mesh->index_buffer.count() )
	 _capIndexBuffer.create(mesh->index_buffer.count() );

	 bf = 0;
	 ff = 0;

	 for (i=0; i<shadow_faces.count(); i++)
	 {
	 unsigned int dst_offset, src_offset = i*3;

	 if (shadow_faces[i].backFace == false)
	 {
	 dst_offset = ff*3;
	 ff++;
	 }
	 else
	 {
	 dst_offset = _capIndexBuffer.count() - (bf + 1)*3;
	 bf++;
	 }

	 _capIndexBuffer[dst_offset] = mesh->index_buffer[src_offset];
	 _capIndexBuffer[dst_offset+1] = mesh->index_buffer[src_offset+1];
	 _capIndexBuffer[dst_offset+2] = mesh->index_buffer[src_offset+2];
	 }

	 _lastOrientation = _AbsoluteRotation;
	 }

	 if (_extrudeVertexBuffer.count() > 0)
	 {
	 // draw the volume
	 glPushAttrib( GL_ALL_ATTRIB_BITS);

	 glDisable(GL_TEXTURE_2D);
	 glDisable(GL_LIGHTING);

	 glEnable( GL_DEPTH_TEST);
	 glDepthMask(GL_FALSE);

	 #if defined(DEBUG_SILHOUETTE) || defined(DEBUG_CAPS) || defined(DEBUG_VOLUME)
	 glColorMask( 1, 1, 1, 1 );
	 glDepthFunc(GL_LEQUAL);
	 #else
	 glColorMask(0, 0, 0, 0);
	 glDepthFunc(GL_LESS);
	 #endif

	 glEnable(GL_STENCIL_TEST);
	 glStencilFunc(GL_ALWAYS, 0, ~0);
	 glStencilMask( ~0);

	 glEnable(GL_CULL_FACE);

	 glMatrixMode ( GL_MODELVIEW);
	 glPushMatrix();
	 Matrix4x4 m(_AbsoluteRotation, _AbsoluteTranslation);
	 glMultMatrixd ( ( GLdouble * ) &m.m );

	 glActiveTextureARB ( GL_TEXTURE2_ARB);
	 glDisable ( GL_TEXTURE_2D);
	 glActiveTextureARB ( GL_TEXTURE1_ARB);
	 glDisable ( GL_TEXTURE_2D);
	 glActiveTextureARB ( GL_TEXTURE0_ARB);
	 glDisable ( GL_TEXTURE_2D);

	 ShaderManager::getSingleton()->useShaderProgram( 0);

	 #ifndef DEBUG_SILHOUETTE

	 glEnableClientState( GL_VERTEX_ARRAY);
	 glDisableClientState( GL_TEXTURE_COORD_ARRAY);
	 glDisableClientState( GL_NORMAL_ARRAY);
	 glDisableClientState( GL_ARRAY_BUFFER_ARB);
	 glDisableClientState( GL_ELEMENT_ARRAY_BUFFER_ARB);

	 for (int p=0; p<2; p++)
	 {
	 if (p==0)
	 {
	 glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
	 glCullFace(GL_FRONT);
	 //glColorMask(0, 1, 0, 0);
	 }
	 else
	 {
	 glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
	 glCullFace(GL_BACK);
	 //glColorMask(1, 0, 0, 0);
	 }

	 if (GLEW_ARB_vertex_buffer_object )
	 {
	 glBindBufferARB ( GL_ARRAY_BUFFER_ARB, 0);
	 glBindBufferARB ( GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
	 }
	 //    #if !defined(DEBUG_CAPS) || defined(DEBUG_VOLUME)
	 glVertexPointer ( 3, GL_FLOAT, 0, _extrudeVertexBuffer.data() );
	 glDrawElements (
	 GL_TRIANGLES,
	 extrude_quad_count * 6,
	 GL_UNSIGNED_SHORT,
	 _extrudeIndexBuffer.data());
	 //    #endif

	 //    #if !defined(DEBUG_VOLUME) || defined(DEBUG_CAPS)
	 // draw caps
	 mesh->vertex_buffer.bind();
	 //glVertexPointer ( 3, GL_FLOAT, sizeof(Vertex), mesh->vertex_buffer.data() );
	 glDrawElements (
	 GL_TRIANGLES,
	 ff*3,
	 GL_UNSIGNED_SHORT,
	 _capIndexBuffer.data());
	 //&_capIndexBuffer[_capIndexBuffer.count() - bf*3]);

	 glPushMatrix();
	 glTranslatef(extrude_vector.x, extrude_vector.y, extrude_vector.z);
	 glDrawElements (
	 GL_TRIANGLES,
	 bf*3,
	 GL_UNSIGNED_SHORT,
	 &_capIndexBuffer[_capIndexBuffer.count() - bf*3]);
	 //_capIndexBuffer.data() );
	 glPopMatrix();
	 //         #endif  
	 }

	 #endif

	 glPopAttrib();

	 glPopMatrix();
	 }
	 */

	Scalar fW, fH;

	fH = tan ( (_FoV / 2) / 180* Pi ) * _NearPlane;
	fW = fH * _AspectRatio;

	// setup projectiom matrix
	glMatrixMode (GL_PROJECTION );
	glLoadIdentity();
	glFrustum ( -fW, fW, -fH, fH, _NearPlane, _FarPlane );

	// save variables for frustum culling
	/*
	 _near = nearZ;
	 _far = farZ;
	 _hNear = tan ( ( fov / 2 ) / 180 * Pi ) * nearZ;
	 _wNear = _hNear * aspect;
	 _hFar = tan ( ( fov / 2 ) / 180 * Pi ) * farZ;
	 _wFar = _hFar * aspect;
	 */
}
#endif
 