/* * ---------------------------------------------------------------------- * NvLIC.h: line integral convolution class * * ====================================================================== * AUTHOR: Insoo Woo * Purdue Rendering and Perceptualization Lab (PURPL) * * Copyright (c) 2004-2006 Purdue Research Foundation * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ====================================================================== */ #include #include #include #include #include "NvLIC.h" #include #include "global.h" NvLIC::NvLIC(int _size, int _width, int _height, int _axis, const Vector3& _offset, CGcontext _context) : Renderable(Vector3(0.0f,0.0f,0.0f)), disListID(0), width(_width), height(_height), size(_size), scale(1.0f, 1.0f, 1.0f), offset(_offset), iframe(0), Npat(64), alpha((int) 0.12*255), tmax(NPIX/(SCALE*NPN)), dmax(SCALE/NPIX), max(1.0f), m_g_context(_context), _vectorFieldId(0), _activate(false) { axis = _axis; slice_vector = new float[size*size*4]; memset(slice_vector, 0, sizeof(float) * size * size * 4); origin.set(0, 0, 0); //initialize the pattern texture glGenTextures(1, &pattern_tex); glBindTexture(GL_TEXTURE_2D, pattern_tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); //initialize frame buffer objects //render buffer for projecting 3D velocity onto a 2D plane glGenFramebuffersEXT(1, &vel_fbo); glGenTextures(1, &slice_vector_tex); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vel_fbo); glBindTexture(GL_TEXTURE_RECTANGLE_NV, slice_vector_tex); glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // ADD INSOO glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGBA32_NV, size, size, 0, GL_RGBA, GL_FLOAT, NULL); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, slice_vector_tex, 0); //render buffer for the convolution glGenFramebuffersEXT(1, &fbo); glGenTextures(1, &color_tex); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); //initialize color texture for lic glBindTexture(GL_TEXTURE_2D, color_tex); // INSOO //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height, 0, GL_RGB, GL_INT, NULL); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, color_tex, 0); // Check framebuffer completeness at the end of initialization. CHECK_FRAMEBUFFER_STATUS(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); m_render_vel_fprog = LoadCgSourceProgram(m_g_context, "render_vel.cg", CG_PROFILE_FP30, "main"); m_vel_tex_param_render_vel = cgGetNamedParameter(m_render_vel_fprog, "vel_tex"); m_plane_normal_param_render_vel = cgGetNamedParameter(m_render_vel_fprog, "plane_normal"); m_max_param = cgGetNamedParameter(m_render_vel_fprog, "vmax"); make_patterns(); } NvLIC::~NvLIC() { glDeleteTextures(1, &pattern_tex); glDeleteTextures(1, &mag_tex); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vel_fbo); glDeleteTextures(1, &slice_vector_tex); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); glDeleteTextures(1, &color_tex); GLuint buffers[2] = {vel_fbo, fbo}; glDeleteFramebuffersEXT(2, buffers); glDeleteLists(disListID, Npat); /* TBD.. cgDestroyParameter(m_vel_tex_param_render_vel); cgDestroyParameter(m_plane_normal_param_render_vel); cgDestroyParameter(m_max_param); */ cgDestroyProgram(m_render_vel_fprog); delete [] slice_vector; } void NvLIC::make_patterns() { TRACE("begin make_patterns\n"); if (disListID > 0) { glDeleteLists(disListID, Npat); } disListID = glGenLists(Npat); TRACE("DisplayList : %d\n", disListID); int lut[256]; int phase[NPN][NPN]; GLubyte pat[NPN][NPN][4]; int i, j, k, t; for (i = 0; i < 256; i++) { lut[i] = i < 127 ? 0 : 255; } for (i = 0; i < NPN; i++) { for (j = 0; j < NPN; j++) { phase[i][j] = rand() >> 8; } } for (k = 0; k < Npat; k++) { t = (k << 8) / Npat; for (i = 0; i < NPN; i++) { for (j = 0; j < NPN; j++) { pat[i][j][0] = pat[i][j][1] = pat[i][j][2] = lut[(t + phase[i][j]) % 255]; pat[i][j][3] = alpha; } } glNewList(disListID + k, GL_COMPILE); glBindTexture(GL_TEXTURE_2D, pattern_tex); glTexImage2D(GL_TEXTURE_2D, 0, 4, NPN, NPN, 0, GL_RGBA, GL_UNSIGNED_BYTE, pat); glEndList(); } glBindTexture(GL_TEXTURE_2D, pattern_tex); glTexImage2D(GL_TEXTURE_2D, 0, 4, NPN, NPN, 0, GL_RGBA, GL_UNSIGNED_BYTE, pat); TRACE("finish make_patterns\n"); } void NvLIC::make_magnitudes() { GLubyte mag[NMESH][NMESH][4]; //read vector filed for(int i=0; imax = max; make_patterns(); get_slice(); } void NvLIC::get_velocity(float x, float y, float *px, float *py) { float vx, vy, r; int xi = (int) (x*size); int yi = (int) (y*size); //TRACE("(xi yi) = (%d %d), ", xi, yi); vx = slice_vector[4 * (xi+yi*size)]; vy = slice_vector[4 * (xi+yi*size)+1]; r = vx*vx + vy*vy; //TRACE("(vx vx) = (%f %f), r=%f, ", vx, vy, r); if (r > (dmax*dmax)) { r = sqrt(r); vx *= dmax/r; vy *= dmax/r; } *px = x + vx; *py = y + vy; //TRACE("vel %f %f -> %f %f, (dmax = %f)\n", x, y, *px, *py, dmax); } void NvLIC::set_offset(float v) { switch (axis) { case 0 : offset.x = v; break; case 1 : offset.y = v; break; case 2 : offset.z = v; break; } get_slice(); } void NvLIC::set_axis(int axis) { this->axis = axis; } void NvLIC::reset() { make_patterns(); }