00001
00004
00005
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
00016
00017
00018 #define BUFFER_OFFSET(bytes) ((GLubyte*) NULL + (bytes))
00019
00020
00021
00022
00023
00024 namespace qglv {
00025
00026
00027
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;
00085 const int color_data_size_in_elements = 4;
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;
00089 int y_length = number_of_cells_y + 1;
00090
00091
00092
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
00099 vertice_array[index++] = x*resolution;
00100 vertice_array[index++] = y*resolution;
00101
00102
00103
00104
00105
00106
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
00125
00126
00127
00128
00129 vertice_array[index++] = intensity;
00130 vertice_array[index++] = 0.0;
00131 vertice_array[index++] = 1.0 - intensity;
00132 }
00133 vertice_array[index++] = alpha;
00134 }
00135 }
00136
00137
00138
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
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
00149 index_array[index++] = static_cast<unsigned int>(y*y_length);
00150 }
00151 for ( int x = 0; x < x_length; ++x) {
00152
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
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);
00167 glBufferData(GL_ARRAY_BUFFER, vertice_array.size() * sizeof(float), vertice_array.data(), GL_STATIC_DRAW);
00168
00169
00170
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);
00176 glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_array.size() * sizeof(unsigned int), index_array.data(), GL_STATIC_DRAW);
00177
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
00186
00187
00188
00189
00190
00191
00192
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
00199
00200
00201
00202
00203
00204
00205
00206 glBindBuffer(GL_ARRAY_BUFFER, gl_vertex_buffer_id);
00207 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl_index_buffer_id);
00208 glDrawElements(GL_TRIANGLE_STRIP, index_count, GL_UNSIGNED_INT, 0);
00209 glBindBuffer(GL_ARRAY_BUFFER, 0);
00210 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
00211
00212
00213 glDisableClientState(GL_VERTEX_ARRAY);
00214 glDisableClientState(GL_COLOR_ARRAY);
00215
00216
00217
00218
00219 glPopMatrix();
00220 glEndList();
00221 }
00222
00223
00224
00225
00226
00227 }