Commit a7b403827fb3abdd039092fbde19bf58bec40323

Authored by Pavel Govyadinov
2 parents 6a13a9c2 b2d10ff1

merged Dev into Branch_Detection

stim/envi/binary.h
... ... @@ -225,6 +225,10 @@ public:
225 225 return true;
226 226 }
227 227  
  228 + /// Reads a plane given a coordinate along the 0-axis (YZ plane)
  229 +
  230 + /// @param p is a pointer to pre-allocated memory of size R[1] * R[2] * sizeof(T)
  231 + /// @param n is the 0-axis coordinate used to retrieve the plane
228 232 bool read_plane_0(T* p, unsigned int n){
229 233  
230 234 if (n >= R[0]){ //make sure the number is within the possible range
... ... @@ -247,6 +251,10 @@ public:
247 251  
248 252 }
249 253  
  254 + /// Reads a plane given a coordinate along the 1-axis (XZ plane)
  255 +
  256 + /// @param p is a pointer to pre-allocated memory of size R[0] * R[2] * sizeof(T)
  257 + /// @param n is the 1-axis coordinate used to retrieve the plane
250 258 bool read_plane_1(T* p, unsigned int n){
251 259  
252 260 unsigned int L = R[0] * sizeof(T); //caculate the number of bytes in a sample line
... ... @@ -268,10 +276,18 @@ public:
268 276 return true;
269 277 }
270 278  
  279 + /// Reads a plane given a coordinate along the 2-axis (XY plane)
  280 +
  281 + /// @param p is a pointer to pre-allocated memory of size R[0] * R[1] * sizeof(T)
  282 + /// @param n is the 2-axis coordinate used to retrieve the plane
271 283 bool read_plane_2(T* p, unsigned int n){
272 284 return read_page(p, n);
273 285 }
274 286  
  287 + /// Reads a single pixel, treating the entire data set as a linear array
  288 +
  289 + /// @param p is a pointer to pre-allocated memory of size sizeof(T)
  290 + /// @param i is the index to the pixel using linear indexing
275 291 bool read_pixel(T* p, unsigned int i){
276 292 if(i >= R[0] * R[1] * R[2]){
277 293 std::cout<<"ERROR read_pixel: n is out of range"<<std::endl;
... ... @@ -283,6 +299,12 @@ public:
283 299  
284 300 }
285 301  
  302 + /// Reads a single pixel, given an x, y, z coordinate
  303 +
  304 + /// @param p is a pointer to pre-allocated memory of size sizeof(T)
  305 + /// @param x is the x (0) axis coordinate
  306 + /// @param y is the y (1) axis coordinate
  307 + /// @param z is the z (2) axis coordinate
286 308 bool read_pixel(T* p, unsigned int x, unsigned int y, unsigned int z){
287 309  
288 310 if(x < 0 || x >= R[0] || y < 0 || y >= R[1] || z < 0 || z > R[2]){
... ... @@ -294,54 +316,6 @@ public:
294 316 return read_pixel(p, i);
295 317 }
296 318  
297   - //saves a hyperplane orthogonal to dimension d at intersection n
298   - /*bool read_plane(T * dest, unsigned int d, unsigned int n){
299   -
300   - //reset the file pointer back to the beginning of the file
301   - file.seekg(0, std::ios::beg);
302   -
303   - //compute the contiguous size C for each readable block
304   - unsigned int C = 1;
305   - for(unsigned int i = 0; i < d; i++) //for each dimension less than d
306   - C *= R[i]; //compute the product
307   -
308   - //compute the non-contiguous size NC for each readable block
309   - unsigned int NC = 1;
310   - for(unsigned int i = d + 1; i < D; i++)
311   - NC *= R[i];
312   -
313   - //for all noncontiguous blocks, read each contiguous block that makes up the hyper-plane
314   - for(unsigned int nc = 0; nc < NC; nc++){
315   - file.seekg(n * C * sizeof(T), std::ios::cur); //skip n contiguous blocks
316   - file.read( (char*)&dest[nc * C], C * sizeof(T)); //read one contiguous block
317   - file.seekg( (R[d] - n - 1) * C * sizeof(T), std::ios::cur); //skip R[d] - n contiguous blocks
318   - }
319   -
320   - return true;
321   -
322   - }*/
323   -
324   - //save one pixel of the file into the memory, and return the pointer
325   - /*bool read_spectrum(T * p, unsigned x, unsigned y){
326   -
327   - unsigned int i;
328   -
329   - if ( x >= R[0] || y >= R[1]){ //make sure the sample and line number is right
330   - std::cout<<"ERROR: sample or line out of range"<<std::endl;
331   - return false;
332   - }
333   -
334   - file.seekg((x + y * R[0]) * sizeof(T), std::ios::beg); //point to the certain sample and line
335   - for (i = 0; i < R[2]; i++)
336   - {
337   - file.read((char *)(p + i), sizeof(T));
338   - file.seekg((R[1] * R[0] - 1) * sizeof(T), std::ios::cur); //go to the next band
339   - }
340   -
341   - return true;
342   - }*/
343   -
344   -
345 319 };
346 320  
347 321 }
... ...
stim/envi/envi.h
... ... @@ -710,6 +710,11 @@ public:
710 710 return false;
711 711 }
712 712  
  713 + /// Retrieve a spectrum from the specified location
  714 +
  715 + /// @param ptr is a pointer to pre-allocated memory of size B*sizeof(T)
  716 + /// @param x is the x-coordinate of the spectrum
  717 + /// @param y is the y-coordinate of the spectrum
