00001
00002
00003
00004
00005
00006
00007
00008 #include <cassert>
00009
00010 using namespace std;
00011
00012 #include "gtex/gl_extensions.H"
00013 #include <GL/glu.h>
00014
00015 #include "gtex/rendering_mode.H"
00016 #include "gtex/curvature_texture.H"
00017
00018 #include "mlib/points.H"
00019
00020 using namespace mlib;
00021
00022
00023
00024
00025
00026
00027 static void make_2D_texture(GLuint texture_name, int texture_size, int line_width,
00028 bool just_line);
00029
00030 static GLuint load_ARB_program(const char *header, GLenum target,
00031 const char *program_string);
00032
00033
00034
00035 const char *CURVATURE_VERTEX_PROGRAM_STR =
00036 "\
00037 !!ARBvp1.0\n\
00038 \n\
00039 ####################################################################\n\
00040 ### Real-time Silhouettes and Suggestive Contours\n\
00041 ### Vertex program for computing view dependent curvature values\n\
00042 ####################################################################\n\
00043 \n\
00044 ## Inputs: ipos : Vertex position\n\
00045 ## ifpd : First principal direction and curvature (k1 in w component)\n\
00046 ## ispd : Second principal direction and curvature (k2 in w component)\n\
00047 ## ider : Derivative of curvature (unique dcurv tensor values)\n\
00048 \n\
00049 ATTRIB ipos = vertex.position;\n\
00050 ATTRIB ifpd = vertex.attrib[6];\n\
00051 ATTRIB ispd = vertex.attrib[7];\n\
00052 ATTRIB ider = vertex.attrib[15];\n\
00053 \n\
00054 ## Output: opos = Output position\n\
00055 ## tc0 = {radial curvature, derivative of radial curvature, n dot v}\n\
00056 \n\
00057 OUTPUT opos = result.position;\n\
00058 OUTPUT ocol = result.color; # Not used\n\
00059 OUTPUT tc0 = result.texcoord[0]; # {rcurv, drcurv, ndotv}\n\
00060 OUTPUT tc1 = result.texcoord[1];\n\
00061 OUTPUT tc2 = result.texcoord[2];\n\
00062 OUTPUT tc3 = result.texcoord[3];\n\
00063 OUTPUT tc4 = result.texcoord[4];\n\
00064 \n\
00065 PARAM MVP[4] = { state.matrix.mvp }; # Modelview*projection matrix\n\
00066 PARAM MV[4] = { state.matrix.modelview }; # Modelview matrix\n\
00067 PARAM MVIT[4] = { state.matrix.modelview.invtrans }; # Modelview^-1 matrix (used to get eye pos)\n\
00068 \n\
00069 PARAM PARAM_DRAW_ENABLE = program.env[0];\n\
00070 PARAM PARAM_FEATURE = program.env[1];\n\
00071 PARAM EYE_POS = program.env[2];\n\
00072 \n\
00073 # Vertex normal vector:\n\
00074 TEMP normvec;\n\
00075 \n\
00076 # Eye vector:\n\
00077 TEMP eyevec;\n\
00078 \n\
00079 # Computed pricipal direction values:\n\
00080 # *pdvals.x = cos(angle between principal direction and eye vector)\n\
00081 # *pdvals.y = (*pdvals.x)^2\n\
00082 # *pdvals.z = principal curvature times *pdvals.y\n\
00083 # *pdvals.w = not used\n\
00084 TEMP fpdvals, spdvals;\n\
00085 \n\
00086 # Final scalar field values:\n\
00087 # finalsf.x = radial curvature\n\
00088 # finalsf.y = derivative of radial curvature\n\
00089 # finalsf.z = n dot v\n\
00090 # finalsf.w = not used\n\
00091 TEMP finalsf;\n\
00092 \n\
00093 # Derivatives of principal curvatures:\n\
00094 # dks.x = derivative of k1\n\
00095 " "\
00096 # dks.y = derivative of k2\n\
00097 # dks.z = not used\n\
00098 # dks.w = not used\n\
00099 TEMP dks;\n\
00100 \n\
00101 # Temporary register (used during various computations)\n\
00102 TEMP temp, temp2;\n\
00103 \n\
00104 #############################################\n\
00105 ## Transform vertex position\n\
00106 #############################################\n\
00107 \n\
00108 DP4 opos.x, MVP[0], ipos;\n\
00109 DP4 opos.y, MVP[1], ipos;\n\
00110 DP4 opos.z, MVP[2], ipos;\n\
00111 DP4 opos.w, MVP[3], ipos;\n\
00112 \n\
00113 #############################################\n\
00114 ## Compute view dependent curvature values\n\
00115 #############################################\n\
00116 \n\
00117 # Compute normal vector (XXX - Maybe replace with GL normal attribute)\n\
00118 XPD normvec.xyz, ifpd, ispd;\n\
00119 \n\
00120 # Compute eye vector, normalize\n\
00121 SUB eyevec, EYE_POS, ipos;\n\
00122 DP3 eyevec.w, eyevec, eyevec;\n\
00123 RSQ eyevec.w, eyevec.w;\n\
00124 MUL eyevec.xyz, eyevec.w, eyevec;\n\
00125 \n\
00126 # Compute n dot v\n\
00127 DP3 finalsf.z, normvec, eyevec;\n\
00128 \n\
00129 # Assuming that ifpd and eyevec are normalized so that dot product is equal to\n\
00130 # the angle between them:\n\
00131 DP3 fpdvals.x, ifpd, eyevec; # fpdvals.x = u = cos\n\
00132 MUL fpdvals.y, fpdvals.x, fpdvals.x; # fpdvals.y = u^2 = cos^2\n\
00133 MUL fpdvals.z, fpdvals.y, ifpd.w; # fpdvals.z = k1 * u^2\n\
00134 \n\
00135 # Assuming that ispd and eyevec are normalized so that dot product is equal to\n\
00136 # the angle between them:\n\
00137 DP3 spdvals.x, ispd, eyevec; # spdvals.x = v = cos\n\
00138 MUL spdvals.y, spdvals.x, spdvals.x; # spdvals.y = v^2 = cos^2\n\
00139 MUL spdvals.z, spdvals.y, ispd.w; # spdvals.z = k2 * v^2\n\
00140 \n\
00141 # Compute radial curvature:\n\
00142 ADD finalsf.x, fpdvals.z, spdvals.z; # k1 * u^2 + k2 * v^2\n\
00143 \n\
00144 # Compute derivative of radial curvature:\n\
00145 \n\
00146 # First, calculate derivative of normal curvature:\n\
00147 PARAM three= {3.0, 0.0, 0.0, 0.0};\n\
00148 MUL temp.x, fpdvals.x, ider.x; # u*P\n\
00149 MUL temp.y, spdvals.x, ider.y; # v*Q\n\
00150 MUL temp.y, three.x, temp.y; # 3*v*Q\n\
00151 ADD temp.x, temp.x, temp.y; # u*P + 3*v*Q\n\
00152 MUL temp.x, temp.x, fpdvals.y; # u^3*P + 3*u^2*v*Q\n\
00153 \n\
00154 MUL temp.y, fpdvals.x, ider.z; # u*S\n\
00155 MUL temp.y, three.x, temp.y; # 3*u*S\n\
00156 MUL temp.z, spdvals.x, ider.w; # v*T\n\
00157 " "\
00158 ADD temp.y, temp.y, temp.z; # 3*u*S + v*T\n\
00159 MUL temp.y, temp.y, spdvals.y; # 3*u*v^2*S + v^3*T\n\
00160 \n\
00161 ADD temp.x, temp.x, temp.y; # u^3*P + 3*u^2*v*Q + 3*u*v^2*S + v^3*T\n\
00162 \n\
00163 # Then add offset to deriv of normal curvature:\n\
00164 # float csc2theta = 1.0f / (u2 + v2);\n\
00165 # sctest_num[i] *= csc2theta;\n\
00166 # float tr = (themesh->curv2[i] - themesh->curv1[i]) *\n\
00167 # u * v * csc2theta;\n\
00168 # sctest_num[i] -= 2.0f * ndotv[i] * sqr(tr);\n\
00169 \n\
00170 ADD temp.y, fpdvals.y, spdvals.y; # u^2 + v^2\n\
00171 RCP temp.y, temp.y; # 1 / sin^2(theta)\n\
00172 MUL temp.x, temp.x, temp.y; # rescale deriv\n\
00173 \n\
00174 # Calculate torsion (tr):\n\
00175 SUB temp.z, ispd.w, ifpd.w; # (k2 - k1)\n\
00176 MUL temp.z, temp.z, fpdvals.x; # (k2 - k1)*u\n\
00177 MUL temp.z, temp.z, spdvals.x; # (k2 - k1)*u*v\n\
00178 MUL temp.y, temp.y, temp.z; # tr = (k2 - k1)*u*v / sin^2(theta)\n\
00179 MUL temp.y, temp.y, temp.y; # tr^2\n\
00180 PARAM two = {2,0,0,0};\n\
00181 MUL temp.y, two.x, temp.y; # 2 * tr^2\n\
00182 MUL temp.y, temp.y, finalsf.z; # 2 * tr^2 * (n dot v)\n\
00183 SUB temp.x, temp.x, temp.y; # whew!\n\
00184 \n\
00185 # #extra stuff necessary for texture\n\
00186 # # if (extra_sin2theta)\n\
00187 # # sctest_num[i] *= u2 + v2;\n\
00188 # ADD temp.y, fpdvals.y, spdvals.y; # u2 + v2\n\
00189 # MUL temp.x, temp.x, temp.y;\n\
00190 \n\
00191 # # sctest_den[i] = ndotv[i];\n\
00192 # # sctest_num[i] -= scthresh * sctest_den[i];\n\
00193 # PARAM thresh = {3.5,0,0,0};\n\
00194 MUL temp.y, PARAM_FEATURE.x, finalsf.z;\n\
00195 RCP temp.z, PARAM_FEATURE.w;\n\
00196 MUL temp.y, temp.y, temp.z;\n\
00197 SUB temp.x, temp.x, temp.y;\n\
00198 \n\
00199 # #sctest_num[i] = sctest_num[i] * feature_size2 / sctest_den[i];\n\
00200 RCP temp.y, finalsf.z;\n\
00201 MUL temp.x, temp.x, temp.y;\n\
00202 MUL temp.x, temp.x, PARAM_FEATURE.w;\n\
00203 \n\
00204 MOV finalsf.y, temp.x;\n\
00205 \n\
00206 # Scale scalar fields by feature size\n\
00207 MUL finalsf.x, finalsf.x, PARAM_FEATURE.z;\n\
00208 \n\
00209 #TODO: this constant is different than RTSC- FIGURE OUT WHAT IT SHOULD BE\n\
00210 PARAM fs={32,0,0,0};\n\
00211 MUL finalsf.y, finalsf.y, fs.x;\n\
00212 \n\
00213 # If disabling contours or suggestive contours is toggled, set the\n\
00214 # scalar field values to some appropriate constants\n\
00215 " "\
00216 MAD finalsf.z, finalsf.z, PARAM_DRAW_ENABLE.x, PARAM_DRAW_ENABLE.y;\n\
00217 MAD finalsf.x, finalsf.x, PARAM_DRAW_ENABLE.z, PARAM_DRAW_ENABLE.w;\n\
00218 \n\
00219 # Project eyevec onto the tangent plane and normalize (w):\n\
00220 MUL temp, normvec, finalsf.zzzz;\n\
00221 SUB temp, eyevec, temp;\n\
00222 DP3 temp.w, temp, temp;\n\
00223 RSQ temp.w, temp.w;\n\
00224 MUL temp.xyz, temp.w, temp;\n\
00225 \n\
00226 # Compute dot products with principal directions\n\
00227 DP3 temp2.x, temp, ifpd; # w dot e1\n\
00228 DP3 temp2.y, temp, ispd; # w dot e2\n\
00229 \n\
00230 # Compute derivatives of principal curvatures in w direction:\n\
00231 MUL dks.x, temp2.x, ider.x; # (w dot e1) * D_e1(k1)\n\
00232 MAD dks.x, temp2.y, ider.y, dks.x; # (w dot e1) * D_e1(k1) + (w dot e2) * D_e2(k1)\n\
00233 MUL dks.y, temp2.x, ider.z; # (w dot e1) * D_e1(k1)\n\
00234 MAD dks.y, temp2.y, ider.w, dks.y; # (w dot e1) * D_e1(k1) + (w dot e2) * D_e2(k1)\n\
00235 \n\
00236 MOV tc0, finalsf;\n\
00237 MOV tc1, ifpd;\n\
00238 MOV tc2, ispd;\n\
00239 MOV tc3, ider;\n\
00240 SWZ tc4, dks, x, y, 0, 0;\n\
00241 \n\
00242 END\n\
00243 ";
00244
00245
00246
00247 const char *CURVATURE_FRAGMENT_PROGRAM_STR =
00248 "\
00249 !!ARBfp1.0 \n\
00250 \n\
00251 ATTRIB tex0 = fragment.texcoord[0];\n\
00252 ATTRIB tex1 = fragment.texcoord[1];\n\
00253 ATTRIB tex2 = fragment.texcoord[2];\n\
00254 ATTRIB tex3 = fragment.texcoord[3];\n\
00255 ATTRIB tex4 = fragment.texcoord[4];\n\
00256 ATTRIB col0 = fragment.color; \n\
00257 ATTRIB ipos = fragment.position;\n\
00258 \n\
00259 OUTPUT out = result.color;\n\
00260 \n\
00261 PARAM PARAM_DRAW_CURVATURE = program.env[0];\n\
00262 PARAM PARAM_RADIAL_FILTER = program.env[1];\n\
00263 PARAM PARAM_MEAN_FILTER = program.env[2];\n\
00264 PARAM PARAM_GAUSSIAN_FILTER = program.env[3];\n\
00265 \n\
00266 TEMP temp, temp2, temp3; #temporary\n\
00267 \n\
00268 TEMP k_r, H, K; # Radial, Gaussian and mean curvature\n\
00269 TEMP dH, dK; # Derivatives of Gaussian and mean curvatures\n\
00270 \n\
00271 TEMP k_r_color, H_color, K_color, final_color;\n\
00272 \n\
00273 PARAM one = {0.0,1.0,-1,1};\n\
00274 PARAM half = {0.5, 1.0, 1.0, 1.0};\n\
00275 PARAM big = {1.0, 0, 0, 0};\n\
00276 \n\
00277 PARAM red = {0.0, 1.0, 1.0, 1.0};\n\
00278 PARAM green = {1.0, 0.0, 1.0, 1.0};\n\
00279 PARAM blue = {1.0, 1.0, 0.0, 1.0};\n\
00280 \n\
00281 # Derivative of mean curvature:\n\
00282 ADD dH.x, tex4.x, tex4.y;\n\
00283 MUL dH.x, dH.x, 0.5.x;\n\
00284 \n\
00285 # Derivative of Gaussian curvature:\n\
00286 MUL dK.x, tex1.w, tex4.y; # k1 * D_w(k2)\n\
00287 MAD dK.x, tex2.w, tex4.x, dK.x; # k1 * D_w(k2) + k2 * D_w(k1)\n\
00288 \n\
00289 # Radial curvature (k_r):\n\
00290 SWZ k_r, tex0, x, 1, 0, 0;\n\
00291 ADD_SAT k_r, k_r, {0.5, 0.5, 0.0, 0.0};\n\
00292 TEX k_r_color, k_r, texture[2], 2D;\n\
00293 #CMP temp.x, tex0.y, 0.25.x, 1.0.x;\n\
00294 #MUL k_r_color, k_r_color, temp.xxxx;\n\
00295 MUL k_r_color, k_r_color, red;\n\
00296 CMP temp.x, PARAM_RADIAL_FILTER.x, tex0.y, 1.0.x;\n\
00297 CMP temp.y, PARAM_RADIAL_FILTER.y, dH.x, 1.0.x;\n\
00298 CMP temp.z, PARAM_RADIAL_FILTER.z, dK.x, 1.0.x;\n\
00299 MUL temp.x, temp.x, temp.y;\n\
00300 MUL temp.x, temp.x, temp.z;\n\
00301 CMP temp.x, temp.x, PARAM_RADIAL_FILTER.w, 1.0.x;\n\
00302 MUL k_r_color, k_r_color, temp.xxxx;\n\
00303 MUL k_r_color, k_r_color, PARAM_DRAW_CURVATURE.xxxx;\n\
00304 #SLT temp.x, tex0.z, 0.99.x;\n\
00305 #MUL k_r_color, k_r_color, temp.xxxx;\n\
00306 \n\
00307 # Mean curvature (H):\n\
00308 ADD H.x, tex1.w, tex2.w;\n\
00309 MUL H.x, H.x, 0.5.x;\n\
00310 ADD_SAT H.x, H.x, 0.5.x;\n\
00311 MOV H.y, 1.0.x;\n\
00312 TEX H_color, H, texture[0], 2D;\n\
00313 MUL H_color, H_color, green;\n\
00314 CMP temp.x, PARAM_MEAN_FILTER.x, tex0.y, 1.0.x;\n\
00315 " "\
00316 CMP temp.y, PARAM_MEAN_FILTER.y, dH.x, 1.0.x;\n\
00317 CMP temp.z, PARAM_MEAN_FILTER.z, dK.x, 1.0.x;\n\
00318 MUL temp.x, temp.x, temp.y;\n\
00319 MUL temp.x, temp.x, temp.z;\n\
00320 CMP temp.x, temp.x, PARAM_MEAN_FILTER.w, 1.0.x;\n\
00321 MUL H_color, H_color, temp.xxxx;\n\
00322 MUL H_color, H_color, PARAM_DRAW_CURVATURE.yyyy;\n\
00323 \n\
00324 # Gaussian curvature (K):\n\
00325 MUL K.x, tex1.w, tex2.w;\n\
00326 ADD_SAT K.x, K.x, 0.5.x;\n\
00327 MOV K.y, 1.0.x;\n\
00328 TEX K_color, K, texture[1], 2D;\n\
00329 MUL K_color, K_color, blue;\n\
00330 CMP temp.x, PARAM_GAUSSIAN_FILTER.x, tex0.y, 1.0.x;\n\
00331 CMP temp.y, PARAM_GAUSSIAN_FILTER.y, dH.x, 1.0.x;\n\
00332 CMP temp.z, PARAM_GAUSSIAN_FILTER.z, dK.x, 1.0.x;\n\
00333 MUL temp.x, temp.x, temp.y;\n\
00334 MUL temp.x, temp.x, temp.z;\n\
00335 CMP temp.x, temp.x, PARAM_GAUSSIAN_FILTER.w, 1.0.x;\n\
00336 MUL K_color, K_color, temp.xxxx;\n\
00337 MUL K_color, K_color, PARAM_DRAW_CURVATURE.zzzz;\n\
00338 \n\
00339 MOV final_color, {0.0, 0.0, 0.0, 1.0};\n\
00340 ADD_SAT final_color, final_color, k_r_color;\n\
00341 ADD_SAT final_color, final_color, H_color;\n\
00342 ADD_SAT final_color, final_color, K_color;\n\
00343 SUB final_color, {1.0, 1.0, 1.0, 0.0}, final_color;\n\
00344 \n\
00345 MOV out, final_color;\n\
00346 \n\
00347 #~ #contours\n\
00348 #~ MOV temp2.x, tex0.z;\n\
00349 #~ ADD temp2.x, temp2.x, half.x;\n\
00350 #~ MOV temp2.y, one.y;\n\
00351 #~ TEX c_color, temp2, texture[0], 2D;\n\
00352 \n\
00353 #~ ADD c_color, c_color, green;\n\
00354 #~ MIN c_color, one.yyyy, c_color;\n\
00355 \n\
00356 #~ #SC\n\
00357 #~ MOV temp.x, tex0.x;\n\
00358 #~ ADD temp.x, temp.x, half.x;\n\
00359 #~ MOV temp.y, one.y;\n\
00360 #~ TEX sc_color, temp, texture[1], 2D;\n\
00361 \n\
00362 #~ ADD sc_color, sc_color, blue;\n\
00363 #~ MIN sc_color, one.yyyy, sc_color;\n\
00364 \n\
00365 #~ # RCP temp.w, tex0.y;\n\
00366 #~ # POW temp.w, tex0.y, big.x;\n\
00367 \n\
00368 #~ # MUL temp.w, one.z, temp.w;\n\
00369 #~ # CMP temp.y, tex0.y, temp.w, one.y;\n\
00370 \n\
00371 #~ SUB sc_color, one.yyyy, sc_color;\n\
00372 #~ MUL sc_color, sc_color, tex0.yyyy;\n\
00373 #~ SUB sc_color, one.yyyy, sc_color;\n\
00374 \n\
00375 #~ MUL final_color, sc_color, c_color;\n\
00376 \n\
00377 END\n\
00378 ";
00379
00380
00381
00382
00383
00384
00385
00386 class CurvatureRenderingMode : public RenderingMode {
00387
00388 public:
00389
00390 class CurvatureStripCB : public RenderingModeStripCB {
00391
00392 };
00393
00394 virtual ~CurvatureRenderingMode() { }
00395
00396 };
00397
00398
00399
00400
00401
00402
00403
00404
00405 class CurvatureARBvpARBfpMultiTextureMode : public CurvatureRenderingMode {
00406
00407 public:
00408
00409 class StripCB : public CurvatureRenderingMode::CurvatureStripCB {
00410
00411 public:
00412
00413
00414 virtual void faceCB(CBvert* v, CBface* f);
00415
00416 };
00417
00418 CurvatureARBvpARBfpMultiTextureMode();
00419
00420 ~CurvatureARBvpARBfpMultiTextureMode();
00421
00422 virtual void setup_for_drawing_outside_dl(const Patch *patch);
00423 virtual void setup_for_drawing_inside_dl(const Patch *patch);
00424
00425 virtual GLStripCB *get_new_strip_cb() const
00426 { return new StripCB; }
00427
00428 private:
00429
00430 GLuint vprog_name, fprog_name;
00431 GLuint line_texture_name, region_texture_name, rcurv_texture_name;
00432
00433 };
00434
00435 CurvatureARBvpARBfpMultiTextureMode::CurvatureARBvpARBfpMultiTextureMode()
00436 : vprog_name(0), fprog_name(0), line_texture_name(0), region_texture_name(0)
00437 {
00438
00439 if(GLExtensions::gl_arb_vertex_program_supported()){
00440
00441 #ifdef GL_ARB_vertex_program
00442
00443 vprog_name = load_ARB_program("CurvatureTexture::init() - ",
00444 GL_VERTEX_PROGRAM_ARB,
00445 CURVATURE_VERTEX_PROGRAM_STR);
00446
00447 #endif // GL_ARB_vertex_program
00448
00449 }
00450
00451 if(GLExtensions::gl_arb_fragment_program_supported()){
00452
00453 #ifdef GL_ARB_fragment_program
00454
00455 fprog_name = load_ARB_program("CurvatureTexture::init() - ",
00456 GL_FRAGMENT_PROGRAM_ARB,
00457 CURVATURE_FRAGMENT_PROGRAM_STR);
00458
00459 #endif // GL_ARB_fragment_program
00460
00461 }
00462
00463 if(GLExtensions::gl_arb_multitexture_supported()){
00464
00465 glGenTextures(1, &line_texture_name);
00466 make_2D_texture(line_texture_name, 1024, 2, true);
00467
00468 glGenTextures(1, ®ion_texture_name);
00469 make_2D_texture(region_texture_name, 1024, 2, false);
00470
00471 glGenTextures(1, &rcurv_texture_name);
00472 make_2D_texture(rcurv_texture_name, 1024, 2, true);
00473
00474 }
00475
00476 }
00477
00478 CurvatureARBvpARBfpMultiTextureMode::~CurvatureARBvpARBfpMultiTextureMode()
00479 {
00480
00481 #if defined(GL_ARB_vertex_program) || defined(GL_ARB_fragment_program)
00482
00483 if(vprog_name)
00484 glDeleteProgramsARB(1, &vprog_name);
00485
00486 if(fprog_name)
00487 glDeleteProgramsARB(1, &fprog_name);
00488
00489 #endif
00490
00491 if(line_texture_name)
00492 glDeleteTextures(1, &line_texture_name);
00493
00494 if(region_texture_name)
00495 glDeleteTextures(1, ®ion_texture_name);
00496
00497 if(rcurv_texture_name)
00498 glDeleteTextures(1, &rcurv_texture_name);
00499
00500 }
00501
00502 void
00503 CurvatureARBvpARBfpMultiTextureMode::setup_for_drawing_outside_dl(const Patch *patch)
00504 {
00505
00506 #ifdef GL_ARB_vertex_program
00507
00508 glEnable(GL_VERTEX_PROGRAM_ARB);
00509 glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vprog_name);
00510
00511 GLfloat sc_thresh = CurvatureTexture::get_sugcontour_thresh();
00512
00513
00514 glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 1,
00515 sc_thresh,
00516 1.0f,
00517 static_cast<GLfloat>(patch->mesh()->avg_len()),
00518 static_cast<GLfloat>(sqr(patch->mesh()->avg_len())) );
00519
00520 Wpt eye = VIEW::eye();
00521
00522 glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 2,
00523 static_cast<GLfloat>(eye[0]),
00524 static_cast<GLfloat>(eye[1]),
00525 static_cast<GLfloat>(eye[2]),
00526 1.0f);
00527
00528 #endif // GL_ARB_vertex_program
00529
00530 #ifdef GL_ARB_fragment_program
00531
00532 glEnable(GL_FRAGMENT_PROGRAM_ARB);
00533 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, fprog_name);
00534
00535 bool draw_radial = CurvatureTexture::get_draw_radial_curv();
00536 bool draw_mean = CurvatureTexture::get_draw_mean_curv();
00537 bool draw_gaussian = CurvatureTexture::get_draw_gaussian_curv();
00538
00539 glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0,
00540 draw_radial ? 1.0f : 0.0f,
00541 draw_mean ? 1.0f : 0.0f,
00542 draw_gaussian ? 1.0f : 0.0f,
00543 0.0f);
00544
00545 int radial_filter
00546 = CurvatureTexture::get_radial_filter();
00547
00548 glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1,
00549 radial_filter == CurvatureTexture::FILTER_RADIAL ? -1.0f : 1.0f,
00550 radial_filter == CurvatureTexture::FILTER_MEAN ? -1.0f : 1.0f,
00551 radial_filter == CurvatureTexture::FILTER_GAUSSIAN ? -1.0f : 1.0f,
00552 0.25f);
00553
00554 int mean_filter
00555 = CurvatureTexture::get_mean_filter();
00556
00557 glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2,
00558 mean_filter == CurvatureTexture::FILTER_RADIAL ? -1.0f : 1.0f,
00559 mean_filter == CurvatureTexture::FILTER_MEAN ? -1.0f : 1.0f,
00560 mean_filter == CurvatureTexture::FILTER_GAUSSIAN ? -1.0f : 1.0f,
00561 0.25f);
00562
00563 int gaussian_filter
00564 = CurvatureTexture::get_gaussian_filter();
00565
00566 glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 3,
00567 gaussian_filter == CurvatureTexture::FILTER_RADIAL ? -1.0f : 1.0f,
00568 gaussian_filter == CurvatureTexture::FILTER_MEAN ? -1.0f : 1.0f,
00569 gaussian_filter == CurvatureTexture::FILTER_GAUSSIAN ? -1.0f : 1.0f,
00570 0.25f);
00571
00572 #endif // GL_ARB_fragment_program
00573
00574 }
00575
00576 void
00577 CurvatureARBvpARBfpMultiTextureMode::setup_for_drawing_inside_dl(const Patch *patch)
00578 {
00579
00580 #ifdef GL_ARB_multitexture
00581
00582 glActiveTextureARB(GL_TEXTURE0_ARB);
00583 glEnable(GL_TEXTURE_2D);
00584 glBindTexture(GL_TEXTURE_2D, line_texture_name);
00585
00586 glActiveTextureARB(GL_TEXTURE1_ARB);
00587 glEnable(GL_TEXTURE_2D);
00588 glBindTexture(GL_TEXTURE_2D, region_texture_name);
00589
00590 glActiveTextureARB(GL_TEXTURE2_ARB);
00591 glEnable(GL_TEXTURE_2D);
00592 glBindTexture(GL_TEXTURE_2D, rcurv_texture_name);
00593
00594 glActiveTextureARB(GL_TEXTURE0);
00595
00596 #endif // GL_ARB_multitexture
00597
00598 #ifdef GL_ARB_vertex_program
00599
00600 glEnable(GL_VERTEX_PROGRAM_ARB);
00601 glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vprog_name);
00602
00603
00604 glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 0, 1.0, 0.0, 1.0, 0.0);
00605
00606 #endif // GL_ARB_vertex_program
00607
00608 #ifdef GL_ARB_fragment_program
00609
00610 glEnable(GL_FRAGMENT_PROGRAM_ARB);
00611 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, fprog_name);
00612
00613 #endif // GL_ARB_fragment_program
00614
00615 }
00616
00617 void
00618 CurvatureARBvpARBfpMultiTextureMode::StripCB::faceCB(CBvert* v, CBface* f)
00619 {
00620
00621 using mlib::Wvec;
00622
00623
00624 Wvec n;
00625 glNormal3dv(f->vert_normal(v,n).data());
00626
00627 if (v->has_color())
00628 GL_COL(v->color(), alpha*v->alpha());
00629
00630 Wvec pdir1 = v->pdir1();
00631 Wvec pdir2 = v->pdir2();
00632
00633
00634 glVertexAttrib4dARB(6, pdir1[0], pdir1[1], pdir1[2], v->k1());
00635 glVertexAttrib4dARB(7, pdir2[0], pdir2[1], pdir2[2], v->k2());
00636 glVertexAttrib4dvARB(15, v->dcurv_tensor().dcurv);
00637
00638
00639 glVertex3dv(v->loc().data());
00640
00641 }
00642
00643
00644
00645 class CurvatureRenderingModeSelectionPolicy {
00646
00647 public:
00648
00649 inline static RenderingMode *SelectRenderingMode();
00650
00651 };
00652
00653 inline RenderingMode*
00654 CurvatureRenderingModeSelectionPolicy::SelectRenderingMode()
00655 {
00656
00657 RenderingMode *mode = 0;
00658
00659 if(GLExtensions::gl_arb_vertex_program_supported()){
00660
00661 if(GLExtensions::gl_arb_fragment_program_supported()){
00662
00663 if(GLExtensions::gl_arb_multitexture_supported()){
00664
00665 mode = new CurvatureARBvpARBfpMultiTextureMode();
00666
00667 }
00668
00669 }
00670
00671 }
00672
00673 return mode;
00674
00675 }
00676
00677 typedef RenderingModeSingleton<CurvatureRenderingModeSelectionPolicy>
00678 CurvatureModeSingleton;
00679
00680
00681
00682 bool CurvatureTexture::draw_radial_curv = true;
00683 bool CurvatureTexture::draw_mean_curv = true;
00684 bool CurvatureTexture::draw_gaussian_curv = true;
00685
00686 CurvatureTexture::curvature_filter_t CurvatureTexture::radial_filter
00687 = CurvatureTexture::FILTER_NONE;
00688 CurvatureTexture::curvature_filter_t CurvatureTexture::mean_filter
00689 = CurvatureTexture::FILTER_NONE;
00690 CurvatureTexture::curvature_filter_t CurvatureTexture::gaussian_filter
00691 = CurvatureTexture::FILTER_NONE;
00692
00693 float CurvatureTexture::sugcontour_thresh = 0.0;
00694
00695 CurvatureTexture::CurvatureTexture(Patch* patch, StripCB* cb)
00696 : BasicTexture(patch, cb)
00697 {
00698
00699 }
00700
00701 int
00702 CurvatureTexture::draw(CVIEWptr& v)
00703 {
00704
00705 assert(cb() != 0);
00706
00707
00708
00709
00710 if(!cb() || !dynamic_cast<CurvatureRenderingMode::CurvatureStripCB*>(cb()))
00711 set_cb(CurvatureModeSingleton::Instance().get_new_strip_cb());
00712
00713 if (_ctrl)
00714 return _ctrl->draw(v);
00715 cb()->alpha = alpha();
00716
00717
00718 check_patch_texture_map();
00719
00720
00721 glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
00722
00723
00724
00725 _patch->apply_texture();
00726
00727
00728 GL_COL(_patch->color(), alpha());
00729
00730 CurvatureModeSingleton::Instance().setup_for_drawing_outside_dl(_patch);
00731
00732
00733 if (BasicTexture::dl_valid(v)) {
00734
00735 BasicTexture::draw(v);
00736
00737 } else {
00738
00739
00740 int dl = _dl.get_dl(v, 1, _patch->stamp());
00741 if (dl)
00742 glNewList(dl, GL_COMPILE);
00743
00744 CurvatureModeSingleton::Instance().setup_for_drawing_inside_dl(_patch);
00745
00746
00747 _patch->draw_tri_strips(_cb);
00748
00749 CurvatureModeSingleton::Instance().after_drawing_inside_dl(_patch);
00750
00751
00752 if(_dl.dl(v)){
00753
00754 _dl.close_dl(v);
00755
00756
00757 BasicTexture::draw(v);
00758 }
00759
00760 }
00761
00762 CurvatureModeSingleton::Instance().after_drawing_outside_dl(_patch);
00763
00764
00765 glPopAttrib();
00766
00767 return _patch->num_faces();
00768
00769 }
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 static void
00850 make_2D_texture(GLuint texture_name, int texture_size, int line_width,
00851 bool just_line)
00852 {
00853
00854 assert(texture_size > 0);
00855 assert(line_width > 0);
00856
00857 GLfloat *pixels = new GLfloat[texture_size * texture_size];
00858
00859
00860
00861 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00862
00863 glBindTexture(GL_TEXTURE_2D, texture_name);
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890 int miplevel = 0;
00891 GLfloat val;
00892
00893 while (texture_size) {
00894
00895 for (int i = 0; i < texture_size*texture_size; i++) {
00896
00897 double x = (double) (i%texture_size) - 0.5 * texture_size + 0.5;
00898 double y = (double) (i/texture_size) - 0.5 * texture_size + 0.5;
00899
00900 val = 0.0f;
00901
00902 if (texture_size >= 4){
00903
00904 if(!just_line && x < 0.0){
00905
00906 val = 0.75f;
00907
00908 }
00909
00910 if (fabs(x) < line_width){
00911
00912 if(y < 0.0){
00913
00914 val = 0.25f;
00915
00916 } else {
00917
00918 val = 1.0f;
00919
00920 }
00921
00922 }
00923
00924 }
00925
00926 pixels[i] = val;
00927
00928 }
00929
00930 glTexImage2D(GL_TEXTURE_2D, miplevel, GL_LUMINANCE, texture_size, texture_size,
00931 0, GL_LUMINANCE, GL_FLOAT, pixels);
00932
00933 texture_size >>= 1;
00934 ++miplevel;
00935
00936 }
00937
00938 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
00939 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00940 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00941 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00942
00943 delete [] pixels;
00944
00945 }
00946
00947 GLuint
00948 load_ARB_program(const char *header, GLenum target, const char *program_string)
00949 {
00950
00951 GLuint program_name = 0;
00952
00953 #if defined(GL_ARB_vertex_program) || defined(GL_ARB_fragment_program)
00954
00955 bool success = false;
00956 bool native;
00957
00958 glGenProgramsARB(1, &program_name);
00959 glBindProgramARB(target, program_name);
00960 glProgramStringARB(target, GL_PROGRAM_FORMAT_ASCII_ARB,
00961 strlen(program_string), program_string);
00962
00963 if(target == GL_VERTEX_PROGRAM_ARB){
00964
00965 success = GLExtensions::gl_arb_vertex_program_loaded(header, native,
00966 reinterpret_cast<const unsigned char *>(program_string));
00967
00968 } else if(target == GL_FRAGMENT_PROGRAM_ARB) {
00969
00970 success = GLExtensions::gl_arb_fragment_program_loaded(header, native,
00971 reinterpret_cast<const unsigned char *>(program_string));
00972
00973 }
00974
00975 if(!success){
00976
00977 glDeleteProgramsARB(1, &program_name);
00978 program_name = 0;
00979
00980 }
00981
00982 #endif
00983
00984 return program_name;
00985
00986 }