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

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