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

dots_ex.C

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

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