source: trunk/packages/vizservers/nanovis/ParticleRenderer.cpp @ 3612

Last change on this file since 3612 was 3612, checked in by ldelgass, 7 years ago

Remove Nv prefix from shader classes now that they are in nv namespace.

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