1 #ifndef SIMPLE_RENDERER_H 2 #define SIMPLE_RENDERER_H 3 4 #include <GL/glew.h> 5 #include <vcg/space/point3.h> 6 #include <vcg/complex/complex.h> 7 #include <vcg/complex/algorithms/update/flag.h> 8 #include <vcg/complex/algorithms/update/color.h> 9 #include <wrap/gl/trimesh.h> 10 11 #include "assert.h" 12 #include <Qt> 13 14 #include <map> 15 16 namespace vs 17 { 18 template< class MeshType > 19 class SimpleRenderer 20 { 21 22 public: SimpleRenderer(MeshType * m)23 SimpleRenderer( MeshType* m ) 24 { 25 assert(m && m->vert.size() > 0 && m->face.size() > 0 ); 26 this->m = m; 27 this->buffersOk = false; 28 //createBuffers(); 29 } 30 ~SimpleRenderer(void)31 ~SimpleRenderer( void ) 32 { 33 //glDeleteBuffers( 4, buffer ); 34 } 35 render(void)36 void render( void ) 37 { 38 /* 39 for( int i=0; i<4; i++ ) 40 { 41 assert( glIsBuffer( buffer[i] ) == GL_TRUE ); 42 } 43 44 glBindBuffer( GL_ARRAY_BUFFER, buffer[0] ); // coordinates 45 glVertexPointer( (GLint)3, GL_FLOAT, 0, 0 ); 46 glEnableClientState( GL_VERTEX_ARRAY ); 47 48 glBindBuffer( GL_ARRAY_BUFFER, buffer[1] ); // normals 49 glNormalPointer( GL_FLOAT, 0, 0 ); 50 glEnableClientState( GL_NORMAL_ARRAY ); 51 52 glBindBuffer( GL_ARRAY_BUFFER, buffer[2] ); // colors 53 glColorPointer( (GLint)4, GL_UNSIGNED_BYTE, 0, 0 ); 54 glEnableClientState( GL_COLOR_ARRAY ); 55 56 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, buffer[3] ); // indices 57 58 glDrawElements( GL_TRIANGLES, elementsToDraw, GL_UNSIGNED_INT, 0 ); 59 60 glDisableClientState( GL_COLOR_ARRAY ); 61 glDisableClientState( GL_NORMAL_ARRAY ); 62 glDisableClientState( GL_VERTEX_ARRAY ); 63 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); 64 glBindBuffer( GL_ARRAY_BUFFER, 0 ); 65 */ 66 67 // immediate-mode rendering 68 if( m->vert.size() == 0 ) return; 69 70 typename MeshType::FaceIterator fi; 71 int i = 0; 72 vcg::Point3f* pp = 0; 73 vcg::Point3f* np = 0; 74 75 glBegin( GL_TRIANGLES ); 76 77 for( fi = m->face.begin(); fi != m->face.end(); ++fi ) 78 { 79 for( i = 0; i < 3; i++ ) 80 { 81 np = &( (*fi).V(i)->N() ); 82 glNormal3f( np->X(), np->Y(), np->Z() ); 83 84 pp = &( (*fi).V(i)->P() ); 85 glVertex3f( pp->X(), pp->Y(), pp->Z() ); 86 } 87 } 88 89 glEnd(); 90 } 91 92 private: 93 94 typedef typename MeshType::VertexIterator VertexIterator; 95 typedef typename MeshType::VertexType VertexType; 96 typedef typename MeshType::VertexPointer VertexPointer; 97 typedef typename MeshType::FaceIterator FaceIterator; 98 typedef typename MeshType::ScalarType ScalarType; 99 100 MeshType* m; 101 GLuint buffer[4]; // coords, normals, colors, indices 102 GLsizei elementsToDraw; // 3 * face_number 103 bool buffersOk; // true => use vbo's 104 105 // create the buffer objects to hold mesh data createBuffers(void)106 void createBuffers( void ) 107 { 108 assert( glGetError() == GL_NO_ERROR ); 109 glGenBuffers( 4, buffer ); 110 111 // prepare buffers 112 size_t scalarTypeSize = sizeof( ScalarType ); // size of scalar type 113 size_t vertexSize = 3 * scalarTypeSize; // size of a vertex 114 size_t verticesSize = m->vn * vertexSize; // size of vertices 115 116 void* vData = malloc( verticesSize ); // vertices buffer 117 void* nData = malloc( verticesSize ); // normals buffer 118 assert( vData && nData ); 119 120 121 // assume that the color type is Color4b 122 size_t colorSize = 4 * m->vn; 123 void* cData = malloc( colorSize ); 124 assert( cData ); 125 bool perVertexColor = m->HasPerVertexColor(); 126 127 // if per-vertex color is not available, we use per-mesh color 128 vcg::Color4b defaultColor = m->C(); 129 130 ScalarType* vP = (ScalarType*)vData; 131 ScalarType* nP = (ScalarType*)nData; 132 unsigned char* cP = (unsigned char*)cData; 133 map< VertexPointer, unsigned int >* ptrToInt = new map< VertexPointer, unsigned int >(); 134 unsigned int vertexIndex = 0; 135 136 for( VertexIterator vi = m->vert.begin(); vi != m->vert.end(); ++vi ) 137 { 138 for( int i=0; i<3; i++ ) 139 { 140 vP[i] = (*vi).P()[i]; 141 nP[i] = (*vi).N()[i]; 142 } 143 144 for( int i=0; i<4; i++ ) 145 { 146 cP[i] = (perVertexColor? (*vi).C()[i] : defaultColor[i] ); 147 } 148 149 vP = &( vP[3] ); 150 nP = &( nP[3] ); 151 cP = &( cP[4] ); 152 (*ptrToInt)[ &(*vi) ] = vertexIndex; 153 vertexIndex++; 154 } 155 156 // fills coordinates buffer 157 glBindBuffer( GL_ARRAY_BUFFER, buffer[0] ); 158 glBufferData( GL_ARRAY_BUFFER, verticesSize, vData, GL_STATIC_DRAW ); 159 glVertexPointer( (GLint)3, GL_FLOAT, 0, 0 ); 160 glBindBuffer( GL_ARRAY_BUFFER, 0 ); 161 free( vData ); 162 163 assert( glGetError() == GL_NO_ERROR ); 164 165 // fills normals buffer 166 glBindBuffer( GL_ARRAY_BUFFER, buffer[1] ); 167 glBufferData( GL_ARRAY_BUFFER, verticesSize, nData, GL_STATIC_DRAW ); 168 glBindBuffer( GL_ARRAY_BUFFER, 0 ); 169 free( nData ); 170 171 assert( glGetError() == GL_NO_ERROR ); 172 173 // fills colors buffer 174 glBindBuffer( GL_ARRAY_BUFFER, buffer[2] ); 175 glBufferData( GL_ARRAY_BUFFER, colorSize, cData, GL_STATIC_DRAW ); 176 glBindBuffer( GL_ARRAY_BUFFER, 0 ); 177 free( cData ); 178 179 assert( glGetError() == GL_NO_ERROR ); 180 181 // prepare indices buffer 182 elementsToDraw = (GLsizei)( m->fn * 3 ); // every face has three indices 183 size_t indicesSize = ((size_t)elementsToDraw) * sizeof(unsigned int); 184 void* iData = malloc( indicesSize ); 185 assert( iData ); 186 unsigned int* iP = (unsigned int*)iData; 187 for( FaceIterator fi = m->face.begin(); fi != m->face.end(); ++fi ) 188 { 189 for( unsigned int i = 0; i < 3; i++ ) 190 { 191 iP[ i ] = (*ptrToInt)[ (*fi).V(i) ]; 192 } 193 iP = &( iP[3] ); 194 } 195 196 // fills indices buffer 197 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, buffer[3] ); 198 glBufferData( GL_ELEMENT_ARRAY_BUFFER, indicesSize, iData, GL_STATIC_DRAW ); 199 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); 200 free( iData ); 201 delete ptrToInt; 202 203 assert( glGetError() == GL_NO_ERROR ); 204 } 205 206 }; 207 } 208 209 210 #endif // SIMPLE_RENDERER_H 211