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

Last change on this file since 2835 was 2835, checked in by ldelgass, 13 years ago

Exclude unused file from build, misc. cleanups

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