source: nanovis/branches/1.2/ParticleRenderer.cpp @ 5394

Last change on this file since 5394 was 5373, checked in by ldelgass, 9 years ago

minor cleanup

  • Property svn:eol-style set to native
File size: 9.6 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 *  Copyright (c) 2004-2013  HUBzero Foundation, LLC
4 *
5 *  Authors:
6 *    Wei Qiao <qiaow@purdue.edu>
7 */
8
9#include <assert.h>
10#include <string.h>
11#include <stdlib.h>
12
13#include <GL/glew.h>
14
15#include <vrmath/Color4f.h>
16
17#include "ParticleRenderer.h"
18#include "define.h"
19#include "Trace.h"
20
21using namespace nv;
22
23ParticleAdvectionShader *ParticleRenderer::_advectionShader = NULL;
24ParticleAdvectionShaderInstance shaderInstance;
25
26ParticleRenderer::ParticleRenderer(int w, int h) :
27    _initPosTex(0),
28    _data(NULL),
29    _psysFrame(0U),
30    _reborn(true),
31    _flip(true),
32    _maxLife(500U),
33    _particleSize(1.2),
34    _vertexArray(NULL),
35    _scale(1, 1, 1),
36    _origin(0, 0, 0),
37    _activate(false),
38    _slicePos(0.0),
39    _sliceAxis(AXIS_Z),
40    _color(0.2, 0.2, 1.0, 1.0),
41    _psysWidth(w),
42    _psysHeight(h)
43{
44    _data = new Particle[w * h];
45    memset(_data, 0, sizeof(Particle) * w * h);
46
47    _vertexArray = new RenderVertexArray(_psysWidth * _psysHeight, 3, GL_FLOAT);
48
49    assert(CheckGL(AT));
50
51    glGenFramebuffersEXT(2, _psysFbo);
52    glGenTextures(2, _psysTex);
53
54    int fboOrig;
55    glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fboOrig);
56
57    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _psysFbo[0]);
58
59    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _psysTex[0]);
60    glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
61    glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
62
63#ifdef HAVE_FLOAT_TEXTURES
64    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA32F_ARB,
65                 _psysWidth, _psysHeight, 0, GL_RGBA, GL_FLOAT, NULL);
66#else
67    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
68                 _psysWidth, _psysHeight, 0, GL_RGBA, GL_FLOAT, NULL);
69#endif
70    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
71                              GL_TEXTURE_RECTANGLE_ARB, _psysTex[0], 0);
72
73    CHECK_FRAMEBUFFER_STATUS();
74
75    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _psysFbo[1]);
76
77    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _psysTex[1]);
78    glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
79    glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
80#ifdef HAVE_FLOAT_TEXTURES
81    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA32F_ARB,
82                 _psysWidth, _psysHeight, 0, GL_RGBA, GL_FLOAT, NULL);
83#else
84    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
85                 _psysWidth, _psysHeight, 0, GL_RGBA, GL_FLOAT, NULL);
86#endif
87    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
88                              GL_TEXTURE_RECTANGLE_ARB, _psysTex[1], 0);
89 
90    CHECK_FRAMEBUFFER_STATUS();
91
92    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboOrig);
93
94    glGenTextures(1, &_initPosTex);
95    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _initPosTex);
96    glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
97    glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
98#ifdef HAVE_FLOAT_TEXTURES
99    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA32F_ARB,
100                 _psysWidth, _psysHeight, 0, GL_RGBA, GL_FLOAT, NULL);
101#else
102    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
103                 _psysWidth, _psysHeight, 0, GL_RGBA, GL_FLOAT, NULL);
104#endif
105
106    if (_advectionShader == NULL) {
107        _advectionShader = new ParticleAdvectionShader();
108    }
109}
110
111ParticleRenderer::~ParticleRenderer()
112{
113    glDeleteTextures(1, &_initPosTex);
114
115    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _psysFbo[0]);
116    glDeleteTextures(1, _psysTex);
117
118    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _psysFbo[1]);
119    glDeleteTextures(1, _psysTex+1);
120
121    glDeleteFramebuffersEXT(2, _psysFbo);
122
123    delete _vertexArray;
124    delete [] _data;
125}
126
127void
128ParticleRenderer::initializeDataArray()
129{
130    size_t n = _psysWidth * _psysHeight * 4;
131    memset(_data, 0, sizeof(float)* n);
132
133    int index;
134    bool particle;
135    float *p = (float *)_data;
136    for (int i = 0; i < _psysWidth; i++) {
137        for (int j = 0; j < _psysHeight; j++) {
138            index = i + _psysHeight*j;
139            particle = (rand() % 256) > 150;
140            if (particle) {
141                //assign any location (x,y,z) in range [0,1]
142                switch (_sliceAxis) {
143                case AXIS_X:
144                    p[4*index]   = _slicePos;
145                    p[4*index+1] = j/float(_psysHeight);
146                    p[4*index+2] = i/float(_psysWidth);
147                    break;
148                case AXIS_Y:
149                    p[4*index]   = j/float(_psysHeight);
150                    p[4*index+1] = _slicePos;
151                    p[4*index+2] = i/float(_psysWidth);
152                    break;
153                case AXIS_Z:
154                    p[4*index]   = j/float(_psysHeight);
155                    p[4*index+1] = i/float(_psysWidth);
156                    p[4*index+2] = _slicePos;
157                    break;
158                default:
159                    p[4*index]   = 0;
160                    p[4*index+1] = 0;
161                    p[4*index+2] = 0;
162                    p[4*index+3] = 0;
163                }
164
165                //shorter life span, quicker iterations
166                p[4*index+3] = rand() / ((float) RAND_MAX) * 0.5  + 0.5f;
167            } else {
168                p[4*index]   = 0;
169                p[4*index+1] = 0;
170                p[4*index+2] = 0;
171                p[4*index+3] = 0;
172            }
173        }
174    }
175}
176
177void
178ParticleRenderer::initialize()
179{
180    initializeDataArray();
181
182    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _psysTex[0]);
183#ifdef HAVE_FLOAT_TEXTURES
184    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA32F_ARB,
185                 _psysWidth, _psysHeight, 0, GL_RGBA, GL_FLOAT, (float*)_data);
186#else
187    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
188                 _psysWidth, _psysHeight, 0, GL_RGBA, GL_FLOAT, (float*)_data);
189#endif
190    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
191
192    _flip = true;
193    _reborn = false;
194
195    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _initPosTex);
196#ifdef HAVE_FLOAT_TEXTURES
197    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA32F_ARB,
198                 _psysWidth, _psysHeight, 0, GL_RGBA, GL_FLOAT, (float*)_data);
199#else
200    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
201                 _psysWidth, _psysHeight, 0, GL_RGBA, GL_FLOAT, (float*)_data);
202#endif
203    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
204
205    TRACE("Leave");
206}
207
208void
209ParticleRenderer::reset()
210{
211    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _psysTex[0]);
212#ifdef HAVE_FLOAT_TEXTURES
213    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA32F_ARB,
214                 _psysWidth, _psysHeight, 0, GL_RGBA, GL_FLOAT, (float*)_data);
215#else
216    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
217                 _psysWidth, _psysHeight, 0, GL_RGBA, GL_FLOAT, (float*)_data);
218#endif
219    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
220    _flip = true;
221    _reborn = false;
222    _psysFrame = 0U;
223}
224
225void
226ParticleRenderer::advect()
227{
228    if (_reborn)
229        reset();
230
231    glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);
232
233    int fboOrig;
234    glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fboOrig);
235
236    glDisable(GL_BLEND);
237    glDisable(GL_DEPTH_TEST);
238
239    int fbo, tex;
240    if (_flip) {
241        fbo = 1;
242        tex = 0;
243    } else {
244        fbo = 0;
245        tex = 1;
246    }
247
248    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _psysFbo[fbo]);
249    glEnable(GL_TEXTURE_RECTANGLE_ARB);
250    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _psysTex[tex]);
251
252    glClear(GL_COLOR_BUFFER_BIT);
253
254    glViewport(0, 0, _psysWidth, _psysHeight);
255    glMatrixMode(GL_PROJECTION);
256    glPushMatrix();
257    glLoadIdentity();
258    glOrtho(0, _psysWidth, 0, _psysHeight, -10.0f, 10.0f);
259    glMatrixMode(GL_MODELVIEW);
260    glPushMatrix();
261    glLoadIdentity();
262
263    _advectionShader->bind(_psysTex[tex], _initPosTex);
264
265    draw_quad(_psysWidth, _psysHeight, _psysWidth, _psysHeight);
266
267    _advectionShader->unbind();
268
269    glMatrixMode(GL_PROJECTION);
270    glPopMatrix();
271
272    glMatrixMode(GL_MODELVIEW);
273    glPopMatrix();
274
275    glDisable(GL_TEXTURE_RECTANGLE_ARB);
276
277    updateVertexBuffer();
278
279    _flip = (!_flip);
280
281    _psysFrame++;
282    if (_psysFrame == _maxLife) {
283        _psysFrame = 0U;
284        // _reborn = true;
285    }
286    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboOrig);
287
288    glPopAttrib();
289}
290
291void
292ParticleRenderer::updateVertexBuffer()
293{
294    _vertexArray->read(_psysWidth, _psysHeight);
295
296    //_vertexArray->loadData(vert);     //does not work??
297    //assert(glGetError()==0);
298}
299
300void
301ParticleRenderer::render()
302{
303    glPushAttrib(GL_ENABLE_BIT);
304    glDisable(GL_TEXTURE_2D);
305    glDisable(GL_BLEND);
306    glEnable(GL_DEPTH_TEST);
307
308    glEnable(GL_COLOR_MATERIAL);
309
310    glMatrixMode(GL_MODELVIEW);
311    glPushMatrix();
312
313    glTranslatef(_origin.x, _origin.y, _origin.z);
314    glScaled(_scale.x, _scale.y, _scale.z);
315
316    glPointSize(_particleSize);
317    glColor4f(_color.x, _color.y, _color.z, _color.w);
318
319    glEnableClientState(GL_VERTEX_ARRAY);
320    _vertexArray->setPointer(0);
321    glDrawArrays(GL_POINTS, 0, _psysWidth * _psysHeight);
322    glDisableClientState(GL_VERTEX_ARRAY);
323
324    glPopMatrix();
325    glPopAttrib();
326}
327
328void
329ParticleRenderer::setVectorField(unsigned int texID, const vrmath::Vector3f& origin,
330                                 float scaleX, float scaleY, float scaleZ,
331                                 float max)
332{
333    _origin = origin;
334    _scale.set(scaleX, scaleY, scaleZ);
335    _advectionShader->setScale(_scale);
336    _advectionShader->setVelocityVolume(texID, max);
337}
338
339void
340ParticleRenderer::setSliceAxis(FlowSliceAxis axis)
341{
342    _sliceAxis = axis;
343    initializeDataArray();
344}
345
346void
347ParticleRenderer::setSlicePosition(float pos)
348{
349    _slicePos = pos;
350    initializeDataArray();
351}
Note: See TracBrowser for help on using the repository browser.