source: trunk/gui/vizservers/nanovis/Lic.cpp @ 404

Last change on this file since 404 was 404, checked in by qiaow, 18 years ago

Added Camera class to hide OpenGL viewing setup.

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