// // Copyright (c) 2012, Marc "Foddex" Oude Kotte // // License: feel free to do whatever you want with this. Commercial, non-commerical, I don't care. // Please notify me when you're using this is something useful! ^^ // // NOTE: best viewed with TAB distance of 4! // #include #include using namespace std; /** Basic types, I'm anal when it comes to typesize info in type names. */ typedef int int32; typedef unsigned char uint8; /** Simple define, you can convert it to doing glGetError checks for realtime OpenGL function call error checking! */ #define c_gl(func,params) { func params; } #define c_gln(func,params) { func params; } #define c_glr(lvar,func,params) { lvar = func params; } /** Vertex type render traits */ template struct render_traits {}; #define DEFINE_RENDER_TRAITS(type, vertex_type, num_vertices, color_type, num_colors, texcoords_type ) \ template<> struct render_traits { enum { VertexType=(vertex_type), ColorType=(color_type), TexcoordType=(texcoords_type), NumVertices=(num_vertices), NumColors=(num_colors) }; } /** Struct for holding 3D floating point vertex data, without a color value, without texture coords. */ struct vertex_3d { float X, Y, Z; }; DEFINE_RENDER_TRAITS( vertex_3d, GL_FLOAT, 3, 0, 0, 0 ); /** Struct for holding 3D floating point vertex data, with a 4-byte color value, without texture coords. */ struct vertex_c32_3d { float X, Y, Z; uint8 R, G, B, A; }; DEFINE_RENDER_TRAITS( vertex_c32_3d, GL_FLOAT, 3, GL_UNSIGNED_BYTE, 4, 0 ); /** Struct for holding 3D floating point vertex data, with a 4-byte color value, and 1 set of texture coords. */ struct vertex_c32_st_3d { float X, Y, Z; uint8 R, G, B, A; float S, T; }; DEFINE_RENDER_TRAITS( vertex_c32_st_3d, GL_FLOAT, 3, GL_UNSIGNED_BYTE, 4, GL_FLOAT ); /** Struct for holding 3D floating point vertex data, with a 4-float color value, without texture coords. */ struct vertex_cf_3d { float X, Y, Z; float R, G, B, A; }; DEFINE_RENDER_TRAITS( vertex_cf_3d, GL_FLOAT, 3, GL_FLOAT, 4, 0 ); /** Struct for holding 3D floating point vertex data, with a 4-float color value, and 1 set of texture coords. */ struct vertex_cf_st_3d { float X, Y, Z; float R, G, B, A; float S, T; }; DEFINE_RENDER_TRAITS( vertex_cf_st_3d, GL_FLOAT, 3, GL_FLOAT, 4, GL_FLOAT ); /** Struct for holding 2D integer vertex data, without a color value, without texture coords. */ struct vertex_2d { int32 X, Y; }; DEFINE_RENDER_TRAITS( vertex_2d, GL_INT, 2, 0, 0, 0 ); /** Struct for holding 2D integer vertex data, with a 4-byte color value, without texture coords. */ struct vertex_c32_2d { int32 X, Y; uint8 R, G, B, A; }; DEFINE_RENDER_TRAITS( vertex_c32_2d, GL_INT, 2, GL_UNSIGNED_BYTE, 4, 0 ); /** Struct for holding 2D integer vertex data, with a 4-byte color value, and 1 set of texture coords. */ struct vertex_c32_st_2d { int32 X, Y; uint8 R, G, B, A; float S, T; }; DEFINE_RENDER_TRAITS( vertex_c32_st_2d, GL_INT, 2, GL_UNSIGNED_BYTE, 4, GL_FLOAT ); /** Struct for holding 2D integer vertex data, with a 4-float color value, without texture coords. */ struct vertex_cf_2d { int32 X, Y; float R, G, B, A; }; DEFINE_RENDER_TRAITS( vertex_cf_2d, GL_INT, 2, GL_FLOAT, 4, 0 ); /** Struct for holding 2D integer vertex data, with a 4-float color value, and 1 set of texture coords. */ struct vertex_cf_st_2d { int32 X, Y; float R, G, B, A; float S, T; }; DEFINE_RENDER_TRAITS( vertex_cf_st_2d, GL_INT, 2, GL_FLOAT, 4, GL_FLOAT ); namespace rendertools { /** Vertices function */ template struct _render_vertices { void operator()( const _V* vertices ) { c_gl(glEnableClientState,( GL_VERTEX_ARRAY )) c_gl(glVertexPointer,( render_traits<_V>::NumVertices, render_traits<_V>::VertexType, sizeof(_V), &(vertices->X) )) } }; template struct _render_vertices<0, _V> { void operator()( const _V* ) { } }; /** Colors function */ template struct _render_colors { void operator()( const _V* colors ) { c_gl(glEnableClientState,( GL_COLOR_ARRAY )) c_gl(glColorPointer,( render_traits<_V>::NumColors, render_traits<_V>::ColorType, sizeof(_V), &(colors->R) )) } }; template struct _render_colors<0, _V> { void operator()( const _V* ) { } }; /** Texcoords function */ template struct _render_texcoords { void operator()( const _V* texcoords ) { c_gl(glEnableClientState,( GL_TEXTURE_COORD_ARRAY )) c_gl(glTexCoordPointer,( 2, render_traits<_V>::TexcoordType, sizeof(_V), &(texcoords->S) )) } }; template struct _render_texcoords<0, _V> { void operator()( const _V* ) { } }; } // rendertools /** Template function to render all vertex types. */ template void render_vertices( const _V* vertices, size_t num_vertices, GLenum primitive_type, size_t offset=0 ) { if (!vertices || !num_vertices) return; glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT ); rendertools::_render_vertices::VertexType, _V>()( vertices ); rendertools::_render_colors::ColorType, _V>()( vertices ); rendertools::_render_texcoords::TexcoordType, _V>()( vertices ); c_gl(glDrawArrays,( primitive_type, offset, num_vertices )) glPopClientAttrib(); } /** Template function to render all vertex types, coming from STL vectors. */ template void render_vertices( const vector<_V>& vertices, GLenum primitive_type, size_t offset=0 ) { if (vertices.empty() || offset > vertices.size()) return; render_vertices( &vertices[0], vertices.size() - offset, primitive_type, offset ); } /* * Example code: * * We want a floating point position, and a color in float format per vertex, so we use * vertex_cf_3d * NOTE: * _2d = only X and Y for coordinates, integer (for GUI rendering) * _3d = X, Y and Z coordinates, float (for normal 3D rendering) * * _cf = color, float * _c32 = color, 32-bits integer (or better, 4 8 bits integers) * * _st = s and t component (texture coordinate) * * vertex_cf_3d axes[6] = { // position color { 0, 0, 0, 0, 0, 1, 1 }, { 0, 0, 16, 0, 0, 1, 1 }, { 0, 0, 0, 0, 1, 0, 1 }, { 0, 16, 0, 0, 1, 0, 1 }, { 0, 0, 0, 1, 0, 0, 1 }, { 16, 0, 0, 1, 0, 0, 1 }, }; render_vertices( axes, 6, GL_LINES );