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

Last change on this file since 1370 was 1370, checked in by vrinside, 16 years ago

improving the flow vis engine

  • particle advection for multiple vector field
  • specifying multiple advection planes
  • specifying the position of a particle injection plane
  • specifying the axis of a particle injection plane
  • specifying the visibility of particle injection planes
  • specifying the particle color for each particle injection plane
  • rendering device shapes

[NOTE] Currently, I commented out with the MACRO NEW_FLOW_ENGINE in config
To use this, please comment NEW_FLOW_ENGINE in

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