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

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

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