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

Last change on this file since 1049 was 1028, checked in by gah, 16 years ago

various cleanups

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