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

Last change on this file since 1429 was 1429, checked in by gah, 15 years ago

Initial commit of new flow visualization command structure

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