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

Last change on this file since 1362 was 1362, checked in by gah, 16 years ago

preparation to remove glui from build

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