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

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

Unirect2d/3d::ParseBuffer? returns a Tcl status code, but if
Tcl_ListObjGetElements() failed, it was returning NULL, which as an int is
equivalent to TCL_OK. Return value has been changed to TCL_ERROR.

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