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

Last change on this file since 1482 was 1482, checked in by vrinside, 15 years ago

delete shaders programs in deleting classes (NvLIC/NvParticleRednerer)

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