source: trunk/packages/vizservers/nanovis/NvLIC.cpp @ 2798

Last change on this file since 2798 was 2798, checked in by ldelgass, 12 years ago

Add emacs mode magic line in preparation for indentation cleanup

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