VertexArrayObject.cpp

00001 #include "VertexArrayObject.h"
00002 #include "Textures.h"
00003 
00004 VertexArrayObject::VertexArrayObject ()
00005 {
00006         // initialize
00007         vertex_pointer = NULL;
00008         num_vertices = 0;
00009         index_pointer = NULL;
00010         num_faces = 0;
00011         normal_pointer = NULL;
00012         texture_pointer = NULL;
00013 
00014         bounding_volumes_computed = false;
00015 }
00016 
00017 VertexArrayObject::~VertexArrayObject ()
00018 {
00019         if (vertex_pointer != NULL) delete vertex_pointer;
00020         if (index_pointer != NULL) delete index_pointer;
00021         if (normal_pointer != NULL) delete normal_pointer;
00022         if (texture_pointer != NULL) delete texture_pointer;
00023 }
00024 
00025 void VertexArrayObject::SetVertexData (float * data, int num_vertices_)
00026 {
00027         vertex_pointer = data;
00028         num_vertices = num_vertices_;
00029         bounding_volumes_computed = false;
00030 }
00031 
00032 void VertexArrayObject::SetVertexIndices (GLuint * indices, int num_faces_)
00033 {
00034         index_pointer = indices;
00035         num_faces = num_faces_;
00036 }
00037 
00038 void VertexArrayObject::SetTextureCoordinates (float * data, GLuint texture_id_)
00039 {
00040         texture_pointer = data;
00041         texture_id = texture_id_;
00042 }
00043 
00044 double VertexArrayObject::GetBoundingRadius ()
00045 {
00046         if (!bounding_volumes_computed)
00047         {ComputeBoundingVolumes ();}
00048 
00049         return bounding_radius;
00050 }
00051 
00052 BoundingBox VertexArrayObject::GetBoundingBox ()
00053 {
00054         if (!bounding_volumes_computed)
00055         {ComputeBoundingVolumes ();}
00056 
00057         return bounding_box;
00058 }
00059 
00060 void VertexArrayObject::Draw ()
00061 {
00062         // enable everything needed to draw the object
00063         glEnableClientState (GL_VERTEX_ARRAY);
00064         if (normal_pointer != NULL) glEnableClientState (GL_NORMAL_ARRAY);
00065         if (texture_pointer != NULL) glEnableClientState (GL_TEXTURE_COORD_ARRAY);
00066 
00067         glVertexPointer (3, GL_FLOAT, 0, vertex_pointer);
00068         if (normal_pointer != NULL) glNormalPointer (GL_FLOAT, 0 , normal_pointer);
00069         if (texture_pointer != NULL)
00070         {
00071                 glEnable (GL_TEXTURE_2D);
00072                 glBindTexture (GL_TEXTURE_2D, texture_id);
00073                 glTexCoordPointer (2, GL_FLOAT, 0, texture_pointer);
00074         }
00075 
00076         // set up color and draw the arrays
00077         glColor4fv (color);
00078         glDrawElements (GL_TRIANGLES, num_faces * 3, GL_UNSIGNED_INT, index_pointer);
00079 
00080         // restore the state by disabling
00081         if (texture_pointer != NULL) 
00082         {
00083                 glDisable (GL_TEXTURE_2D);
00084                 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
00085         }
00086         if (normal_pointer != NULL) glDisableClientState (GL_NORMAL_ARRAY);
00087         glDisableClientState (GL_VERTEX_ARRAY);
00088 
00089         if (show_normals)
00090         {Draw_Normals ();}
00091 }
00092 
00093 void VertexArrayObject::Draw_Normals ()
00094 {
00095         Point p2;
00096 
00097         glColor3f (0.4f, 0.4f, 0.8f);
00098         glBegin (GL_LINES);
00099 
00100         for (int index = 0; index < num_vertices; index++)
00101         {
00102                 glVertex3f (vertex_pointer[3*index], vertex_pointer[3*index+1], vertex_pointer[3*index+2]);
00103                 p2.x = vertex_pointer[3*index] + normal_pointer[3*index] * normal_length;
00104                 p2.y = vertex_pointer[3*index+1] + normal_pointer[3*index+1] * normal_length;
00105                 p2.z = vertex_pointer[3*index+2] + normal_pointer[3*index+2] * normal_length;
00106                 glVertex3f (p2.x, p2.y, p2.z);
00107         }
00108 
00109         glEnd ();
00110 }
00111 
00112 void VertexArrayObject::ComputeNormals (bool clock_wise)
00113 {
00114         Point p1, p2, p3;
00115         Vector v1, v2;
00116         Vector cross_result;
00117         Vector normal;
00118         float weight;
00119         int base, i1, i2, i3;
00120 
00121         // check if there already is an array
00122         if (normal_pointer != NULL) delete [] normal_pointer;
00123 
00124         normal_pointer = new float[num_vertices*3];
00125 
00126         for (int curr_vertex = 0; curr_vertex < num_vertices; curr_vertex++)
00127         {
00128                 normal.x = 0.0f;
00129                 normal.y = 0.0f;
00130                 normal.z = 0.0f;
00131 
00132                 for (int curr_index = 0; curr_index < num_faces*3; curr_index ++)
00133                 {
00134                         if (index_pointer[curr_index] == curr_vertex)
00135                         {
00136                                 base = curr_index / 3;
00137                                 i1 = index_pointer[curr_index];
00138                                 i2 = index_pointer[3*base + (curr_index+1)%3];
00139                                 i3 = index_pointer[3*base + (curr_index+2)%3];
00140 
00141                                 p1.x = vertex_pointer[3*i1];
00142                                 p1.y = vertex_pointer[3*i1 + 1];
00143                                 p1.z = vertex_pointer[3*i1 + 2];
00144 
00145                                 p2.x = vertex_pointer[3*i2];
00146                                 p2.y = vertex_pointer[3*i2 + 1];
00147                                 p2.z = vertex_pointer[3*i2 + 2];
00148 
00149                                 p3.x = vertex_pointer[3*i3];
00150                                 p3.y = vertex_pointer[3*i3 + 1];
00151                                 p3.z = vertex_pointer[3*i3 + 2];
00152 
00153                                 v1.x = p3.x - p1.x;
00154                                 v1.y = p3.y - p1.y;
00155                                 v1.z = p3.z - p1.z;
00156 
00157                                 v2.x = p2.x - p1.x;
00158                                 v2.y = p2.y - p1.y;
00159                                 v2.z = p2.z - p1.z;
00160 
00161                                 cross_result = Geometry::CrossProduct (v1, v2);
00162                                 weight = Geometry::EnclosingAngle (v1, v2);
00163 
00164                                 cross_result.x *= weight;
00165                                 cross_result.y *= weight;
00166                                 cross_result.z *= weight;                       
00167 
00168                                 normal.x += cross_result.x;
00169                                 normal.y += cross_result.y;
00170                                 normal.z += cross_result.z;
00171                         }
00172                 }
00173 
00174                 Geometry::VectorNormalize (normal);
00175 
00176                 if (!clock_wise)
00177                 {
00178                         normal.x *= -1;
00179                         normal.y *= -1;
00180                         normal.z *= -1;
00181                 }
00182 
00183                 normal_pointer[3*curr_vertex] = normal.x;
00184                 normal_pointer[3*curr_vertex+1] = normal.y;
00185                 normal_pointer[3*curr_vertex+2] = normal.z;
00186         }
00187 }
00188 
00189 void VertexArrayObject::ComputeSphericalTextureCoordinates (GLuint texture_id_)
00190 {
00191         int curr_vertex;
00192 
00193         if (normal_pointer == NULL) return;
00194         
00195         if (texture_pointer != NULL) delete texture_pointer;
00196         texture_pointer = new float[2*num_vertices];
00197 
00198         texture_id = texture_id_;
00199 
00200         for (curr_vertex = 0; curr_vertex < num_vertices; curr_vertex++)
00201         {
00202                 texture_pointer[2*curr_vertex] = asin (normal_pointer[3*curr_vertex]) / MY_PI + 0.5;
00203                 texture_pointer[2*curr_vertex+1] = asin (normal_pointer[3*curr_vertex+1]) / MY_PI + 0.5;
00204         }
00205 }
00206 
00207 void VertexArrayObject::ComputeBoundingVolumes ()
00208 {
00209         float x, y, z;
00210         float dist;
00211 
00212         // initialize
00213         bounding_radius = 0.0;
00214         bounding_box.xmin = 0.0;
00215         bounding_box.xmax = 0.0;
00216         bounding_box.ymin = 0.0;
00217         bounding_box.ymax = 0.0;
00218         bounding_box.zmin = 0.0;
00219         bounding_box.zmax = 0.0;
00220 
00221         for (int curr_vertex = 0; curr_vertex < num_vertices; curr_vertex++)
00222         {
00223                 // update radius if necessary
00224                 x = vertex_pointer[curr_vertex*3];
00225                 y = vertex_pointer[curr_vertex*3+1];
00226                 z = vertex_pointer[curr_vertex*3+2];
00227 
00228                 dist = x*x + y*y + z*z;
00229 
00230                 if ( dist > bounding_radius) bounding_radius = dist;
00231 
00232                 if (x > bounding_box.xmax) bounding_box.xmax = x;
00233                 if (x < bounding_box.xmin) bounding_box.xmin = x;
00234                 if (y > bounding_box.ymax) bounding_box.ymax = y;
00235                 if (y < bounding_box.ymin) bounding_box.ymin = y;
00236                 if (z > bounding_box.zmax) bounding_box.zmax = z;
00237                 if (z < bounding_box.zmin) bounding_box.zmin = z;
00238         }
00239 
00240         bounding_radius = sqrt (bounding_radius);
00241         bounding_volumes_computed = true;
00242 }
00243 
00244 void VertexArrayObject::PrintToConsole ()
00245 {
00246         int index;
00247 
00248         printf ("------------ Printing Vertex Data ---------------\n");
00249         for (index = 0; index < num_vertices; index++)
00250         {
00251                 printf ("{%g, %g, %g}\n", vertex_pointer[3*index], vertex_pointer[3*index+1], vertex_pointer[3*index+2]);
00252         }
00253 
00254         printf ("------------ Printing Vertex Indices --------------\n");
00255         for (index = 0; index < num_faces; index++)
00256         {
00257                 printf ("{%u, %u, %u}\n", index_pointer[3*index], index_pointer[3*index+1], index_pointer[3*index+2]);
00258         }
00259         printf ("------------ Printing Faces --------------\n");
00260         for (index = 0; index < num_faces; index ++)
00261         {
00262                 printf ("{%g, %g, %g}, ", vertex_pointer[index_pointer[3*index]*3], vertex_pointer[index_pointer[3*index]*3+1], vertex_pointer[index_pointer[3*index]*3+2]);
00263                 printf ("{%g, %g, %g}, ", vertex_pointer[index_pointer[3*index+1]*3], vertex_pointer[index_pointer[3*index+1]*3+1], vertex_pointer[index_pointer[3*index+1]*3+2]);
00264                 printf ("{%g, %g, %g}\n", vertex_pointer[index_pointer[3*index+2]*3], vertex_pointer[index_pointer[3*index+2]*3+1], vertex_pointer[index_pointer[3*index+2]*3+2]);
00265         }
00266 
00267         if (normal_pointer != NULL)
00268         {
00269                 printf ("------------ Printing Normals ---------------\n");
00270                 for (index = 0; index < num_vertices; index++)
00271                 {
00272                         printf ("{%g, %g, %g}\n", normal_pointer[3*index], normal_pointer[3*index+1], normal_pointer[3*index+2]);
00273                 }
00274         }
00275         else
00276         {printf ("------------ No Normals Detected ---------------\n");}
00277 
00278         printf ("----------- End Of Vertex Array Component ---------------\n");
00279 }
00280 
00281 bool VertexArrayObject::show_normals = false;
00282 float VertexArrayObject::normal_length = 3.0f;

Generated on Sun Jul 2 13:20:39 2006 for Demo by  doxygen 1.4.6-NO