source: trunk/packages/vizservers/nanovis/VelocityArrowsSlice.cpp @ 2822

Last change on this file since 2822 was 2822, checked in by ldelgass, 12 years ago

Const correctness fixes, pass vector/matrix objects by reference, various
formatting and style cleanups, don't spam syslog and uncomment openlog() call.
Still needs to be compiled with -DWANT_TRACE to get tracing, but now trace
output will be output to file in /tmp.

  • Property svn:eol-style set to native
File size: 16.9 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2#include "nvconf.h"
3
4#include <GL/glew.h>
5#ifdef _WIN32
6#include <windows.h>
7#endif
8#include <GL/gl.h>
9#ifdef WIN32
10#include <GL/glaux.h>
11#else
12#ifdef HAVE_OPENCV_H
13#include <opencv/cv.h>
14#endif
15#ifdef HAVE_OPENCV_HIGHGUI_H
16#include <opencv/highgui.h>
17#endif
18#endif
19
20#include "VelocityArrowsSlice.h"
21
22#ifdef USE_NANOVIS_LIB
23#include "global.h"
24#include "R2/R2FilePath.h"
25#endif
26
27#define USE_VERTEX_BUFFER
28
29VelocityArrowsSlice::VelocityArrowsSlice()
30{
31    _enabled = false;
32    _context = cgCreateContext();
33    _vectorFieldGraphicsID = 0;
34    _vfXscale = _vfYscale = _vfZscale = 0;
35    _slicePos = 0.5f;
36    _vertexBufferGraphicsID = 0;
37    axis(2);
38    //_renderMode = GLYPHS;
39    _renderMode = LINES;
40       
41    _tickCountForMinSizeAxis = 10;
42
43    _queryVelocityFP =
44#ifdef USE_NANOVIS_LIB
45        LoadCgSourceProgram(_context, "queryvelocity.cg", CG_PROFILE_FP30, "main");
46#else
47        cgCreateProgramFromFile(_context, CG_SOURCE, "queryvelocity.cg",
48                                CG_PROFILE_FP30, "main", NULL);
49    cgGLLoadProgram(_queryVelocityFP);
50#endif
51    _qvVectorFieldParam = cgGetNamedParameter(_queryVelocityFP, "vfield");
52
53    _dirty = true;
54    _dirtySamplingPosition = true;
55    _dirtyRenderTarget = true;
56    _maxVelocityScale.x = _maxVelocityScale.y = _maxVelocityScale.z = 1.0f;
57
58    _renderTargetWidth = 128;
59    _renderTargetHeight = 128;
60    _velocities = new Vector3[_renderTargetWidth * _renderTargetHeight];
61
62    ::glGenBuffers(1, &_vertexBufferGraphicsID);
63    glBindBufferARB(GL_ARRAY_BUFFER_ARB, _vertexBufferGraphicsID);
64    glBufferDataARB(GL_ARRAY_BUFFER, _renderTargetWidth * _renderTargetHeight * 3 * sizeof(float),
65                    0, GL_DYNAMIC_DRAW_ARB);
66    glBindBufferARB(GL_ARRAY_BUFFER, 0);
67    createRenderTarget();
68    _pointCount = 0;
69
70    /*
71      _particleVP =
72#ifdef USE_NANOVIS_LIB
73          LoadCgSourceProgram(_context, "velocityslicevp.cg", CG_PROFILE_VP40, "vpmain");
74#else
75          cgCreateProgramFromFile(_context, CG_SOURCE, "velocityslicevp.cg",
76                                  CG_PROFILE_VP40, "vpmain", NULL);
77      cgGLLoadProgram(_particleVP);
78#endif
79      _mvpParticleParam = cgGetNamedParameter(_particleVP, "mvp");
80      _mvParticleParam = cgGetNamedParameter(_particleVP, "modelview");
81      _mvTanHalfFOVParam = cgGetNamedParameter(_particleVP, "tanHalfFOV");
82
83      // TBD..
84      _particleFP =
85#ifdef USE_NANOVIS_LIB
86          LoadCgSourceProgram(_context, "velocityslicefp.cg", CG_PROFILE_FP40, "fpmain");
87#else
88          cgCreateProgramFromFile(_context, CG_SOURCE, "velocityslicefp.cg",
89                                  CG_PROFILE_FP40, "fpmain", NULL);
90      cgGLLoadProgram(_particleFP);
91#endif
92      _vectorParticleParam = cgGetNamedParameter(_particleVP, "vfield");
93    */
94
95#ifdef USE_NANOVIS_LIB
96
97#ifdef WIN32
98    AUX_RGBImageRec *pTextureImage = auxDIBImageLoad("arrows.bmp");
99    _arrowsTex->setPixels(CF_RGB, DT_UBYTE, pTextureImage->sizeX, pTextureImage->sizeY, (void*) pTextureImage->data);
100
101    _arrowsTex = new Texture2D(pTextureImage->sizeX, pTextureImage->sizeY, GL_FLOAT, GL_LINEAR, 3, (void*) pTextureImage->data);
102
103    //delete pTextureImage;
104#else
105    /*
106      TRACE("test1\n");
107      const char *path = R2FilePath::getInstance()->getPath("arrows_flip2.png");
108      if (path) {
109          TRACE("test2 %s\n", path);
110      } else {
111          TRACE("tt\n");
112      }
113      IplImage* pTextureImage = cvLoadImage(path);
114      TRACE("test3\n");
115      if (pTextureImage) {
116          TRACE("file(%s) has been loaded\n", path);
117          _arrowsTex = new Texture2D(pTextureImage->width, pTextureImage->height, GL_FLOAT, GL_LINEAR, 3, (float*) pTextureImage->imageData);
118          TRACE("file(%s) has been loaded\n", path);
119          //cvReleaseImage(&pTextureImage);
120      } else {
121          TRACE("not found\n");
122      }
123      if (path) delete [] path;
124    */
125
126#endif
127
128#else
129    _arrowsTex = new Texture2D();
130    _arrowsTex->setWrapS(TW_MIRROR);
131    _arrowsTex->setWrapT(TW_MIRROR);
132#ifdef WIN32
133    AUX_RGBImageRec *pTextureImage = auxDIBImageLoad("arrows.bmp");
134    _arrowsTex->setPixels(CF_RGB, DT_UBYTE, pTextureImage->sizeX, pTextureImage->sizeY, (void*) pTextureImage->data);
135
136    //delete pTextureImage;
137#else
138    IplImage* pTextureImage = cvLoadImage("arrows_flip2.png");
139    _arrowsTex->setPixels(CF_RGB, DT_UBYTE, pTextureImage->width, pTextureImage->height, (void*) pTextureImage->imageData);
140
141    //cvReleaseImage(&pTextureImage);
142#endif
143
144#endif
145    _arrowColor.set(1, 1, 0);
146
147    TRACE("test1\n");
148}
149
150VelocityArrowsSlice::~VelocityArrowsSlice()
151{
152    cgDestroyProgram(_queryVelocityFP);
153    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo);
154    glDeleteTextures(1, &_tex);
155    glDeleteFramebuffersEXT(1, &_fbo);
156
157#ifdef USE_NANOVIS_LIB
158    delete _arrowsTex;
159#else
160    _arrowsTex->unref();
161#endif
162    cgDestroyProgram(_particleFP);
163    cgDestroyProgram(_particleVP);
164
165    glDeleteBuffers(1, &_vertexBufferGraphicsID);
166    delete [] _velocities;
167}
168
169void VelocityArrowsSlice::createRenderTarget()
170{
171    glGenFramebuffersEXT(1, &_fbo);
172    glGenTextures(1, &_tex);
173
174    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo);
175   
176    glViewport(0, 0, _renderTargetWidth, _renderTargetHeight);
177    glMatrixMode(GL_PROJECTION);
178    glLoadIdentity();
179    glOrtho(0, _renderTargetWidth, 0, _renderTargetHeight, -10.0f, 10.0f);
180    glMatrixMode(GL_MODELVIEW);
181    glLoadIdentity();
182
183    glBindTexture(GL_TEXTURE_RECTANGLE_NV, _tex);
184    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
185    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
186    glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
187    glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
188
189    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGBA32_NV,
190                 _renderTargetWidth, _renderTargetHeight, 0,
191                 GL_RGBA, GL_FLOAT, NULL);
192 
193    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
194                              GL_TEXTURE_RECTANGLE_NV, _tex, 0);
195
196    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
197}
198
199void VelocityArrowsSlice::axis(int axis)
200{
201    _axis = axis;
202    switch (_axis) {
203    case 0:
204        _projectionVector.x = 0;
205        _projectionVector.y = 1;
206        _projectionVector.z = 1;
207        break;
208    case 1 :
209        _projectionVector.x = 1;
210        _projectionVector.y = 0;
211        _projectionVector.z = 1;
212        break;
213    case 2:
214        _projectionVector.x = 1;
215        _projectionVector.y = 1;
216        _projectionVector.z = 0;
217        break;
218    }
219    _dirtySamplingPosition = true;
220    _dirtyRenderTarget = true;
221    //_dirty = true;
222}
223
224void VelocityArrowsSlice::queryVelocity()
225{
226    if (!_enabled) return;
227
228    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo);
229    glDisable(GL_DEPTH_TEST);
230    cgGLBindProgram(_queryVelocityFP);
231    cgGLEnableProfile(CG_PROFILE_FP30);
232    cgGLSetTextureParameter(_qvVectorFieldParam, _vectorFieldGraphicsID);
233    cgGLEnableTextureParameter(_qvVectorFieldParam);
234
235    glPushAttrib(GL_VIEWPORT_BIT);
236    glViewport(0, 0, _renderTargetWidth, _renderTargetHeight);
237    glMatrixMode(GL_PROJECTION);
238    glPushMatrix();
239    glLoadIdentity();
240    glOrtho(0, _renderTargetWidth, 0, _renderTargetHeight, -10.0f, 10.0f);
241    glMatrixMode(GL_MODELVIEW);
242    glPushMatrix();
243    glLoadIdentity();
244
245    glBegin(GL_POINTS);
246
247    for (unsigned int index = 0; index < _samplingPositions.size(); ++index) {
248        glMultiTexCoord3f(0, _samplingPositions[index].x,_samplingPositions[index].y,_samplingPositions[index].z);
249        glVertex2f(index % _renderTargetWidth,
250                   index / _renderTargetHeight);
251    }
252
253    glEnd();
254
255    glDisable(GL_TEXTURE_RECTANGLE_NV);
256    cgGLDisableTextureParameter(_qvVectorFieldParam);
257    cgGLDisableProfile(CG_PROFILE_FP30);
258
259    glReadPixels(0, 0, _renderTargetWidth, _renderTargetHeight, GL_RGB, GL_FLOAT, _velocities);
260
261    glMatrixMode(GL_PROJECTION);
262    glPopMatrix();
263    glMatrixMode(GL_MODELVIEW);
264    glPopMatrix();
265    glPopAttrib();
266
267    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
268}
269
270void VelocityArrowsSlice::render()
271{
272    //if (!_enabled || (_vectorFieldGraphicsID == 0)) return;   
273    if (!_enabled) return;
274
275    if (_dirty) {
276        computeSamplingTicks();
277        queryVelocity();
278        _dirty = false;
279    }
280
281    glPushMatrix();
282 
283    glScalef(_vfXscale,_vfYscale, _vfZscale);
284    glTranslatef(-0.5f, -0.5f, -0.5f);
285    if (_renderMode == LINES) {
286        glDisable(GL_TEXTURE_2D);
287        glLineWidth(2.0);
288        glColor3f(_arrowColor.x, _arrowColor.y, _arrowColor.z);
289        glBegin(GL_LINES);
290        Vector3 pos;
291        Vector3 pos2;
292        Vector3 vel(1, 0, 0);
293        Vector3 v, v2;
294        if (_axis == 2) {
295            int index = 0;
296            for (int y = 1; y <= _tickCountY; ++y) {
297                for (int x = 1; x <= _tickCountX; ++x, ++index) {
298                    pos = this->_samplingPositions[index];
299                    pos2 = this->_velocities[index].scale(_projectionVector).scale(_maxVelocityScale) + pos;
300                    glVertex3f(pos.x, pos.y, pos.z);
301                    glVertex3f(pos2.x, pos2.y, pos2.z);
302                    /*v = pos - pos2;
303                      v2.x = 1;
304                      v2.y = 1;
305                      v2.z = (-(x1-x2)-(y1-y2))/(z1-z2)
306                      adj = v.length() / (4 * sqrt((x3^2)+(y3^2)+(z3^2)));
307                      x3 *= adj
308                      y3 *= adj
309                      z3 *= adj
310                    */
311                }
312            }
313        } else if (_axis == 1) {
314            int index = 0;
315            for (int z = 1; z <= _tickCountZ; ++z) {
316                for (int x = 1; x <= _tickCountX; ++x, ++index) {
317                    pos = _samplingPositions[index];
318                    pos2 = this->_velocities[index].scale(_projectionVector).scale(_maxVelocityScale) + pos;
319                   
320                    glVertex3f(pos.x, pos.y, pos.z);
321                    glVertex3f(pos2.x, pos2.y, pos2.z);
322                }
323            }
324        } else if (_axis == 0) {
325            int index = 0;
326            for (int z = 1; z <= _tickCountZ; ++z) {
327                for (int y = 1; y <= _tickCountY; ++y, ++index) {
328                    pos = _samplingPositions[index];
329                    pos2 = this->_velocities[index].scale(_projectionVector).scale(_maxVelocityScale) + pos;
330                   
331                    glVertex3f(pos.x, pos.y, pos.z);
332                    glVertex3f(pos2.x, pos2.y, pos2.z);
333                }
334            }
335        }
336
337        glEnd();
338        glLineWidth(1.0);
339    } else {
340        glColor3f(_arrowColor.x, _arrowColor.y, _arrowColor.z);
341        glEnable(GL_BLEND);
342        glBlendFunc(GL_SRC_ALPHA, GL_ONE);
343        glEnable(GL_POINT_SPRITE_NV);
344        glPointSize(20);                               
345        glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_NV);
346       
347#ifdef USE_NANOVIS_LIB
348        _arrowsTex->activate();
349#else
350        _arrowsTex->bind(0);
351        glEnable(GL_TEXTURE_2D);
352#endif
353        glPointParameterfARB( GL_POINT_FADE_THRESHOLD_SIZE_ARB, 0.0f );
354       
355        glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, 1.0f);
356        glPointParameterfARB( GL_POINT_SIZE_MAX_ARB, 100.0f);
357        glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
358       
359        cgGLBindProgram(_particleVP);
360        cgGLBindProgram(_particleFP);
361        cgGLEnableProfile(CG_PROFILE_VP40);
362        cgGLEnableProfile(CG_PROFILE_FP40);
363       
364        cgGLSetTextureParameter(_vectorParticleParam, _vectorFieldGraphicsID);
365        cgGLEnableTextureParameter(_vectorParticleParam);
366       
367       
368        //cgSetParameter1f(_mvTanHalfFOVParam, -tan(_fov * 0.5) * _screenHeight * 0.5);
369       
370        cgGLSetStateMatrixParameter(_mvpParticleParam,
371                                    CG_GL_MODELVIEW_PROJECTION_MATRIX,
372                                    CG_GL_MATRIX_IDENTITY);
373        cgGLSetStateMatrixParameter(_mvParticleParam,
374                                    CG_GL_MODELVIEW_MATRIX,
375                                    CG_GL_MATRIX_IDENTITY);
376       
377        glEnableClientState(GL_VERTEX_ARRAY);
378        glBindBufferARB(GL_ARRAY_BUFFER_ARB, _vertexBufferGraphicsID);
379        glVertexPointer(3, GL_FLOAT, 0, 0);
380        //glEnableClientState(GL_COLOR_ARRAY);
381       
382        // TBD..
383        glDrawArrays(GL_POINTS, 0, _pointCount);
384        glPointSize(1);
385        glDrawArrays(GL_POINTS, 0, _pointCount);
386       
387        glDisableClientState(GL_VERTEX_ARRAY);
388       
389        cgGLDisableProfile(CG_PROFILE_VP40);
390        cgGLDisableProfile(CG_PROFILE_FP40);
391       
392        glDepthMask(GL_TRUE);
393       
394        glDisable(GL_POINT_SPRITE_NV);
395        glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_NV);
396       
397        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
398        glDisable(GL_BLEND);
399#ifdef USE_NANOVIS_LIB
400        _arrowsTex->deactivate();
401#else
402        _arrowsTex->unbind();
403#endif
404    }
405    glPopMatrix();
406}
407
408
409void
410VelocityArrowsSlice::vectorField(unsigned int vfGraphicsID,
411                                 float xScale, float yScale, float zScale)
412{
413    _vectorFieldGraphicsID = vfGraphicsID;
414    _vfXscale = xScale;
415    _vfYscale = yScale;
416    _vfZscale = zScale;
417
418    //_dirty = true;
419}
420
421void VelocityArrowsSlice::tickCountForMinSizeAxis(int tickCount)
422{
423    _tickCountForMinSizeAxis = tickCount;
424       
425    //_dirty = true;
426}
427
428void VelocityArrowsSlice::computeSamplingTicks()
429{
430    if (_vfXscale < _vfYscale) {
431        if (_vfXscale < _vfZscale) {
432            // vfXscale
433            _tickCountX = _tickCountForMinSizeAxis;
434                       
435            float step = _vfXscale / (_tickCountX + 1);
436                       
437            _tickCountY = (int)(_vfYscale/step);
438            _tickCountZ = (int)(_vfZscale/step);
439            //vscalex = 1;
440            //vscaley = _vfXscale / _vfXscale;
441            //vscalez = _vfZscale / _vfXscale;
442        } else {
443            // vfZscale
444            _tickCountZ = _tickCountForMinSizeAxis;
445
446            float step = _vfZscale / (_tickCountZ + 1);
447            _tickCountX = (int)(_vfXscale/step);
448            _tickCountY = (int)(_vfYscale/step);
449            //vscalex = _vfXscale / _vfZscale;
450            //vscaley = _vfYscale / _vfZscale;
451            //vscalez = 1;
452        }
453    } else {
454        if (_vfYscale < _vfZscale) {
455            // _vfYscale
456            _tickCountY = _tickCountForMinSizeAxis;
457
458            float step = _vfYscale / (_tickCountY + 1);
459            _tickCountX = (int)(_vfXscale/step);
460            _tickCountZ = (int)(_vfZscale/step);
461
462            //vscalex = _vfXscale / _vfYscale;
463            //vscaley = 1;
464            //vscalez = _vfZscale / _vfYscale;
465        } else {
466            // vfZscale
467            _tickCountZ = _tickCountForMinSizeAxis;
468                       
469            float step = _vfZscale / (_tickCountZ + 1);
470            _tickCountX = (int)(_vfXscale/step);
471            _tickCountY = (int)(_vfYscale/step);
472
473            //vscalex = _vfXscale / _vfZscale;
474            //vscaley = _vfYscale / _vfZscale;
475            //vscalez = 1;
476        }
477    }
478
479    _maxVelocityScale.x = 1.0f / _tickCountX * 0.8f;
480    _maxVelocityScale.y = 1.0f / _tickCountY * 0.8f;
481    _maxVelocityScale.z = 1.0f / _tickCountZ * 0.8f;
482
483    int pointCount = _tickCountX * _tickCountY * _tickCountZ;
484    if (_pointCount != pointCount) {
485        _samplingPositions.clear();
486        _samplingPositions.reserve(pointCount);
487        _pointCount = pointCount;
488    }
489
490    if (_renderMode == LINES) {
491        Vector3 pos;
492        if (_axis == 2) {
493            for (int y = 1; y <= _tickCountY; ++y) {
494                for (int x = 1; x <= _tickCountX; ++x) {
495                    pos.x = (1.0f / (_tickCountX + 1)) * x;
496                    pos.y = (1.0f / (_tickCountY + 1)) * y;
497                    pos.z = _slicePos;
498                    _samplingPositions.push_back(pos);
499                }
500            }
501        } else if (_axis == 1) {
502            for (int z = 1; z <= _tickCountZ; ++z) {
503                for (int x = 1; x <= _tickCountX; ++x) {
504                    pos.x = (1.0f / (_tickCountX + 1)) * x;
505                    pos.y = _slicePos;
506                    pos.z = (1.0f / (_tickCountZ + 1)) * z;
507                    _samplingPositions.push_back(pos);
508                }
509            }
510        } else if (_axis == 0) {
511            for (int z = 1; z <= _tickCountZ; ++z) {
512                for (int y = 1; y <= _tickCountY; ++y) {
513                    pos.x = _slicePos;
514                    pos.y = (1.0f / (_tickCountY + 1)) * y;
515                    pos.z = (1.0f / (_tickCountZ + 1)) * z;
516                    _samplingPositions.push_back(pos);
517                }
518            }
519        }
520    } else {
521        glBindBufferARB(GL_ARRAY_BUFFER_ARB, _vertexBufferGraphicsID);
522        Vector3* pinfo = (Vector3*) glMapBufferARB(GL_ARRAY_BUFFER, GL_WRITE_ONLY_ARB);
523
524        Vector3 pos;
525        if (_axis == 2) {
526            for (int y = 1; y <= _tickCountY; ++y) {
527                for (int x = 1; x <= _tickCountX; ++x) {
528                    pos.x = (1.0f / (_tickCountX + 1)) * x;
529                    pos.y = (1.0f / (_tickCountY + 1)) * y;
530                    pos.z = _slicePos;
531
532                    *pinfo = pos;
533                    ++pinfo;
534                }
535            }
536        } else if (_axis == 1) {
537            for (int z = 1; z <= _tickCountZ; ++z) {
538                for (int x = 1; x <= _tickCountX; ++x) {
539                    pos.x = (1.0f / (_tickCountX + 1)) * x;
540                    pos.y = _slicePos;
541                    pos.z = (1.0f / (_tickCountZ + 1)) * z;
542
543                    *pinfo = pos;
544                    ++pinfo;
545                }
546            }
547        } else if (_axis == 0) {
548            for (int z = 1; z <= _tickCountZ; ++z) {
549                for (int y = 1; y <= _tickCountY; ++y) {
550                    pos.x = _slicePos;
551                    pos.y = (1.0f / (_tickCountY + 1)) * y;
552                    pos.z = (1.0f / (_tickCountZ + 1)) * z;
553
554                    *pinfo = pos;
555                    ++pinfo;
556                }
557            }
558        }
559
560        glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
561    }
562}
563
564void VelocityArrowsSlice::slicePos(float pos)
565{
566    _slicePos = pos;
567    _dirty = true;
568}
Note: See TracBrowser for help on using the repository browser.