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