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

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

nanovis/heightmap update

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  fprintf(stderr, "initialize lic ...\n");
104}
105
106Lic::~Lic(){
107  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vel_fbo);
108  glDeleteTextures(1, &slice_vector_tex);
109
110  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
111  glDeleteTextures(1, &color_tex);
112
113  NVISid buffers[2] = {vel_fbo, fbo};
114  glDeleteFramebuffersEXT(2, buffers);
115
116  delete slice_vector;
117}
118
119void Lic::make_patterns()
120{
121   int lut[256];
122   int phase[NPN][NPN];
123   GLubyte pat[NPN][NPN][4];
124   int i, j, k, t;
125   
126   for (i = 0; i < 256; i++) lut[i] = i < 127 ? 0 : 255;
127   for (i = 0; i < NPN; i++)
128   for (j = 0; j < NPN; j++) phase[i][j] = rand() % 256;
129
130   for (k = 0; k < Npat; k++) {
131     t = k*256/Npat;
132     for (i = 0; i < NPN; i++)
133     for (j = 0; j < NPN; j++) {
134       pat[i][j][0] =
135       pat[i][j][1] =
136       pat[i][j][2] = lut[(t + phase[i][j]) % 255];
137       pat[i][j][3] = alpha;
138     }
139
140     glNewList(k + 1, GL_COMPILE);
141     glBindTexture(GL_TEXTURE_2D, pattern_tex);
142     glTexImage2D(GL_TEXTURE_2D, 0, 4, NPN, NPN, 0,
143                     GL_RGBA, GL_UNSIGNED_BYTE, pat);
144     glEndList();
145   }
146}
147
148
149void Lic::make_magnitudes()
150{
151
152  GLubyte mag[NMESH][NMESH][4];
153
154  //read vector filed
155  for(int i=0; i<NMESH; i++){
156    for(int j=0; j<NMESH; j++){
157
158      float x=DM*i;
159      float y=DM*j;
160
161      float magnitude = sqrt(x*x+y*y)/1.414;
162     
163      //from green to red
164      GLubyte r = floor(magnitude*255);
165      GLubyte g = 0;
166      GLubyte b = 255 - r;
167      GLubyte a = 122;
168
169      mag[i][j][0] = r;
170      mag[i][j][1] = g;
171      mag[i][j][2] = b;
172      mag[i][j][3] = a;
173    }
174  }
175
176  glGenTextures(1, &mag_tex);
177  glBindTexture(GL_TEXTURE_2D, mag_tex);
178  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
179  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
180  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
181  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
182  //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
183  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, NMESH, NMESH, 0, GL_RGBA, GL_UNSIGNED_BYTE, mag);
184
185}
186
187//project 3D vectors to a 2D slice for line integral convolution
188void Lic::get_slice(){
189  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vel_fbo);
190  glBindTexture(GL_TEXTURE_RECTANGLE_NV, slice_vector_tex);
191
192  glClear(GL_COLOR_BUFFER_BIT);
193
194  glViewport(0, 0, NMESH, NMESH);
195  glMatrixMode(GL_PROJECTION);
196  glLoadIdentity();
197  gluOrtho2D(0, NMESH, 0, NMESH);
198  glMatrixMode(GL_MODELVIEW);
199  glLoadIdentity();
200
201  cgGLBindProgram(m_render_vel_fprog);
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.