00001
00002
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"
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;
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
00065
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
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
00096 glTexCoord2dv(att_function->get_attrib(v,f).data());
00097
00098 send_d(v,f);
00099
00100
00101 glVertex3dv(v->loc().data());
00102 }
00103
00104
00105
00106
00107
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
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
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;
00167
00168 }
00169
00170 valid_gradients = true;
00171 }
00172
00173
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));
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
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
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
00225 acc_U = (acc_U / double(faces.num()) );
00226 acc_V = (acc_V / double(faces.num()) );
00227
00228
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
00249
00250
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
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
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
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
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
00324
00325
00326
00327
00328 Wtransf P_matrix = VIEW::peek()->wpt_to_pix_proj();
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 glUniformMatrix4fv(_proj_der_loc,1,GL_TRUE ,(const GLfloat*) float16(P_matrix.inverse()));
00340
00341
00342 return true;
00343 }
00344
00345
00346
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);
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
00374 GL_COL(VIEW::peek()->color(), alpha());
00375 }
00376
00377
00378
00379 RefImageClient::ref_img_t
00380 HalftoneShaderEx::use_ref_image()
00381 {
00382
00383 return ref_img_t(REF_IMG_TEX_MEM);
00384 }
00385
00386 int
00387 HalftoneShaderEx::draw_tex_mem_ref()
00388 {
00389
00390 return m_toon_tone_shader->draw(VIEW::peek());
00391 }
00392
00393 int
00394 HalftoneShaderEx::draw(CVIEWptr &v)
00395 {
00396
00397 ((StripTexCoordsCB2*)cb())->compute_face_gradients(patch());
00398
00399 return GLSLShader::draw(v);
00400 }
00401
00402 void
00403 HalftoneShaderEx::set_patch(Patch* p)
00404 {
00405
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