source: trunk/packages/vizservers/nanovis/ParticleSystem.cpp @ 2817

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

Remove a couple of unneeded headers

File size: 62.2 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
3#include <time.h>
4#include <stdlib.h>
5#include <stdio.h>
6#include <pthread.h>
7
8#include <vr3d/vr3d.h>
9#include <vr3d/vrTexture3D.h>
10
11#include <Cg/cgGL.h>
12
13#include <vrutil/vrFilePath.h>
14
15#include <vrmath/vrMatrix4x4f.h>
16#include <vrmath/vrVector3f.h>
17#include <vrmath/vrVector4f.h>
18
19#ifdef _WIN32
20#include <GL/glaux.h>
21#else
22#ifdef notdef
23#include <opencv/cv.h>
24#include <opencv/highgui.h>
25#endif
26#endif
27
28#include "ParticleSystem.h"
29#include "ParticleEmitter.h"
30#include "Trace.h"
31
32#define USE_RGBA_ARROW
33
34//#define TEST
35// TEST
36extern void*
37LoadFlowDx(const char* fname, int& width, int& height, int& depth,
38           float& min, float& max, float& nonzero_min,
39           float& axisScaleX, float& axisScaleY, float& axisScaleZ);
40
41extern void*
42LoadFlowRaw(const char* fname, int width, int height, int depth,
43            float& min, float& max, float& nonzero_min,
44            float& axisScaleX, float& axisScaleY, float& axisScaleZ,
45            int skipByte, bool bigEndian);
46
47extern void*
48LoadProcessedFlowRaw(const char* fname, int width, int height, int depth,
49                     float min, float max,
50                     float& axisScaleX, float& axisScaleY, float& axisScaleZ,
51                     int skipByte);
52
53extern void
54LoadProcessedFlowRaw(const char* fname, int width, int height, int depth,
55                     float* data);
56
57inline float randomRange(float rangeMin, float rangeMax)
58{
59    return ((float)rand() / RAND_MAX) * (rangeMax - rangeMin) + rangeMin ;
60}
61
62inline int logd(int value)
63{
64    int l;
65    for (l = 0; value >> l; l++);
66    return l - 1;
67}
68
69inline void swap(int& x, int& y)
70{
71    if (x != y) {
72        x ^= y;
73        y ^= x;
74        x ^= y;
75    }
76}
77
78void *ParticleSystem::dataLoadMain(void *data)
79{
80    ParticleSystem *particleSystem = (ParticleSystem *)data;
81    CircularFifo<float*, 10>& queue = particleSystem->_queue;
82
83    // TBD..
84    //float min = particleSystem->_time_series_vel_mag_min;
85    //float max = particleSystem->_time_series_vel_mag_max;
86
87    int startIndex = particleSystem->_flowFileStartIndex;
88    int endIndex = particleSystem->_flowFileEndIndex;
89
90    int curIndex = startIndex;
91    int flowWidth = particleSystem->_flowWidth;
92    int flowHeight = particleSystem->_flowHeight;
93    int flowDepth = particleSystem->_flowDepth;
94
95    const char* fileNameFormat = particleSystem->_fileNameFormat.c_str();
96    char buff[256];
97
98    bool done = false;
99    while (!done) {
100        if (curIndex > endIndex) {
101            curIndex = startIndex;
102        }
103
104        if (!queue.isFull()) {
105            int tail = queue.tailIndex();
106            if (tail != -1) {
107                sprintf(buff, fileNameFormat, curIndex);
108                //std::string path = vrFilePath::getInstance()->getPath(buff);
109#ifdef WANT_TRACE
110                float t = clock() /(float) CLOCKS_PER_SEC;
111#endif
112                LoadProcessedFlowRaw(buff, flowWidth, flowHeight, flowDepth, queue.array[tail]);
113#ifdef WANT_TRACE
114                float ti = clock() / (float) CLOCKS_PER_SEC;
115                TRACE("LoadProcessedFlowRaw time: %f\n", ti - t);
116#endif
117                queue.push();
118                TRACE("%d loaded\n", curIndex);
119                ++curIndex;
120            }
121        }
122    }
123
124    return 0;
125}
126
127CGcontext ParticleSystem::_context = 0;
128
129unsigned int SpotTexID = 0;
130
131void MakeSphereTexture()
132{
133    const int DIM = 128;
134    const int DIM2 = 63;
135    //const float TEX_SCALE = 6.0;
136
137    glGenTextures(1, (GLuint *)&SpotTexID);
138    glBindTexture(GL_TEXTURE_2D, SpotTexID);
139
140    float col[4] = {1.f, 1.f, 1.f, 1.f};
141    glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, col);
142    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
143
144    float *img = new float[DIM*DIM];
145
146    vrVector3f light(1,1,3);
147    light.normalize();
148
149    for (int y = 0; y < DIM; y++) {
150        for (int x = 0; x < DIM; x++) {
151            // Clamping the edges to zero allows Nvidia's blend optimizations to do their thing.
152            if (x == 0 || x == DIM-1 || y == 0 || y == DIM-1) {
153                img[y*DIM+x] = 0;
154            } else {
155                vrVector3f p(x, y, 0);
156                p = p - vrVector3f(DIM2, DIM2, 0);
157                float len = p.length();
158                float z = sqrt(DIM2*DIM2 - len*len);
159                p.z = z;
160                if (len >= DIM2) {
161                    img[y*DIM+x] = 0.0;
162                    continue;
163                }
164
165                p.normalize();
166                float v = p.dot(light);
167                if(v < 0) v = 0;
168
169                img[y*DIM+x] = v;
170            }
171        }
172    }
173
174    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
175    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
176    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
177    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
178
179    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_ALPHA16, DIM, DIM, GL_ALPHA, GL_FLOAT, img);
180}
181
182//extern void algorithm_test(vrVector4f* data, int flowWidth, int flowHeight, int flowDepth);
183//extern std::vector<vrVector3f>* find_critical_points(vrVector4f* data, int flowWidth, int flowHeight, int flowDepth);
184ParticleSystem::ParticleSystem(int width, int height,
185                               const std::string& fileName,
186                               int fieldWidth, int fieldHeight, int fieldDepth,
187                               bool timeVaryingData,
188                               int flowFileStartIndex, int flowFileEndIndex) :
189    _width(width),
190    _height(height)
191{
192    ////////////////////////////////
193    // TIME-VARYING SERIES
194    _isTimeVaryingField = timeVaryingData;
195    _flowFileStartIndex = flowFileStartIndex;
196    _flowFileEndIndex = flowFileEndIndex;
197    _userDefinedParticleMaxCount = width * height;
198
199    _skipByte = 0;
200
201    _screenWidth = _screenHeight = 1;
202    _fov = 60.0f;
203
204    _particleMaxCount = _width * _height;
205
206    _pointSize = 10.0f;
207    _camx = 0.0f;
208    _camy = 0.0f;
209    _camz = 0.0f;
210
211    _scalex = _scaley = _scalez = 1.0f;
212    _currentSortIndex = 0;
213    _destSortIndex = 1;
214
215    _currentPosIndex = 0;
216    _destPosIndex = 1;
217
218    _currentSortPass = 0;
219    // TBD
220    //_sortPassesPerFrame = 5;
221    _sortPassesPerFrame = 4;
222    _maxSortPasses = 0;
223
224    _sortBegin = 0;
225    _sortEnd = _sortPassesPerFrame;
226    _currentTime = 0;
227    _sortEnabled = false;
228    _glypEnabled = false;
229    _advectionEnabled = false;
230    _streamlineEnabled = false;
231    _particles = new Particle[_particleMaxCount];
232    memset(_particles, 0, sizeof(Particle) * _particleMaxCount);
233
234    _colorBuffer = new color4[_particleMaxCount];
235    memset(_colorBuffer, 0, sizeof(color4) * _particleMaxCount);
236
237    _positionBuffer = new vrVector3f[_particleMaxCount];
238    _vertices = new RenderVertexArray(_particleMaxCount, 3, GL_FLOAT);
239
240    srand(time(0));
241
242    /*
243    // TBD..
244    glGenBuffersARB(1, &_colorBufferID);
245    glBindBufferARB(GL_ARRAY_BUFFER, _colorBufferID);
246    glBufferDataARB(GL_ARRAY_BUFFER, _width * _height * 4, _colorBuffer, GL_STREAM_DRAW_ARB); // undefined data
247    glBindBufferARB(GL_ARRAY_BUFFER, 0);
248    */
249
250    _flowWidth = fieldWidth;
251    _flowHeight = fieldHeight;
252    _flowDepth = fieldDepth;
253
254    float min, max, nonzero_min, axisScaleX, axisScaleY, axisScaleZ;
255    int index = fileName.rfind('.');
256    std::string ext = fileName.substr(index + 1, fileName.size() - (index + 1));
257    float *data = 0;
258
259    if (this->isTimeVaryingField()) {
260        axisScaleX = _flowWidth;
261        axisScaleY = _flowHeight;
262        axisScaleZ = _flowDepth;
263        _fileNameFormat = fileName;
264        for (int i = 0; i < CircularFifo<float*, 10>::Capacity; ++i) {
265            _queue.array[i] = new float[_flowWidth * _flowHeight * _flowDepth * 4];
266        }
267
268        // INSOO
269        // TBD
270        min = 0;
271        max = 234.99;
272    } else {
273        if (ext == "dx") {
274            data = (float*) LoadFlowDx(fileName.c_str(), _flowWidth, _flowHeight, _flowDepth, min, max, nonzero_min, axisScaleX, axisScaleY, axisScaleZ);
275        } else if (ext == "raw") {
276            data = (float*) LoadFlowRaw(fileName.c_str(), _flowWidth, _flowHeight, _flowDepth, min, max, nonzero_min, axisScaleX, axisScaleY, axisScaleZ, 0, false);
277            //data = (float*) LoadProcessedFlowRaw(fileName.c_str(), _flowWidth, _flowHeight, _flowDepth, min, max, axisScaleX, axisScaleY, axisScaleZ);
278#ifdef notdef
279        } else if (ext == "raws") {
280            data = (float*) LoadFlowRaw(fileName.c_str(), _flowWidth, _flowHeight, _flowDepth, min, max, nonzero_min, axisScaleX, axisScaleY, axisScaleZ, 5 * sizeof(int), true);
281        } else if (ext == "data") {
282            data = (float*) LoadFlowRaw(fileName.c_str(), _flowWidth, _flowHeight, _flowDepth, min, max, nonzero_min, axisScaleX, axisScaleY, axisScaleZ, 0, true);
283#endif
284        }
285        //_criticalPoints = find_critical_points((vrVector4f*) data, _flowWidth,  _flowHeight,  _flowDepth);
286        //algorithm_test((vrVector4f*) data,  _flowWidth,  _flowHeight,  _flowDepth);
287    }
288
289    _scalex = 1;
290    _scaley = axisScaleY / axisScaleX;
291    _scalez = axisScaleZ / axisScaleX;
292    _maxVelocityScale = max;
293
294    if (!this->isTimeVaryingField()) {
295        vrTexture3D* flow = new vrTexture3D();
296        flow->setMinFilter(TF_LINEAR);
297        flow->setMagFilter(TF_LINEAR);
298        flow->setPixels(CF_RGBA, DT_FLOAT, _flowWidth, _flowHeight, _flowDepth, data);
299        this->_curVectorFieldID = flow->getGraphicsObjectID();
300        _vectorFieldIDs.push_back(_curVectorFieldID);
301    } else {
302        for (int i = 0; i < 3; ++i) {
303            vrTexture3D* flow = new vrTexture3D();
304            flow->setMinFilter(TF_LINEAR);
305            flow->setMagFilter(TF_LINEAR);
306            flow->setPixels(CF_RGBA, DT_FLOAT, _flowWidth, _flowHeight, _flowDepth, data);
307            _vectorFields.push_back(flow);
308            _vectorFieldIDs.push_back(flow->getGraphicsObjectID());
309        }
310        this->_curVectorFieldID = _vectorFieldIDs[0];
311    }
312
313    _arrows = new vrTexture2D();
314    _arrows->setWrapS(TW_MIRROR);
315    _arrows->setWrapT(TW_MIRROR);
316
317#ifdef _WIN32
318#ifndef USE_RGBA_ARROW
319    std::string path = vrFilePath::getInstance()->getPath("arrows.bmp");
320    AUX_RGBImageRec *pTextureImage = auxDIBImageLoad(path.c_str());
321    _arrows->setPixels(CF_RGB, DT_UBYTE, pTextureImage->sizeX, pTextureImage->sizeY, (void*) pTextureImage->data);
322#else
323    std::string path = vrFilePath::getInstance()->getPath("arrows_red_bg.bmp");
324    AUX_RGBImageRec *pTextureImage = auxDIBImageLoad(path.c_str());
325    unsigned char* pixels = new unsigned char [pTextureImage->sizeX * pTextureImage->sizeY * sizeof(unsigned char) * 4];
326    unsigned char* srcPixels = pTextureImage->data;
327    unsigned char* dstPixels = pixels;
328    for (int i = 0; i < pTextureImage->sizeX * pTextureImage->sizeY; ++i) {
329        *dstPixels = *srcPixels; ++srcPixels;
330        *(dstPixels + 1) = *srcPixels; ++srcPixels;
331        *(dstPixels + 2) = *srcPixels; ++srcPixels;
332
333        if ((*dstPixels > 127) && (*(dstPixels + 1) < 127) && (*(dstPixels + 2) < 127)) {
334            *(dstPixels + 3) = 0;
335        } else {
336            *(dstPixels + 3) = 255;
337        }
338
339        dstPixels += 4;
340    }
341    _arrows->setPixels(CF_RGBA, DT_UBYTE, pTextureImage->sizeX, pTextureImage->sizeY, (void*) pixels);
342#endif
343
344#else
345#ifndef USE_RGBA_ARROW
346    IplImage* pTextureImage = cvLoadImage("arrows_flip2.png");
347    _arrows->setPixels(CF_RGB, DT_UBYTE, pTextureImage->width, pTextureImage->height, (void*) pTextureImage->imageData);
348#else
349
350#ifdef notdef
351    // TBD..
352    std::string path = vrFilePath::getInstance()->getPath("arrows_red_bg.bmp");
353    AUX_RGBImageRec *pTextureImage = auxDIBImageLoad(path.c_str());
354    unsigned char* pixels = new unsigned char [pTextureImage->sizeX * pTextureImage->sizeY * sizeof(unsigned char) * 4];
355    unsigned char* srcPixels = pTextureImage->data;
356    unsigned char* dstPixels = pixels;
357    for (int i = 0; i < pTextureImage->sizeX * pTextureImage->sizeY; ++i) {
358        *dstPixels = *srcPixels; ++srcPixels;
359        *(dstPixels + 1) = *srcPixels; ++srcPixels;
360        *(dstPixels + 2) = *srcPixels; ++srcPixels;
361
362        if ((*dstPixels > 127) && (*(dstPixels + 1) < 127) && (*(dstPixels + 2) < 127)) {
363            *(dstPixels + 3) = 0;
364        } else {
365            *(dstPixels + 3) = 255;
366        }
367
368        dstPixels += 4;
369    }
370
371    _arrows->setPixels(CF_RGBA, DT_UBYTE, pTextureImage->sizeX, pTextureImage->sizeY, (void*) pixels);
372#endif
373
374#endif // USE_RGBA_ARROW
375#endif // _WIN32
376
377#ifdef TEST
378    MakeSphereTexture();
379#endif
380
381    glGenBuffersARB(1, &_particleInfoBufferID);
382    glBindBufferARB(GL_ARRAY_BUFFER_ARB, _particleInfoBufferID);
383    glBufferDataARB(GL_ARRAY_BUFFER_ARB, _particleMaxCount * 4 * sizeof(float), 0, GL_DYNAMIC_DRAW);
384    glVertexAttribPointerARB(8, 4, GL_FLOAT, GL_FALSE, 0, 0);  // 8 = texcoord0
385    glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
386
387    // TBD..
388    initStreamlines(_width, _height);
389    initInitPosTex();
390
391    initShaders();
392    createRenderTargets();
393    createSortRenderTargets();
394    createStreamlineRenderTargets();
395
396    if (this->isTimeVaryingField()) {
397        pthread_t _threads;
398        pthread_attr_t pthread_custom_attr;
399        pthread_attr_init(&pthread_custom_attr);
400        pthread_create(&_threads, &pthread_custom_attr, dataLoadMain, (void *) this);
401    }
402}
403
404void ParticleSystem::initInitPosTex()
405{
406    glGenFramebuffersEXT(1, &_initPos_fbo);
407    glGenTextures(1, &_initPosTex);
408
409    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _initPos_fbo);
410
411    glViewport(0, 0, _width, _height);
412    glMatrixMode(GL_PROJECTION);
413    glLoadIdentity();
414    glOrtho(0, _width, 0, _height, -10.0f, 10.0f);
415    glMatrixMode(GL_MODELVIEW);
416    glLoadIdentity();
417
418    glBindTexture(GL_TEXTURE_RECTANGLE_NV, _initPosTex);
419    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
420    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
421    glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
422    glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
423    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGB_NV,
424                 _width, _height, 0, GL_RGB, GL_FLOAT, NULL);
425    glBindTexture(GL_TEXTURE_RECTANGLE_NV, 0);
426
427    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
428                              GL_TEXTURE_RECTANGLE_NV, _initPosTex, 0);
429
430    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
431}
432
433void ParticleSystem::initStreamlines(int width, int height)
434{
435    _atlas_x = 32;
436    _atlas_y = 32;
437
438    _atlasWidth = width * _atlas_x;
439    _atlasHeight = height * _atlas_y;
440    _maxAtlasCount = _atlas_x * _atlas_y;
441
442    _stepSizeStreamline = 1;
443    _curStepCount = 0;
444    _particleCount = width * height;
445
446    _currentStreamlineOffset = 0;
447    _currentStreamlineIndex = 0;
448    _streamVertices = new RenderVertexArray(_atlasWidth*_atlasHeight * 2, 3, GL_FLOAT);
449
450    _maxIndexBufferSize = _width * _height * _atlas_x * _atlas_y;
451    _indexBuffer = new unsigned int[_maxIndexBufferSize * 2];
452    unsigned int* pindex = _indexBuffer;
453    int ax, ay, old_ax = 0, old_ay = 0;
454    for (unsigned int i = 1; i < _maxAtlasCount; ++i) {
455        ax = (i % _atlas_x) * width;
456        ay = (i / _atlas_x) * height;
457
458        for (int y = 0; y < height ; ++y) {
459            for (int x = 0; x < width; ++x) {
460                *pindex = (old_ay + y) * _atlasWidth + old_ax + x; ++pindex;
461                *pindex = (ay + y) * _atlasWidth + ax + x; ++pindex;
462            }
463        }
464
465        old_ax = ax;
466        old_ay = ay;
467    }
468}
469
470void ParticleSystem::callbackForCgError()
471{
472    CGerror lastError = cgGetError();
473    if (lastError) {
474        const char *listing = cgGetLastListing(_context);
475        ERROR("\n---------------------------------------------------\n");
476        ERROR("%s\n\n", cgGetErrorString(lastError));
477        ERROR("%s\n", listing);
478        ERROR("-----------------------------------------------------\n");
479        ERROR("Cg error, exiting...\n");
480
481        cgDestroyContext(_context);
482        getchar();
483        exit(-1);
484    }
485}
486
487void ParticleSystem::initShaders()
488{
489    // TBD...
490    _context = cgCreateContext();
491    cgSetErrorCallback(callbackForCgError);
492
493    std::string path = vrFilePath::getInstance()->getPath("distance.cg");
494    _distanceInitFP = 
495        cgCreateProgramFromFile(_context, CG_SOURCE, path.c_str(),
496                                CG_PROFILE_FP30, "initSortIndex", NULL);
497    cgGLLoadProgram(_distanceInitFP);
498
499    _distanceSortFP =
500        cgCreateProgramFromFile(_context, CG_SOURCE,  path.c_str(),
501                                CG_PROFILE_FP30, "computeDistance", NULL);
502    _viewPosParam = cgGetNamedParameter(_distanceSortFP, "viewerPosition");
503    cgGLLoadProgram(_distanceSortFP);
504
505    _distanceSortLookupFP =
506        cgCreateProgramFromFile(_context, CG_SOURCE,  path.c_str(),
507                                CG_PROFILE_FP30, "lookupPosition", NULL);
508    cgGLLoadProgram(_distanceSortLookupFP);
509
510    path = vrFilePath::getInstance()->getPath("mergesort.cg");
511    _sortRecursionFP =
512        cgCreateProgramFromFile(_context, CG_SOURCE, path.c_str(),
513                                CG_PROFILE_FP30, "mergeSortRecursion", NULL);
514    cgGLLoadProgram(_sortRecursionFP);
515
516    _srSizeParam = cgGetNamedParameter(_sortRecursionFP, "_Size");
517    _srStepParam = cgGetNamedParameter(_sortRecursionFP, "_Step");
518    _srCountParam = cgGetNamedParameter(_sortRecursionFP, "_Count");
519
520    _sortEndFP =
521        cgCreateProgramFromFile(_context, CG_SOURCE, path.c_str(),
522                                CG_PROFILE_FP30, "mergeSortEnd", NULL);
523    cgGLLoadProgram(_sortEndFP);
524
525    _seSizeParam = cgGetNamedParameter(_sortEndFP, "size");
526    _seStepParam = cgGetNamedParameter(_sortEndFP, "step");
527
528    path = vrFilePath::getInstance()->getPath("passthrough.cg");
529    _passthroughFP =
530        cgCreateProgramFromFile(_context, CG_SOURCE, path.c_str(),
531                                CG_PROFILE_FP30, "main", NULL);
532    cgGLLoadProgram(_passthroughFP);
533
534    _scaleParam = cgGetNamedParameter(_passthroughFP, "scale");
535    _biasParam = cgGetNamedParameter(_passthroughFP, "bias");
536
537    path = vrFilePath::getInstance()->getPath("moveparticles.cg");
538    _moveParticlesFP =
539        cgCreateProgramFromFile(_context, CG_SOURCE, path.c_str(),
540                                CG_PROFILE_FP30, "main", NULL);
541    cgGLLoadProgram(_moveParticlesFP);
542    _mpTimeScale = cgGetNamedParameter(_moveParticlesFP, "timeStep");
543    _mpVectorField = cgGetNamedParameter(_moveParticlesFP, "vfield");
544    _mpUseInitTex= cgGetNamedParameter(_moveParticlesFP, "useInitPos");
545    _mpCurrentTime= cgGetNamedParameter(_moveParticlesFP, "currentTime");
546    _mpMaxScale = cgGetNamedParameter(_moveParticlesFP, "maxScale");
547    _mpScale= cgGetNamedParameter(_moveParticlesFP, "scale");
548
549    path = vrFilePath::getInstance()->getPath("particlevp.cg");
550    _particleVP =
551        cgCreateProgramFromFile(_context, CG_SOURCE, path.c_str(),
552                                CG_PROFILE_VP40, "vpmain", NULL);
553    cgGLLoadProgram(_particleVP);
554    _mvpParticleParam = cgGetNamedParameter(_particleVP, "mvp");
555    _mvParticleParam = cgGetNamedParameter(_particleVP, "modelview");
556    _mvTanHalfFOVParam = cgGetNamedParameter(_particleVP, "tanHalfFOV");
557    _mvCurrentTimeParam =  cgGetNamedParameter(_particleVP, "currentTime");
558
559    path = vrFilePath::getInstance()->getPath("particlefp.cg");
560    _particleFP =
561        cgCreateProgramFromFile(_context, CG_SOURCE, path.c_str(),
562                                CG_PROFILE_FP40, "fpmain", NULL);
563    cgGLLoadProgram(_particleFP);
564    _vectorParticleParam = cgGetNamedParameter(_particleVP, "vfield");
565
566    path = vrFilePath::getInstance()->getPath("moveparticles.cg");
567    _initParticlePosFP =
568        cgCreateProgramFromFile(_context, CG_SOURCE, path.c_str(),
569                                CG_PROFILE_FP30, "initParticlePosMain", NULL);
570    cgGLLoadProgram(_initParticlePosFP);
571    _ipVectorFieldParam = cgGetNamedParameter(_moveParticlesFP, "vfield");
572}
573
574void ParticleSystem::passThoughPositions()
575{
576    cgGLBindProgram(_passthroughFP);
577    cgGLEnableProfile(CG_PROFILE_FP30);
578
579    cgGLSetParameter4f(_scaleParam, 1.0, 1.0, 1.0, 1.0);
580    cgGLSetParameter4f(_biasParam, 0.0, 0.0, 0.0, 0.0);
581
582    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGB_NV,
583                 _width, _height, 0, GL_RGB, GL_FLOAT, (GLfloat *) _positionBuffer);
584
585    drawQuad();
586
587    cgGLDisableProfile(CG_PROFILE_FP30);
588}
589
590void ParticleSystem::resetStreamlines()
591{
592    _currentStreamlineIndex = 0;
593    _currentStreamlineOffset = 0;
594    _curStepCount = 0;
595}
596
597void ParticleSystem::reset()
598{
599    _currentTime = 0.0f;
600    _sortBegin = 0;
601    _sortEnd = _sortPassesPerFrame;
602
603    glPushAttrib(GL_VIEWPORT_BIT);
604    glMatrixMode(GL_PROJECTION);
605    glPushMatrix();
606    glMatrixMode(GL_MODELVIEW);
607
608    resetStreamlines();
609
610    unsigned int maxsize = _userDefinedParticleMaxCount;
611
612    while (!_availableIndices.empty())
613        _availableIndices.pop();
614    while (!_activeParticles.empty())
615        _activeParticles.pop();
616
617    _activeParticles.reserve(maxsize);
618    _availableIndices.reserve(maxsize);
619
620    for (unsigned int i = 0; i < maxsize; i++)
621        _availableIndices.push(i);
622
623    for (int i = 0; i < _particleMaxCount; i++) {
624        _particles[i].timeOfBirth = -1.0f;
625        _particles[i].lifeTime = 0.0f;
626        _particles[i].attributeType = 0.0f;
627        _particles[i].index = (float)i;
628    }
629
630    glBindBufferARB(GL_ARRAY_BUFFER_ARB, _particleInfoBufferID);
631    Particle* pinfo = (Particle*) glMapBufferARB(GL_ARRAY_BUFFER, GL_WRITE_ONLY_ARB);
632
633    for (int i = 0; i < _particleMaxCount; i++) {
634        pinfo[i] = _particles[i];
635    }
636
637    glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
638
639    // POSITION
640    memset(_positionBuffer, 0, sizeof(vrVector3f) * _width * _height);
641    for (int y = 0; y < _height; y++) {
642        for (int x = 0; x < _width; x++) {
643            _positionBuffer[_width * y + x].x = (float)rand() / (float) RAND_MAX;
644            //_positionBuffer[_width * y + x].x = 0.9;
645            _positionBuffer[_width * y + x].y = (float)rand() / (float) RAND_MAX;
646            _positionBuffer[_width * y + x].z = (float)rand() / (float) RAND_MAX;
647        }
648    }
649
650    glBindTexture(GL_TEXTURE_RECTANGLE_NV, _initPosTex);
651    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGB_NV,
652                 _width, _height, 0, GL_RGB, GL_FLOAT, (float*)_positionBuffer);
653    glBindTexture(GL_TEXTURE_RECTANGLE_NV, 0);
654
655    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[_currentPosIndex]);
656    glViewport(0, 0, _width, _height);
657    glMatrixMode(GL_PROJECTION);
658    glLoadIdentity();
659    glOrtho(0, _width, 0, _height, -10.0f, 10.0f);
660    glMatrixMode(GL_MODELVIEW);
661    glLoadIdentity();
662    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
663    passThoughPositions();
664    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
665
666    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, velocity_fbo[_currentPosIndex]);
667    glViewport(0, 0, _width, _height);
668    glMatrixMode(GL_PROJECTION);
669    glLoadIdentity();
670    glOrtho(0, _width, 0, _height, -10.0f, 10.0f);
671    glMatrixMode(GL_MODELVIEW);
672    glLoadIdentity();
673    glClearColor(0, 0, 0, 0);
674    glClear(GL_COLOR_BUFFER_BIT);
675    // TBD..
676    // velocity
677    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
678
679
680    /// TBD...
681    //DeathTimePBuffer->BeginCapture();
682    //glClear(GL_COLOR_BUFFER_BIT);
683    //DeathTimePBuffer->EndCapture();
684
685    if (_sortEnabled) {
686        glDisable(GL_BLEND);
687        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, sort_fbo[_currentSortIndex]);
688        glViewport(0, 0, _width, _height);
689        glMatrixMode(GL_PROJECTION);
690        glLoadIdentity();
691        glOrtho(0, _width, 0, _height, -10.0f, 10.0f);
692        glMatrixMode(GL_MODELVIEW);
693        glLoadIdentity();
694
695        cgGLBindProgram(_distanceInitFP);
696        cgGLEnableProfile(CG_PROFILE_FP30);
697
698        drawQuad();
699
700        cgGLDisableProfile(CG_PROFILE_FP30);
701        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);           
702
703        _currentSortPass = 0;
704        this->_maxSortPasses = 100000;
705    }
706
707    glMatrixMode(GL_PROJECTION);
708    glPopMatrix();
709    glMatrixMode(GL_MODELVIEW);
710    glPopAttrib();
711}
712
713void ParticleSystem::createRenderTargets()
714{
715    glGenFramebuffersEXT(2, psys_fbo);
716    glGenTextures(2, psys_tex);
717
718    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[0]);
719
720    glViewport(0, 0, _width, _height);
721    glMatrixMode(GL_PROJECTION);
722    glLoadIdentity();
723    glOrtho(0, _width, 0, _height, -10.0f, 10.0f);
724    glMatrixMode(GL_MODELVIEW);
725    glLoadIdentity();
726
727    glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[0]);
728    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
729    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
730    glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
731    glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
732
733    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGBA32_NV,
734                 _width, _height, 0, GL_RGBA, GL_FLOAT, NULL);
735
736    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
737                              GL_TEXTURE_RECTANGLE_NV, psys_tex[0], 0);
738
739    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[1]);
740
741    glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[1]);
742    glViewport(0, 0, _width, _height);
743    glMatrixMode(GL_PROJECTION);
744    glLoadIdentity();
745    glOrtho(0, _width, 0, _height, -10.0f, 10.0f);
746    glMatrixMode(GL_MODELVIEW);
747    glLoadIdentity();
748
749    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
750    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
751    glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
752    glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
753
754    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGBA32_NV,
755                 _width, _height, 0, GL_RGBA, GL_FLOAT, NULL);
756
757    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
758                              GL_TEXTURE_RECTANGLE_NV, psys_tex[1], 0);
759 
760    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
761}
762
763//#define ATLAS_TEXTURE_TARGET GL_TEXTURE_RECTANGLE_NV
764//#define ATLAS_INTERNAL_TYPE GL_FLOAT_RGBA32_NV
765#define ATLAS_TEXTURE_TARGET GL_TEXTURE_2D
766#define ATLAS_INTERNAL_TYPE GL_RGBA
767
768void ParticleSystem::createStreamlineRenderTargets()
769{
770    glGenFramebuffersEXT(1, &_atlas_fbo);
771    glGenTextures(1, &_atlas_tex);
772    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _atlas_fbo);
773    glViewport(0, 0, _atlasWidth, _atlasHeight);
774    glMatrixMode(GL_PROJECTION);
775    glLoadIdentity();
776    glOrtho(0, _atlasWidth, 0, _atlasHeight, -10.0f, 10.0f);
777    glMatrixMode(GL_MODELVIEW);
778    glLoadIdentity();
779
780    glBindTexture(ATLAS_TEXTURE_TARGET, _atlas_tex);
781    glTexParameterf(ATLAS_TEXTURE_TARGET, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
782    glTexParameterf(ATLAS_TEXTURE_TARGET, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
783    //glTexParameteri(ATLAS_TEXTURE_TARGET, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
784    //glTexParameteri(ATLAS_TEXTURE_TARGET, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
785
786    glTexImage2D(ATLAS_TEXTURE_TARGET, 0, ATLAS_INTERNAL_TYPE,
787                 _atlasWidth, _atlasHeight, 0, GL_RGBA, GL_FLOAT, NULL);
788
789    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
790                              ATLAS_TEXTURE_TARGET, _atlas_tex, 0);
791 
792    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
793}
794
795//#define SORT_TEXTURE_FORMAT  GL_LUMINANCE_ALPHA
796//#define SORT_TEXTURE_INNER_FORMAT GL_LUMINANCE_ALPHA_FLOAT32_ATI
797#define SORT_TEXTURE_FORMAT  GL_RGB
798#define SORT_TEXTURE_INNER_FORMAT GL_FLOAT_RGB32_NV
799
800void ParticleSystem::createSortRenderTargets()
801{
802    glGenFramebuffersEXT(2, sort_fbo);
803    glGenTextures(2, sort_tex);
804
805    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, sort_fbo[0]);
806    glViewport(0, 0, _width, _height);
807    glMatrixMode(GL_PROJECTION);
808    glLoadIdentity();
809    glOrtho(0, _width, 0, _height, -10.0f, 10.0f);
810    glMatrixMode(GL_MODELVIEW);
811    glLoadIdentity();
812
813    glBindTexture(GL_TEXTURE_RECTANGLE_NV, sort_tex[0]);
814    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
815    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
816    glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
817    glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
818    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, SORT_TEXTURE_INNER_FORMAT,
819                 _width, _height, 0, SORT_TEXTURE_FORMAT, GL_FLOAT, NULL);
820
821    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
822                              GL_TEXTURE_RECTANGLE_NV, sort_tex[0], 0);
823
824    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, sort_fbo[1]);
825    glViewport(0, 0, _width, _height);
826    glMatrixMode(GL_PROJECTION);
827    glLoadIdentity();
828    glOrtho(0, _width, 0, _height, -10.0f, 10.0f);
829    glMatrixMode(GL_MODELVIEW);
830    glLoadIdentity();
831
832    glBindTexture(GL_TEXTURE_RECTANGLE_NV, sort_tex[1]);
833    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
834    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
835    glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
836    glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
837    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, SORT_TEXTURE_INNER_FORMAT,
838                 _width, _height, 0, SORT_TEXTURE_FORMAT, GL_FLOAT, NULL);
839
840    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
841                              GL_TEXTURE_RECTANGLE_NV, sort_tex[1], 0);
842
843    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
844}
845
846ParticleSystem::~ParticleSystem()
847{
848    std::vector<ParticleEmitter*>::iterator iter;
849    for (iter = _emitters.begin(); iter != _emitters.end(); ++iter)
850        delete (*iter);
851
852    // Particle Position
853    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[0]);
854    glDeleteTextures(1, psys_tex);
855    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[1]);
856    glDeleteTextures(1, psys_tex+1);
857    glDeleteFramebuffersEXT(2, psys_fbo);
858
859    // Sort
860    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, sort_fbo[0]);
861    glDeleteTextures(1, sort_tex);
862    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, sort_fbo[1]);
863    glDeleteTextures(1, sort_tex+1);
864    glDeleteFramebuffersEXT(2, sort_fbo);
865
866    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, velocity_fbo[0]);
867    glDeleteTextures(1, velocity_tex);
868    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, velocity_fbo[1]);
869    glDeleteTextures(1, velocity_tex+1);
870    glDeleteFramebuffersEXT(2, velocity_fbo);
871
872    if (_vertices) delete _vertices;
873
874    delete [] _particles;
875    delete [] _positionBuffer;
876    delete [] _colorBuffer;
877
878    if (_arrows) delete _arrows;
879
880    // STREAM LINE
881    if (_streamVertices) delete _streamVertices;
882    if (_indexBuffer) delete _indexBuffer;
883
884    cgDestroyProgram(_distanceInitFP);
885
886    cgDestroyParameter(_viewPosParam);
887    cgDestroyProgram(_distanceSortFP);
888
889    cgDestroyProgram(_distanceSortLookupFP);
890
891    cgDestroyParameter(_scaleParam);
892    cgDestroyParameter(_biasParam);
893    cgDestroyProgram(_passthroughFP);
894
895    cgDestroyParameter(_srSizeParam);
896    cgDestroyParameter(_srStepParam);
897    cgDestroyParameter(_srCountParam);
898
899    cgDestroyProgram(_sortRecursionFP);
900
901    cgDestroyParameter(_seSizeParam);
902    cgDestroyParameter(_seStepParam);
903    cgDestroyProgram(_sortEndFP);
904
905    cgDestroyParameter(_mpTimeScale);
906    cgDestroyParameter(_mpVectorField);
907    cgDestroyParameter(_mpUseInitTex);
908    cgDestroyParameter(_mpCurrentTime);
909    cgDestroyProgram(_moveParticlesFP);
910
911    cgDestroyParameter(_ipVectorFieldParam);
912    cgDestroyProgram(_initParticlePosFP);
913
914    cgDestroyParameter(_mvpParticleParam);
915    cgDestroyParameter(_mvParticleParam);
916    cgDestroyParameter(_mvTanHalfFOVParam);
917    cgDestroyParameter(_mvCurrentTimeParam);
918    cgDestroyProgram(_particleFP);
919
920    cgDestroyParameter(_vectorParticleParam);
921    cgDestroyProgram(_particleVP);
922}
923
924bool ParticleSystem::isEnabled(EnableEnum enabled)
925{
926    switch (enabled) {
927    case PS_SORT :
928        return _sortEnabled;
929        break;
930    case PS_GLYPE :
931        return _glypEnabled;
932        break;
933    case PS_DRAW_BBOX :
934        return _drawBBoxEnabled;
935        break;
936    case PS_ADVECTION :
937        return _advectionEnabled;
938    case PS_STREAMLINE :
939        return _streamlineEnabled;
940    }
941    return false;
942}
943
944void ParticleSystem::enable(EnableEnum enabled)
945{
946    switch (enabled) {
947    case PS_SORT :
948        _sortEnabled = true;
949        break;
950    case PS_GLYPE :
951        _glypEnabled = true;
952        break;
953    case PS_DRAW_BBOX :
954        _drawBBoxEnabled = true;
955        break;
956    case PS_ADVECTION :
957        _advectionEnabled = true;
958        break;
959    case PS_STREAMLINE :
960        _streamlineEnabled = true;
961        break;
962    }
963}
964
965void ParticleSystem::disable(EnableEnum enabled)
966{
967    switch (enabled) {
968    case PS_SORT :
969        _sortEnabled = false;
970        break;
971    case PS_GLYPE :
972        _glypEnabled = false;
973        break;
974    case PS_DRAW_BBOX :
975        _drawBBoxEnabled = false;
976        break;
977    case PS_ADVECTION :
978        _advectionEnabled = false;
979        break;
980    case PS_STREAMLINE :
981        _streamlineEnabled = false;
982        break;
983    }
984}
985
986void ParticleSystem::advectStreamlines()
987{
988    glDisable(GL_BLEND);
989    glDisable(GL_DEPTH_TEST);
990
991    //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[_destPosIndex]);
992    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
993
994    glPushAttrib(GL_VIEWPORT_BIT);
995    glViewport(0, 0, _width, _height);
996    glMatrixMode(GL_PROJECTION);
997    glPushMatrix();
998    glLoadIdentity();
999    glOrtho(0, _width, 0, _height, -10.0f, 10.0f);
1000    glMatrixMode(GL_MODELVIEW);
1001    glPushMatrix();
1002    glLoadIdentity();
1003
1004    glEnable(GL_TEXTURE_RECTANGLE_NV);
1005
1006    cgGLBindProgram(_moveParticlesFP);
1007    cgGLEnableProfile(CG_PROFILE_FP30);
1008    cgGLSetParameter1f(_mpTimeScale, 0.005);
1009    cgGLSetParameter1f(_mpUseInitTex, 1.0);
1010    cgGLSetParameter1f(_mpCurrentTime, _currentTime);
1011    cgGLSetParameter3f(_mpScale, _scalex, _scaley, _scalez);
1012    cgGLSetParameter1f(_mpMaxScale, _maxVelocityScale);
1013    cgGLSetTextureParameter(_mpVectorField, _curVectorFieldID);
1014    cgGLEnableTextureParameter(_mpVectorField);
1015
1016    for (int i = 0; i < _stepSizeStreamline; ++i) {
1017        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[_destPosIndex]);
1018        glClear(GL_COLOR_BUFFER_BIT);
1019        glActiveTextureARB(GL_TEXTURE0_ARB);
1020        glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[_currentPosIndex]);
1021        glActiveTextureARB(GL_TEXTURE1_ARB);
1022        glBindTexture(GL_TEXTURE_RECTANGLE_NV, _initPosTex);
1023        drawQuad();
1024        swap(_currentPosIndex, _destPosIndex);
1025    }
1026
1027    cgGLDisableTextureParameter(_mpVectorField);
1028    glDisable(GL_TEXTURE_RECTANGLE_NV);
1029    cgGLDisableProfile(CG_PROFILE_FP30);
1030
1031    glMatrixMode(GL_PROJECTION);
1032    glPopMatrix();
1033    glMatrixMode(GL_MODELVIEW);
1034    glPopMatrix();
1035    glPopAttrib();
1036    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1037
1038    if (_currentStreamlineIndex < _maxAtlasCount) {
1039        int xoffset = (_currentStreamlineIndex % _atlas_x) * _width;
1040        int yoffset = (_currentStreamlineIndex / _atlas_x) * _height;
1041
1042        glActiveTextureARB(GL_TEXTURE0_ARB);
1043        glEnable(ATLAS_TEXTURE_TARGET);
1044        glBindTexture(ATLAS_TEXTURE_TARGET, _atlas_tex);
1045
1046        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[_destPosIndex]);
1047        //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[_currentPosIndex]);
1048        glCopyTexSubImage2D(ATLAS_TEXTURE_TARGET, 0, xoffset, yoffset,
1049                            0, 0, _width, _height);
1050        glActiveTextureARB(GL_TEXTURE0_ARB);
1051        glBindTexture(ATLAS_TEXTURE_TARGET, 0);
1052        glDisable(ATLAS_TEXTURE_TARGET);
1053
1054        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _atlas_fbo);
1055        _streamVertices->Read(_atlasWidth, _atlasHeight);
1056        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1057        _currentStreamlineIndex++;
1058
1059        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1060    }
1061}
1062
1063bool ParticleSystem::advect(float deltaT, float camx, float camy, float camz)
1064{
1065    static bool firstLoad = true;
1066    if (this->isTimeVaryingField()) {
1067        static float oldTime = vrGetTimeStamp();
1068#ifdef WANT_TRACE
1069        static int index = 0;
1070#endif
1071        float time = vrGetTimeStamp();
1072        if ((time - oldTime) > 2.0) {
1073            if (!_queue.isEmpty()) {
1074                float* data = 0;
1075                if (_queue.top(data)) {
1076#ifdef WANT_TRACE
1077                    float t = clock() /(float) CLOCKS_PER_SEC;
1078#endif
1079                    _vectorFields[0]->updatePixels(data);
1080#ifdef WANT_TRACE
1081                    float ti = clock() / (float) CLOCKS_PER_SEC;
1082                    TRACE("updatePixels time: %f\n", ti - t);
1083#endif
1084                    _queue.pop();
1085                    oldTime = time;
1086
1087                    firstLoad = false;
1088                    TRACE("%d bound\n", index++);
1089                }
1090            }           
1091        }
1092        if (firstLoad) return false;
1093    }
1094
1095    if (!_advectionEnabled) return true;
1096    if (this->_streamlineEnabled) {
1097        advectStreamlines();
1098        _currentTime += deltaT;
1099    } else {
1100        _camx = camx;
1101        _camy = camy;
1102        _camz = camz;
1103
1104        glDisable(GL_BLEND);
1105        glDisable(GL_DEPTH_TEST);
1106
1107        glPushAttrib(GL_VIEWPORT_BIT);
1108        glViewport(0, 0, _width, _height);
1109        glMatrixMode(GL_PROJECTION);
1110        glPushMatrix();
1111        glLoadIdentity();
1112        glOrtho(0, _width, 0, _height, -10.0f, 10.0f);
1113        glMatrixMode(GL_MODELVIEW);
1114        glPushMatrix();
1115        glLoadIdentity();
1116
1117        glEnable(GL_TEXTURE_RECTANGLE_NV);
1118
1119        cgGLBindProgram(_moveParticlesFP);
1120        cgGLEnableProfile(CG_PROFILE_FP30);
1121
1122        // INSOO
1123        // TIME SCALE
1124
1125        cgGLSetParameter1f(_mpTimeScale, 0.005);
1126
1127        //////////////////////////////////////////////////////
1128        // UPDATE POS
1129        cgGLSetTextureParameter(_mpVectorField, _curVectorFieldID);
1130        cgGLEnableTextureParameter(_mpVectorField);
1131        cgGLSetParameter3f(_mpScale, _scalex, _scaley, _scalez);
1132        cgGLSetParameter1f(_mpMaxScale, _maxVelocityScale);
1133        for (int i = 0; i < _stepSizeStreamline; ++i) {
1134            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[_destPosIndex]);
1135            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1136            glActiveTextureARB(GL_TEXTURE0_ARB);
1137            glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[_currentPosIndex]);
1138            glActiveTextureARB(GL_TEXTURE1_ARB);
1139            glBindTexture(GL_TEXTURE_RECTANGLE_NV, _initPosTex);
1140            drawQuad();
1141            swap(_currentPosIndex, _destPosIndex);
1142        }
1143        cgGLDisableTextureParameter(_mpVectorField);
1144
1145        glActiveTextureARB(GL_TEXTURE1_ARB);
1146        glDisable(GL_TEXTURE_RECTANGLE_NV);
1147        glActiveTextureARB(GL_TEXTURE0_ARB);
1148        glDisable(GL_TEXTURE_RECTANGLE_NV);
1149
1150        glDisable(GL_TEXTURE_RECTANGLE_NV);
1151        cgGLDisableProfile(CG_PROFILE_FP30);
1152
1153        glMatrixMode(GL_PROJECTION);
1154        glPopMatrix();
1155        glMatrixMode(GL_MODELVIEW);
1156        glPopMatrix();
1157        glPopAttrib();
1158        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1159
1160        if (_sortEnabled) {
1161            sort();
1162
1163            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[_destPosIndex]);
1164            _vertices->Read(_width, _height);
1165            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1166        } else {
1167            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[_currentPosIndex]);
1168            _vertices->Read(_width, _height);
1169            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1170        }
1171
1172        // NEW PARTICLES
1173        for (unsigned int i = 0; i < _emitters.size(); ++i) {
1174            // TBD..
1175            unsigned int numOfNewParticles = (unsigned int)(randomRange(_emitters[i]->_minNumOfNewParticles, _emitters[i]->_maxNumOfNewParticles) * deltaT);
1176            for (unsigned int k = 0; k < numOfNewParticles; ++k) {
1177                vrVector3f position = _emitters[i]->_position;
1178                position += _emitters[i]->_maxPositionOffset *
1179                    vrVector3f(randomRange(-1.0f, 1.0f), randomRange(-1.0f, 1.0f), randomRange(-1.0f, 1.0f));
1180
1181                float lifetime = randomRange(_emitters[i]->_minLifeTime, _emitters[i]->_maxLifeTime);
1182
1183                // TBD..
1184                allocateParticle(position, vrVector3f(0.0f, 0.0f, 0.0f),  lifetime, 1 - (float) k / numOfNewParticles);
1185            }
1186        }
1187
1188        initNewParticles();
1189
1190        _currentTime += deltaT;
1191
1192        cleanUpParticles();
1193    }
1194
1195    return true;
1196}
1197
1198void ParticleSystem::allocateParticle(const vrVector3f& position, const vrVector3f& velocity,
1199                                      float lifeTime, float initTimeStep)
1200{
1201    if (_availableIndices.empty()) {
1202        return;
1203    }
1204
1205    int index = _availableIndices.top();
1206    _availableIndices.pop();
1207
1208    ActiveParticle p;
1209    p.index = index;
1210    p.timeOfDeath = _currentTime + lifeTime;
1211    _activeParticles.push(p);
1212
1213    NewParticle newParticle;
1214    newParticle.index = index;
1215    newParticle.position = position;
1216    newParticle.velocity = velocity;
1217    newParticle.timeOfDeath = p.timeOfDeath;
1218    newParticle.initTimeStep = initTimeStep;
1219
1220    _newParticles.push_back(newParticle);
1221
1222    _particles[index].timeOfBirth = _currentTime;
1223    _particles[index].lifeTime = lifeTime;
1224}
1225
1226void ParticleSystem::initNewParticles()
1227{
1228    /////////////////////////////
1229    // INIT NEW PARTICLE
1230    glBindBufferARB(GL_ARRAY_BUFFER_ARB, _particleInfoBufferID);
1231    Particle* pinfo = (Particle*) glMapBufferARB(GL_ARRAY_BUFFER, GL_WRITE_ONLY_ARB);
1232
1233    std::vector<NewParticle>::iterator iter;
1234    for (iter = _newParticles.begin(); iter != _newParticles.end(); ++iter) {
1235        pinfo[iter->index] = _particles[iter->index];
1236    }
1237
1238    glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
1239
1240    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[_currentPosIndex]);
1241
1242    glPushAttrib(GL_VIEWPORT_BIT);
1243    glViewport(0, 0, _width, _height);
1244    glMatrixMode(GL_PROJECTION);
1245    glPushMatrix();
1246    glLoadIdentity();
1247    glOrtho(0, _width, 0, _height, -10.0f, 10.0f);
1248    glMatrixMode(GL_MODELVIEW);
1249    glPushMatrix();
1250    glLoadIdentity();
1251
1252    cgGLBindProgram(_initParticlePosFP);
1253    cgGLEnableProfile(CG_PROFILE_FP30);
1254    cgGLSetTextureParameter(_ipVectorFieldParam, _curVectorFieldID);
1255    cgGLEnableTextureParameter(_ipVectorFieldParam);
1256    // TBD..
1257    //glActiveTextureARB(GL_TEXTURE0_ARB);
1258    //VelocityPBuffers[VelocityCurrent]->Bind();
1259
1260    glActiveTextureARB(GL_TEXTURE0_ARB);
1261    glEnable(GL_TEXTURE_RECTANGLE_NV);
1262    glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[_destPosIndex]);
1263
1264    glBegin(GL_POINTS);
1265    for (iter = _newParticles.begin(); iter != _newParticles.end(); iter++) {
1266        //TRACE("[%d] %f %f %f\n", iter->index, iter->position.x,iter->position.y,iter->position.z);
1267        glMultiTexCoord3f(GL_TEXTURE0, iter->position.x,iter->position.y,iter->position.z);
1268
1269        // TBD..
1270        //glMultiTexCoord2f(GL_TEXTURE1_ARB, (float)(i->Index % Width), (float)(i->Index / Height));
1271        //glMultiTexCoord1f(GL_TEXTURE2_ARB, iter->initTimeStep);
1272
1273        glVertex2f((float)(iter->index % _width),
1274                   (float)(iter->index / _height) + 1/* + offsetY*/ /* + offsetY shouldn't be */);
1275        //TRACE("%f %f\n", (float) (iter->index % _width), (float)(iter->index / _width));
1276    }
1277    glEnd();
1278
1279    glDisable(GL_TEXTURE_RECTANGLE_NV);
1280    cgGLDisableTextureParameter(_ipVectorFieldParam);
1281    cgGLDisableProfile(CG_PROFILE_FP30);
1282
1283    glMatrixMode(GL_PROJECTION);
1284    glPopMatrix();
1285    glMatrixMode(GL_MODELVIEW);
1286    glPopMatrix();
1287    glPopAttrib();
1288
1289    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1290
1291    // INIT NEW END
1292    /////////////////////////////
1293#if 1
1294    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _initPos_fbo);
1295    glPushAttrib(GL_VIEWPORT_BIT);
1296    glViewport(0, 0, _width, _height);
1297    glMatrixMode(GL_PROJECTION);
1298    glPushMatrix();
1299    glLoadIdentity();
1300    glOrtho(0, _width, 0, _height, -10.0f, 10.0f);
1301    glMatrixMode(GL_MODELVIEW);
1302    glPushMatrix();
1303    glLoadIdentity();
1304
1305    cgGLBindProgram(_initParticlePosFP);
1306    cgGLEnableProfile(CG_PROFILE_FP30);
1307    cgGLSetTextureParameter(_ipVectorFieldParam, _curVectorFieldID);
1308    cgGLEnableTextureParameter(_ipVectorFieldParam);
1309    // TBD..
1310    //glActiveTextureARB(GL_TEXTURE0_ARB);
1311    //VelocityPBuffers[VelocityCurrent]->Bind();
1312
1313    glActiveTextureARB(GL_TEXTURE0_ARB);
1314    glEnable(GL_TEXTURE_RECTANGLE_NV);
1315    //glBindTexture(GL_TEXTURE_RECTANGLE_NV, _initPosTex);
1316    glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[_destPosIndex]);
1317
1318    glBegin(GL_POINTS);
1319    for (iter = _newParticles.begin(); iter != _newParticles.end(); iter++) {
1320        //TRACE("[%d] %f %f %f\n", iter->index, iter->position.x,iter->position.y,iter->position.z);
1321        glMultiTexCoord3f(GL_TEXTURE0, iter->position.x,iter->position.y,iter->position.z);
1322
1323        // TBD..
1324        //glMultiTexCoord2f(GL_TEXTURE1_ARB, (float)(i->Index % Width), (float)(i->Index / Height));
1325        //glMultiTexCoord1f(GL_TEXTURE2_ARB, iter->initTimeStep);
1326
1327        glVertex2f((float)(iter->index % _width),
1328                   (float)(iter->index / _height) + 1/* + offsetY*/ /* + offsetY shouldn't be */);
1329        //TRACE("%f %f\n", (float) (iter->index % _width), (float)(iter->index / _width));
1330    }
1331    glEnd();
1332
1333    glDisable(GL_TEXTURE_RECTANGLE_NV);
1334    cgGLDisableTextureParameter(_ipVectorFieldParam);
1335    cgGLDisableProfile(CG_PROFILE_FP30);
1336
1337    glMatrixMode(GL_PROJECTION);
1338    glPopMatrix();
1339    glMatrixMode(GL_MODELVIEW);
1340    glPopMatrix();
1341    glPopAttrib();
1342
1343    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1344#endif
1345
1346    // Free array.
1347    _newParticles.clear();
1348}
1349
1350void ParticleSystem::cleanUpParticles()
1351{
1352    if (! _activeParticles.empty()) {
1353        while (_activeParticles.top().timeOfDeath < _currentTime) {
1354            unsigned int i = _activeParticles.top().index;
1355            _activeParticles.pop();
1356            _availableIndices.push(i);
1357            //_usedIndices[i] = false;
1358
1359            //if (i >= _maxUsedIndex)
1360            //    while (!_usedIndices[_maxUsedIndex])
1361            //        _maxUsedIndex--;
1362        }
1363    }
1364}
1365
1366void ParticleSystem::sort()
1367{
1368    ///////////////////////////////////////////////////////////
1369    // BEGIN - COMPUTE DISTANCE
1370    vrVector3f pos;
1371    vrMatrix4x4f mat;
1372    glPushMatrix();
1373    glLoadIdentity();
1374    glScalef(_scalex, _scaley, _scalez);
1375    glTranslatef(-0.5f, -0.5f, -0.5f);
1376    glGetFloatv(GL_MODELVIEW_MATRIX, mat.get());
1377    glPopMatrix();
1378    mat.invert();
1379    mat.getTranslation(pos);
1380
1381    cgGLBindProgram(_distanceSortFP);
1382    cgGLEnableProfile(CG_PROFILE_FP30);
1383
1384    glActiveTextureARB(GL_TEXTURE0_ARB);
1385    glEnable(GL_TEXTURE_RECTANGLE_NV);
1386    glBindTexture(GL_TEXTURE_RECTANGLE_NV, sort_tex[_currentSortIndex]);
1387
1388    glActiveTextureARB(GL_TEXTURE1_ARB);
1389    glEnable(GL_TEXTURE_RECTANGLE_NV);
1390    glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[_currentPosIndex]);
1391
1392    cgGLSetParameter3f(_viewPosParam, pos.x, pos.y, pos.z);
1393
1394    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, sort_fbo[_destSortIndex]);
1395    glPushAttrib(GL_VIEWPORT_BIT);
1396    glViewport(0, 0, _width, _height);
1397    glMatrixMode(GL_PROJECTION);
1398    glPushMatrix();
1399    glLoadIdentity();
1400    glOrtho(0, _width, 0, _height, -10.0f, 10.0f);
1401    glMatrixMode(GL_MODELVIEW);
1402    glPushMatrix();
1403    glLoadIdentity();
1404
1405    drawQuad();
1406
1407    cgGLDisableProfile(CG_PROFILE_FP30);
1408
1409    glMatrixMode(GL_PROJECTION);
1410    glPopMatrix();
1411    glMatrixMode(GL_MODELVIEW);
1412    glPopMatrix();
1413    glPopAttrib();
1414    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1415
1416    // _DEBUG
1417    /*
1418    {
1419        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, sort_fbo[_destSortIndex]);
1420        static float debug[256];
1421        glReadPixels(0, 0, _width, _height, GL_RGB, GL_FLOAT, (float*)debug);
1422        TRACE("[%d]", _currentSortIndex);
1423        for (int i = 0; i < _width * _height * 3; i += 3)
1424            TRACE("%.2f, %.2f, %.2f\n", debug[i], debug[i+1], debug[i+2]);
1425        TRACE("\n");
1426        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1427    }
1428    */
1429
1430    // _DEBUG
1431    /*
1432    {
1433        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[_currentPosIndex]);
1434        static float debug[256];
1435        glReadPixels(0, 0, _width, _height, GL_RGB, GL_FLOAT, (float*)debug);
1436        TRACE("\n");
1437        TRACE("currentPos[%d]", _currentPosIndex);
1438        for (int i = 0; i < _width * _height * 3; i += 3)
1439            TRACE("%.2f, %.2f, %.2f\n", debug[i], debug[i+1], debug[i+2]);
1440        TRACE("\n");
1441        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1442    }
1443    */
1444
1445    // compute distance
1446    swap(_currentSortIndex, _destSortIndex);
1447
1448    // END - COMPUTE DISTANCE
1449    ///////////////////////////////////////////////////////////
1450
1451    ///////////////////////////////////////////////////////////
1452    // BEGIN - MERGE SORT
1453    _currentSortPass = 0;
1454
1455    int logdSize = logd(_particleMaxCount);
1456    _maxSortPasses = (logdSize + 1) * logdSize / 2;
1457
1458    _sortBegin = _sortEnd;
1459    _sortEnd = (_sortBegin + _sortPassesPerFrame) % _maxSortPasses;
1460
1461    cgGLSetParameter2f(_srSizeParam, (float)_width, (float)_height);
1462    cgGLSetParameter2f(_seSizeParam, (float)_width, (float)_height);
1463
1464    mergeSort(this->_particleMaxCount);
1465
1466    // _DEBUG
1467    /*
1468    {
1469        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, sort_fbo[_currentSortIndex]);
1470        static float debug[256];
1471        glReadPixels(0, 0, _width, _height, GL_RGB, GL_FLOAT, (float*)debug);
1472        TRACE("\n");
1473        TRACE("[%d]", _currentSortIndex);
1474        for (int i = 0; i < _width * _height * 3; i += 3)
1475            TRACE("%.2f, %.2f, %.2f\n", debug[i], debug[i+1], debug[i+2]);
1476        TRACE("\n");
1477        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1478    }
1479    */
1480
1481    // END - MERGE SORT
1482    ///////////////////////////////////////////////////////////
1483
1484    ///////////////////////////////////////////////////////////
1485    // POSITION LOOKUP
1486    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[_destPosIndex]);
1487    cgGLBindProgram(_distanceSortLookupFP);
1488    cgGLEnableProfile(CG_PROFILE_FP30);
1489
1490    glActiveTextureARB(GL_TEXTURE0_ARB);
1491    glBindTexture(GL_TEXTURE_RECTANGLE_NV, sort_tex[_currentSortIndex]);
1492
1493    glActiveTextureARB(GL_TEXTURE1_ARB);
1494    glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[_currentPosIndex]);
1495
1496    glPushAttrib(GL_VIEWPORT_BIT);
1497    glViewport(0, 0, _width, _height);
1498    glMatrixMode(GL_PROJECTION);
1499    glPushMatrix();
1500    glLoadIdentity();
1501    glOrtho(0, _width, 0, _height, -10.0f, 10.0f);
1502    glMatrixMode(GL_MODELVIEW);
1503    glPushMatrix();
1504    glLoadIdentity();
1505
1506    drawQuad();
1507
1508    glMatrixMode(GL_PROJECTION);
1509    glPopMatrix();
1510    glMatrixMode(GL_MODELVIEW);
1511    glPopMatrix();
1512    glPopAttrib();
1513
1514    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1515    cgGLDisableProfile(CG_PROFILE_FP30);
1516
1517    // POSITION LOOKUP
1518    ///////////////////////////////////////////////////////////
1519    glActiveTextureARB(GL_TEXTURE1_ARB);
1520    glDisable(GL_TEXTURE_RECTANGLE_NV);
1521
1522    glActiveTextureARB(GL_TEXTURE0_ARB);
1523    glDisable(GL_TEXTURE_RECTANGLE_NV);
1524
1525    // _DEBUG
1526    /*
1527    {
1528        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[_destPosIndex]);
1529        static float debug[256];
1530        glReadPixels(0, 0, _width, _height, GL_RGB, GL_FLOAT, (float*)debug);
1531        TRACE("\n");
1532        TRACE("[%d]", _currentSortIndex);
1533        for (int i = 0; i < _width * _height * 3; i += 3)
1534            TRACE("%.2f, %.2f, %.2f\n", debug[i], debug[i+1], debug[i+2]);
1535        TRACE("\n");
1536        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1537    }
1538    */
1539}
1540
1541void ParticleSystem::mergeSort(int count)
1542{
1543    if (count > 1) {
1544        mergeSort(count >> 1);
1545        merge(count, 1);
1546    }
1547}
1548
1549void ParticleSystem::merge(int count, int step)
1550{
1551    if (count > 2) {
1552        merge(count >> 1, step << 1);
1553
1554        ++_currentSortPass;
1555
1556        if (_sortBegin < _sortEnd) {
1557            if (_currentSortPass < _sortBegin || _currentSortPass >= _sortEnd)
1558                return;
1559        } else {
1560            if (_currentSortPass < _sortBegin && _currentSortPass >= _sortEnd)
1561                return;
1562        }
1563
1564        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, sort_fbo[_destSortIndex]);
1565        cgGLBindProgram(_sortRecursionFP);
1566        cgGLEnableProfile(CG_PROFILE_FP30);
1567
1568        glActiveTextureARB(GL_TEXTURE0_ARB);
1569        glBindTexture(GL_TEXTURE_RECTANGLE_NV , sort_tex[_currentSortIndex]);
1570
1571        cgGLSetParameter1f(_srStepParam, (float)step);
1572        cgGLSetParameter1f(_srCountParam, (float)count);
1573
1574        glPushAttrib(GL_VIEWPORT_BIT);
1575        glViewport(0, 0, _width, _height);
1576        glMatrixMode(GL_PROJECTION);
1577        glPushMatrix();
1578        glLoadIdentity();
1579        glOrtho(0, _width, 0, _height, -10.0f, 10.0f);
1580        glMatrixMode(GL_MODELVIEW);
1581        glPushMatrix();
1582        glLoadIdentity();
1583
1584        drawQuad();
1585
1586        glMatrixMode(GL_PROJECTION);
1587        glPopMatrix();
1588        glMatrixMode(GL_MODELVIEW);
1589        glPopMatrix();
1590        glPopAttrib();
1591
1592        cgGLDisableProfile(CG_PROFILE_FP30);
1593
1594        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1595        glBindTexture(GL_TEXTURE_RECTANGLE_NV , 0);
1596    } else {
1597        _currentSortPass++;
1598
1599        if (_sortBegin < _sortEnd) {
1600            if (_currentSortPass < _sortBegin || _currentSortPass >= _sortEnd)
1601                return;
1602        } else {
1603            if (_currentSortPass < _sortBegin && _currentSortPass >= _sortEnd)
1604                return;
1605        }
1606
1607        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, sort_fbo[_destSortIndex]);
1608        cgGLBindProgram(_sortEndFP);
1609        cgGLEnableProfile(CG_PROFILE_FP30);
1610
1611        glActiveTextureARB(GL_TEXTURE0_ARB);
1612        glBindTexture(GL_TEXTURE_RECTANGLE_NV , sort_tex[_currentSortIndex]);
1613
1614        cgGLSetParameter1f(_seStepParam, (float)step);
1615
1616        glPushAttrib(GL_VIEWPORT_BIT);
1617        glViewport(0, 0, _width, _height);
1618        glMatrixMode(GL_PROJECTION);
1619        glPushMatrix();
1620        glLoadIdentity();
1621        glOrtho(0, _width, 0, _height, -10.0f, 10.0f);
1622        glMatrixMode(GL_MODELVIEW);
1623        glPushMatrix();
1624        glLoadIdentity();
1625
1626        drawQuad();
1627
1628        glMatrixMode(GL_PROJECTION);
1629        glPopMatrix();
1630        glMatrixMode(GL_MODELVIEW);
1631        glPopMatrix();
1632        glPopAttrib();
1633
1634        cgGLDisableProfile(CG_PROFILE_FP30);
1635
1636        glBindTexture(GL_TEXTURE_RECTANGLE_NV , 0);
1637        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1638    }
1639
1640    swap(_currentSortIndex, _destSortIndex);
1641}
1642
1643void ParticleSystem::renderStreamlines()
1644{
1645    if (_currentStreamlineIndex > 2) {
1646        glPushMatrix();
1647        glScalef(_scalex, _scaley, _scalez);
1648        glTranslatef(-0.5f, -0.5f, -0.5f);
1649
1650        if (_drawBBoxEnabled) drawUnitBox();
1651
1652        glColor3f(1.0f, 0.0f, 0.0f);
1653        glEnableClientState(GL_VERTEX_ARRAY);
1654        //glEnableClientState(GL_COLOR_ARRAY);
1655
1656        _streamVertices->SetPointer(0);
1657        //glColorPointer(4, GL_FLOAT, 0, 0);
1658
1659        ::glDrawElements(GL_LINES, _particleCount * 2 * (_currentStreamlineIndex - 1),
1660                         GL_UNSIGNED_INT, _indexBuffer);
1661        glDisableClientState(GL_VERTEX_ARRAY);
1662        glPopMatrix();
1663    }
1664}
1665
1666void ParticleSystem::render()
1667{
1668    glPushMatrix();
1669
1670    if (_streamlineEnabled) {
1671        renderStreamlines();
1672    } else {
1673        glScalef(_scalex, _scaley, _scalez);
1674        glTranslatef(-0.5f, -0.5f, -0.5f);
1675        if (_glypEnabled) {
1676            if (_drawBBoxEnabled) drawUnitBox();
1677            glColor3f(1, 1, 1);
1678            glDepthMask(GL_FALSE);
1679            glEnable(GL_BLEND);
1680
1681#ifndef USE_RGBA_ARROW
1682            glBlendFunc(GL_SRC_ALPHA, GL_ONE);
1683#else
1684            glEnable(GL_ALPHA_TEST);
1685            //glAlphaFunc(GL_GEQUAL, 0.5);
1686            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1687#endif
1688            glEnable(GL_POINT_SPRITE_NV);
1689            glPointSize(_pointSize);
1690
1691            glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_NV);
1692
1693#ifndef TEST
1694            _arrows->bind(0);
1695            glEnable(GL_TEXTURE_2D);
1696            //glPointParameterfARB( GL_POINT_FADE_THRESHOLD_SIZE_ARB, 60.0f );
1697            glPointParameterfARB( GL_POINT_FADE_THRESHOLD_SIZE_ARB, 0.0f );
1698
1699            glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, 1.0f);
1700            glPointParameterfARB( GL_POINT_SIZE_MAX_ARB, 100.0f);
1701            glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
1702
1703            cgGLBindProgram(_particleVP);
1704            cgGLBindProgram(_particleFP);
1705            cgGLEnableProfile(CG_PROFILE_VP40);
1706            cgGLEnableProfile(CG_PROFILE_FP40);
1707
1708            cgSetParameter1f(_mvCurrentTimeParam, _currentTime);
1709            //TRACE("%f %f, %f %d\n", _fov, tan(_fov), tan(_fov / 2.0), _screenHeight);
1710            //cgSetParameter1f(_mvTanHalfFOVParam, -tan(_fov * PI / 180 * 0.5) * _screenHeight * 0.5);
1711            //float v = tan(_fov * PI / 180 * 0.5) * _screenHeight * 0.5;
1712            cgSetParameter1f(_mvTanHalfFOVParam, tan(_fov * PI / 180 * 0.5) * _screenHeight * 0.5);
1713            //cgSetParameter1f(_mvTanHalfFOVParam,  _screenHeight * 0.5 / tan(_fov * PI / 180 * 0.5));
1714
1715            cgGLSetStateMatrixParameter(_mvpParticleParam,
1716                                        CG_GL_MODELVIEW_PROJECTION_MATRIX,
1717                                        CG_GL_MATRIX_IDENTITY);
1718            cgGLSetStateMatrixParameter(_mvParticleParam,
1719                                        CG_GL_MODELVIEW_MATRIX,
1720                                        CG_GL_MATRIX_IDENTITY);
1721
1722            // TBD..
1723            glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);                     
1724            glEnableVertexAttribArrayARB(8);
1725            glEnableClientState(GL_VERTEX_ARRAY);
1726            //glEnableClientState(GL_COLOR_ARRAY);
1727            _vertices->SetPointer(0);
1728            //glBindBufferARB(GL_ARRAY_BUFFER, _colorBufferID);
1729            //glColorPointer(4, GL_FLOAT, 0, 0);
1730            //glBindBufferARB(GL_ARRAY_BUFFER, 0);
1731
1732            // TBD...
1733            glDrawArrays(GL_POINTS, 0, this->_particleMaxCount);
1734            glPointSize(1);
1735
1736            glDisableClientState(GL_VERTEX_ARRAY);
1737            //glDisableClientState(GL_COLOR_ARRAY);
1738
1739            // TBD...
1740            ::glDisableVertexAttribArray(8);
1741            glPopClientAttrib();
1742
1743            cgGLDisableProfile(CG_PROFILE_VP40);
1744            cgGLDisableProfile(CG_PROFILE_FP40);
1745
1746            glDepthMask(GL_TRUE);
1747
1748            glDisable(GL_POINT_SPRITE_NV);
1749            glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_NV);
1750
1751            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1752            glDisable(GL_BLEND);
1753#else
1754            glBindTexture(GL_TEXTURE_2D, ::SpotTexID);
1755            glEnable(GL_TEXTURE_2D);
1756            //glPointParameterfARB( GL_POINT_FADE_THRESHOLD_SIZE_ARB, 60.0f );
1757            glPointParameterfARB( GL_POINT_FADE_THRESHOLD_SIZE_ARB, 0.0f );
1758
1759            glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, 1.0f);
1760            glPointParameterfARB( GL_POINT_SIZE_MAX_ARB, 100.0f);
1761            glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
1762
1763            glEnableClientState(GL_VERTEX_ARRAY);
1764            //glEnableClientState(GL_COLOR_ARRAY);
1765            _vertices->SetPointer(0);
1766            //glBindBufferARB(GL_ARRAY_BUFFER, _colorBufferID);
1767            //glColorPointer(4, GL_FLOAT, 0, 0);
1768            //glBindBufferARB(GL_ARRAY_BUFFER, 0);
1769
1770            // TBD...
1771            glDrawArrays(GL_POINTS, 0, this->_particleMaxCount);
1772            glPointSize(1);
1773            glDrawArrays(GL_POINTS, 0, this->_particleMaxCount);
1774
1775            glDisableClientState(GL_VERTEX_ARRAY);
1776
1777            glDepthMask(GL_TRUE);
1778
1779            glDisable(GL_POINT_SPRITE_NV);
1780            glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_NV);
1781
1782            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1783            glDisable(GL_BLEND);
1784#endif
1785        } else {
1786            if (_drawBBoxEnabled) drawUnitBox();
1787
1788            glColor3f(1, 1, 1);
1789            glEnableClientState(GL_VERTEX_ARRAY);
1790            //glEnableClientState(GL_COLOR_ARRAY);
1791            glPointSize(10);
1792            _vertices->SetPointer(0);
1793            //glBindBufferARB(GL_ARRAY_BUFFER, _colorBufferID);
1794            //glColorPointer(4, GL_FLOAT, 0, 0);
1795            //glBindBufferARB(GL_ARRAY_BUFFER, 0);
1796            glDrawArrays(GL_POINTS, 0, _particleMaxCount);
1797
1798            glPointSize(1);
1799            _vertices->SetPointer(0);
1800            //glBindBufferARB(GL_ARRAY_BUFFER, _colorBufferID);
1801            //glColorPointer(4, GL_FLOAT, 0, 0);
1802            //glBindBufferARB(GL_ARRAY_BUFFER, 0);
1803            glDrawArrays(GL_POINTS, 0, _particleMaxCount);
1804
1805            glDisableClientState(GL_VERTEX_ARRAY);
1806        }
1807
1808#ifdef notdef
1809        if (_criticalPoints && _criticalPoints->size()) {
1810            std::vector<vrVector3f>::iterator iter;
1811            glColor4f(1, 1, 1, 1);
1812            glPointSize(10);
1813            glBegin(GL_POINTS);
1814            for (iter = _criticalPoints->begin(); iter != _criticalPoints->end(); ++iter) {
1815                glVertex3f((*iter).x, (*iter).y, (*iter).z);
1816            }
1817            glEnd();
1818            glPointSize(1);
1819        }
1820#endif
1821    }
1822
1823    glPopMatrix();
1824}
1825
1826void ParticleSystem::drawQuad(int x1, int y1, int x2, int y2)
1827{
1828    glBegin(GL_QUADS);
1829
1830    glTexCoord2f(x1, y1);
1831    glVertex2f(x1, y1);
1832
1833    glTexCoord2f(x2, y1);
1834    glVertex2f(x2, y1);
1835
1836    glTexCoord2f(x2, y2);
1837    glVertex2f(x2, y2);
1838
1839    glTexCoord2f(x1, y2);
1840    glVertex2f(x1, y2);
1841
1842    glEnd();
1843}
1844
1845void ParticleSystem::drawQuad()
1846{
1847    glBegin(GL_QUADS);
1848
1849    glTexCoord2f(0, 0);
1850    glVertex2f(0, 0);
1851
1852    glTexCoord2f((float)_width, 0);
1853    glVertex2f((float)_width, 0);
1854
1855    glTexCoord2f((float)_width, (float)_height);
1856    glVertex2f((float)_width, (float)_height);
1857
1858    glTexCoord2f(0, (float)_height);
1859    glVertex2f(0, (float)_height);
1860
1861    glEnd();
1862}
1863
1864void ParticleSystem::addEmitter(ParticleEmitter* emitter)
1865{
1866    _emitters.push_back(emitter);
1867}
1868
1869void ParticleSystem::removeEmitter(int index)
1870{
1871    // TBD...
1872}
1873
1874void ParticleSystem::removeAllEmitters()
1875{
1876    std::vector<ParticleEmitter*>::iterator iter;
1877    for (iter = _emitters.begin(); iter != _emitters.end(); ++iter) {
1878        delete *iter;
1879    }
1880    _emitters.clear();
1881}
1882
1883void ParticleSystem::drawUnitBox()
1884{
1885    float x0 = 0.0f, y0 = 0.0f, z0 = 0.0f;
1886    float x1 = 1.0f, y1 = 1.0f, z1 = 1.0f;
1887    float r = 1.0f, g = 1.0f, b = 0.0f;
1888    float line_width = 2.0f;
1889    glEnable(GL_DEPTH_TEST);
1890    glDisable(GL_TEXTURE_2D);
1891    glEnable(GL_BLEND);
1892
1893    glColor4d(r, g, b, 1.0);
1894    glLineWidth(line_width);
1895
1896    glBegin(GL_LINE_LOOP);
1897    {
1898        glVertex3d(x0, y0, z0);
1899        glVertex3d(x1, y0, z0);
1900        glVertex3d(x1, y1, z0);
1901        glVertex3d(x0, y1, z0);
1902    }
1903    glEnd();
1904
1905    glBegin(GL_LINE_LOOP);
1906    {
1907        glVertex3d(x0, y0, z1);
1908        glVertex3d(x1, y0, z1);
1909        glVertex3d(x1, y1, z1);
1910        glVertex3d(x0, y1, z1);
1911    }
1912    glEnd();
1913
1914    glBegin(GL_LINE_LOOP);
1915    {
1916        glVertex3d(x0, y0, z0);
1917        glVertex3d(x0, y0, z1);
1918        glVertex3d(x0, y1, z1);
1919        glVertex3d(x0, y1, z0);
1920    }
1921    glEnd();
1922
1923    glBegin(GL_LINE_LOOP);
1924    {
1925        glVertex3d(x1, y0, z0);
1926        glVertex3d(x1, y0, z1);
1927        glVertex3d(x1, y1, z1);
1928        glVertex3d(x1, y1, z0);
1929    }
1930    glEnd();
1931    glLineWidth(1.0f);
1932}
1933
1934void ParticleSystem::setUserDefinedNumOfParticles(int numParticles)
1935{
1936    if (numParticles < _particleMaxCount)
1937        _userDefinedParticleMaxCount = numParticles;
1938    else
1939        _userDefinedParticleMaxCount = _particleMaxCount;
1940    reset();
1941}
Note: See TracBrowser for help on using the repository browser.