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

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

Found memory leak in reset_patterns

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