source: trunk/gui/vizservers/nanovis/ParticleSystem.cpp @ 401

Last change on this file since 401 was 401, checked in by qiaow, 18 years ago

Added Renderable class, the superclass of every class that can be drawn.

File size: 6.9 KB
Line 
1/*
2 * ----------------------------------------------------------------------
3 * ParticleSystem.cpp: particle system class
4 *
5 * ======================================================================
6 *  AUTHOR:  Wei Qiao <qiaow@purdue.edu>
7 *           Purdue Rendering and Perceptualization Lab (PURPL)
8 *
9 *  Copyright (c) 2004-2006  Purdue Research Foundation
10 *
11 *  See the file "license.terms" for information on usage and
12 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 * ======================================================================
14 */
15
16#include <stdio.h>
17#include <assert.h>
18#include <malloc.h>
19#include <string.h>
20
21#include "ParticleSystem.h"
22
23
24ParticleSystem::ParticleSystem(int w, int h, CGcontext context, NVISid volume, float scale_x,
25                float scale_y, float scale_z){
26
27  fprintf(stderr, "%f, %f, %f\n", scale_x, scale_y, scale_z);
28  scale = Vector3(scale_x, scale_y, scale_z);
29 
30  psys_width = w;
31  psys_height = h;
32
33  psys_frame = 0;
34  reborn = true;
35  flip = true;
36  max_life = 500;
37
38  data = (Particle*) malloc(w*h*sizeof(Particle));
39
40  m_vertex_array = new RenderVertexArray(psys_width*psys_height, 3, GL_FLOAT);
41  assert(glGetError()==0);
42
43  glGenFramebuffersEXT(2, psys_fbo);
44  glGenTextures(2, psys_tex);
45
46  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[0]);
47
48  glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[0]);
49  glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
50  glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
51  glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGBA32_NV, psys_width, psys_height, 0, GL_RGBA, GL_FLOAT, NULL);
52  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, psys_tex[0], 0);
53
54  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[1]);
55
56  glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[1]);
57  glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
58  glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
59  glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGBA32_NV, psys_width, psys_height, 0, GL_RGBA, GL_FLOAT, NULL);
60  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, psys_tex[1], 0);
61
62  CHECK_FRAMEBUFFER_STATUS();
63  assert(glGetError()==0);
64
65  //load related shaders
66  m_g_context = context;
67
68  m_pos_fprog = loadProgram(m_g_context, CG_PROFILE_FP30, CG_SOURCE, "./shaders/update_pos.cg");
69  m_pos_timestep_param  = cgGetNamedParameter(m_pos_fprog, "timestep");
70  m_vel_tex_param = cgGetNamedParameter(m_pos_fprog, "vel_tex");
71  m_pos_tex_param = cgGetNamedParameter(m_pos_fprog, "pos_tex");
72  m_scale_param = cgGetNamedParameter(m_pos_fprog, "scale");
73  cgGLSetTextureParameter(m_vel_tex_param, volume);
74  cgGLSetParameter3f(m_scale_param, scale_x, scale_y, scale_z);
75
76  fprintf(stderr, "init_psys\n");
77}
78
79
80ParticleSystem::~ParticleSystem(){
81  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[0]);
82  glDeleteTextures(1, psys_tex);
83
84  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[1]);
85  glDeleteTextures(1, psys_tex+1);
86
87  glDeleteFramebuffersEXT(2, psys_fbo);
88
89  free(data);
90}
91
92
93void ParticleSystem::initialize(Particle* p){
94  //also store the data on main memory for next initialization
95  memcpy(data, p, psys_width*psys_height*sizeof(Particle));
96
97  glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[0]);
98  glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGBA32_NV, psys_width, psys_height, 0, GL_RGBA, GL_FLOAT, (float*)p);
99 
100  assert(glGetError()==0);
101
102  flip = true;
103  reborn = false;
104
105  //fprintf(stderr, "init particles\n");
106}
107
108void ParticleSystem::reset(){
109  glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[0]);
110  glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGBA32_NV, psys_width, psys_height, 0, GL_RGBA, GL_FLOAT, (float*)data);
111 
112  assert(glGetError()==0);
113
114  flip = true;
115  reborn = false;
116  psys_frame = 0;
117}
118
119
120void ParticleSystem::advect(){
121   if(reborn) reset();
122
123   glDisable(GL_BLEND);
124   
125   if(flip){
126
127     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[1]);
128     glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[0]);
129
130     glClear(GL_COLOR_BUFFER_BIT);
131
132     glViewport(0, 0, psys_width, psys_height);
133     glMatrixMode(GL_PROJECTION);
134     glLoadIdentity();
135     gluOrtho2D(0, psys_width, 0, psys_height);
136     glMatrixMode(GL_MODELVIEW);
137     glLoadIdentity();
138
139     cgGLBindProgram(m_pos_fprog);
140     cgGLSetParameter1f(m_pos_timestep_param, 0.05);
141     cgGLEnableTextureParameter(m_vel_tex_param);
142     cgGLSetTextureParameter(m_pos_tex_param, psys_tex[0]);
143     cgGLEnableTextureParameter(m_pos_tex_param);
144
145     cgGLEnableProfile(CG_PROFILE_FP30);
146     draw_quad(psys_width, psys_height, psys_width, psys_height);
147     cgGLDisableProfile(CG_PROFILE_FP30);
148   
149     cgGLDisableTextureParameter(m_vel_tex_param);
150     cgGLDisableTextureParameter(m_pos_tex_param);
151   }
152   else
153   {
154
155     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, psys_fbo[0]);
156     glBindTexture(GL_TEXTURE_RECTANGLE_NV, psys_tex[1]);
157
158     glClear(GL_COLOR_BUFFER_BIT);
159
160     glViewport(0, 0, psys_width, psys_height);
161     glMatrixMode(GL_PROJECTION);
162     glLoadIdentity();
163     gluOrtho2D(0, psys_width, 0, psys_height);
164     glMatrixMode(GL_MODELVIEW);
165     glLoadIdentity();
166
167     cgGLBindProgram(m_pos_fprog);
168     cgGLSetParameter1f(m_pos_timestep_param, 0.05);
169     cgGLEnableTextureParameter(m_vel_tex_param);
170     cgGLSetTextureParameter(m_pos_tex_param, psys_tex[1]);
171     cgGLEnableTextureParameter(m_pos_tex_param);
172
173     cgGLEnableProfile(CG_PROFILE_FP30);
174     draw_quad(psys_width, psys_height, psys_width, psys_height);
175     cgGLDisableProfile(CG_PROFILE_FP30);
176   
177     cgGLDisableTextureParameter(m_vel_tex_param);
178     cgGLDisableTextureParameter(m_pos_tex_param);
179   }
180
181   assert(glGetError()==0);
182
183   //soft_read_verts();
184   update_vertex_buffer();
185
186   flip = (!flip);
187
188   psys_frame++;
189   if(psys_frame==max_life){
190     psys_frame=0;
191     reborn = true;
192   }
193
194   //fprintf(stderr, "advect: %d ", psys_frame);
195}
196
197
198void ParticleSystem::update_vertex_buffer(){
199  m_vertex_array->Read(psys_width, psys_height);
200  //m_vertex_array->LoadData(vert);     //does not work??
201  assert(glGetError()==0);
202}
203
204
205void ParticleSystem::render(){ display_vertices(); }
206
207void ParticleSystem::display_vertices(){
208  glDisable(GL_TEXTURE_2D);
209  glDisable(GL_BLEND);
210  glEnable(GL_DEPTH_TEST);
211
212  glPointSize(1.2);
213  glColor4f(.2,.2,.8,1.);
214 
215  glPushMatrix();
216  glScaled(1./scale.x, 1./scale.y, 1./scale.z);
217
218  m_vertex_array->SetPointer(0);
219  //glEnableVertexAttribArray(0);
220  glEnableClientState(GL_VERTEX_ARRAY);
221  glDrawArrays(GL_POINTS, 0, psys_width*psys_height);
222  //glDisableVertexAttribArray(0);
223  glDisableClientState(GL_VERTEX_ARRAY);
224
225  glPopMatrix();
226 
227  glDisable(GL_DEPTH_TEST);
228  assert(glGetError()==0);
229}
230
231
Note: See TracBrowser for help on using the repository browser.