potential_field.cpp
Go to the documentation of this file.
00001 
00004 /*****************************************************************************
00005 ** Includes
00006 *****************************************************************************/
00007 
00008 #include <limits>
00009 #include <numeric>
00010 
00011 #include "../../include/qglv/gl/headers.hpp"
00012 #include "../../include/qglv/objects/potential_field.hpp"
00013 
00014 /*****************************************************************************
00015  ** Macros
00016  *****************************************************************************/
00017 
00018 #define BUFFER_OFFSET(bytes) ((GLubyte*) NULL + (bytes))
00019 
00020 /*****************************************************************************
00021 ** Namespaces
00022 *****************************************************************************/
00023 
00024 namespace qglv {
00025 
00026 /*****************************************************************************
00027 ** Implementation
00028 *****************************************************************************/
00029 
00030 PotentialField::PotentialField(const unsigned int& nx,
00031                                const unsigned int& ny,
00032                                const float& resolution,
00033                                const std::vector<unsigned char>& potential_array
00034                               )
00035 : gl_id(-1)
00036 , gl_vertex_buffer_id(0)
00037 , gl_index_buffer_id(0)
00038 , number_of_cells_x(nx)
00039 , number_of_cells_y(ny)
00040 , resolution(resolution)
00041 , values(potential_array.size())
00042 {
00043   _init(potential_array);
00044 }
00045 
00046 PotentialField::PotentialField(const unsigned int& nx,
00047                                const unsigned int& ny,
00048                                const float& resolution,
00049                                const std::vector<float>& potential_array
00050                               )
00051 : gl_id(-1)
00052 , gl_vertex_buffer_id(0)
00053 , gl_index_buffer_id(0)
00054 , number_of_cells_x(nx)
00055 , number_of_cells_y(ny)
00056 , resolution(resolution)
00057 , values(potential_array.size())
00058 {
00059   _init(potential_array);
00060 }
00061 
00062 PotentialField::~PotentialField() {
00063   if ( gl_id > 0 ) {
00064     glDeleteLists(gl_id, 1);
00065   }
00066   if ( gl_vertex_buffer_id > 0 ) {
00067     ::glDeleteBuffers(1, &gl_vertex_buffer_id);
00068   }
00069   if ( gl_index_buffer_id > 0 ) {
00070     ::glDeleteBuffers(1, &gl_index_buffer_id);
00071   }
00072 }
00073 
00074 void PotentialField::draw() {
00075   if ( gl_id == -1 ) {
00076     _glGenLists();
00077   }
00078   ::glCallList(gl_id);
00079 }
00080 
00081 void PotentialField::_glGenLists() {
00082   float alpha = 0.3;
00083   const int position_data_size_in_elements = 2;
00084   const int normal_data_size_in_elements = 0; //3;
00085   const int color_data_size_in_elements = 4;  // DJS : 4 for alpha
00086 
00087   int floats_per_vertex = position_data_size_in_elements + normal_data_size_in_elements + color_data_size_in_elements;
00088   int x_length = number_of_cells_x + 1;  // no. of vertices along the x-side
00089   int y_length = number_of_cells_y + 1;  // no. of vertices along the y-side
00090 
00091   /********************
00092    ** Build Vertices
00093    ********************/
00094   std::vector<float> vertice_array(x_length*y_length*floats_per_vertex);
00095   int index = 0;
00096   for ( int y = 0; y < y_length; ++y) {
00097     for ( int x = 0; x < x_length; ++x) {
00098       //position
00099       vertice_array[index++] = x*resolution;
00100       vertice_array[index++] = y*resolution;
00101 //      vertice_array[index++] = 0.0; // only 2d drawing here
00102       // normals
00103 //      vertice_array[index++] = 0.0;
00104 //      vertice_array[index++] = 0.0;
00105 //      vertice_array[index++] = 1.0;
00106       // colour
00107       float intensity = 0.0;
00108       if ( ( x > 0 ) && (y > 0) && (x < (x_length - 1)) && (y < (y_length - 1)) ) {
00109         std::vector<float> sub_intensities;
00110         float i;
00111         if ( (i = values[(y-1)*number_of_cells_x + (x-1)]) > 0.0 ) { sub_intensities.push_back(i); }
00112         if ( (i = values[(y-1)*number_of_cells_x + (x)]) > 0.0 ) { sub_intensities.push_back(i); }
00113         if ( (i = values[(y)*number_of_cells_x + (x-1)]) > 0.0 ) { sub_intensities.push_back(i); }
00114         if ( (i = values[(y)*number_of_cells_x + (x)]) > 0.0 ) { sub_intensities.push_back(i); }
00115         if ( sub_intensities.size() > 0 ) {
00116           intensity = std::accumulate(sub_intensities.begin(), sub_intensities.end(), 0.0) / static_cast<float>(sub_intensities.size());
00117         }
00118       }
00119       if ( intensity == 0.0 ) {
00120         vertice_array[index++] = 0.2;
00121         vertice_array[index++] = 0.2;
00122         vertice_array[index++] = 0.2;
00123       } else {
00124         // float r, g, b;
00125         // dslam_common::valueToRgb()((1.0 - intensity)*(1.0 - intensity), r, g, b);
00126         // vertice_array[index++] = r;
00127         // vertice_array[index++] = g;
00128         // vertice_array[index++] = b;
00129         vertice_array[index++] = intensity;
00130         vertice_array[index++] = 0.0;
00131         vertice_array[index++] = 1.0 - intensity;
00132       }
00133       vertice_array[index++] = alpha;  // uncomment and set colour_data_size_in_elements to 4
00134     }
00135   }
00136 
00137   /********************
00138    ** Build Index Data
00139    ********************/
00140   const int number_of_strips_required = y_length - 1;
00141   const int number_of_degenerates_required = 2*(number_of_strips_required - 1);
00142   const int number_of_vertices_per_strip = 2*x_length;
00143   // opengl index data must be unsigned bytes or shorts
00144   std::vector<unsigned int> index_array(number_of_vertices_per_strip*number_of_strips_required + number_of_degenerates_required);
00145   index = 0;
00146   for ( int y = 0; y < number_of_strips_required; ++y) {
00147     if ( y > 0 ) {
00148       // degenerate, repeat first vertex
00149       index_array[index++] = static_cast<unsigned int>(y*y_length);
00150     }
00151     for ( int x = 0; x < x_length; ++x) {
00152       // one part of the strip
00153       index_array[index++] = static_cast<unsigned int>((y*y_length) + x);
00154       index_array[index++] = static_cast<unsigned int>(((y+1)*y_length) + x);
00155     }
00156     if ( y < y_length - 2) {
00157       index_array[index++] = static_cast<unsigned int>(((y + 1) * y_length) + (x_length - 1));
00158     }
00159   }
00160 
00161   // Create a vertex attributes buffer (e.g. position, colour etc)
00162   if ( gl_vertex_buffer_id > 0 ) {
00163     glDeleteBuffers(1, &gl_vertex_buffer_id);
00164   }
00165   glGenBuffers(1, &gl_vertex_buffer_id);
00166   glBindBuffer(GL_ARRAY_BUFFER, gl_vertex_buffer_id);  // make it the active buffer
00167   glBufferData(GL_ARRAY_BUFFER, vertice_array.size() * sizeof(float), vertice_array.data(), GL_STATIC_DRAW); // add the data to the buffer
00168 //  glBindBuffer(GL_ARRAY_BUFFER, 0); // release the buffer (i.e. make it not active)
00169 
00170   // Create an index buffer (https://www.opengl.org/sdk/docs/man/html/glBindBuffer.xhtml)
00171   if ( gl_index_buffer_id > 0 ) {
00172     glDeleteBuffers(1, &gl_index_buffer_id);
00173   }
00174   glGenBuffers(1, &gl_index_buffer_id);
00175   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl_index_buffer_id);  // make it the active buffer
00176   glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_array.size() * sizeof(unsigned int), index_array.data(), GL_STATIC_DRAW); // add the data to the buffer
00177 //  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // release the buffer (i.e. make it not active)
00178 
00179   int stride = floats_per_vertex*sizeof(float);
00180   int index_count = index_array.size();
00181 
00182   gl_id = ::glGenLists(1);
00183   glNewList( gl_id, GL_COMPILE );
00184   glPushMatrix();
00185   // nvidia defaults for built-in attribute indices : https://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/attributes.php
00186   // 0 - gl_Vertex, 2 - gl_Normal, 3 - gl_Color
00187   // how to actually get the built-in attribute indices without guessing like this?
00188   //  * you have to use glVertexPointer, glColorPointer for built-ins (glVertexAttribPointer is for custom attributes)
00189   //    * nvidia aliases to these, so its just a lucky chance
00190   //  * built-ins are deprecated and you will eventually have to supply your own (hopefully some system will add reasonable default shaders)
00191 
00192   // Attributes - legacy built-in calls
00193   glEnableClientState(GL_VERTEX_ARRAY);
00194   glVertexPointer(position_data_size_in_elements, GL_FLOAT, stride, BUFFER_OFFSET(0));
00195   glEnableClientState(GL_COLOR_ARRAY);
00196   glColorPointer(color_data_size_in_elements, GL_FLOAT, stride, BUFFER_OFFSET((position_data_size_in_elements+normal_data_size_in_elements)*sizeof(float)));
00197 
00198   // Attributes - future custom attribute call (using nvidia aliases to built-ins)
00199   // glEnableVertexAttribArray(0);
00200   // glVertexAttribPointer(0, position_data_size_in_elements, GL_FLOAT, false, stride, 0);
00201   // glVertexAttribPointer(2, normal_data_size_in_elements, GL_FLOAT, false, stride, BUFFER_OFFSET(position_data_size_in_elements*sizeof(float)));
00202   // glEnableVertexAttribArray(2);
00203   // glEnableVertexAttribArray(3);
00204   // glVertexAttribPointer(3, color_data_size_in_elements, GL_FLOAT, false, stride, BUFFER_OFFSET((position_data_size_in_elements+normal_data_size_in_elements)*sizeof(float)));
00205 
00206   glBindBuffer(GL_ARRAY_BUFFER, gl_vertex_buffer_id);  // make it the active buffer
00207   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl_index_buffer_id);  // make it the active buffer
00208   glDrawElements(GL_TRIANGLE_STRIP, index_count, GL_UNSIGNED_INT, 0); // UNSIGNED_SHORT is faster, but only goes up to 65k indices.
00209   glBindBuffer(GL_ARRAY_BUFFER, 0); // release the buffer (i.e. make it not active)
00210   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // release the buffer (i.e. make it not active)
00211 
00212   // legacy built-in attribute usage
00213   glDisableClientState(GL_VERTEX_ARRAY);
00214   glDisableClientState(GL_COLOR_ARRAY);
00215   // future custom attribute usage
00216   //glDisableVertexAttribArray(0);
00217   //glDisableVertexAttribArray(1);
00218   //glDisableVertexAttribArray(3);
00219   glPopMatrix();
00220   glEndList();
00221 }
00222 
00223 /*****************************************************************************
00224  ** Trailers
00225  *****************************************************************************/
00226 
00227 } // namespace dslam_viewer


qglv_opengl
Author(s): Daniel Stonier
autogenerated on Sat Jun 18 2016 08:19:28