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

curvature_texture.C

Go to the documentation of this file.
00001 /*!
00002  *  \file curvature_texture.C
00003  *  \brief Contains the implementation of the classes that implement the
00004  *  curvature visualization gTexture.
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 /* Utility Function Prototypes */
00023 
00024 // static void make_1D_texture(GLuint texture_name, int texture_size, int line_width,
00025 //                          bool just_line);
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  *  \brief Abstract base class for all curvature gTexture rendering modes.
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  *  \brief A curvature gTexture rendering mode that uses ARB vertex and
00402  *  fragment programs and multitexturing.
00403  *
00404  */
00405 class CurvatureARBvpARBfpMultiTextureMode : public CurvatureRenderingMode {
00406    
00407    public:
00408    
00409       class StripCB : public CurvatureRenderingMode::CurvatureStripCB {
00410          
00411          public:
00412          
00413             //! \brief "face" callback.
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, &region_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, &region_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    // Setting various parameters:
00514    glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 1,
00515                               sc_thresh,          // Suggestive Contour Threshold
00516                               1.0f,               // Bounding sphere radius (not used here)
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    // Enabling various features:
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    // normal
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    // Send curvature data as vertex attributes:
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    // vertex coords
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    // XXX - This is a temporary hack to remove use of the CurvatureModeSingleton
00708    // from the CurvatureTexture constructor due to static initialization
00709    // ordering problems.
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    // XXX - dumb hack
00718    check_patch_texture_map();
00719 
00720    // set gl state (lighting, shade model)
00721    glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
00722 
00723    // this is a no-op unless needed:
00724    // (don't put it inside display list creation):
00725    _patch->apply_texture();     // GL_ENABLE_BIT
00726 
00727    // set color (affects GL_CURRENT_BIT):
00728    GL_COL(_patch->color(), alpha()); // GL_CURRENT_BIT
00729    
00730    CurvatureModeSingleton::Instance().setup_for_drawing_outside_dl(_patch);
00731       
00732    // Execute display list if it's valid:
00733    if (BasicTexture::dl_valid(v)) {
00734       
00735       BasicTexture::draw(v);
00736       
00737    } else { // Otherwise build a new display list:
00738 
00739       // Try to generate a display list:
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       // draw the triangle strips
00747       _patch->draw_tri_strips(_cb);
00748       
00749       CurvatureModeSingleton::Instance().after_drawing_inside_dl(_patch);
00750    
00751       // End the display list here:
00752       if(_dl.dl(v)){
00753          
00754          _dl.close_dl(v);
00755    
00756          // The display list is built; now execute it:
00757          BasicTexture::draw(v);
00758       }
00759    
00760    }
00761    
00762    CurvatureModeSingleton::Instance().after_drawing_outside_dl(_patch);
00763 
00764    // Restore gl state:
00765    glPopAttrib();
00766 
00767    return _patch->num_faces();
00768 
00769 }
00770 
00771 //----------------------------------------------------------------------------//
00772 
00773 /* Utility Functions */
00774 
00775 /*
00776 static void
00777 make_texture_row(GLfloat *row_data, int row_width, int line_width,
00778                  GLfloat left_val, GLfloat line_val, GLfloat right_val)
00779 {
00780    
00781    int cur_row_pos = 0;
00782    
00783    if(row_width > line_width){
00784    
00785       for(; cur_row_pos < (row_width - line_width)/2; ++cur_row_pos){
00786          
00787          row_data[cur_row_pos] = left_val;
00788          
00789       }
00790       
00791       for(int i = 0; i < line_width; ++i, ++cur_row_pos){
00792          
00793          row_data[cur_row_pos] = line_val;
00794          
00795       }
00796       
00797    }
00798    
00799    for(; cur_row_pos < row_width; ++cur_row_pos){
00800       
00801       row_data[cur_row_pos] = right_val;
00802       
00803    }
00804    
00805 }
00806 
00807 static void
00808 make_1D_texture(GLuint texture_name, int texture_size, int line_width,
00809                 bool just_line)
00810 {
00811    
00812    assert(texture_size > 0);
00813    assert(line_width > 0);
00814    
00815    GLfloat *pixels = new GLfloat[texture_size];
00816    
00817    GLfloat less_than_zero_value = just_line ? 0.0f : 0.75f;
00818    
00819    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00820    
00821    glBindTexture(GL_TEXTURE_1D, texture_name);
00822    
00823    int miplevel = 0;
00824    
00825    while(texture_size){
00826       
00827       for(int i = 0; i < texture_size; ++i)
00828          pixels[i] = 0.0f;
00829    
00830       make_texture_row(pixels, texture_size, line_width, less_than_zero_value, 1.0, 0.0);
00831       
00832       glTexImage1D(GL_TEXTURE_1D, miplevel, GL_LUMINANCE, texture_size, 0,
00833                    GL_LUMINANCE, GL_FLOAT, pixels);
00834                    
00835       texture_size >>= 1;
00836       ++miplevel;
00837       
00838    }
00839    
00840    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);   
00841    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00842    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00843    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00844    
00845    delete [] pixels;
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 //   GLfloat less_than_zero_value = just_line ? 0.0f : 0.75f;
00860    
00861    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00862    
00863    glBindTexture(GL_TEXTURE_2D, texture_name);
00864    
00865 //    int miplevel = 0;
00866 //    
00867 //    while(texture_size){
00868 //       
00869 //       int cur_pos  = 0;
00870 //       
00871 //       for(int row = 0; row < texture_size; ++row){
00872 //          
00873 //          GLfloat line_value = row > texture_size/2 ? 1.0f : 0.25f;
00874 //    
00875 //          make_texture_row(pixels + cur_pos, texture_size, line_width,
00876 //                           less_than_zero_value, line_value, 0.0);
00877 //          
00878 //          cur_pos += texture_size;
00879 //          
00880 //       }
00881 //       
00882 //       glTexImage2D(GL_TEXTURE_2D, miplevel, GL_LUMINANCE, texture_size, texture_size,
00883 //                    0, GL_LUMINANCE, GL_FLOAT, pixels);
00884 //                    
00885 //       texture_size >>= 1;
00886 //       ++miplevel;
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; //sqr(max(1.0 - y, 0.0));
00915                
00916                } else {
00917                   
00918                   val = 1.0f; // sqr(max(1.0f - y, 0.0));
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 }

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