00001
00002
00003
00004 #include "gtex/gl_extensions.H"
00005 #include "gtex/util.H"
00006 #include "geom/gl_util.H"
00007 #include "mesh/patch.H"
00008 #include "glsl_xtoon.H"
00009
00010 static bool debug = Config::get_var_bool("DEBUG_GLSL_XTOON", false);
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 class XToonStripCB : public GLStripCB {
00021 public:
00022 XToonStripCB() : _blend_type(1) {}
00023
00024 void set_loc(GLint L) { _loc = L; }
00025 void set_blendType(int d) { _blend_type = d; }
00026
00027 virtual void faceCB(CBvert* v, CBface*);
00028
00029
00030 enum normal_t { SMOOTH=0, SPHERIC, ELLIPTIC, CYLINDRIC };
00031
00032 private:
00033
00034 GLint _loc;
00035 int _blend_type;
00036 };
00037
00038 void
00039 XToonStripCB::faceCB(CBvert* v, CBface* f)
00040 {
00041 assert(v && f);
00042 Wvec bNorm;
00043
00044
00045 switch(_blend_type) {
00046 case XToonStripCB::SMOOTH: {
00047
00048 bNorm = v->get_all_faces().n_ring_faces(3).avg_normal();
00049 }
00050 break;
00051 case XToonStripCB::SPHERIC: {
00052 BMESH* mesh = v->mesh();
00053 Wpt c = mesh->get_bb().center();
00054 bNorm = (v->loc()-c).normalized();
00055 }
00056 break;
00057 case XToonStripCB::ELLIPTIC: {
00058 BMESH* mesh = v->mesh();
00059 Wvec c_to_v = v->loc() - mesh->get_bb().center();
00060 Wvec dim = mesh->get_bb().dim();
00061 double a = dim[0]*0.5;
00062 double b = dim[1]*0.5;
00063 double c = dim[2]*0.5;
00064 bNorm = Wvec(c_to_v[0]/a, c_to_v[1]/b, c_to_v[2]/c).normalized();
00065 }
00066 break;
00067 case XToonStripCB::CYLINDRIC: {
00068 BMESH* mesh = v->mesh();
00069 Wpt c = mesh->get_bb().center();
00070 Wvec axis;
00071 Wvec dim = mesh->get_bb().dim();
00072 if (dim[0]>dim[1] && dim[0]>dim[2])
00073 axis = dim.X();
00074 else if (dim[1]>dim[0] && dim[1]>dim[2])
00075 axis = dim.Y();
00076 else
00077 axis = dim.Z();
00078
00079 Wpt v_proj = c + ((v->loc()-c)*axis) * axis;
00080 bNorm = (v->loc()-v_proj).normalized();
00081 }
00082 break;
00083 default:
00084 assert(0);
00085 }
00086
00087
00088 glVertexAttrib3f(_loc, bNorm[0], bNorm[1], bNorm[2]);
00089 glNormal3dv(f->vert_normal(v).data());
00090 glVertex3dv(v->loc().data());
00091 }
00092
00093
00094
00095
00096
00097
00098 GLSLXToonShader::GLSLXToonShader(Patch* p) :
00099 GLSLShader(p, new XToonStripCB),
00100 _layer_name("Shader"),
00101 _use_paper(0),
00102 _travel_paper(0),
00103 _transparent(1),
00104 _annotate(1),
00105 _color(COLOR::white),
00106 _alpha(1.0),
00107 _light_index(-1),
00108 _light_dir(1),
00109 _light_cam(1),
00110 _light_coords(mlib::Wvec(0,0,1)),
00111 _detail_map(1),
00112 _target_length(0.03),
00113 _max_factor(6.968),
00114 _normals_smoothed(false),
00115 _normals_elliptic(false),
00116 _normals_spheric(false),
00117 _normals_cylindric(false),
00118 _smooth_factor(0.5),
00119 _update_curvatures(false),
00120 _frame_rate(0.0),
00121 _nb_stat_frames(0),
00122 _invert_detail(false),
00123 _update_uniforms(true),
00124 _tex_is_good(false),
00125 _smoothNormal(1),
00126 _smoothDetail(1)
00127 {
00128 _tex_name = "nprdata/toon_textures/contrast2_512_2d.png";
00129 set_tex(_tex_name);
00130 }
00131
00132 void
00133 GLSLXToonShader::set_normals(int i)
00134 {
00135 _smoothNormal = i;
00136
00137 if(i==0)
00138 _normals_smoothed = true;
00139 else if(i==1)
00140 _normals_spheric = true;
00141 else if(i==2)
00142 _normals_elliptic = true;
00143 else if(i==3)
00144 _normals_cylindric = true;
00145
00146 XToonStripCB* cb = dynamic_cast<XToonStripCB*>(_cb);
00147 assert(cb);
00148 cb->set_blendType(_smoothNormal);
00149
00150 Patch* p = dynamic_cast<Patch*>(_patch);
00151 p->changed();
00152 }
00153
00154 void
00155 GLSLXToonShader::set_tex(Cstr_ptr& filename)
00156 {
00157
00158 if (_tex) {
00159 _tex->set_texture(Config::JOT_ROOT() + filename);
00160 } else {
00161 _tex = new TEXTUREgl(Config::JOT_ROOT()+ filename);
00162 assert(_tex);
00163 _tex->set_wrap_s(GL_CLAMP_TO_EDGE);
00164 _tex->set_wrap_t(GL_CLAMP_TO_EDGE);
00165 }
00166 }
00167
00168 void
00169 GLSLXToonShader::set_gl_state(GLbitfield mask) const
00170 {
00171 GLSLShader::set_gl_state(mask | GL_COLOR_BUFFER_BIT);
00172 glEnable(GL_BLEND);
00173 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00174 }
00175
00176 void
00177 GLSLXToonShader::init_textures()
00178 {
00179
00180 if (!load_texture(_tex))
00181 return;
00182 }
00183
00184 void
00185 GLSLXToonShader::activate_textures()
00186 {
00187 activate_texture(_tex);
00188 }
00189
00190 bool
00191 GLSLXToonShader::get_variable_locs()
00192 {
00193
00194 XToonStripCB* cb = dynamic_cast<XToonStripCB*>(_cb);
00195 GLint normLoc = glGetAttribLocation(_program,"blendNorm");
00196 cb->set_loc(normLoc);
00197 cb->set_blendType(_smoothNormal);
00198
00199 get_uniform_loc("toonTex", _tex_loc);
00200 get_uniform_loc("detailMap",_Dmap_loc);
00201 get_uniform_loc("smoothDetail",_Sdtl_loc);
00202 get_uniform_loc("smoothFactor",_Sfct_loc);
00203 get_uniform_loc("targetLength", _trgt_loc);
00204 get_uniform_loc("maxFactor", _Mfct_loc);
00205 get_uniform_loc("focusPoint", _Fpnt_loc);
00206 get_uniform_loc("lightIndex",_Lidx_loc);
00207 get_uniform_loc("lightDir",_Ldir_loc);
00208 get_uniform_loc("lightCam",_Lcam_loc);
00209 get_uniform_loc("lightCoords", _Lcoord_loc);
00210
00211 return true;
00212 }
00213
00214 bool
00215 GLSLXToonShader::set_uniform_variables() const
00216 {
00217
00218
00219 glUniform1i(_tex_loc, _tex->get_tex_unit() - GL_TEXTURE0);
00220
00221
00222
00223
00224 glUniform1f(_Dmap_loc,_detail_map);
00225
00226 glUniform1f(_Sdtl_loc,_smoothDetail);
00227 glUniform1f(_Sfct_loc,_smooth_factor);
00228
00229 glUniform1f(_trgt_loc,_target_length);
00230 glUniform1f(_Mfct_loc,_max_factor);
00231
00232
00233 Wpt focus = VIEW::peek_cam()->data()->center();
00234 glUniform4fv(_Fpnt_loc, 1, float4(focus));
00235
00236
00237
00238
00239 glUniform1f(_Lidx_loc,_light_index);
00240
00241 glUniform1f(_Ldir_loc,_light_dir);
00242
00243 glUniform1f(_Lcam_loc,_light_cam);
00244
00245 glUniform3fv(_Lcoord_loc, 1, float3(_light_coords));
00246 return true;
00247 }
00248
00249