source: trunk/vizservers/nanovis/NvLIC.cpp @ 984

Last change on this file since 984 was 984, checked in by gah, 13 years ago
File size: 12.6 KB
Line 
1/*
2 * ----------------------------------------------------------------------
3 * NvLIC.h: line integral convolution class
4 *
5 * ======================================================================
6 *  AUTHOR:  Insoo Woo <iwoo@purdue.edu, 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
17#include <stdlib.h>
18#include <math.h>
19#include <assert.h>
20
21#include <R2/R2FilePath.h>
22#include "NvLIC.h"
23#include <Trace.h>
24
25NvLIC::NvLIC(int _size, int _width, int _height, float _offset, CGcontext _context)
26    : Renderable(Vector3(0.0f,0.0f,0.0f)),
27    disListID(0),
28        width(_width),
29        height(_height),
30        size(_size),
31    scale(1.0f, 1.0f, 1.0f),
32        offset(_offset),
33    iframe(0),
34        Npat(64),
35        alpha((int) 0.12*255),
36        tmax(NPIX/(SCALE*NPN)),
37        dmax(SCALE/NPIX),
38    max(1.0f),
39        m_g_context(_context),
40    vectorFieldID((NVISid) 0),
41    _activate(false)
42{
43    slice_vector = new float[size*size*4];
44    memset(slice_vector, 0, sizeof(float) * size * size * 4);
45
46    //initialize the pattern texture
47    glGenTextures(1, &pattern_tex);
48    glBindTexture(GL_TEXTURE_2D, pattern_tex);
49    glTexParameteri(GL_TEXTURE_2D,
50                  GL_TEXTURE_WRAP_S, GL_REPEAT);
51    glTexParameteri(GL_TEXTURE_2D,
52                  GL_TEXTURE_WRAP_T, GL_REPEAT);
53    glTexParameteri(GL_TEXTURE_2D,
54                  GL_TEXTURE_MAG_FILTER, GL_LINEAR);
55    glTexParameteri(GL_TEXTURE_2D,
56                  GL_TEXTURE_MIN_FILTER, GL_LINEAR);
57    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
58
59    //initialize frame buffer objects
60    //render buffer for projecting 3D velocity onto a 2D plane
61    glGenFramebuffersEXT(1, &vel_fbo);
62    glGenTextures(1, &slice_vector_tex);
63
64    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vel_fbo);
65
66    glBindTexture(GL_TEXTURE_RECTANGLE_NV, slice_vector_tex);
67    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
68    glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
69
70    // ADD INSOO
71    glTexParameteri(GL_TEXTURE_RECTANGLE_NV,
72                  GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
73    glTexParameteri(GL_TEXTURE_RECTANGLE_NV,
74                  GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
75
76    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0,
77        GL_FLOAT_RGBA32_NV, size, size, 0, GL_RGBA, GL_FLOAT, NULL);
78
79    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
80                  GL_TEXTURE_RECTANGLE_NV, slice_vector_tex, 0);
81
82
83    //render buffer for the convolution
84    glGenFramebuffersEXT(1, &fbo);
85    glGenTextures(1, &color_tex);
86
87    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
88
89    //initialize color texture for lic
90    glBindTexture(GL_TEXTURE_2D, color_tex);
91    // INSOO
92    //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
93    //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
94    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
95    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
96
97    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height, 0,
98                 GL_RGB, GL_INT, NULL);
99
100    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
101                            GL_COLOR_ATTACHMENT0_EXT,
102                            GL_TEXTURE_2D, color_tex, 0);
103
104
105    // Check framebuffer completeness at the end of initialization.
106    CHECK_FRAMEBUFFER_STATUS();
107
108    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
109
110    R2string path = R2FilePath::getInstance()->getPath("render_vel.cg");
111    m_render_vel_fprog = loadProgram(m_g_context, CG_PROFILE_FP30, CG_SOURCE, path);
112    m_vel_tex_param_render_vel = cgGetNamedParameter(m_render_vel_fprog, "vel_tex");
113    m_plane_normal_param_render_vel = cgGetNamedParameter(m_render_vel_fprog, "plane_normal");
114    m_max_param = cgGetNamedParameter(m_render_vel_fprog, "vmax");
115
116
117    make_patterns();
118}
119
120NvLIC::~NvLIC()
121{
122    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vel_fbo);
123    glDeleteTextures(1, &slice_vector_tex);
124
125    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
126    glDeleteTextures(1, &color_tex);
127
128    NVISid buffers[2] = {vel_fbo, fbo};
129    glDeleteFramebuffersEXT(2, buffers);
130
131    glDeleteLists(disListID, Npat);
132
133    delete slice_vector;
134}
135
136void
137NvLIC::make_patterns()
138{
139    Trace("begin make_patterns\n");
140   
141    disListID = glGenLists(Npat);
142   
143    Trace("DisplayList : %d\n", disListID);
144   
145    int lut[256];
146    int phase[NPN][NPN];
147    GLubyte pat[NPN][NPN][4];
148    int i, j, k, t;
149   
150    for (i = 0; i < 256; i++) {
151        lut[i] = i < 127 ? 0 : 255;
152    }
153    for (i = 0; i < NPN; i++) {
154        for (j = 0; j < NPN; j++) {
155            phase[i][j] = rand() % 256;
156        }
157    }
158    for (k = 0; k < Npat; k++) {
159        t = k*256/Npat;
160        for (i = 0; i < NPN; i++) {
161            for (j = 0; j < NPN; j++) {
162                pat[i][j][0] =
163                    pat[i][j][1] =
164                    pat[i][j][2] = lut[(t + phase[i][j]) % 255];
165                pat[i][j][3] = alpha;
166            }
167        }
168        glNewList(disListID + k, GL_COMPILE);
169        glBindTexture(GL_TEXTURE_2D, pattern_tex);
170        glTexImage2D(GL_TEXTURE_2D, 0, 4, NPN, NPN, 0,
171                     GL_RGBA, GL_UNSIGNED_BYTE, pat);
172        glEndList();
173    }
174   
175    glBindTexture(GL_TEXTURE_2D, pattern_tex);
176    glTexImage2D(GL_TEXTURE_2D, 0, 4, NPN, NPN, 0,
177                 GL_RGBA, GL_UNSIGNED_BYTE, pat);
178    Trace("finish make_patterns\n");
179}
180
181
182void NvLIC::make_magnitudes()
183{
184    GLubyte mag[NMESH][NMESH][4];
185
186    //read vector filed
187    for(int i=0; i<NMESH; i++){
188        for(int j=0; j<NMESH; j++){
189
190      float x=DM*i;
191      float y=DM*j;
192
193      float magnitude = sqrt(x*x+y*y)/1.414;
194     
195      //from green to red
196      GLubyte r = (GLubyte) floor(magnitude*255);
197      GLubyte g = 0;
198      GLubyte b = 255 - r;
199      GLubyte a = 122;
200
201      mag[i][j][0] = r;
202      mag[i][j][1] = g;
203      mag[i][j][2] = b;
204      mag[i][j][3] = a;
205        }
206    }
207
208    glGenTextures(1, &mag_tex);
209    glBindTexture(GL_TEXTURE_2D, mag_tex);
210    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
211    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
212    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
213    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
214    //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
215    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, NMESH, NMESH, 0, GL_RGBA, GL_UNSIGNED_BYTE, mag);
216    glBindTexture(GL_TEXTURE_2D, 0);
217}
218
219void NvLIC::get_slice()
220{
221    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vel_fbo);
222
223    glClear(GL_COLOR_BUFFER_BIT);
224
225    glViewport(0, 0, size, size);
226    glMatrixMode(GL_PROJECTION);
227    glLoadIdentity();
228    gluOrtho2D(0, size, 0, size);
229    glMatrixMode(GL_MODELVIEW);
230    glLoadIdentity();
231
232    glEnable(GL_TEXTURE_3D);
233    glBindTexture(GL_TEXTURE_3D, vectorFieldID);
234    cgGLBindProgram(m_render_vel_fprog);
235
236    cgGLSetTextureParameter(m_vel_tex_param_render_vel, vectorFieldID);
237    cgGLEnableTextureParameter(m_vel_tex_param_render_vel);
238    cgGLSetParameter4f(m_plane_normal_param_render_vel, 1., 1., 0., 0);
239    cgGLSetParameter1f(m_max_param, max);
240
241    cgGLEnableProfile(CG_PROFILE_FP30);
242
243    glBegin(GL_QUADS);
244        glTexCoord3f(0., 0., offset); glVertex2f(0.,   0.);
245        glTexCoord3f(1., 0., offset); glVertex2f(size, 0.);
246        glTexCoord3f(1., 1., offset); glVertex2f(size, size);
247        glTexCoord3f(0., 1., offset); glVertex2f(0.,   size);
248    glEnd();
249   
250    cgGLDisableProfile(CG_PROFILE_FP30);
251   
252    cgGLDisableTextureParameter(m_vel_tex_param_render_vel);
253
254    glBindTexture(GL_TEXTURE_3D, 0);
255    glDisable(GL_TEXTURE_3D);
256
257    //read the vectors
258    glReadPixels(0, 0, size, size, GL_RGBA, GL_FLOAT, slice_vector);
259    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
260
261    int lim = size * size * 4;
262    float* v= slice_vector;
263    for (int i = 0; i < lim; ++i)
264    {
265        if (isnan(*v)) *v = 0.0f;   
266        ++v;
267    }
268}
269
270//line integral convolution
271void NvLIC::convolve()
272{
273    int   i, j;
274    float x1, x2, y, px, py;
275
276    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
277
278    glMatrixMode(GL_PROJECTION);
279    glLoadIdentity();
280    glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);
281    glViewport(0, 0, (GLsizei) NPIX, (GLsizei) NPIX);
282    //glTranslatef(-1.0, -1.0, 0.0);
283    //glScalef(2.0, 2.0, 1.0);
284    glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -10.0f, 10.0f);
285
286    glMatrixMode(GL_MODELVIEW);
287    glLoadIdentity();
288
289    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
290
291    //sa = 0.010*cos(iframe*2.0*M_PI/200.0);
292    glEnable(GL_TEXTURE_2D);
293    glBindTexture(GL_TEXTURE_2D, pattern_tex);
294    sa = 0.01;
295
296    for (i = 0; i < NMESH-1; i++)
297    {
298        x1 = DM*i; x2 = x1 + DM;
299        glBegin(GL_QUAD_STRIP);
300        for (j = 0; j < NMESH-1; j++) {
301          y = DM*j;
302          glTexCoord2f(x1, y);
303          get_velocity(x1, y, &px, &py);
304          glVertex2f(px, py);
305
306          glTexCoord2f(x2, y);
307          get_velocity(x2, y, &px, &py);
308          glVertex2f(px, py);
309        }
310        glEnd();
311   }
312   iframe = iframe + 1;
313
314   glEnable(GL_BLEND);
315
316    // INSOO ADD
317    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
318
319    glEnable(GL_TEXTURE_2D);
320   glCallList(iframe % Npat + disListID);
321   glBegin(GL_QUAD_STRIP);
322      glTexCoord2f(0.0,  0.0);  glVertex2f(0.0, 0.0);
323      glTexCoord2f(0.0,  tmax); glVertex2f(0.0, 1.0);
324      glTexCoord2f(tmax, 0.0);  glVertex2f(1.0, 0.0);
325      glTexCoord2f(tmax, tmax); glVertex2f(1.0, 1.0);
326   glEnd();
327    glDisable(GL_TEXTURE_2D);
328
329   /*
330   //inject dye
331   glDisable(GL_TEXTURE_2D);
332   glColor4f(1.,0.8,0.,1.);
333   glBegin(GL_QUADS);
334     glVertex2d(0.6, 0.6);
335     glVertex2d(0.6, 0.62);
336     glVertex2d(0.62, 0.62);
337     glVertex2d(0.62, 0.6);
338   glEnd();
339   */
340
341    /// INSOO ADDED
342    glDisable(GL_ALPHA_TEST);
343
344   glDisable(GL_BLEND);
345   glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, NPIX, NPIX, 0);
346   
347   /*
348   //blend magnitude texture
349   glBindTexture(GL_TEXTURE_2D, mag_tex);
350   glEnable(GL_TEXTURE_2D);
351   glEnable(GL_BLEND);
352   glBegin(GL_QUADS);
353      glTexCoord2f(0.0,  0.0);  glVertex2f(0.0, 0.0);
354      glTexCoord2f(0.0,  1.0); glVertex2f(0.0, 1.);
355      glTexCoord2f(1.0, 1.0);  glVertex2f(1., 1.);
356      glTexCoord2f(1.0, 0.0); glVertex2f(1., 0.0);
357   glEnd();
358   */
359
360   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
361
362    glPopAttrib();
363
364    glPopMatrix();
365    glMatrixMode(GL_PROJECTION);
366    glPopMatrix();
367    glMatrixMode(GL_MODELVIEW);
368}
369
370void NvLIC::render(){ display(); }
371
372
373void NvLIC::display()
374{
375  glBindTexture(GL_TEXTURE_2D, color_tex);
376  glEnable(GL_TEXTURE_2D);
377
378  //draw line integral convolution quad
379  glEnable(GL_DEPTH_TEST);
380
381  glPushMatrix();
382
383    //glScalef(scale.x, scale.y, scale.z);
384    float w = 1.0f / scale.x;
385    glScalef(1.0f, 1.0f / scale.y / w, 1.0f / scale.z / w);
386
387  glBegin(GL_QUADS);
388    glTexCoord2f(0, 0); glVertex3f(0, 0, offset);
389    glTexCoord2f(1, 0); glVertex3f(1, 0, offset);
390    glTexCoord2f(1, 1); glVertex3f(1, 1, offset);
391    glTexCoord2f(0, 1); glVertex3f(0, 1, offset);
392  glEnd();
393
394  glPopMatrix();
395
396  glBindTexture(GL_TEXTURE_2D,0);
397
398  glDisable(GL_DEPTH_TEST);
399  glDisable(GL_TEXTURE_2D);
400
401}
402/*
403{
404    //Trace("RENDER LIC\n");
405   //glBindTexture(GL_TEXTURE_2D, pattern_tex);
406   glCallList(1 % Npat + disListID);
407   glEnable(GL_TEXTURE_2D);
408
409    //draw line integral convolution quad
410    glEnable(GL_DEPTH_TEST);
411
412  glPushMatrix();
413
414  glScalef(scale.x, scale.y, scale.z);
415
416    glColor3f(1, 0, 1);
417  glBegin(GL_QUADS);
418    glTexCoord2f(0, 0); glVertex3f(0, 0, offset);
419    glTexCoord2f(1, 0); glVertex3f(1, 0, offset);
420    glTexCoord2f(1, 1); glVertex3f(1, 1, offset);
421    glTexCoord2f(0, 1); glVertex3f(0, 1, offset);
422  glEnd();
423
424  glPopMatrix();
425
426  glBindTexture(GL_TEXTURE_2D,0);
427  glDisable(GL_TEXTURE_2D);
428
429  glDisable(GL_DEPTH_TEST);
430  glDisable(GL_TEXTURE_RECTANGLE_NV);
431}
432*/
433
434
435void NvLIC::setVectorField(unsigned int texID, float scaleX, float scaleY, float scaleZ, float max)
436{
437    Trace("NvLIC: vector field is assigned [%d]\n", texID);
438    vectorFieldID = texID;
439    scale = Vector3(scaleX, scaleY, scaleZ);
440    this->max = max;
441 
442    get_slice();
443}
444
445void NvLIC::get_velocity(float x, float y, float *px, float *py)
446{
447   float vx, vy, r;
448
449   int xi = (int) (x*size);
450   int yi = (int) (y*size);
451
452    //Trace("(xi yi) = (%d %d), ", xi, yi);
453   vx = slice_vector[4 * (xi+yi*size)];
454   vy = slice_vector[4 * (xi+yi*size)+1];
455   r  = vx*vx + vy*vy;
456
457    //Trace("(vx vx) = (%f %f), r=%f, ", vx, vy, r);
458   if (r > dmax*dmax) {
459      r  = sqrt(r);
460      vx *= dmax/r;
461      vy *= dmax/r;
462   }
463
464   *px = x + vx;         
465   *py = y + vy;
466
467    //Trace("vel %f %f -> %f %f, (dmax = %f)\n", x, y, *px, *py, dmax);
468}
469
470void NvLIC::set_offset(float v)
471{
472  offset = v;
473  get_slice();
474}
Note: See TracBrowser for help on using the repository browser.