source: trunk/packages/vizservers/nanovis/Lic.cpp @ 1489

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

Fix volume management routines to handle deletion

File size: 9.5 KB
Line 
1/*
2 * ----------------------------------------------------------------------
3 * Lic.h: line integral convolution class
4 *
5 * ======================================================================
6 *  AUTHOR:  Wei Qiao <qiaow@purdue.edu>
7 *           Purdue Rendering and Perceptualization Lab (PURPL)
8 *
9 *  Copyright (c) 2004-2006  Purdue Research Foundation
10 *
11 *  See the file "license.terms" for information on usage and
12 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 * ======================================================================
14 */
15
16
17#include <stdlib.h>
18#include <math.h>
19#include <assert.h>
20
21#include <R2/R2FilePath.h>
22#include "Lic.h"
23
24Lic::Lic(int _size, int _width, int _height, float _offset,
25                CGcontext _context, NVISid _vector_field,
26                float scalex, float scaley, float scalez):
27        Renderable(Vector3(0.,0.,0.)),
28        size(_size),
29        offset(_offset),
30        m_g_context(_context),
31        width(_width),
32        height(_height),
33        iframe(0),
34        Npat(64),
35        alpha(0.12*255),
36        tmax(NPIX/(SCALE*NPN)),
37        dmax(SCALE/NPIX)
38{
39  scale = Vector3(scalex, scaley, scalez);
40  slice_vector = new float[size*size*4];
41
42  //initialize the pattern texture
43  glGenTextures(1, &pattern_tex);
44  glBindTexture(GL_TEXTURE_2D, pattern_tex);
45  glTexParameteri(GL_TEXTURE_2D,
46                  GL_TEXTURE_WRAP_S, GL_REPEAT);
47  glTexParameteri(GL_TEXTURE_2D,
48                  GL_TEXTURE_WRAP_T, GL_REPEAT);
49  glTexParameteri(GL_TEXTURE_2D,
50                  GL_TEXTURE_MAG_FILTER, GL_LINEAR);
51  glTexParameteri(GL_TEXTURE_2D,
52                  GL_TEXTURE_MIN_FILTER, GL_LINEAR);
53  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
54
55  //initialize frame buffer objects
56
57  //render buffer for projecting 3D velocity onto a 2D plane
58  glGenFramebuffersEXT(1, &vel_fbo);
59  glGenTextures(1, &slice_vector_tex);
60
61  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vel_fbo);
62
63  glBindTexture(GL_TEXTURE_RECTANGLE_NV, slice_vector_tex);
64  glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
65  glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
66  glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0,
67                  GL_FLOAT_RGBA32_NV, size, size, 0, GL_RGBA, GL_FLOAT, NULL);
68  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
69                  GL_TEXTURE_RECTANGLE_NV, slice_vector_tex, 0);
70
71
72  //render buffer for the convolution
73  glGenFramebuffersEXT(1, &fbo);
74  glGenTextures(1, &color_tex);
75
76  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
77
78  //initialize color texture for lic
79  glBindTexture(GL_TEXTURE_2D, color_tex);
80  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
81  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
82  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height, 0,
83               GL_RGB, GL_INT, NULL);
84  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
85                            GL_COLOR_ATTACHMENT0_EXT,
86                            GL_TEXTURE_2D, color_tex, 0);
87
88  // Check framebuffer completeness at the end of initialization.
89  CHECK_FRAMEBUFFER_STATUS();
90  assert(glGetError()==0);
91
92  m_render_vel_fprog = LoadProgram(m_g_context, CG_PROFILE_FP30, CG_SOURCE,
93        NULL, "render_vel.cg");
94  m_vel_tex_param_render_vel = cgGetNamedParameter(m_render_vel_fprog,
95        "vel_tex");
96  m_plane_normal_param_render_vel = cgGetNamedParameter(m_render_vel_fprog,
97        "plane_normal");
98  cgGLSetTextureParameter(m_vel_tex_param_render_vel, _vector_field);
99
100  get_slice();
101  make_patterns();
102}
103
104Lic::~Lic(){
105  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vel_fbo);
106  glDeleteTextures(1, &slice_vector_tex);
107
108  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
109  glDeleteTextures(1, &color_tex);
110
111  NVISid buffers[2] = {vel_fbo, fbo};
112  glDeleteFramebuffersEXT(2, buffers);
113
114  delete slice_vector;
115}
116
117void Lic::make_patterns()
118{
119    int lut[256];
120    int phase[NPN][NPN];
121    GLubyte pat[NPN][NPN][4];
122    int i, j, k, t;
123   
124    for (i = 0; i < 256; i++) lut[i] = i < 127 ? 0 : 255;
125    for (i = 0; i < NPN; i++)
126        for (j = 0; j < NPN; j++) phase[i][j] = rand() % 256;
127   
128    for (k = 0; k < Npat; k++) {
129        t = k*256/Npat;
130        for (i = 0; i < NPN; i++)
131            for (j = 0; j < NPN; j++) {
132                pat[i][j][0] =
133                    pat[i][j][1] =
134                    pat[i][j][2] = lut[(t + phase[i][j]) % 255];
135                pat[i][j][3] = alpha;
136            }
137       
138        glNewList(k + 1, GL_COMPILE);
139        glBindTexture(GL_TEXTURE_2D, pattern_tex);
140        glTexImage2D(GL_TEXTURE_2D, 0, 4, NPN, NPN, 0,
141                     GL_RGBA, GL_UNSIGNED_BYTE, pat);
142        glEndList();
143    }
144}
145
146
147void Lic::make_magnitudes()
148{
149
150  GLubyte mag[NMESH][NMESH][4];
151
152  //read vector filed
153  for(int i=0; i<NMESH; i++){
154    for(int j=0; j<NMESH; j++){
155
156      float x=DM*i;
157      float y=DM*j;
158
159      float magnitude = sqrt(x*x+y*y)/1.414;
160     
161      //from green to red
162      GLubyte r = floor(magnitude*255);
163      GLubyte g = 0;
164      GLubyte b = 255 - r;
165      GLubyte a = 122;
166
167      mag[i][j][0] = r;
168      mag[i][j][1] = g;
169      mag[i][j][2] = b;
170      mag[i][j][3] = a;
171    }
172  }
173
174  glGenTextures(1, &mag_tex);
175  glBindTexture(GL_TEXTURE_2D, mag_tex);
176  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
177  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
178  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
179  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
180  //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
181  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, NMESH, NMESH, 0, GL_RGBA, GL_UNSIGNED_BYTE, mag);
182
183}
184
185//project 3D vectors to a 2D slice for line integral convolution
186void Lic::get_slice(){
187  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vel_fbo);
188  glBindTexture(GL_TEXTURE_RECTANGLE_NV, slice_vector_tex);
189
190  glClear(GL_COLOR_BUFFER_BIT);
191
192  glViewport(0, 0, NMESH, NMESH);
193  glMatrixMode(GL_PROJECTION);
194  glLoadIdentity();
195  gluOrtho2D(0, NMESH, 0, NMESH);
196  glMatrixMode(GL_MODELVIEW);
197  glLoadIdentity();
198
199  Trace("get_slice: binding lic vec prog");
200  cgGLBindProgram(m_render_vel_fprog);
201  Trace("get_slice: done binding lic vec prog");
202  cgGLEnableTextureParameter(m_vel_tex_param_render_vel);
203  cgGLSetParameter4f(m_plane_normal_param_render_vel, 1., 1., 0., 0);
204
205  cgGLEnableProfile(CG_PROFILE_FP30);
206  glBegin(GL_QUADS);
207    glTexCoord3f(0., 0., offset); glVertex2f(0.,   0.);
208    glTexCoord3f(1., 0., offset); glVertex2f(size, 0.);
209    glTexCoord3f(1., 1., offset); glVertex2f(size, size);
210    glTexCoord3f(0., 1., offset); glVertex2f(0.,   size);
211  glEnd();
212  cgGLDisableProfile(CG_PROFILE_FP30);
213   
214  cgGLDisableTextureParameter(m_vel_tex_param_render_vel);
215
216  //read the vectors
217  glReadPixels(0, 0, NMESH, NMESH, GL_RGBA, GL_FLOAT, slice_vector);
218  /*
219  for(int i=0; i<NMESH*NMESH; i++){
220    fprintf(stderr, "%f,%f,%f,%f", slice_vector[4*i], slice_vector[4*i+1], slice_vector[4*i+2], slice_vector[4*i+3]);
221  }
222  */
223  assert(glGetError()==0);
224}
225
226
227//line integral convolution
228void Lic::convolve(){
229
230   int   i, j;
231   float x1, x2, y, px, py;
232
233   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
234
235   glViewport(0, 0, (GLsizei) NPIX, (GLsizei) NPIX);
236   glMatrixMode(GL_PROJECTION);
237   glLoadIdentity();
238   glTranslatef(-1.0, -1.0, 0.0);
239   glScalef(2.0, 2.0, 1.0);
240
241   //sa = 0.010*cos(iframe*2.0*M_PI/200.0);
242   glBindTexture(GL_TEXTURE_2D, pattern_tex);
243   glEnable(GL_TEXTURE_2D);
244   sa = 0.01;
245   for (i = 0; i < NMESH-1; i++) {
246      x1 = DM*i; x2 = x1 + DM;
247      glBegin(GL_QUAD_STRIP);
248      for (j = 0; j < NMESH-1; j++) {
249          y = DM*j;
250          glTexCoord2f(x1, y);
251          get_velocity(x1, y, &px, &py);
252          glVertex2f(px, py);
253
254          glTexCoord2f(x2, y);
255          get_velocity(x2, y, &px, &py);
256          glVertex2f(px, py);
257      }
258      glEnd();
259   }
260   iframe = iframe + 1;
261
262   glEnable(GL_BLEND);
263   glCallList(iframe % Npat + 1);
264   glBegin(GL_QUAD_STRIP);
265      glTexCoord2f(0.0,  0.0);  glVertex2f(0.0, 0.0);
266      glTexCoord2f(0.0,  tmax); glVertex2f(0.0, 1.0);
267      glTexCoord2f(tmax, 0.0);  glVertex2f(1.0, 0.0);
268      glTexCoord2f(tmax, tmax); glVertex2f(1.0, 1.0);
269   glEnd();
270
271   /*
272   //inject dye
273   glDisable(GL_TEXTURE_2D);
274   glColor4f(1.,0.8,0.,1.);
275   glBegin(GL_QUADS);
276     glVertex2d(0.6, 0.6);
277     glVertex2d(0.6, 0.62);
278     glVertex2d(0.62, 0.62);
279     glVertex2d(0.62, 0.6);
280   glEnd();
281   */
282
283   glDisable(GL_BLEND);
284   glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, NPIX, NPIX, 0);
285   
286   /*
287   //blend magnitude texture
288   glBindTexture(GL_TEXTURE_2D, mag_tex);
289   glEnable(GL_TEXTURE_2D);
290   glEnable(GL_BLEND);
291   glBegin(GL_QUADS);
292      glTexCoord2f(0.0,  0.0);  glVertex2f(0.0, 0.0);
293      glTexCoord2f(0.0,  1.0); glVertex2f(0.0, 1.);
294      glTexCoord2f(1.0, 1.0);  glVertex2f(1., 1.);
295      glTexCoord2f(1.0, 0.0); glVertex2f(1., 0.0);
296   glEnd();
297   */
298}
299
300void Lic::render(){ display(); }
301
302
303void Lic::display(){
304
305  glBindTexture(GL_TEXTURE_2D, color_tex);
306  glEnable(GL_TEXTURE_2D);
307
308  //draw line integral convolution quad
309  glEnable(GL_DEPTH_TEST);
310  glPushMatrix();
311  glScalef(scale.x, scale.y, scale.z);
312
313  glBegin(GL_QUADS);
314    glTexCoord2f(0, 0); glVertex3f(0, 0, offset);
315    glTexCoord2f(1, 0); glVertex3f(1, 0, offset);
316    glTexCoord2f(1, 1); glVertex3f(1, 1, offset);
317    glTexCoord2f(0, 1); glVertex3f(0, 1, offset);
318  glEnd();
319
320  glPopMatrix();
321
322  glDisable(GL_DEPTH_TEST);
323  glDisable(GL_TEXTURE_2D);
324}
325
326
327void Lic::get_velocity(float x, float y, float *px, float *py)
328{
329   float dx, dy, vx, vy, r;
330
331   int xi = x*NMESH;
332   int yi = y*NMESH;
333
334   vx = slice_vector[4*(xi+yi*NMESH)];
335   vy = slice_vector[4*(xi+yi*NMESH)+1];
336   r  = vx*vx + vy*vy;
337   if (r > dmax*dmax) {
338      r  = sqrt(r);
339      vx *= dmax/r;
340      vy *= dmax/r;
341   }
342   *px = x + vx;         
343   *py = y + vy;
344}
345
346void Lic::set_offset(float v)
347{
348  offset = v;
349  get_slice();
350}
Note: See TracBrowser for help on using the repository browser.