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

Last change on this file since 1297 was 1111, checked in by gah, 16 years ago

nanovis/heightmap update

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#include "global.h"
26
27NvLIC::NvLIC(int _size, int _width, int _height, float _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    slice_vector = new float[size*size*4];
47    memset(slice_vector, 0, sizeof(float) * size * size * 4);
48
49    //initialize the pattern texture
50    glGenTextures(1, &pattern_tex);
51    glBindTexture(GL_TEXTURE_2D, pattern_tex);
52    glTexParameteri(GL_TEXTURE_2D,
53                  GL_TEXTURE_WRAP_S, GL_REPEAT);
54    glTexParameteri(GL_TEXTURE_2D,
55                  GL_TEXTURE_WRAP_T, GL_REPEAT);
56    glTexParameteri(GL_TEXTURE_2D,
57                  GL_TEXTURE_MAG_FILTER, GL_LINEAR);
58    glTexParameteri(GL_TEXTURE_2D,
59                  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,
75                  GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
76    glTexParameteri(GL_TEXTURE_RECTANGLE_NV,
77                  GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
78
79    glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0,
80        GL_FLOAT_RGBA32_NV, size, size, 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
211    glGenTextures(1, &mag_tex);
212    glBindTexture(GL_TEXTURE_2D, mag_tex);
213    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
214    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
215    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
216    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
217    //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
218    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, NMESH, NMESH, 0, GL_RGBA,
219                 GL_UNSIGNED_BYTE, mag);
220    glBindTexture(GL_TEXTURE_2D, 0);
221}
222
223void
224NvLIC::get_slice()
225{
226    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vel_fbo);
227
228    glClear(GL_COLOR_BUFFER_BIT);
229
230    glViewport(0, 0, size, size);
231    glMatrixMode(GL_PROJECTION);
232    glLoadIdentity();
233    gluOrtho2D(0, size, 0, size);
234    glMatrixMode(GL_MODELVIEW);
235    glLoadIdentity();
236
237    glEnable(GL_TEXTURE_3D);
238    glBindTexture(GL_TEXTURE_3D, vectorFieldID);
239    cgGLBindProgram(m_render_vel_fprog);
240
241    cgGLSetTextureParameter(m_vel_tex_param_render_vel, vectorFieldID);
242    cgGLEnableTextureParameter(m_vel_tex_param_render_vel);
243    cgGLSetParameter4f(m_plane_normal_param_render_vel, 1., 1., 0., 0);
244    cgGLSetParameter1f(m_max_param, max);
245
246    cgGLEnableProfile(CG_PROFILE_FP30);
247
248    glBegin(GL_QUADS);
249    {
250        glTexCoord3f(0., 0., offset); glVertex2f(0.,   0.);
251        glTexCoord3f(1., 0., offset); glVertex2f(size, 0.);
252        glTexCoord3f(1., 1., offset); glVertex2f(size, size);
253        glTexCoord3f(0., 1., offset); glVertex2f(0.,   size);
254    }
255    glEnd();
256   
257    cgGLDisableProfile(CG_PROFILE_FP30);
258   
259    cgGLDisableTextureParameter(m_vel_tex_param_render_vel);
260
261    glBindTexture(GL_TEXTURE_3D, 0);
262    glDisable(GL_TEXTURE_3D);
263
264    //read the vectors
265    glReadPixels(0, 0, size, size, GL_RGBA, GL_FLOAT, slice_vector);
266    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
267
268    int lim = size * size * 4;
269    float* v= slice_vector;
270    for (int i = 0; i < lim; ++i) {
271        if (isnan(*v)) {
272            *v = 0.0f;   
273        }
274        ++v;
275    }
276}
277
278//line integral convolution
279void
280NvLIC::convolve()
281{
282    int   i, j;
283    float x1, x2, y, px, py;
284   
285    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
286   
287    glMatrixMode(GL_PROJECTION);
288    glLoadIdentity();
289    glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);
290    glViewport(0, 0, (GLsizei) NPIX, (GLsizei) NPIX);
291    //glTranslatef(-1.0, -1.0, 0.0);
292    //glScalef(2.0, 2.0, 1.0);
293    glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -10.0f, 10.0f);
294   
295    glMatrixMode(GL_MODELVIEW);
296    glLoadIdentity();
297   
298    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
299   
300    //sa = 0.010*cos(iframe*2.0*M_PI/200.0);
301    glEnable(GL_TEXTURE_2D);
302    glBindTexture(GL_TEXTURE_2D, pattern_tex);
303    sa = 0.01;
304   
305    for (i = 0; i < NMESH-1; i++) {
306        x1 = DM*i; x2 = x1 + DM;
307        glBegin(GL_QUAD_STRIP);
308        for (j = 0; j < NMESH-1; j++) {
309            y = DM*j;
310            glTexCoord2f(x1, y);
311            get_velocity(x1, y, &px, &py);
312            glVertex2f(px, py);
313           
314            glTexCoord2f(x2, y);
315            get_velocity(x2, y, &px, &py);
316            glVertex2f(px, py);
317        }
318        glEnd();
319    }
320    iframe = iframe + 1;
321   
322    glEnable(GL_BLEND);
323   
324    // INSOO ADD
325    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
326   
327    glEnable(GL_TEXTURE_2D);
328    glCallList(iframe % Npat + disListID);
329    glBegin(GL_QUAD_STRIP);
330    {
331        glTexCoord2f(0.0,  0.0);  glVertex2f(0.0, 0.0);
332        glTexCoord2f(0.0,  tmax); glVertex2f(0.0, 1.0);
333        glTexCoord2f(tmax, 0.0);  glVertex2f(1.0, 0.0);
334        glTexCoord2f(tmax, tmax); glVertex2f(1.0, 1.0);
335        glEnd();
336    }
337    glDisable(GL_TEXTURE_2D);
338   
339    /*
340    //inject dye
341    glDisable(GL_TEXTURE_2D);
342    glColor4f(1.,0.8,0.,1.);
343    glBegin(GL_QUADS);
344    glVertex2d(0.6, 0.6);
345    glVertex2d(0.6, 0.62);
346    glVertex2d(0.62, 0.62);
347    glVertex2d(0.62, 0.6);
348    glEnd();
349    */
350   
351    /// INSOO ADDED
352    glDisable(GL_ALPHA_TEST);
353   
354    glDisable(GL_BLEND);
355    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, NPIX, NPIX, 0);
356   
357    /*
358    //blend magnitude texture
359    glBindTexture(GL_TEXTURE_2D, mag_tex);
360    glEnable(GL_TEXTURE_2D);
361    glEnable(GL_BLEND);
362    glBegin(GL_QUADS);
363    glTexCoord2f(0.0,  0.0);  glVertex2f(0.0, 0.0);
364    glTexCoord2f(0.0,  1.0); glVertex2f(0.0, 1.);
365    glTexCoord2f(1.0, 1.0);  glVertex2f(1., 1.);
366    glTexCoord2f(1.0, 0.0); glVertex2f(1., 0.0);
367    glEnd();
368    */
369
370    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
371    glPopAttrib();
372    glPopMatrix();
373    glMatrixMode(GL_PROJECTION);
374    glPopMatrix();
375    glMatrixMode(GL_MODELVIEW);
376}
377
378void NvLIC::render(){ display(); }
379
380
381void
382NvLIC::display()
383{
384    glBindTexture(GL_TEXTURE_2D, color_tex);
385    glEnable(GL_TEXTURE_2D);
386   
387    //draw line integral convolution quad
388    glEnable(GL_DEPTH_TEST);
389   
390    glPushMatrix();
391   
392    //glScalef(scale.x, scale.y, scale.z);
393    float w = 1.0f / scale.x;
394    glScalef(1.0f, 1.0f / scale.y / w, 1.0f / scale.z / w);
395   
396    glBegin(GL_QUADS);
397    {
398        glTexCoord2f(0, 0); glVertex3f(0, 0, offset);
399        glTexCoord2f(1, 0); glVertex3f(1, 0, offset);
400        glTexCoord2f(1, 1); glVertex3f(1, 1, offset);
401        glTexCoord2f(0, 1); glVertex3f(0, 1, offset);
402    }
403    glEnd();
404   
405    glPopMatrix();
406   
407    glBindTexture(GL_TEXTURE_2D,0);
408   
409    glDisable(GL_DEPTH_TEST);
410    glDisable(GL_TEXTURE_2D);
411}
412
413/*
414{
415    //Trace("RENDER LIC\n");
416   //glBindTexture(GL_TEXTURE_2D, pattern_tex);
417   glCallList(1 % Npat + disListID);
418   glEnable(GL_TEXTURE_2D);
419
420    //draw line integral convolution quad
421    glEnable(GL_DEPTH_TEST);
422
423  glPushMatrix();
424
425  glScalef(scale.x, scale.y, scale.z);
426
427    glColor3f(1, 0, 1);
428  glBegin(GL_QUADS);
429    glTexCoord2f(0, 0); glVertex3f(0, 0, offset);
430    glTexCoord2f(1, 0); glVertex3f(1, 0, offset);
431    glTexCoord2f(1, 1); glVertex3f(1, 1, offset);
432    glTexCoord2f(0, 1); glVertex3f(0, 1, offset);
433  glEnd();
434
435  glPopMatrix();
436
437  glBindTexture(GL_TEXTURE_2D,0);
438  glDisable(GL_TEXTURE_2D);
439
440  glDisable(GL_DEPTH_TEST);
441  glDisable(GL_TEXTURE_RECTANGLE_NV);
442}
443*/
444
445
446void
447NvLIC::setVectorField(unsigned int texID, float scaleX, float scaleY,
448                      float scaleZ, float max)
449{
450    Trace("NvLIC: vector field is assigned [%d]\n", texID);
451    vectorFieldID = texID;
452    scale = Vector3(scaleX, scaleY, scaleZ);
453    this->max = max;
454 
455    get_slice();
456}
457
458void
459NvLIC::get_velocity(float x, float y, float *px, float *py)
460{
461   float vx, vy, r;
462
463   int xi = (int) (x*size);
464   int yi = (int) (y*size);
465
466    //Trace("(xi yi) = (%d %d), ", xi, yi);
467   vx = slice_vector[4 * (xi+yi*size)];
468   vy = slice_vector[4 * (xi+yi*size)+1];
469   r  = vx*vx + vy*vy;
470
471    //Trace("(vx vx) = (%f %f), r=%f, ", vx, vy, r);
472   if (r > (dmax*dmax)) {
473      r  = sqrt(r);
474      vx *= dmax/r;
475      vy *= dmax/r;
476   }
477
478   *px = x + vx;         
479   *py = y + vy;
480
481    //Trace("vel %f %f -> %f %f, (dmax = %f)\n", x, y, *px, *py, dmax);
482}
483
484void
485NvLIC::set_offset(float v)
486{
487    offset = v;
488    get_slice();
489}
Note: See TracBrowser for help on using the repository browser.