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

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

Refactor texture classes, misc. cleanups, cut down on header pollution -- still
need to fix header deps in Makefile.in

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