DrawableMesh.cpp

Go to the documentation of this file.
00001 
00005 /* Copyright © 2009, 2010 James Legg.
00006     This program is free software: you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation, either version 3 of the License, or
00009     (at your option) any later version.
00010 */
00011 #include "DrawableMesh.h"
00012 
00013 #include <GL/glew.h>
00014 #include <GL/gl.h>
00015 
00016 #include <Debug.h>
00017 
00018 // Remove to force vertex arrays instead of vertex buffer objects.
00019 #define USE_VERTEX_BUFFER_OBJECTS
00020 // If USE_VERTEX_BUFFER_OBJECTS is defined, VBOs are used only when supported.
00021 // When VBOs are not supported vertex arrays are used anyway.
00022 
00023 namespace Track
00024 {
00025 
00026 DrawableMesh::DrawableMesh(std::istream & source, RenderMode render_mode)
00027     :   MeshFaces(source)
00028     ,   display_list(0)
00029     ,   render_mode(render_mode)
00030 {
00031 }
00032 
00033 DrawableMesh::DrawableMesh(const MeshFaces & mesh, RenderMode render_mode)
00034     :   MeshFaces(mesh)
00035     ,   display_list(0)
00036     ,   render_mode(render_mode)
00037 {
00038 }
00039 
00040 DrawableMesh::DrawableMesh(std::string filename, RenderMode render_mode)
00041     :   MeshFaces(filename)
00042     ,   display_list(0)
00043     ,   render_mode(render_mode)
00044 {
00045 }
00046 
00047 DrawableMesh::DrawableMesh(RenderMode render_mode)
00048     :   display_list(0)
00049     ,   render_mode(render_mode)
00050 {
00051 }
00052 
00053 DrawableMesh::~DrawableMesh()
00054 {
00055 }
00056 
00057 void DrawableMesh::draw() const
00058 {
00059     if (!display_list)
00060     {
00061         // we haven't made the display list for the mesh yet. Do that now.
00062         make_cache();
00063     }
00064     glCallList(display_list);
00065 }
00066 
00067 void DrawableMesh::make_cache() const
00068 {
00069     if (!display_list)
00070     {
00071         list_handle = boost::shared_ptr<unsigned int>(make_list(), delete_list);
00072     }
00073 }
00074 
00075 unsigned int * DrawableMesh::make_list() const
00076 {
00077     // OpenGL vertex buffer names for mesh data.
00078     unsigned int buffer_name;
00079     std::vector<GLfloat> data;
00080     // normal, tex u, tex v, position; for 3 vertices a face
00081     const unsigned int elements_per_vertex = 8;
00082     data.reserve(faces.size() * 3 * (elements_per_vertex));
00083     for (std::vector<MeshFaces::Face>::const_iterator it = faces.begin();
00084          it != faces.end();
00085          it++)
00086     {
00087 #define do_vert(v)\
00088         data.push_back(v.normal.getX());\
00089         data.push_back(v.normal.getY());\
00090         data.push_back(v.normal.getZ());\
00091         data.push_back(v.texture_coord_u);\
00092         data.push_back(v.texture_coord_v);\
00093         data.push_back(vertices_position[v.vertex_index].getX());\
00094         data.push_back(vertices_position[v.vertex_index].getY());\
00095         data.push_back(vertices_position[v.vertex_index].getZ());
00096         
00097         do_vert(it->fv1)
00098         do_vert(it->fv2)
00099         do_vert(it->fv3)
00100 #undef do_vert
00101     }
00102     float * pointer_offset = 0;
00103 #ifdef USE_VERTEX_BUFFER_OBJECTS
00104     if (GLEW_ARB_vertex_buffer_object)
00105     {
00106         // use a vertex buffer object if supported.
00107         glGenBuffersARB(1, &buffer_name);
00108         glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer_name);
00109         glBufferDataARB(GL_ARRAY_BUFFER_ARB,
00110                         sizeof(GLfloat) * data.size(),
00111                         &(data[0]),
00112                         GL_STATIC_DRAW_ARB);
00113     } else {
00114 #endif
00115         // Use vertex arrays.
00116         pointer_offset = &(data[0]);
00117 
00118 #ifdef USE_VERTEX_BUFFER_OBJECTS
00119     }
00120 #endif
00121     glEnableClientState(GL_NORMAL_ARRAY);
00122     glNormalPointer(GL_FLOAT, 8 * sizeof(GLfloat), pointer_offset);
00123 
00124     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00125     glTexCoordPointer(2, GL_FLOAT, 8 * sizeof(GLfloat), pointer_offset + 3);
00126     
00127     glEnableClientState(GL_VERTEX_ARRAY);
00128     glVertexPointer(3, GL_FLOAT, 8 * sizeof(GLfloat), pointer_offset + 5);
00129         
00130     display_list = glGenLists(1);
00131     glNewList(display_list, GL_COMPILE);
00132         switch (render_mode)
00133         {
00134             case RM_SOLID:
00135                 glDrawArrays(GL_TRIANGLES, 0, faces.size() * 3);
00136                 break;
00137             case RM_WIREFRAME:
00138                 for (unsigned int i = 0; i < faces.size(); i++)
00139                 {
00140                     glDrawArrays(GL_LINE_LOOP, i * 3, 3);
00141                 }
00142                 break;
00143         }
00144     glEndList();
00145     
00146     glDisableClientState(GL_NORMAL_ARRAY);
00147     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00148     glDisableClientState(GL_VERTEX_ARRAY);
00149     
00150 #ifdef USE_VERTEX_BUFFER_OBJECTS
00151     if (GLEW_ARB_vertex_buffer_object)
00152     {
00153         glDeleteBuffersARB(1, &buffer_name);
00154     }
00155 #endif
00156 
00157     return &display_list;
00158 }
00159 
00160 void DrawableMesh::delete_list(unsigned int * display_list)
00161 {
00162     glDeleteLists(*display_list, 1);
00163 }
00164 
00165 void DrawableMesh::set_render_mode(RenderMode new_render_mode)
00166 {
00167     if (new_render_mode == render_mode) return;
00168     render_mode = new_render_mode;
00169     // this cleans up the display list if there was one already.
00170     list_handle = boost::shared_ptr<unsigned int>();
00171 }
00172 
00173 }

Get Racer at SourceForge.net. Fast, secure and Free Open Source software downloads

Generated at Mon Sep 6 00:41:11 2010 by Doxygen version 1.4.7 for Racer version svn335.