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

Last change on this file since 401 was 401, checked in by qiaow, 19 years ago

Added Renderable class, the superclass of every class that can be drawn.

File size: 9.4 KB
RevLine 
[396]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
[397]17#include <stdlib.h>
18#include <math.h>
19#include <assert.h>
[396]20
21#include "Lic.h"
22
[397]23Lic::Lic(int _size, int _width, int _height, float _offset,
24                CGcontext _context, NVISid _vector_field,
25                float scalex, float scaley, float scalez):
[401]26        Renderable(Vector3(0.,0.,0.)),
[396]27        size(_size),
[397]28        offset(_offset),
29        m_g_context(_context),
[401]30        width(_width),
31        height(_height),
[397]32        iframe(0),
33        Npat(64),
34        alpha(0.12*255),
35        tmax(NPIX/(SCALE*NPN)),
36        dmax(SCALE/NPIX)
[396]37{
[397]38  scale = Vector3(scalex, scaley, scalez);
39  slice_vector = new float[NMESH*NMESH*4];
[396]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
[397]55
56  //render buffer for projecting 3D velocity onto a 2D plane
[396]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
[397]71  //render buffer for the convolution
[396]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);
[401]81  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height, 0,
[396]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
[397]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");
[396]100}
101
[397]102Lic::~Lic(){
103  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vel_fbo);
104  glDeleteTextures(1, &slice_vector_tex);
[396]105
[397]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()
[396]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
[397]145void Lic::make_magnitudes()
[396]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
[397]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);
[396]187
[397]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
[396]223//line integral convolution
224void Lic::convolve(){
[397]225
[396]226   int   i, j;
227   float x1, x2, y, px, py;
228
[397]229   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
230
[396]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);
[397]247          get_velocity(x1, y, &px, &py);
[396]248          glVertex2f(px, py);
249
250          glTexCoord2f(x2, y);
[397]251          get_velocity(x2, y, &px, &py);
[396]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);
[397]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   */
[396]294}
295
[401]296void Lic::render(){ display(); }
297
298
[397]299void Lic::display(){
[396]300
[397]301  glBindTexture(GL_TEXTURE_2D, color_tex);
302  glEnable(GL_TEXTURE_2D);
[396]303
[397]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);
[396]320}
321
[397]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.