713 718 bool spectrum(void* ptr, unsigned int x, unsigned int y){
714 719  
715 720 if(header.interleave == envi_header::BSQ){ //if the infile is bsq file
... ...
stim/gl/gl_spider.h
... ... @@ -29,32 +29,33 @@ namespace stim
29 29 {
30 30  
31 31 template<typename T>
32   -class gl_spider : public virtual gl_texture<T>
  32 +class gl_spider
33 33 {
34 34 //doen't use gl_texture really, just needs the GLuint id.
35 35 //doesn't even need the texture iD really.
36 36 private:
37   - stim::vec<float> position; //vector designating the position of the spider.
38   - stim::vec<float> direction; //vector designating the orientation of the spider
  37 + stim::vec<float> p; //vector designating the position of the spider.
  38 + stim::vec<float> d; //vector designating the orientation of the spider
39 39 //always a unit vector.
40   - stim::vec<float> magnitude; //magnitude of the direction vector.
  40 + stim::vec<float> m; //magnitude of the spider vector.
41 41 //mag[0] = length.
42 42 //mag[1] = width.
43   - std::vector<stim::vec<float> > dirVectors;
44   - std::vector<stim::vec<float> > posVectors;
45   - std::vector<stim::vec<float> > magVectors;
46   - stim::matrix<float, 4> currentTransform;
47   - using gl_texture<T>::texID;
48   - using gl_texture<T>::S;
49   - using gl_texture<T>::R;
  43 + std::vector<stim::vec<float> > dV;
  44 + std::vector<stim::vec<float> > pV;
  45 + std::vector<stim::vec<float> > mV;
  46 + //currentTransform
  47 + stim::matrix<float, 4> cT;
  48 + GLuint texID;
  49 + stim::vec<float> S;
  50 + stim::vec<float> R;
50 51 cudaGraphicsResource_t resource;
51 52  
52 53 GLuint dList;
53   - GLubyte list[4];
54 54 GLuint fboID;
55 55 GLuint texbufferID;
56 56 int iter; //temporary for testing
57 57 int numSamples;
  58 + float stepsize = 3.0;
58 59  
59 60 /// Method for finding the best scale for the spider.
60 61 /// changes the x, y, z size of the spider to minimize the cost
... ... @@ -62,45 +63,41 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
62 63 void
63 64 findOptimalDirection()
64 65 {
65   - //genTemplate(dirVectors, 0);
66   - Bind();
67   - positionTemplate();
  66 + //genTemplate(dV, 0);
  67 + setMatrix();
68 68 glCallList(dList);
69 69 int best = getCost();
70 70 stim::vec<float, 4> next;
71   - next[0] = dirVectors[best][0]*S[1]*R[1];
72   - next[1] = dirVectors[best][1]*S[2]*R[2];
73   - next[2] = dirVectors[best][2]*S[3]*R[3];
  71 + next[0] = dV[best][0]*S[0]*R[0];
  72 + next[1] = dV[best][1]*S[1]*R[1];
  73 + next[2] = dV[best][2]*S[2]*R[2];
74 74 next[3] = 1;
75   - next = (currentTransform*next).norm();
76   - setPosition( position[0]+next[0]*magnitude[0]/3,
77   - position[1]+next[1]*magnitude[0]/3,
78   - position[2]+next[2]*magnitude[0]/3);
  75 + next = (cT*next).norm();
  76 + setPosition( p[0]+next[0]*m[0]/stepsize,
  77 + p[1]+next[1]*m[0]/stepsize,
  78 + p[2]+next[2]*m[0]/stepsize);
79 79 setDirection(next[0], next[1], next[2]);
80   - Unbind();
81 80 }
82 81  
83   - /// Method for finding the best direction for the spider.
84   - /// Not sure if necessary since the next position for the spider
85   - /// will be at direction * magnitude.
  82 + /// Method for finding the best d for the spider.
  83 + /// Not sure if necessary since the next p for the spider
  84 + /// will be at d * m.
86 85 void
87 86 findOptimalPosition()
88 87 {
89   - Bind();
90   - positionTemplate();
  88 + setMatrix();
91 89 glCallList(dList+1);
92 90 int best = getCost();
93 91 stim::vec<float, 4> next;
94   - next[0] = posVectors[best][0];
95   - next[1] = posVectors[best][1];
96   - next[2] = posVectors[best][2];
  92 + next[0] = pV[best][0];
  93 + next[1] = pV[best][1];
  94 + next[2] = pV[best][2];
97 95 next[3] = 1;
98   - next = currentTransform*next;
99   - std::cout << "Optimal Position:"<< next << std::endl;
100   - setPosition( next[0]*S[1]*R[1],
101   - next[1]*S[2]*R[2],
102   - next[2]*S[3]*R[3]);
103   - Unbind();
  96 + next = cT*next;
  97 + std::cout << "Optimal p:"<< next << std::endl;
  98 + setPosition( next[0]*S[0]*R[0],
  99 + next[1]*S[1]*R[1],
  100 + next[2]*S[2]*R[2]);
104 101 }
105 102  
106 103 /// Method for finding the best scale for the spider.
... ... @@ -109,19 +106,17 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
109 106 void
110 107 findOptimalScale()
111 108 {
112   - Bind();
113   - positionTemplate();
  109 + setMatrix();
114 110 glCallList(dList+2);
115 111 int best = getCost();
116 112 stim::vec<float, 4> next;
117   - next[0] = magVectors[best][0]*S[1]*R[1];
118   - next[1] = magVectors[best][1]*S[2]*R[2];
119   - next[2] = magVectors[best][2]*S[3]*R[3];
  113 + next[0] = mV[best][0]*S[0]*R[0];
  114 + next[1] = mV[best][1]*S[1]*R[1];
  115 + next[2] = mV[best][2]*S[2]*R[2];
120 116 next[3] = 1;
121   - next = currentTransform*next;
  117 + next = cT*next;
122 118 std::cout << "Optimal Scale:"<< next << std::endl;
123 119 setMagnitude(next[0]);
124   - Unbind();
125 120 }
126 121  
127 122 void
... ... @@ -140,7 +135,7 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
140 135 void
141 136 Optimize()
142 137 {
143   - /*find the optimum direction and scale */
  138 + /*find the optimum d and scale */
144 139 }
145 140  
146 141  
... ... @@ -152,35 +147,53 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
152 147  
153 148 ///@param solidAngle, the size of the arc to sample.
154 149 ///Method for populating the vector arrays with sampled vectors.
155   - ///uses the default direction vector <0,0,1>
  150 + ///uses the default d vector <0,0,1>
156 151 void
157 152 genDirectionVectors(float solidAngle = M_PI)
158 153 {
159   - float x = 0.0;
  154 + //Set up the vectors necessary for Rectangle creation.
160 155 vec<float> Y(1.0,0.0,0.0);
161 156 vec<float> pos(0.0,0.0,0.0);
162 157 vec<float> mag(1.0, 1.0, 1.0);
163 158 vec<float> dir(0.0, 0.0, 1.0);
164 159  
165 160 vec<float> d_s = direction.cart2sph().norm();
  161 + //Set up the variable necessary for vector creation.
  162 + vec<float> d_s = d.cart2sph().norm();
166 163 vec<float> temp;
167 164 int dim = (sqrt(numSamples)-1)/2;
168 165 float p0 = -M_PI;
169 166 float dt = solidAngle/(2.0 * ((float)dim + 1.0));
170 167 float dp = p0/(2.0*((float)dim + 1.0));
  168 +
  169 + glNewList(dList, GL_COMPILE);
  170 + //Loop over the space
  171 + int idx = 0;
171 172 for(int i = -dim; i <= dim; i++){
172 173 for(int j = -dim; j <= dim; j++){
173 174  
174 175 //Create linear index
175   -
  176 + idx = (j+dim)+(i+dim)*((dim*2)+1);
176 177 temp[0] = d_s[0]; //rotate vector
177 178 temp[1] = d_s[1]+dp*(float) i;
178 179 temp[2] = d_s[2]+dt*(float) j;
179 180  
180 181 temp = (temp.sph2cart()).norm(); //back to cart
181   - dirVectors.push_back(temp);
  182 + dV.push_back(temp);
  183 + if(cos(Y.dot(temp))< 0.087){ Y[0] = 0.0; Y[1] = 1.0;}
  184 + else{Y[0] = 1.0; Y[1] = 0.0;}
  185 +
  186 + hor = stim::rect<float>(mag,
  187 + pos, temp,
  188 + ((Y.cross(temp)).cross(temp)).norm());
  189 + ver = stim::rect<float>(mag,
  190 + pos, temp,
  191 + hor.n());
  192 + UpdateBuffer(0.0, 0.0+idx*10.0);
  193 + CHECK_OPENGL_ERROR
182 194 }
183 195 }
  196 + glEndList();
184 197 }
185 198  
186 199 ///@param solidAngle, the size of the arc to sample.
... ... @@ -189,38 +202,61 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
189 202 void
190 203 genPositionVectors(float delta = 0.2)
191 204 {
192   - ofstream file;
193   - //file.open("dvectors.txt");
  205 + //Set up the vectors necessary for Rectangle creation.
  206 + vec<float> Y(1.0,0.0,0.0);
  207 + vec<float> pos(0.0,0.0,0.0);
  208 + vec<float> mag(1.0, 1.0, 1.0);
  209 + vec<float> dir(0.0, 0.0, 1.0);
  210 +
  211 + //Set up the variable necessary for vector creation.
194 212 vec<float> temp;
195 213 int dim = (sqrt(numSamples)-1)/2;
196 214 stim::rect<float> samplingPlane =
197   - stim::rect<float>(magnitude[0]*delta, position, direction);
  215 + stim::rect<float>(m[0]*delta, p, d);
198 216 float step = 1.0/(dim);
199   - //Loop over the samples, keeping the original position sample
200   - //in the center of the resulting texture.
201 217  
  218 + //Loop over the samples, keeping the original p sample
  219 + //in the center of the resulting texture.
  220 + int idx;
  221 + glNewList(dList+1, GL_COMPILE);
202 222 for(int i = -dim; i <= dim; i++){
203 223 for(int j = -dim; j <= dim; j++){
204 224 //Create linear index
  225 + idx = (j+dim)+(i+dim)*((dim*2)+1);
205 226  
206 227 temp = samplingPlane.p(
207 228 0.5+step*i,
208 229 0.5+step*j
209 230 );
210   - //file << temp[0] << ";" << temp[1]
211   - // << ";" << temp[2] << endl;
212   - posVectors.push_back(temp);
  231 + pV.push_back(temp);
  232 + hor = stim::rect<float>(mag,
  233 + temp, dir,
  234 + ((Y.cross(d)).cross(d))
  235 + .norm());
  236 + ver = stim::rect<float>(mag,
  237 + temp, dir,
  238 + hor.n());
  239 + UpdateBuffer(0.0, 0.0+idx*10.0);
  240 + CHECK_OPENGL_ERROR
213 241 }
214 242 }
  243 + glEndList();
215 244 }
216 245  
217 246 ///@param solidAngle, the size of the arc to sample.
218 247 ///Method for populating the buffer with the sampled texture.
219   - ///uses the default magnitude <1,1,0>
  248 + ///uses the default m <1,1,0>
220 249 void
221 250 genMagnitudeVectors(float delta = 0.5)
222 251 {
223 252  
  253 + //Set up the vectors necessary for Rectangle creation.
  254 + vec<float> Y(1.0,0.0,0.0);
  255 + vec<float> pos(0.0,0.0,0.0);
  256 + vec<float> mag(1.0, 1.0, 1.0);
  257 + vec<float> dir(0.0, 0.0, 1.0);
  258 +
  259 + //Set up the variable necessary for vector creation.
224 260 int dim = (sqrt(numSamples)-1)/2;
225 261 float min = 1.0-delta;
226 262 float max = 1.0+delta;
... ... @@ -228,95 +264,23 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
228 264 float factor;
229 265 vec<float> temp;
230 266  
  267 + glNewList(dList+2, GL_COMPILE);
231 268 for(int i = 0; i < numSamples; i++){
232 269 //Create linear index
233   - factor = (min+step*i)*magnitude[0];
  270 + factor = (min+step*i)*m[0];
234 271 temp = factor;
235   - magVectors.push_back(temp);
  272 + mV.push_back(temp);
  273 + hor = stim::rect<float>(temp,
  274 + pos, dir,
  275 + ((Y.cross(d)).cross(d))
  276 + .norm());
  277 + ver = stim::rect<float>(temp,
  278 + pos, dir,
  279 + hor.n());
  280 + UpdateBuffer(0.0, 0.0+i*10.0);
  281 + CHECK_OPENGL_ERROR
236 282 }
237   - }
238   - ///@param vector of stim::vec in that stores all of the samplable vectors.
239   - ///@param type, one of three operations, 0 for Direction vectors
240   - /// 1 for Position, 2 for Magnitude.
241   - ///Function for filling the buffer up with the data based on the vectors
242   - ///Each vector represents a two rectangular templates.
243   - ///Loops through all of the vectors and transfers rect. associated with it
244   - ///Into buffer-space.
245   - void
246   - genTemplate(std::vector<stim::vec<float> > in, int type)
247   - {
248   - float x = 0.0;
249   - vec<float> Y(1.0,0.0,0.0);
250   - vec<float> pos(0.0,0.0,0.0);
251   - vec<float> mag(1.0, 1.0, 1.0);
252   - vec<float> dir(0.0, 0.0, 1.0);
253   - switch(type) {
254   - case 0: //Direction
255   - Bind();
256   - glNewList(dList+type, GL_COMPILE);
257   - for(int i = 0; i < in.size(); i++)
258   - {
259   - if(cos(Y.dot(in[i]))< 0.087){ Y[0] = 0.0; Y[1] = 1.0;}
260   - else{Y[0] = 1.0; Y[1] = 0.0;}
261   -
262   - hor = stim::rect<float>(mag,
263   - pos, in[i],
264   - ((Y.cross(in[i])).cross(in[i])).norm());
265   - ver = stim::rect<float>(mag,
266   - pos, in[i],
267   - hor.n());
268   - UpdateBuffer(x, x+i*10.0);
269   - }
270   - glEndList();
271   - Unbind();
272   - break;
273   - case 1: //Position
274   - Bind();
275   - glNewList(dList+type, GL_COMPILE);
276   - if(cos(Y.dot(direction))< 0.087){ Y[0] = 0.0; Y[1] = 1.0;}
277   - else{Y[0] = 1.0; Y[1] = 0.0;}
278   -
279   - for(int i = 0; i < in.size(); i++)
280   - {
281   - hor = stim::rect<float>(mag,
282   - in[i], dir,
283   - ((Y.cross(direction)).cross(direction))
284   - .norm());
285   - ver = stim::rect<float>(mag,
286   - in[i], dir,
287   - hor.n());
288   - UpdateBuffer(x, x+i*10.0);
289   - }
290   - glEndList();
291   - Unbind();
292   - break;
293   - case 2: //Scale
294   - Bind();
295   - glNewList(dList+type, GL_COMPILE);
296   - if(cos(Y.dot(direction))< 0.087){ Y[0] = 0.0; Y[1] = 1.0;}
297   - else{Y[0] = 1.0; Y[1] = 0.0;}
298   -
299   - for(int i = 0; i < in.size(); i++)
300   - {
301   - hor = stim::rect<float>(in[i],
302   - pos, dir,
303   - ((Y.cross(direction)).cross(direction))
304   - .norm());
305   - ver = stim::rect<float>(in[i],
306   - pos, dir,
307   - hor.n());
308   - UpdateBuffer(x, x+i*10.0);
309   - }
310   - glEndList();
311   - Unbind();
312   - break;
313   - default:
314   - std::cout << "unknown case have been passed"
315   - << std::endl;
316   - break;
317   - }
318   - Unbind();
319   - CHECK_OPENGL_ERROR
  283 + glEndList();
320 284 }
321 285 ///@param v_x x-coordinate in buffer-space,
322 286 ///@param v_y y-coordinate in buffer-space.
... ... @@ -392,7 +356,6 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
392 356 );
393 357 glVertex2f(v_x+len, v_y+len);
394 358 glEnd();
395   - CHECK_OPENGL_ERROR
396 359 }
397 360  
398 361  
... ... @@ -468,25 +431,25 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
468 431  
469 432 ///Method for using the gl manipulation to alighn templates from
470 433 ///Template space (-0.5 0.5) to Texture space (0.0, 1.0),
471   - ///Based on the position of the spider in real space (arbitrary).
472   - void positionTemplate()
  434 + ///Based on the p of the spider in real space (arbitrary).
  435 + void setMatrix()
473 436 {
474   - stim::vec<float, 4> rot = getRotation(direction);
  437 + stim::vec<float, 4> rot = getRotation(d);
475 438 glMatrixMode(GL_TEXTURE);
476 439 glLoadIdentity();
477 440  
478 441 glRotatef(rot[0], rot[1], rot[2], rot[3]);
479   - glScalef(1.0/S[1]/R[1], 1.0/S[2]/R[2], 1.0/S[3]/R[3]);
480   - glTranslatef(position[0],
481   - position[1],
482   - position[2]);
483   - glScalef(magnitude[0],
484   - magnitude[1],
485   - magnitude[0]);
  442 + glScalef(1.0/S[0]/R[0], 1.0/S[1]/R[1], 1.0/S[2]/R[2]);
  443 + glTranslatef(p[0],
  444 + p[1],
  445 + p[2]);
  446 + glScalef(m[0],
  447 + m[1],
  448 + m[0]);
486 449  
487 450 float curTrans[16];
488 451 glGetFloatv(GL_TEXTURE_MATRIX, curTrans);
489   - fillTransform(curTrans);
  452 + cT.set(curTrans);
490 453 printTransform();
491 454  
492 455 CHECK_OPENGL_ERROR
... ... @@ -545,21 +508,11 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
545 508 //--------------------------------------------------------------------------//
546 509  
547 510  
548   - ///Default Constructor
549   - gl_spider
550   - ()
551   - {
552   - setPosition(0.0,0.0,0.0);
553   - setDirection(0.0,0.0,1.0);
554   - setMagnitude(1.0);
555   - numSamples = 1089;
556   - //numSamples = 9;
557   - }
558 511 ///@param samples, the number of samples this spider is going to use.
559 512 ///best results if samples is can create a perfect root.
560 513 ///Default Constructor
561 514 gl_spider
562   - (int samples)
  515 + (int samples = 1089)
563 516 {
564 517 setPosition(0.0,0.0,0.0);
565 518 setDirection(0.0,0.0,1.0);
... ... @@ -577,9 +530,18 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
577 530 setMagnitude(mag_x);
578 531  
579 532 }
  533 +
  534 + ~gl_spider
  535 + (void)
  536 + {
  537 + Unbind();
  538 + glDeleteTextures(1, &texbufferID);
  539 + glDeleteBuffers(1, &fboID);
  540 + }
  541 +
580 542 ///@param GLuint id texture that is going to be sampled.
581 543 ///Attached the spider to the texture with the given GLuint ID.
582   - ///Samples in the default direction acting as the init method.
  544 + ///Samples in the default d acting as the init method.
583 545 ///Also acts an init.
584 546 void
585 547 attachSpider(GLuint id)
... ... @@ -587,110 +549,116 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
587 549 texID = id;
588 550 iter = 0; ///for debugging purposes
589 551 GenerateFBO(20, numSamples*10);
590   - genDirectionVectors();
591   - genPositionVectors();
592   - genMagnitudeVectors();
593   -
594   - gl_texture<T>::setDims(0.6, 0.6, 1.0);
595   - setSize(512, 512, 426);
  552 + setDims(0.6, 0.6, 1.0);
  553 + setSize(512.0, 512.0, 426.0);
596 554  
597   - dList = glGenLists(4);
598   - list[0] = 0; list[1] = 1; list[2] = 2; list[3] = 3;
  555 + dList = glGenLists(3);
599 556 glListBase(dList);
600   - genTemplate(dirVectors, 0);
601   - genTemplate(posVectors, 1);
602   - genTemplate(magVectors, 2);
  557 + Bind();
  558 + genDirectionVectors(5*M_PI/4);
  559 + genPositionVectors();
  560 + genMagnitudeVectors();
603 561 DrawCylinder();
  562 + Unbind();
604 563 }
605 564  
606 565 //--------------------------------------------------------------------------//
607 566 //-----------------------------ACCESS METHODS-------------------------------//
608 567 //--------------------------------------------------------------------------//
609   - ///Returns the position vector.
  568 + ///Returns the p vector.
610 569 vec<float>
611 570 getPosition()
612 571 {
613   - return position;
  572 + return p;
614 573 }
615 574  
616   - ///Returns the direction vector.
  575 + ///Returns the d vector.
617 576 vec<float>
618 577 getDirection()
619 578 {
620   - return direction;
  579 + return d;
621 580 }
622 581  
623   - ///Returns the magnitude vector.
  582 + ///Returns the m vector.
624 583 vec<float>
625 584 getMagnitude()
626 585 {
627   - return magnitude;
  586 + return m;
628 587 }
629 588  
630   - ///@param vector pos, the new position.
631   - ///Sets the position vector to input vector pos.
  589 + ///@param vector pos, the new p.
  590 + ///Sets the p vector to input vector pos.
632 591 void
633 592 setPosition(vec<float> pos)
634 593 {
635   - position = pos;
  594 + p = pos;
636 595 }
637 596  
638 597 ///@param x x-coordinate.
639 598 ///@param y y-coordinate.
640 599 ///@param z z-coordinate.
641   - ///Sets the position vector to the input float coordinates x,y,z.
  600 + ///Sets the p vector to the input float coordinates x,y,z.
642 601 void
643 602 setPosition(float x, float y, float z)
644 603 {
645   - position[0] = x;
646   - position[1] = y;
647   - position[2] = z;
  604 + p[0] = x;
  605 + p[1] = y;
  606 + p[2] = z;
648 607 }
649 608  
650   - ///@param vector dir, the new direction.
651   - ///Sets the direction vector to input vector dir.
  609 + ///@param vector dir, the new d.
  610 + ///Sets the d vector to input vector dir.
652 611 void
653 612 setDirection(vec<float> dir)
654 613 {
655   - direction = dir;
  614 + d = dir;
656 615 }
657 616  
658 617 ///@param x x-coordinate.
659 618 ///@param y y-coordinate.
660 619 ///@param z z-coordinate.
661   - ///Sets the direction vector to the input float coordinates x,y,z.
  620 + ///Sets the d vector to the input float coordinates x,y,z.
662 621 void
663 622 setDirection(float x, float y, float z)
664 623 {
665   - direction[0] = x;
666   - direction[1] = y;
667   - direction[2] = z;
  624 + d[0] = x;
  625 + d[1] = y;
  626 + d[2] = z;
668 627 }
669 628  
670   - ///@param vector dir, the new direction.
671   - ///Sets the magnitude vector to the input vector mag.
  629 + ///@param vector dir, the new d.
  630 + ///Sets the m vector to the input vector mag.
672 631 void
673 632 setMagnitude(vec<float> mag)
674 633 {
675   - magnitude[0] = mag[0];
676   - magnitude[1] = mag[0];
  634 + m[0] = mag[0];
  635 + m[1] = mag[0];
677 636 }
678 637  
679 638 ///@param mag size of the sampled region.
680   - ///Sets the magnitude vector to the input mag for both templates.
  639 + ///Sets the m vector to the input mag for both templates.
681 640 void
682 641 setMagnitude(float mag)
683 642 {
684   - magnitude[0] = mag;
685   - magnitude[1] = mag;
  643 + m[0] = mag;
  644 + m[1] = mag;
686 645 }
687 646  
  647 +
  648 + void
  649 + setDims(float x, float y, float z)
  650 + {
  651 + S[0] = x;
  652 + S[1] = y;
  653 + S[2] = z;
  654 + }
  655 +
688 656 void
689   - setSize(int x, int y, int z)
  657 + setSize(float x, float y, float z)
690 658 {
691   - R[1] = x;
692   - R[2] = y;
693   - R[3] = z;
  659 + R[0] = x;
  660 + R[1] = y;
  661 + R[2] = z;
694 662 }
695 663  
696 664 ///@param dir, the vector to which we are rotating
... ... @@ -716,18 +684,6 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
716 684 }
717 685 return out;
718 686 }
719   - ///Function that fills the transform data from GL output to a matrix format.
720   - ///@param mat, a 16 value matrix representing the transformation in row order.
721   - void
722   - fillTransform(float mat[16])
723   - {
724   - for(int r = 0; r < 4; r++){
725   - for(int c = 0; c < 4; c++){
726   - currentTransform(r,c) = mat[c*4+r];
727   - }
728   - }
729   -
730   - }
731 687  
732 688 ///Function to get back the framebuffer Object attached to the spider.
733 689 ///For external access.
... ... @@ -746,11 +702,11 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
746 702 Update()
747 703 {
748 704 vec<float> Y(1.0,0.0,0.0);
749   - if(cos(Y.dot(direction))< 0.087){
  705 + if(cos(Y.dot(d))< 0.087){
750 706 Y[0] = 0.0; Y[1] = 1.0;}
751   - hor = stim::rect<float>(magnitude, position, direction.norm(),
752   - ((Y.cross(direction)).cross(direction)).norm());
753   - ver = stim::rect<float>(magnitude, position, direction.norm(),
  707 + hor = stim::rect<float>(m, p, d.norm(),
  708 + ((Y.cross(d)).cross(d)).norm());
  709 + ver = stim::rect<float>(m, p, d.norm(),
754 710 hor.n());
755 711 }
756 712  
... ... @@ -758,17 +714,19 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
758 714 void
759 715 Step()
760 716 {
761   - // findOptimalDirection();
762   - // findOptimalPosition();
763   - // findOptimalScale();
  717 + Bind();
  718 + findOptimalDirection();
  719 + findOptimalPosition();
  720 + findOptimalScale();
764 721 branchDetection();
  722 + Unbind();
765 723 }
766 724  
767 725  
768 726 void
769 727 printTransform()
770 728 {
771   - std::cout << currentTransform << std::endl;
  729 + std::cout << cT << std::endl;
772 730 }
773 731  
774 732 /* Method for initializing the cuda devices, necessary only
... ...
stim/math/matrix.h
... ... @@ -25,6 +25,17 @@ struct matrix
25 25 (*this)(r, c) = 0;
26 26 }
27 27  
  28 + CUDA_CALLABLE matrix(T rhs[N*N])
  29 + {
  30 + memcpy(M,rhs, sizeof(T)*N*N);
  31 + }
  32 +
  33 + CUDA_CALLABLE matrix<T,N> set(T rhs[N*N])
  34 + {
  35 + memcpy(M, rhs, sizeof(T)*N*N);
  36 + return *this;
  37 + }
  38 +
28 39 CUDA_CALLABLE T& operator()(int row, int col)
29 40 {
30 41 return M[col * N + row];
... ... @@ -39,6 +50,7 @@ struct matrix
39 50 return *this;
40 51 }
41 52  
  53 +
42 54 template<typename Y>
43 55 CUDA_CALLABLE vec<Y, N> operator*(vec<Y, N> rhs)
44 56 {
... ... @@ -51,18 +63,18 @@ struct matrix
51 63 return result;
52 64 }
53 65  
54   - CUDA_CALLABLE std::string toStr()
  66 + std::string toStr()
55 67 {
56 68 std::stringstream ss;
57 69  
58 70 for(int r = 0; r < N; r++)
59 71 {
60   - ss<<"| ";
  72 + ss << "| ";
61 73 for(int c=0; c<N; c++)
62 74 {
63   - ss<<(*this)(r, c)<<" ";
  75 + ss << (*this)(r, c) << " ";
64 76 }
65   - ss<<"|"<<std::endl;
  77 + ss << "|" << std::endl;
66 78 }
67 79  
68 80 return ss.str();
... ...
stim/parser/arguments.h
... ... @@ -256,14 +256,16 @@ namespace stim{
256 256 args.add("foo", "foo takes a single integer value", "", "[intval]");
257 257 args.add("bar", "bar takes two floating point values", "", "[value1], [value2]");
258 258  
259   - 4) You generally want to immediately test for help and output available arguments:
  259 + 4) Parse the command line:
  260 +
  261 + args.parse(argc, argv);
  262 +
  263 + 5) You generally want to immediately test for help and output available arguments:
260 264  
261 265 if(args["help"].is_set())
262 266 std::cout<<args.str();
263 267  
264   - 5) Parse the command line:
265   -
266   - args.parse(argc, argv);
  268 +
267 269  
268 270 6) Retrieve values:
269 271  
... ... @@ -436,7 +438,8 @@ namespace stim{
436 438 }
437 439  
438 440 //set the last option
439   - set(name, params);
  441 + if(name != "")
  442 + set(name, params);
440 443 }
441 444  
442 445 ///Determines of a parameter has been set and returns true if it has
... ...
stim/visualization/camera.h
... ... @@ -167,14 +167,14 @@ public:
167 167 //output the camera settings
168 168 const void print(std::ostream& output)
169 169 {
170   - output<<"Position: "<<p<<std::endl;
  170 + output<<"Position: "<<p.str()<<std::endl;
171 171  
172 172 }
173 173 friend std::ostream& operator<<(std::ostream& out, const camera& c)
174 174 {
175   - out<<"Position: "<<c.p<<std::endl;
176   - out<<"Direction: "<<c.d<<std::endl;
177   - out<<"Up: "<<c.up<<std::endl;
  175 + out<<"Position: "<<c.p.str()<<std::endl;
  176 + out<<"Direction: "<<c.d.str()<<std::endl;
  177 + out<<"Up: "<<c.up.str()<<std::endl;
178 178 out<<"Focal Distance: "<<c.focus<<std::endl;
179 179 return out;
180 180 }
... ...
stim/visualization/colormap.h
... ... @@ -221,7 +221,11 @@ static void cpuApplyBrewer(T* cpuSource, unsigned char* cpuDest, unsigned int N,
221 221 for(int i=0; i<N; i++)
222 222 {
223 223 //compute the normalized value on [minVal maxVal]
224   - float a = (cpuSource[i] - minVal) / (maxVal - minVal);
  224 + float a;
  225 + if(minVal != maxVal)
  226 + a = (cpuSource[i] - minVal) / (maxVal - minVal);
  227 + else
  228 + a = 0.5;
225 229 if(a < 0) a = 0;
226 230 if(a > 1) a = 1;
227 231  
... ... @@ -263,11 +267,15 @@ static void cpu2cpu(T* cpuSource, unsigned char* cpuDest, unsigned int nVals, T
263 267 int i;
264 268 float a;
265 269 float range = valMax - valMin;
  270 +
266 271 for(i = 0; i<nVals; i++)
267 272 {
268 273 //normalize to the range [valMin valMax]
269   - a = (cpuSource[i] - valMin) / range;
270   -
  274 + if(range != 0)
  275 + a = (cpuSource[i] - valMin) / range;
  276 + else
  277 + a = 0.5;
  278 +
271 279 if(a < 0) a = 0;
272 280 if(a > 1) a = 1;
273 281  
... ... @@ -279,22 +287,26 @@ static void cpu2cpu(T* cpuSource, unsigned char* cpuDest, unsigned int nVals, T
279 287 }
280 288  
281 289 template<class T>
282   -static void cpu2cpu(T* cpuSource, unsigned char* cpuDest, unsigned int nVals, colormapType cm = cmGrayscale, bool positive = false)
  290 +static void cpu2cpu(T* cpuSource, unsigned char* cpuDest, unsigned int nVals, colormapType cm = cmGrayscale)//, bool positive = false)
283 291 {
284 292 //computes the max and min range automatically
285 293  
286 294 //find the largest magnitude value
287   - T maxVal = fabs(cpuSource[0]);
288   - for(int i=0; i<nVals; i++)
  295 + T maxVal = cpuSource[0];
  296 + T minVal = cpuSource[0];
  297 + for(int i=1; i<nVals; i++)
289 298 {
290   - if(fabs(cpuSource[i]) > maxVal)
291   - maxVal = fabs(cpuSource[i]);
  299 + if(cpuSource[i] > maxVal)
  300 + maxVal = cpuSource[i];
  301 + if(cpuSource[i] < minVal)
  302 + minVal = cpuSource[i];
292 303 }
293 304  
294   - if(positive)
295   - cpu2cpu(cpuSource, cpuDest, nVals, (T)0, maxVal, cm);
296   - else
297   - cpu2cpu(cpuSource, cpuDest, nVals, -maxVal, maxVal, cm);
  305 + //if(positive)
  306 + // cpu2cpu(cpuSource, cpuDest, nVals, (T)0, maxVal, cm);
  307 + //else
  308 + // cpu2cpu(cpuSource, cpuDest, nVals, -maxVal, maxVal, cm);
  309 + cpu2cpu(cpuSource, cpuDest, nVals, minVal, maxVal, cm);
298 310  
299 311 }
300 312  
... ...
stim/visualization/sph_harmonics.h 0 โ†’ 100644
  1 +#ifndef STIM_SPH_HARMONICS
  2 +#define STIM_SPH_HARMONICS
  3 +
  4 +#include <GL/gl.h>
  5 +
  6 +#include <stim/gl/error.h>
  7 +#include <stim/visualization/colormap.h>
  8 +#include <vector>
  9 +
  10 +#define PI 3.14159
  11 +#define WIRE_SCALE 1.001
  12 +namespace stim{
  13 +
  14 + class sph_harmonics{
  15 +
  16 + private:
  17 +
  18 + double* func; //stores the raw function data (samples at each point)
  19 +
  20 + GLuint color_tex; //texture map that acts as a colormap for the spherical function
  21 +
  22 + unsigned int N; //resolution of the spherical grid
  23 +
  24 + std::vector<double> C; //list of SH coefficients
  25 +
  26 +
  27 + //evaluates an associated Legendre polynomial (-l <= m <= l)
  28 + double P(int l,int m,double x)
  29 + {
  30 + // evaluate an Associated Legendre Polynomial P(l,m,x) at x
  31 + double pmm = 1.0;
  32 + if(m>0) {
  33 + double somx2 = sqrt((1.0-x)*(1.0+x));
  34 + double fact = 1.0;
  35 + for(int i=1; i<=m; i++) {
  36 + pmm *= (-fact) * somx2;
  37 + fact += 2.0;
  38 + }
  39 + }
  40 + if(l==m) return pmm;
  41 + double pmmp1 = x * (2.0*m+1.0) * pmm;
  42 + if(l==m+1) return pmmp1;
  43 + double pll = 0.0;
  44 + for(int ll=m+2; ll<=l; ++ll) {
  45 + pll = ( (2.0*ll-1.0)*x*pmmp1-(ll+m-1.0)*pmm ) / (ll-m);
  46 + pmm = pmmp1;
  47 + pmmp1 = pll;
  48 + }
  49 + return pll;
  50 + }
  51 +
  52 + //recursively calculate a factorial given a positive integer n
  53 + unsigned int factorial(unsigned int n) {
  54 + if (n == 0)
  55 + return 1;
  56 + return n * factorial(n - 1);
  57 + }
  58 +
  59 + //calculate the SH scaling constant
  60 + double K(int l, int m){
  61 +
  62 + // renormalisation constant for SH function
  63 + double temp = ((2.0*l+1.0)*factorial(l-m)) / (4.0*PI*factorial(l+m));
  64 + return sqrt(temp);
  65 + }
  66 +
  67 + //calculate the value of the SH basis function (l, m) at (theta, phi)
  68 + //here, theta = [0, PI], phi = [0, 2*PI]
  69 + double SH(int l, int m, double theta, double phi){
  70 + // return a point sample of a Spherical Harmonic basis function
  71 + // l is the band, range [0..N]
  72 + // m in the range [-l..l]
  73 + // theta in the range [0..Pi]
  74 + // phi in the range [0..2*Pi]
  75 + const double sqrt2 = sqrt(2.0);
  76 + if(m==0) return K(l,0)*P(l,m,cos(theta));
  77 + else if(m>0) return sqrt2*K(l,m)*cos(m*phi)*P(l,m,cos(theta));
  78 + else return sqrt2*K(l,-m)*sin(-m*phi)*P(l,-m,cos(theta));
  79 + }
  80 +
  81 + void gen_function(){
  82 +
  83 + //initialize the function to zero
  84 + memset(func, 0, sizeof(double) * N * N);
  85 +
  86 + double theta, phi;
  87 + double result;
  88 + int l, m;
  89 +
  90 + l = m = 0;
  91 + for(unsigned int c = 0; c < C.size(); c++){
  92 +
  93 +
  94 + for(unsigned int xi = 0; xi < N; xi++)
  95 + for(unsigned int yi = 0; yi < N; yi++){
  96 +
  97 + theta = (2 * PI) * ((double)xi / (N-1));
  98 + phi = PI * ((double)yi / (N-1));
  99 + result = C[c] * SH(l, m, phi, theta); //phi and theta are reversed here (damn physicists)
  100 + func[yi * N + xi] += result;
  101 + }
  102 +
  103 + m++; //increment m
  104 +
  105 + //if we're in a new tier, increment l and set m = -l
  106 + if(m > l){
  107 + l++;
  108 + m = -l;
  109 + }
  110 + }
  111 + }
  112 +
  113 + void gl_prep_draw(){
  114 +
  115 + //enable depth testing
  116 + //this has to be used instead of culling because the sphere can have negative values
  117 + glEnable(GL_DEPTH_TEST);
  118 + glDepthMask(GL_TRUE);
  119 + glEnable(GL_TEXTURE_2D); //enable 2D texture mapping
  120 + }
  121 +
  122 + //draw a texture mapped sphere representing the function surface
  123 + void gl_draw_sphere() {
  124 +
  125 + //PI is used to convert from spherical to cartesian coordinates
  126 + //const double PI = 3.14159;
  127 +
  128 + //bind the 2D texture representing the color map
  129 + glBindTexture(GL_TEXTURE_2D, color_tex);
  130 +
  131 + //Draw the Sphere
  132 + int i, j;
  133 +
  134 + for(i = 1; i <= N-1; i++) {
  135 + double phi0 = PI * ((double) (i - 1) / (N-1));
  136 + double phi1 = PI * ((double) i / (N-1));
  137 +
  138 + glBegin(GL_QUAD_STRIP);
  139 + for(j = 0; j <= N; j++) {
  140 +
  141 + //calculate the indices into the function array
  142 + int phi0_i = i-1;
  143 + int phi1_i = i;
  144 + int theta_i = j;
  145 + if(theta_i == N)
  146 + theta_i = 0;
  147 +
  148 + double v0 = func[phi0_i * N + theta_i];
  149 + double v1 = func[phi1_i * N + theta_i];
  150 +
  151 + v0 = fabs(v0);
  152 + v1 = fabs(v1);
  153 +
  154 +
  155 + double theta = 2 * PI * (double) (j - 1) / N;
  156 + double x0 = v0 * cos(theta) * sin(phi0);
  157 + double y0 = v0 * sin(theta) * sin(phi0);
  158 + double z0 = v0 * cos(phi0);
  159 +
  160 + double x1 = v1 * cos(theta) * sin(phi1);
  161 + double y1 = v1 * sin(theta) * sin(phi1);
  162 + double z1 = v1 * cos(phi1);
  163 +
  164 + glTexCoord2f(theta / (2 * PI), phi0 / PI);
  165 + glVertex3f(x0, y0, z0);
  166 +
  167 + glTexCoord2f(theta / (2 * PI), phi1 / PI);
  168 + glVertex3f(x1, y1, z1);
  169 + }
  170 + glEnd();
  171 + }
  172 + }
  173 +
  174 + //draw a wire frame sphere representing the function surface
  175 + void gl_draw_wireframe() {
  176 +
  177 + //PI is used to convert from spherical to cartesian coordinates
  178 + //const double PI = 3.14159;
  179 +
  180 + //bind the 2D texture representing the color map
  181 + glDisable(GL_TEXTURE_2D);
  182 + glColor3f(0.0f, 0.0f, 0.0f);
  183 +
  184 + //Draw the Sphere
  185 + int i, j;
  186 +
  187 + for(i = 1; i <= N-1; i++) {
  188 + double phi0 = PI * ((double) (i - 1) / (N-1));
  189 + double phi1 = PI * ((double) i / (N-1));
  190 +
  191 + glBegin(GL_LINE_STRIP);
  192 + for(j = 0; j <= N; j++) {
  193 +
  194 + //calculate the indices into the function array
  195 + int phi0_i = i-1;
  196 + int phi1_i = i;
  197 + int theta_i = j;
  198 + if(theta_i == N)
  199 + theta_i = 0;
  200 +
  201 + double v0 = func[phi0_i * N + theta_i];
  202 + double v1 = func[phi1_i * N + theta_i];
  203 +
  204 + v0 = fabs(v0);
  205 + v1 = fabs(v1);
  206 +
  207 +
  208 + double theta = 2 * PI * (double) (j - 1) / N;
  209 + double x0 = WIRE_SCALE * v0 * cos(theta) * sin(phi0);
  210 + double y0 = WIRE_SCALE * v0 * sin(theta) * sin(phi0);
  211 + double z0 = WIRE_SCALE * v0 * cos(phi0);
  212 +
  213 + double x1 = WIRE_SCALE * v1 * cos(theta) * sin(phi1);
  214 + double y1 = WIRE_SCALE * v1 * sin(theta) * sin(phi1);
  215 + double z1 = WIRE_SCALE * v1 * cos(phi1);
  216 +
  217 + glTexCoord2f(theta / (2 * PI), phi0 / PI);
  218 + glVertex3f(x0, y0, z0);
  219 +
  220 + glTexCoord2f(theta / (2 * PI), phi1 / PI);
  221 + glVertex3f(x1, y1, z1);
  222 + }
  223 + glEnd();
  224 + }
  225 + }
  226 +
  227 + void init(unsigned int n){
  228 +
  229 + //set the sphere resolution
  230 + N = n;
  231 +
  232 + //allocate space for the color map
  233 + unsigned int bytes = N * N * sizeof(unsigned char) * 3;
  234 + unsigned char* color_image;
  235 + color_image = (unsigned char*) malloc(bytes);
  236 +
  237 + //allocate space for the function
  238 + func = (double*) malloc(N * N * sizeof(double));
  239 +
  240 + //generate a function (temporary)
  241 + gen_function();
  242 +
  243 + //generate a colormap from the function
  244 + stim::cpu2cpu<double>(func, color_image, N*N, stim::cmBrewer);
  245 +
  246 + //prep everything for drawing
  247 + gl_prep_draw();
  248 +
  249 + //generate an OpenGL texture map in the current context
  250 + glGenTextures(1, &color_tex);
  251 + //bind the texture
  252 + glBindTexture(GL_TEXTURE_2D, color_tex);
  253 +
  254 + //copy the color data from the buffer to the GPU
  255 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, N, N, 0, GL_RGB, GL_UNSIGNED_BYTE, color_image);
  256 +
  257 + //initialize all of the texture parameters
  258 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  259 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  260 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  261 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  262 + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  263 +
  264 + //free the buffer
  265 + free(color_image);
  266 + }
  267 +
  268 +
  269 + public:
  270 +
  271 + void glRender(){
  272 + //set all OpenGL parameters required for drawing
  273 + gl_prep_draw();
  274 +
  275 + //draw the sphere
  276 + gl_draw_sphere();
  277 + //gl_draw_wireframe();
  278 +
  279 + }
  280 +
  281 + void glInit(unsigned int n){
  282 + init(n);
  283 + }
  284 +
  285 + void push(double c){
  286 + C.push_back(c);
  287 + }
  288 +
  289 +
  290 +
  291 +
  292 +
  293 + }; //end class sph_harmonics
  294 +
  295 +
  296 +
  297 +
  298 +}
  299 +
  300 +
  301 +#endif
... ...