00001
00002
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
00024 class UV_grad
00025 {
00026 public :
00027 Wvec U_grad;
00028 Wvec V_grad;
00029 };
00030
00031
00032 class UV_attrib : public VertAttrib<UVpt,UVvec>
00033 {
00034 public:
00035
00036 UV_attrib()
00037 {
00038 auto_UV = new GLSphirTexCoordGen;
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
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
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
00099 glTexCoord2dv(att_function->get_attrib(v,f).data());
00100
00101 send_d(v,f);
00102
00103
00104 glVertex3dv(v->loc().data());
00105 }
00106
00107
00108
00109
00110
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
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;
00168
00169 }
00170
00171 valid_gradients = true;
00172 }
00173
00174
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));
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
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 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
00223 acc_U = (acc_U / double(faces.num()) );
00224 acc_V = (acc_V / double(faces.num()) );
00225
00226
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
00260
00261
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
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
00312 get_uniform_loc("P_inverse", _proj_der_loc);
00313
00314
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
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
00351
00352
00353
00354
00355
00356
00357
00358
00359 glUniformMatrix4fv(_proj_der_loc,1,GL_TRUE ,(const GLfloat*) float16(P_matrix.inverse()));
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
00378 GL_COL(VIEW::peek()->color(), alpha());
00379 }
00380
00381 RefImageClient::ref_img_t
00382 DotsShader_EX::use_ref_image()
00383 {
00384
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
00397 return _tone_shader->draw(VIEW::peek());
00398 }
00399
00400
00401 void
00402 DotsShader_EX::set_patch(Patch* p)
00403 {
00404
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