Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

halftone_shader_ex.C

Go to the documentation of this file.
00001 /**************************************************************************
00002  * haltone_shader_ex.C
00003  *************************************************************************/
00004 #include <map>
00005 
00006 #include "halftone_shader_ex.H"
00007 #include "gtex/gl_extensions.H"
00008 #include "gtex/util.H"
00009 #include "gtex/glsl_toon.H"             // Temp for testing ref images.
00010 #include "gtex/ref_image.H"
00011 #include "mesh/patch.H"
00012 
00013 #include "mesh/uv_data.H"
00014 #include "mesh/lmesh.H"
00015 #include "mesh/ledge_strip.H"
00016 #include "mesh/vert_attrib.H"
00017 
00018 #include "gl_sphir_tex_coord_gen.H"
00019 
00020 
00021 
00022 class UV_grad 
00023 {
00024 public :
00025    Wvec U_grad;
00026    Wvec V_grad;
00027 };
00028 
00029 class UV_attrib  :  public VertAttrib<UVpt,UVvec>
00030 {
00031 public:
00032    
00033    UV_attrib()
00034    {
00035        auto_UV = new GLSphirTexCoordGen; //automatic generator
00036        auto_UV->setup();
00037    }
00038 
00039    virtual ~UV_attrib()
00040    {
00041       delete auto_UV;
00042    }
00043 
00044    virtual  UVpt get_attrib(CBvert* v, CBface* f)
00045    {
00046      assert(v&&f);
00047 
00048      TexCoordGen* tg = f->patch()->tex_coord_gen();
00049       if (tg)
00050          return tg->uv_from_vert(v,f);
00051       else 
00052        if (UVdata::lookup(f))
00053            return UVdata::get_uv(v,f);
00054        else
00055          return auto_UV->uv_from_vert(v,f); 
00056    }
00057 
00058 protected :
00059    TexCoordGen* auto_UV;
00060 };
00061 
00062 
00063 
00064 //using model's texture coordinates as primary source
00065 //or generate automatic spherical mapping 
00066 
00067 class StripTexCoordsCB2 : public GLStripCB {
00068  public:
00069     StripTexCoordsCB2() 
00070     { 
00071       att_function = new UV_attrib();
00072       dU_loc =0;
00073       dV_loc =0;
00074 
00075     }
00076 
00077     virtual ~StripTexCoordsCB2()
00078     {
00079        delete att_function;
00080     }
00081 
00082    //******** TRI STRIPS ********
00083    virtual void faceCB(CBvert* v, CBface* f) {
00084   
00085       assert(v && f);
00086       
00087      glNormal3dv(f->norm().data());
00088 
00089      if (v->has_color()) 
00090      {
00091          GL_COL(v->color(), alpha*v->alpha());
00092      }
00093       
00094 
00095     //pass texture coordinates to opengl
00096      glTexCoord2dv(att_function->get_attrib(v,f).data());
00097 
00098      send_d(v,f);
00099     
00100    
00101       glVertex3dv(v->loc().data());     // vertex coordinates
00102    }
00103 
00104  
00105 
00106 
00107 //set uniform var location <- comes from the GLSL texture class
00108    void set_dU_loc(GLint loc)
00109    {
00110       dU_loc = loc;
00111    }
00112 
00113    void set_dV_loc(GLint loc)
00114    {
00115       dV_loc = loc;
00116    }
00117 
00118 
00119 //send the texture coord derivatives on its way
00120    void send_dU(Wvec dU)
00121    {
00122       if (dU_loc)
00123       glVertexAttrib3f(dU_loc, GLfloat(dU[0]),GLfloat(dU[1]),GLfloat(dU[2]));
00124    }
00125 
00126    void send_dV(Wvec dV)
00127    {
00128       if (dV_loc)
00129       glVertexAttrib3f(dV_loc, GLfloat(dV[0]),GLfloat(dV[1]),GLfloat(dV[2]));
00130    }
00131 
00132    bool get_valid_grad() { return valid_gradients; }
00133    void set_valid_grad() { valid_gradients = true; }
00134    void inv_valid_grad() { valid_gradients = false; }
00135 
00136 
00137 //compute face gradients and store them inside the map
00138    void compute_face_gradients(Patch* patch)
00139    {
00140       if(valid_gradients) return;
00141 
00142       face_gradient_map.clear();
00143 
00144       Bface_list faces = patch->faces();
00145 
00146       UV_grad gradient;
00147       UVvec derivative;
00148 
00149       for(int i=0; i<faces.num(); i++)
00150       {
00151          derivative = att_function->dFdx(faces[i]);
00152 
00153          gradient.U_grad[0] = derivative[0]; 
00154          gradient.V_grad[0] = derivative[1]; 
00155 
00156          derivative = att_function->dFdy(faces[i]);
00157 
00158          gradient.U_grad[1] = derivative[0]; 
00159          gradient.V_grad[1] = derivative[1]; 
00160 
00161          derivative = att_function->dFdz(faces[i]);
00162 
00163          gradient.U_grad[2] = derivative[0]; 
00164          gradient.V_grad[2] = derivative[1]; 
00165          
00166          face_gradient_map[int(faces[i])]= gradient; //uses the face pointer as a key
00167 
00168       }
00169 
00170       valid_gradients = true;
00171    }
00172 
00173 //computes the texture coord derivative on per vertex basis and sends to GLSL program
00174 
00175    void send_d(CBvert* v, CBface* f)
00176    {
00177    assert(v && f);   
00178       
00179    Bface_list faces = v->get_faces();
00180 
00181    Wvec acc_U(0,0,0);
00182    Wvec acc_V(0,0,0);
00183 
00184    Wvec U_vec,V_vec;
00185 
00186    UVvec derivative;
00187 
00188    Wvec vertex_normal = v->norm();
00189    Wvec base_2 = cross(vertex_normal,Wvec(1.0,0.0,0.0)); //use perpend!!
00190    Wvec base_3 = cross(vertex_normal,base_2);
00191 
00192 
00193    base_2 = base_2.normalized();
00194    base_3 = base_3.normalized();
00195 
00196 
00197       for(int i=0; i<faces.num(); i++)
00198       {
00199          //getting the previously computed face gradients
00200 
00201          UV_grad grad = face_gradient_map[int(faces[i])];
00202          
00203          U_vec = grad.U_grad;
00204          V_vec = grad.V_grad;
00205 
00206 
00207 
00208          //rotate to tangent plane
00209 
00210          double U_magnitude = U_vec.length();
00211          double V_magnitude = V_vec.length();
00212 
00213          U_vec =  Wvec((base_2 * (base_2 * U_vec)) + (base_3 * (base_3 * U_vec)));
00214          V_vec =  Wvec((base_2 * (base_2 * V_vec)) + (base_3 * (base_3 * V_vec)));
00215 
00216          U_vec = U_vec.normalized() * U_magnitude;
00217          V_vec = V_vec.normalized() * V_magnitude;
00218 
00219          acc_U += U_vec;
00220          acc_V += V_vec;
00221 
00222       }
00223 
00224       //just simple average for now
00225       acc_U = (acc_U / double(faces.num()) );
00226       acc_V = (acc_V / double(faces.num()) );
00227 
00228       //cerr << " dV = " << acc_V << endl;
00229 
00230       send_dU(acc_U);
00231       send_dV(acc_V);
00232 
00233    }
00234 
00235 protected :
00236    UV_attrib* att_function;
00237    GLint  dU_loc;
00238    GLint  dV_loc;
00239 
00240    map<int,UV_grad> face_gradient_map;
00241    bool valid_gradients;
00242 
00243 };
00244 
00245 
00246 
00247 /**********************************************************************
00248  * HalftoneShaderEx:
00249  *
00250  *   Doesn't do anything yet.
00251  **********************************************************************/
00252 HalftoneShaderEx::HalftoneShaderEx(Patch* patch) :
00253    GLSLShader(patch, new StripTexCoordsCB2() ),
00254    m_toon_tone_shader(new GLSLToonShader(patch)),
00255    _style_loc(-1),
00256    _style(0)
00257 {
00258    // Specify the texture we'd like to use.
00259    str_ptr tex_name = "nprdata/toon_textures/clear-black.png";
00260    m_toon_tone_shader->set_tex(Config::JOT_ROOT() + tex_name);
00261 
00262    _perlin=0;
00263    _perlin_generator= Perlin::get_instance();
00264    if (!_perlin_generator)
00265       _perlin_generator= new Perlin();
00266 
00267    
00268    ((StripTexCoordsCB2*)cb())->inv_valid_grad();
00269 
00270 }
00271 
00272 
00273 
00274 bool 
00275 HalftoneShaderEx::get_variable_locs()
00276 {
00277 
00278    //get_uniform_loc("lod", _lod_loc);
00279    
00280    get_uniform_loc("tone_map", m_tex_loc);
00281    get_uniform_loc("width", m_width);
00282    get_uniform_loc("height", m_height);
00283    get_uniform_loc("sampler2D_perlin", _perlin_loc);
00284    get_uniform_loc("style", _style_loc);
00285    
00286    get_uniform_loc("P_inverse", _proj_der_loc);
00287 
00288    GLint tmp;
00289 
00290    //query the vertex attribute loacations
00291 
00292    tmp = glGetAttribLocation(program(),"dU_XYZ");
00293    ((StripTexCoordsCB2*)cb())->set_dU_loc(tmp);
00294 
00295    cerr << "dU_loc = " << tmp <<endl;
00296 
00297    tmp = glGetAttribLocation(program(),"dV_XYZ");
00298    ((StripTexCoordsCB2*)cb())->set_dV_loc(tmp);
00299    
00300    cerr << "dV_loc = " << tmp <<endl;
00301 
00302    return true;
00303 }
00304 
00305 bool
00306 HalftoneShaderEx::set_uniform_variables() const
00307 {
00308    assert(_patch);
00309    _patch->update_dynamic_samples();
00310     
00311    // glUniform1f (_lod_loc, float(0));
00312    
00313 
00314    glUniform1i (m_tex_loc, m_texture->get_tex_unit() - GL_TEXTURE0);
00315    glUniform1i (m_width, VIEW::peek()->width());
00316    glUniform1i (m_height, VIEW::peek()->height());
00317    if(_perlin)
00318       glUniform1i(_perlin_loc, _perlin->get_tex_unit() - GL_TEXTURE0);
00319    
00320    glUniform1i(_style_loc, _style);
00321 
00322 
00323    //send the derivative of the transformation matrix
00324    //under construction ... seems to be working now
00325 
00326 
00327    
00328    Wtransf P_matrix =  VIEW::peek()->wpt_to_pix_proj();
00329 
00330    //make sure that the matrix derivative is taken at the correct Z value 
00331 
00332   
00333    //cerr << "Projection Matrix : " << endl << P_matrix << endl;
00334 
00335    //GLSL stroes matrices in column major order
00336    //while jot's mlib stores matrices in row major order
00337    //therefore a transpose is needed
00338 
00339    glUniformMatrix4fv(_proj_der_loc,1,GL_TRUE /* transpose = true */,(const GLfloat*) float16(P_matrix.inverse())/*temp*/);
00340 
00341 
00342    return true;
00343 }
00344 
00345 // This may seem a little odd, but since the texture is in texture
00346 // memory, we need to look it up from the reference image.
00347 void 
00348 HalftoneShaderEx::init_textures()
00349 {
00350    TexMemRefImage * ref_img = TexMemRefImage::lookup(VIEW::peek());
00351    m_texture = ref_img->get_texture();
00352    _perlin = _perlin_generator->create_perlin_texture2();
00353 }
00354 
00355 void
00356 HalftoneShaderEx::activate_textures()
00357 {
00358    activate_texture(m_texture);      // GL_ENABLE_BIT
00359    if(_perlin)
00360       activate_texture(_perlin);
00361 
00362 }
00363 
00364 GTexture_list HalftoneShaderEx::gtextures() const
00365 {
00366    return GTexture_list(m_toon_tone_shader);
00367 }
00368 
00369 void
00370 HalftoneShaderEx::set_gl_state(GLbitfield mask) const
00371 {
00372    GLSLShader::set_gl_state(mask);
00373    // set the color from the VIEW background color:
00374    GL_COL(VIEW::peek()->color(), alpha());    // GL_CURRENT_BIT
00375 }
00376 
00377 // ******** GTexture VIRTUAL METHODS ********
00378 
00379 RefImageClient::ref_img_t 
00380 HalftoneShaderEx::use_ref_image()
00381 {
00382    // Tells the caller that we want to use a TexMemRefImage
00383    return ref_img_t(REF_IMG_TEX_MEM);
00384 }
00385 
00386 int 
00387 HalftoneShaderEx::draw_tex_mem_ref()
00388 {
00389    // Draw the reference image for tone.
00390    return m_toon_tone_shader->draw(VIEW::peek());
00391 }
00392 
00393 int 
00394 HalftoneShaderEx::draw(CVIEWptr &v)
00395 {   
00396    //setup the UV gradients
00397    ((StripTexCoordsCB2*)cb())->compute_face_gradients(patch());
00398    //use the base draw
00399    return GLSLShader::draw(v);
00400 }
00401 
00402 void
00403 HalftoneShaderEx::set_patch(Patch* p)
00404 {
00405    //invalidates the gradient map for new patch 
00406    ((StripTexCoordsCB2*)cb())->inv_valid_grad();
00407    return GLSLShader::set_patch(p);
00408 }
00409 void 
00410 HalftoneShaderEx::changed()
00411 {
00412    ((StripTexCoordsCB2*)cb())->inv_valid_grad();
00413    GLSLShader::changed();
00414 }
00415 
00416 
00417 // End of file halftone_shader_EX.C

Generated on Mon Sep 18 11:39:31 2006 for jot by  doxygen 1.4.4