source: trunk/packages/vizservers/nanovis/NvParticleRenderer.cpp @ 1497

Last change on this file since 1497 was 1497, checked in by gah, 15 years ago

added particle size option, movie token for flowvis

File size: 12.6 KB
Line 
1
2/*
3 * ----------------------------------------------------------------------
4 * NvParticleRenderer.cpp: particle system class
5 *
6 * ======================================================================
7 *  AUTHOR:  Wei Qiao <qiaow@purdue.edu>
8 *           Purdue Rendering and Perceptualization Lab (PURPL)
9 *
10 *  Copyright (c) 2004-2006  Purdue Research Foundation
11 *
12 *  See the file "license.terms" for information on usage and
13 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14 * ======================================================================
15 */
16
17#include <stdio.h>
18#include <assert.h>
19#include <malloc.h>
20#include <string.h>
21
22#include <R2/R2FilePath.h>
23#include "NvParticleRenderer.h"
24#include <Trace.h>
25#include <stdlib.h>
26
27#define NV_32
28
29NvParticleAdvectionShader* NvParticleRenderer::_advectionShader = NULL;
30
31class NvParticleAdvectionShaderInstance {
32public :
33        NvParticleAdvectionShaderInstance()
34        {
35        }
36        ~NvParticleAdvectionShaderInstance()
37        {
38                if (NvParticleRenderer::_advectionShader)
39                {
40                        delete NvParticleRenderer::_advectionShader;
41                }
42        }
43};
44NvParticleAdvectionShaderInstance shaderInstance;
45
46NvParticleRenderer::NvParticleRenderer(int w, int h, CGcontext context) :
47    _particleSize(1.2),
48    scale(1, 1, 1),
49    origin(0, 0, 0),
50    _activate(false)
51{
52    psys_width = w;
53    psys_height = h;
54
55    psys_frame = 0;
56    reborn = true;
57    flip = true;
58
59    _color.set(0.2, 0.2, 1.0, 1.0);
60    max_life = 500;
61
62    _slice_axis = 0;
63    _slice_pos = 0.0;
64
65    data = new Particle[w*h];
66    memset(data, 0, sizeof(Particle) * w * h);
67
68    m_vertex_array = new RenderVertexArray(psys_width*psys_height, 3, GL_FLOAT);
69
70    assert(CheckGL(AT));
71
72    glGenFramebuffersEXT(2, psys_fbo);
73    glGenTextures(2, psys_tex);
74
75    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[0]);
76
77    glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[0]);
78    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
79    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
80
81#ifdef NV_32
82    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGBA32_NV,
83        psys_width, psys_height, 0, GL_RGBA, GL_FLOAT, NULL);
84#else
85    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA, psys_width, psys_height,
86        0, GL_RGBA, GL_FLOAT, NULL);
87#endif
88    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
89        GL_TEXTURE_RECTANGLE_NV, psys_tex[0], 0);
90
91
92    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[1]);
93
94    glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[1]);
95    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
96    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
97#ifdef NV_32
98    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGBA32_NV,
99        psys_width, psys_height, 0, GL_RGBA, GL_FLOAT, NULL);
100#else
101    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA, psys_width, psys_height,
102        0, GL_RGBA, GL_FLOAT, NULL);
103#endif
104    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
105        GL_TEXTURE_RECTANGLE_NV, psys_tex[1], 0);
106 
107    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
108
109    glGenTextures(1, &initPosTex);
110    glBindTexture(GL_TEXTURE_RECTANGLE_NV, initPosTex);
111    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
112    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
113#ifdef NV_32
114    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGBA32_NV,
115        psys_width, psys_height, 0, GL_RGBA, GL_FLOAT, NULL);
116#else
117    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA, psys_width,
118        psys_height, 0, GL_RGBA, GL_FLOAT, NULL);
119#endif
120
121    CHECK_FRAMEBUFFER_STATUS();
122
123    //load related shaders
124    /*
125      m_g_context = context;
126
127      m_pos_fprog = LoadCgSourceProgram(m_g_context, "update_pos.cg",
128        CG_PROFILE_FP30, NULL);
129      m_pos_timestep_param  = cgGetNamedParameter(m_pos_fprog, "timestep");
130      m_vel_tex_param = cgGetNamedParameter(m_pos_fprog, "vel_tex");
131      m_pos_tex_param = cgGetNamedParameter(m_pos_fprog, "pos_tex");
132      m_scale_param = cgGetNamedParameter(m_pos_fprog, "scale");
133      cgGLSetTextureParameter(m_vel_tex_param, volume);
134      cgGLSetParameter3f(m_scale_param, scale_x, scale_y, scale_z);
135    */
136    if (_advectionShader == NULL) {
137        _advectionShader = new NvParticleAdvectionShader();
138    }
139}
140
141NvParticleRenderer::~NvParticleRenderer()
142{
143    glDeleteTextures(1, &initPosTex);
144
145    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[0]);
146    glDeleteTextures(1, psys_tex);
147
148    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[1]);
149    glDeleteTextures(1, psys_tex+1);
150
151    glDeleteFramebuffersEXT(2, psys_fbo);
152
153    delete m_vertex_array;
154    delete [] data;
155}
156
157void NvParticleRenderer::initializeDataArray()
158{
159    size_t n = psys_width * psys_height * 4;
160    memset(data, 0, sizeof(float)* n);
161
162    int index;
163    bool particle;
164    float* p = (float*) data;
165    for (int i=0; i<psys_width; i++) {
166        for (int j=0; j<psys_height; j++) {
167            index = i + psys_height*j;
168            particle = (rand() % 256) > 150;
169            if(particle) {
170                //assign any location (x,y,z) in range [0,1]
171                switch (_slice_axis) {
172                case 0 :
173                    p[4*index] = _slice_pos;
174                    p[4*index+1]= j/float(psys_height);
175                    p[4*index+2]= i/float(psys_width);
176                    break;
177                case 1 :
178                    p[4*index]= j/float(psys_height);
179                    p[4*index+1] = _slice_pos;
180                    p[4*index+2]= i/float(psys_width);
181                    break;
182                case 2 :
183                    p[4*index]= j/float(psys_height);
184                    p[4*index+1]= i/float(psys_width);
185                    p[4*index+2] = _slice_pos;
186                    break;
187                default :
188                    p[4*index] = 0;
189                    p[4*index+1]= 0;
190                    p[4*index+2]= 0;
191                    p[4*index+3]= 0;
192                }
193               
194                //shorter life span, quicker iterations
195                p[4*index+3]= rand() / ((float) RAND_MAX) * 0.5  + 0.5f;
196            } else {
197                p[4*index] = 0;
198                p[4*index+1]= 0;
199                p[4*index+2]= 0;
200                p[4*index+3]= 0;
201            }
202        }
203    }
204}
205
206void NvParticleRenderer::initialize()
207{
208    initializeDataArray();
209
210    //also store the data on main memory for next initialization
211    //memcpy(data, p, psys_width*psys_height*sizeof(Particle));
212
213    glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[0]);
214    // I need to find out why GL_FLOAT_RGBA32_NV doesn't work
215#ifdef NV_32
216    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGBA32_NV,
217                 psys_width, psys_height, 0, GL_RGBA, GL_FLOAT, (float*)data);
218#else
219    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA, psys_width,
220                 psys_height, 0, GL_RGBA, GL_FLOAT, (float*)data);
221#endif
222    glBindTexture(GL_TEXTURE_RECTANGLE_NV, 0);
223 
224    flip = true;
225    reborn = false;
226
227    glBindTexture(GL_TEXTURE_RECTANGLE_NV, initPosTex);
228    // I need to find out why GL_FLOAT_RGBA32_NV doesn't work
229#ifdef NV_32
230    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGBA32_NV,
231                 psys_width, psys_height, 0, GL_RGBA, GL_FLOAT, (float*)data);
232#else
233    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA, psys_width, psys_height,
234                 0, GL_RGBA, GL_FLOAT, (float*)p);
235#endif
236    glBindTexture(GL_TEXTURE_RECTANGLE_NV, 0);
237
238    //fprintf(stderr, "init particles\n");
239}
240
241void NvParticleRenderer::reset()
242{
243    glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[0]);
244
245#ifdef NV_32
246    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGBA32_NV,
247                 psys_width, psys_height, 0, GL_RGBA, GL_FLOAT, (float*)data);
248#else
249    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA, psys_width, psys_height,
250                 0, GL_RGBA, GL_FLOAT, (float*)data);
251#endif
252    glBindTexture(GL_TEXTURE_RECTANGLE_NV, 0);
253    flip = true;
254    reborn = false;
255    psys_frame = 0;
256}
257
258void
259NvParticleRenderer::advect()
260{
261    if (reborn)
262        reset();
263   
264    glDisable(GL_BLEND);
265    glDisable(GL_DEPTH_TEST);
266   
267    if (flip) {
268        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[1]);
269        glEnable(GL_TEXTURE_RECTANGLE_NV);
270        glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[0]);
271       
272        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
273        //glClear(GL_COLOR_BUFFER_BIT);
274       
275        glViewport(0, 0, psys_width, psys_height);
276        glMatrixMode(GL_PROJECTION);
277        glLoadIdentity();
278        //gluOrtho2D(0, psys_width, 0, psys_height);
279        glOrtho(0, psys_width, 0, psys_height, -10.0f, 10.0f);
280        glMatrixMode(GL_MODELVIEW);
281        glLoadIdentity();
282       
283        _advectionShader->bind(psys_tex[0], initPosTex);
284       
285        //cgGLBindProgram(m_pos_fprog);
286        //cgGLSetParameter1f(m_pos_timestep_param, 0.05);
287        //cgGLEnableTextureParameter(m_vel_tex_param);
288        //cgGLSetTextureParameter(m_pos_tex_param, psys_tex[0]);
289        //cgGLEnableTextureParameter(m_pos_tex_param);
290        //cgGLEnableProfile(CG_PROFILE_FP30);
291       
292        draw_quad(psys_width, psys_height, psys_width, psys_height);
293       
294        //cgGLDisableProfile(CG_PROFILE_FP30);
295        //cgGLDisableTextureParameter(m_vel_tex_param);
296        //cgGLDisableTextureParameter(m_pos_tex_param);
297        glDisable(GL_TEXTURE_RECTANGLE_NV);
298    } else {
299        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[0]);
300        glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[1]);
301       
302        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
303        //glClear(GL_COLOR_BUFFER_BIT);
304       
305        glViewport(0, 0, psys_width, psys_height);
306        glMatrixMode(GL_PROJECTION);
307        glLoadIdentity();
308        //gluOrtho2D(0, psys_width, 0, psys_height);
309        glOrtho(0, psys_width, 0, psys_height, -10.0f, 10.0f);
310        glMatrixMode(GL_MODELVIEW);
311        glLoadIdentity();
312       
313        _advectionShader->bind(psys_tex[1], initPosTex);
314       
315        //cgGLBindProgram(m_pos_fprog);
316        //cgGLSetParameter1f(m_pos_timestep_param, 0.05);
317        //cgGLEnableTextureParameter(m_vel_tex_param);
318        //cgGLSetTextureParameter(m_pos_tex_param, psys_tex[1]);
319        //cgGLEnableTextureParameter(m_pos_tex_param);
320        //cgGLEnableProfile(CG_PROFILE_FP30);
321       
322        draw_quad(psys_width, psys_height, psys_width, psys_height);
323        //draw_quad(psys_width, psys_height, 1.0f, 1.0f);
324       
325        //cgGLDisableProfile(CG_PROFILE_FP30);
326        //cgGLDisableTextureParameter(m_vel_tex_param);
327        //cgGLDisableTextureParameter(m_pos_tex_param);
328    }
329   
330    _advectionShader->unbind();
331   
332    //soft_read_verts();
333   
334    update_vertex_buffer();
335   
336    flip = (!flip);
337   
338    psys_frame++;
339    if(psys_frame==max_life) {
340        psys_frame=0;
341//      reborn = true;
342    }
343    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
344}
345
346void
347NvParticleRenderer::update_vertex_buffer()
348{
349    m_vertex_array->Read(psys_width, psys_height);
350
351    //m_vertex_array->LoadData(vert);     //does not work??
352    //assert(glGetError()==0);
353}
354
355void
356NvParticleRenderer::render()
357{
358    display_vertices();
359}
360
361void
362NvParticleRenderer::draw_bounding_box(float x0, float y0, float z0,
363                                      float x1, float y1, float z1,
364                                      float r, float g, float b,
365                                      float line_width)
366{
367    glPushMatrix();
368    glEnable(GL_DEPTH_TEST);
369    glDisable(GL_TEXTURE_2D);
370    glEnable(GL_BLEND);
371
372    glColor4d(r, g, b, 1.0);
373    glLineWidth(line_width);
374   
375    glBegin(GL_LINE_LOOP);
376    {
377        glVertex3d(x0, y0, z0);
378        glVertex3d(x1, y0, z0);
379        glVertex3d(x1, y1, z0);
380        glVertex3d(x0, y1, z0);
381    }
382    glEnd();
383   
384    glBegin(GL_LINE_LOOP);
385    {
386        glVertex3d(x0, y0, z1);
387        glVertex3d(x1, y0, z1);
388        glVertex3d(x1, y1, z1);
389        glVertex3d(x0, y1, z1);
390    }
391    glEnd();
392   
393    glBegin(GL_LINE_LOOP);
394    {
395        glVertex3d(x0, y0, z0);
396        glVertex3d(x0, y0, z1);
397        glVertex3d(x0, y1, z1);
398        glVertex3d(x0, y1, z0);
399    }
400    glEnd();
401   
402    glBegin(GL_LINE_LOOP);
403    {
404        glVertex3d(x1, y0, z0);
405        glVertex3d(x1, y0, z1);
406        glVertex3d(x1, y1, z1);
407        glVertex3d(x1, y1, z0);
408    }
409    glEnd();
410
411    glPopMatrix();
412    glDisable(GL_DEPTH_TEST);
413    glDisable(GL_BLEND);
414    glEnable(GL_TEXTURE_2D);
415}
416
417void
418NvParticleRenderer::display_vertices()
419{
420    glDisable(GL_TEXTURE_2D);
421    glDisable(GL_BLEND);
422    glEnable(GL_DEPTH_TEST);
423
424    glEnable(GL_COLOR_MATERIAL);
425
426    glPushMatrix();
427
428    glTranslatef(origin.x, origin.y, origin.z);
429    glScaled(scale.x, scale.y, scale.z);
430
431// TBD...
432/*
433    draw_bounding_box(
434        0, 0, 0,
435        1, 1, 1,
436        1, 1, 1, 2);
437
438    draw_bounding_box(
439        0, 0.5f / 4.5f, 0.5f / 4.5,
440        1, 4.0f / 4.5f, 4.0f / 4.5,
441        1, 0, 0, 2);
442
443    draw_bounding_box(
444        1/3.0f, 1.0f / 4.5f, 0.5f / 4.5,
445        2/3.0f, 3.5f / 4.5f, 3.5f / 4.5,
446        1, 1, 0, 2);
447*/
448
449    glPointSize(_particleSize);
450    //glColor4f(.2,.2,.8,1.);
451    glColor4f(_color.x, _color.y, _color.z, _color.w);
452    glEnableClientState(GL_VERTEX_ARRAY);
453    m_vertex_array->SetPointer(0);
454    glDrawArrays(GL_POINTS, 0, psys_width*psys_height);
455    glDisableClientState(GL_VERTEX_ARRAY);
456
457    glPopMatrix();
458 
459    glDisable(GL_DEPTH_TEST);
460
461    //assert(glGetError()==0);
462}
463
464void
465NvParticleRenderer::setVectorField(unsigned int texID, const Vector3& ori,
466                                   float scaleX, float scaleY, float scaleZ,
467                                   float max)
468{
469    origin = ori;
470    scale.set(scaleX, scaleY, scaleZ);
471    _advectionShader->setScale(scale);
472    _advectionShader->setVelocityVolume(texID, max);
473}
474
475void NvParticleRenderer::setAxis(int axis)
476{
477        _slice_axis = axis;
478        initializeDataArray();
479}
480
481void NvParticleRenderer::setPos(float pos)
482{
483        _slice_pos = pos;
484        initializeDataArray();
485}
486
487
Note: See TracBrowser for help on using the repository browser.