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

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

Initial commit of new flow visualization command structure

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