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

line_drawing.C

Go to the documentation of this file.
00001 /*!
00002  *  \file line_drawing.C
00003  *  \brief Contains the implementation of the classes that implement the
00004  *  "Line Drawing" rendering style gTexture.
00005  *
00006  */
00007 
00008 #include <iostream>
00009 #include <vector>
00010 #include <algorithm>
00011 #include <typeinfo>
00012 #include <cstring>
00013 #include <cassert>
00014 
00015 using namespace std;
00016 
00017 #include "gtex/gl_extensions.H"
00018 #include "gtex/rendering_mode.H"
00019 #include "gtex/basic_texture.H"
00020 #include "gtex/solid_color.H"
00021 #include "gtex/line_drawing.H"
00022 
00023 #include "mlib/points.H"
00024 
00025 using namespace mlib;
00026 
00027 /* Vertex and Fragment Shaders */
00028 
00029 const char *LINE_DRAWING_VERTEX_PROGRAM_STR =
00030 "\
00031 !!ARBvp1.0\n\
00032 \n\
00033 ####################################################################\n\
00034 ### Real-time Silhouettes and Suggestive Contours\n\
00035 ### Vertex program for computing view dependent curvature values\n\
00036 ####################################################################\n\
00037 \n\
00038 ## Inputs:   ipos : Vertex position\n\
00039 ##           ifpd : First principal direction and curvature (k1 in w component)\n\
00040 ##           ispd : Second principal direction and curvature (k2 in w component)\n\
00041 ##           ider : Derivative of curvature (unique dcurv tensor values)\n\
00042 \n\
00043 ATTRIB ipos = vertex.position;\n\
00044 ATTRIB ifpd = vertex.attrib[6];\n\
00045 ATTRIB ispd = vertex.attrib[7];\n\
00046 ATTRIB ider = vertex.attrib[15];\n\
00047 \n\
00048 ## Output:   opos = Output position\n\
00049 ##           tc0 = {radial curvature, derivative of radial curvature, n dot v}\n\
00050 \n\
00051 OUTPUT opos = result.position;\n\
00052 OUTPUT ocol = result.color;      # Not used\n\
00053 OUTPUT tc0 = result.texcoord[0]; # {rcurv, drcurv, ndotv}\n\
00054 \n\
00055 PARAM MVP[4] = { state.matrix.mvp };                  # Modelview*projection matrix\n\
00056 PARAM MV[4] = { state.matrix.modelview };             # Modelview matrix\n\
00057 PARAM MVIT[4] = { state.matrix.modelview.invtrans };  # Modelview^-1 matrix (used to get eye pos)\n\
00058 \n\
00059 PARAM PARAM_DRAW_ENABLE = program.env[0];\n\
00060 PARAM PARAM_FEATURE = program.env[1];\n\
00061 PARAM EYE_POS = program.env[2];\n\
00062 \n\
00063 # Vertex normal vector:\n\
00064 TEMP normvec;\n\
00065 \n\
00066 # Eye vector:\n\
00067 TEMP eyevec;\n\
00068 \n\
00069 # Computed pricipal direction values:\n\
00070 #     *pdvals.x = cos(angle between principal direction and eye vector)\n\
00071 #     *pdvals.y = (*pdvals.x)^2\n\
00072 #     *pdvals.z = principal curvature times *pdvals.y\n\
00073 #     *pdvals.w = not used\n\
00074 TEMP fpdvals, spdvals;\n\
00075 \n\
00076 # Final scalar field values:\n\
00077 #     finalsf.x = radial curvature\n\
00078 #     finalsf.y = derivative of radial curvature\n\
00079 #     finalsf.z = n dot v\n\
00080 #     finalsf.w = not used\n\
00081 TEMP finalsf;\n\
00082 \n\
00083 # Temporary register (used during various computations)\n\
00084 TEMP   temp;\n\
00085 \n\
00086 #############################################\n\
00087 ## Transform vertex position\n\
00088 #############################################\n\
00089 \n\
00090 " "\
00091 DP4 opos.x, MVP[0], ipos;\n\
00092 DP4 opos.y, MVP[1], ipos;\n\
00093 DP4 opos.z, MVP[2], ipos;\n\
00094 DP4 opos.w, MVP[3], ipos;\n\
00095 \n\
00096 #############################################\n\
00097 ## Compute view dependent curvature values\n\
00098 #############################################\n\
00099 \n\
00100 # Compute normal vector (XXX - Maybe replace with GL normal attribute)\n\
00101 XPD normvec.xyz, ifpd, ispd;\n\
00102 \n\
00103 # Compute eye vector, normalize\n\
00104 SUB eyevec, EYE_POS, ipos;\n\
00105 DP3 eyevec.w, eyevec, eyevec;\n\
00106 RSQ eyevec.w, eyevec.w;\n\
00107 MUL eyevec.xyz, eyevec.w, eyevec;\n\
00108 \n\
00109 # Compute n dot v\n\
00110 DP3 finalsf.z, normvec, eyevec;\n\
00111 \n\
00112 # Assuming that ifpd and eyevec are normalized so that dot product is equal to\n\
00113 # the angle between them:\n\
00114 DP3 fpdvals.x, ifpd, eyevec;           # fpdvals.x = u = cos\n\
00115 MUL fpdvals.y, fpdvals.x, fpdvals.x;   # fpdvals.y = u^2 = cos^2\n\
00116 MUL fpdvals.z, fpdvals.y, ifpd.w;      # fpdvals.z = k1 * u^2\n\
00117 \n\
00118 # Assuming that ispd and eyevec are normalized so that dot product is equal to\n\
00119 # the angle between them:\n\
00120 DP3 spdvals.x, ispd, eyevec;           # spdvals.x = v = cos\n\
00121 MUL spdvals.y, spdvals.x, spdvals.x;   # spdvals.y = v^2 = cos^2\n\
00122 MUL spdvals.z, spdvals.y, ispd.w;      # spdvals.z = k2 * v^2\n\
00123 \n\
00124 # Compute radial curvature:\n\
00125 ADD finalsf.x, fpdvals.z, spdvals.z;   # k1 * u^2 + k2 * v^2\n\
00126 \n\
00127 # Compute derivative of radial curvature:\n\
00128 \n\
00129 # First, calculate derivative of normal curvature:\n\
00130 PARAM three= {3.0, 0.0, 0.0, 0.0};\n\
00131 MUL temp.x, fpdvals.x, ider.x;   # u*P\n\
00132 MUL temp.y, spdvals.x, ider.y;   # v*Q\n\
00133 MUL temp.y, three.x, temp.y;     # 3*v*Q\n\
00134 ADD temp.x, temp.x, temp.y;      # u*P + 3*v*Q\n\
00135 MUL temp.x, temp.x, fpdvals.y;   # u^3*P + 3*u^2*v*Q\n\
00136 \n\
00137 MUL temp.y, fpdvals.x, ider.z;   # u*S\n\
00138 MUL temp.y, three.x, temp.y;     # 3*u*S\n\
00139 MUL temp.z, spdvals.x, ider.w;   # v*T\n\
00140 ADD temp.y, temp.y, temp.z;      # 3*u*S + v*T\n\
00141 MUL temp.y, temp.y, spdvals.y;   # 3*u*v^2*S + v^3*T\n\
00142 \n\
00143 ADD temp.x, temp.x, temp.y;      # u^3*P + 3*u^2*v*Q + 3*u*v^2*S + v^3*T\n\
00144 \n\
00145 # Then add offset to deriv of normal curvature:\n\
00146 #      float csc2theta = 1.0f / (u2 + v2);\n\
00147 #      sctest_num[i] *= csc2theta;\n\
00148 " "\
00149 #      float tr = (themesh->curv2[i] - themesh->curv1[i]) *\n\
00150 #            u * v * csc2theta;\n\
00151 #      sctest_num[i] -= 2.0f * ndotv[i] * sqr(tr);\n\
00152 \n\
00153 ADD temp.y, fpdvals.y, spdvals.y;   # u^2 + v^2\n\
00154 RCP temp.y, temp.y;                 # 1 / sin^2(theta)\n\
00155 MUL temp.x, temp.x, temp.y;         # rescale deriv\n\
00156 \n\
00157 # Calculate torsion (tr):\n\
00158 SUB temp.z, ispd.w, ifpd.w;      # (k2 - k1)\n\
00159 MUL temp.z, temp.z, fpdvals.x;   # (k2 - k1)*u\n\
00160 MUL temp.z, temp.z, spdvals.x;   # (k2 - k1)*u*v\n\
00161 MUL temp.y, temp.y, temp.z;      # tr = (k2 - k1)*u*v / sin^2(theta)\n\
00162 MUL temp.y, temp.y, temp.y;      # tr^2\n\
00163 PARAM two = {2,0,0,0};\n\
00164 MUL temp.y, two.x, temp.y;       # 2 * tr^2\n\
00165 MUL temp.y, temp.y, finalsf.z;   # 2 * tr^2 * (n dot v)\n\
00166 SUB temp.x, temp.x, temp.y;      # whew!\n\
00167 \n\
00168 # #extra stuff necessary for texture\n\
00169 # #      if (extra_sin2theta)\n\
00170 # #         sctest_num[i] *= u2 + v2;\n\
00171 # ADD temp.y, fpdvals.y, spdvals.y; # u2 + v2\n\
00172 # MUL temp.x, temp.x, temp.y;\n\
00173 \n\
00174 # #      sctest_den[i] = ndotv[i];\n\
00175 # #      sctest_num[i] -= scthresh * sctest_den[i];\n\
00176 # PARAM thresh = {3.5,0,0,0};\n\
00177 MUL temp.y, PARAM_FEATURE.x, finalsf.z;\n\
00178 RCP temp.z, PARAM_FEATURE.w;\n\
00179 MUL temp.y, temp.y, temp.z;\n\
00180 SUB temp.x, temp.x, temp.y;\n\
00181 \n\
00182 # #sctest_num[i] = sctest_num[i] * feature_size2 / sctest_den[i];\n\
00183 RCP temp.y, finalsf.z;\n\
00184 MUL temp.x, temp.x, temp.y;\n\
00185 MUL temp.x, temp.x, PARAM_FEATURE.w;\n\
00186 \n\
00187 MOV finalsf.y, temp.x;\n\
00188 \n\
00189 # Scale scalar fields by feature size\n\
00190 MUL finalsf.x, finalsf.x, PARAM_FEATURE.z;\n\
00191 \n\
00192 #TODO: this constant is different than RTSC- FIGURE OUT WHAT IT SHOULD BE\n\
00193 PARAM fs={32,0,0,0};\n\
00194 MUL finalsf.y, finalsf.y, fs.x;\n\
00195 \n\
00196 # If disabling contours or suggestive contours is toggled, set the\n\
00197 # scalar field values to some appropriate constants\n\
00198 MAD finalsf.z, finalsf.z, PARAM_DRAW_ENABLE.x, PARAM_DRAW_ENABLE.y;\n\
00199 MAD finalsf.x, finalsf.x, PARAM_DRAW_ENABLE.z, PARAM_DRAW_ENABLE.w;\n\
00200 \n\
00201 MOV tc0, finalsf;\n\
00202 \n\
00203 END\n\
00204 ";
00205 
00206 const char *LINE_DRAWING_FRAGMENT_PROGRAM_NO_SSD_STR =
00207 "\
00208 !!ARBfp1.0 \n\
00209 \n\
00210 ATTRIB tex0 = fragment.texcoord[0];\n\
00211 ATTRIB col0 = fragment.color; \n\
00212 ATTRIB ipos = fragment.position;\n\
00213 \n\
00214 OUTPUT out = result.color;\n\
00215 \n\
00216 PARAM PARAM_DRAW_COLOR = program.env[0];\n\
00217 \n\
00218 TEMP temp, temp2, temp3;   #temporary\n\
00219 \n\
00220 TEMP c_color, sc_color, final_color;\n\
00221 \n\
00222 \n\
00223 PARAM one = {0.0,1.0,-1,1};\n\
00224 PARAM half = {0.5, 1.0, 1.0, 1.0};\n\
00225 PARAM big = {1.0, 0, 0, 0};\n\
00226 PARAM blue = {0.0, 0.0, 1.0, 0.0};\n\
00227 PARAM green = {0.0, 1.0, 0.0, 0.0};\n\
00228 \n\
00229 #contours\n\
00230 MOV temp2.x, tex0.z;\n\
00231 ADD temp2.x, temp2.x, half.x;\n\
00232 MOV temp2.y, one.y;\n\
00233 TEX c_color, temp2, texture[0], 2D;\n\
00234 \n\
00235 CMP temp, PARAM_DRAW_COLOR.xxxx, green, {0.0, 0.0, 0.0, 0.0};\n\
00236 ADD_SAT c_color, c_color, temp;\n\
00237 \n\
00238 #SC\n\
00239 MOV temp.x, tex0.x;\n\
00240 ADD temp.x, temp.x, half.x;\n\
00241 MOV temp.y, one.y;\n\
00242 TEX sc_color, temp, texture[1], 2D;\n\
00243 \n\
00244 CMP temp, PARAM_DRAW_COLOR.xxxx, blue, {0.0, 0.0, 0.0, 0.0};\n\
00245 ADD_SAT sc_color, sc_color, temp;\n\
00246 \n\
00247 # RCP temp.w, tex0.y;\n\
00248 # POW temp.w, tex0.y, big.x;\n\
00249 \n\
00250 # MUL temp.w, one.z, temp.w;\n\
00251 # CMP temp.y, tex0.y, temp.w, one.y;\n\
00252 \n\
00253 SUB sc_color, one.yyyy, sc_color;\n\
00254 MUL sc_color, sc_color, tex0.yyyy;\n\
00255 SUB sc_color, one.yyyy, sc_color;\n\
00256 \n\
00257 MUL final_color, sc_color, c_color;\n\
00258 \n\
00259 # fix alpha (may not be necessary)\n\
00260 #PARAM testcnst = {-0.1, 0.1, 0, 0};\n\
00261 #RCP temp.x, tex0.x;\n\
00262 #MUL temp.y, temp.x, testcnst.x;\n\
00263 #MOV temp.zw, testcnst.w;\n\
00264 \n\
00265 #test toon shader\n\
00266 #MOV temp2, tex1;\n\
00267 #MOV temp2.y, ipos.z;\n\
00268 #TEX temp2, temp2, texture[2], 2D;\n\
00269 #ADD temp2, temp2, program.env[1];\n\
00270 #MIN temp2, temp2, {1,1,1,1};\n\
00271 \n\
00272 #MUL temp, temp2, temp;\n\
00273 \n\
00274 MOV out, final_color;\n\
00275 #MOV out.xyz, tex0.z;\n\
00276 \n\
00277 END\n\
00278 ";
00279 
00280 //----------------------------------------------------------------------------//
00281 
00282 const char *LINE_DRAWING_VERTEX_SHADER_STR =
00283 "\
00284 /*\n\
00285  *  Line Drawing Vertex Shader\n\
00286  *\n\
00287  */\n\
00288 \n\
00289 #version 110\n\
00290 \n\
00291 uniform bool contours_on;    // Enable contour drawing\n\
00292 uniform bool sugcontours_on; // Enable suggestive contour drawing\n\
00293 uniform float scthresh;      // Suggestive contour threshold\n\
00294 uniform float feature_size;  // Mesh feature size\n\
00295 \n\
00296 uniform vec3 eye_pos;        // Eye position in world coordinates\n\
00297 \n\
00298 attribute vec3 pdir1, pdir2; // Principal directions (normalized)\n\
00299 attribute float k1, k2;      // Principal curvatures\n\
00300 attribute vec4 dcurv_tensor; // Derivative of curvature tensor\n\
00301 \n\
00302 varying float rcurv;         // Radial curvature\n\
00303 varying float drcurv;        // Derivative of radial curvature\n\
00304 varying float ndotv;         // Normal vector dotted with view vector\n\
00305 \n\
00306 const float FS = 32.0;         // Feature size constant from RTSC (may need tweaking)\n\
00307 \n\
00308 void\n\
00309 main()\n\
00310 {\n\
00311    \n\
00312    gl_Position = ftransform();\n\
00313    \n\
00314    // Compute view vector:\n\
00315    vec3 view_vec = normalize(eye_pos - vec3(gl_Vertex));\n\
00316    \n\
00317    // Compute N dot V:\n\
00318    ndotv = dot(gl_Normal, view_vec);\n\
00319    \n\
00320    float u = dot(pdir1, view_vec); // cos(angle between pdir1 and view_vec)\n\
00321    float u2 = u*u;\n\
00322    float v = dot(pdir2, view_vec); // cos(angle between pdir2 and view_vec)\n\
00323    float v2 = v*v;\n\
00324    \n\
00325    // Compute radial curvature:\n\
00326    rcurv = k1*u2 + k2*v2;\n\
00327    \n\
00328    // Compute derivative of radial curvature:\n\
00329    float csc2theta = 1.0/(u2 + v2);\n\
00330    \n\
00331    drcurv = (u*u2*dcurv_tensor.x\n\
00332           + 3.0*u2*v*dcurv_tensor.y\n\
00333           + 3.0*v2*u*dcurv_tensor.z\n\
00334           + v*v2*dcurv_tensor.w)\n\
00335           * csc2theta;\n\
00336    \n\
00337    float tr = (k2 - k1)*u*v*csc2theta;\n\
00338    \n\
00339    drcurv -= 2.0*ndotv*tr*tr;\n\
00340    \n\
00341    float feature_size2 = feature_size*feature_size;\n\
00342    \n\
00343    drcurv -= ndotv*scthresh/feature_size2;\n\
00344    \n\
00345    drcurv *= feature_size2/ndotv;\n\
00346    \n\
00347    drcurv *= FS;\n\
00348    \n\
00349    // Enable/disable features based on uniform values:\n\
00350    ndotv = contours_on ? ndotv : 1.0;\n\
00351    rcurv = sugcontours_on ? rcurv : -1.0;\n\
00352    \n\
00353 }\n\
00354 ";
00355 
00356 const char *LINE_DRAWING_FRAGMENT_SHADER_STR =
00357 "\
00358 /*\n\
00359  *  Line Drawing Fragment Shader\n\
00360  *\n\
00361  */\n\
00362 \n\
00363 #version 110\n\
00364 \n\
00365 uniform float width;         // Line width\n\
00366 \n\
00367 varying float rcurv;         // Radial curvature\n\
00368 varying float drcurv;        // Derivative of radial curvature\n\
00369 varying float ndotv;         // Normal vector dotted with view vector\n\
00370 \n\
00371 void\n\
00372 main()\n\
00373 {\n\
00374    \n\
00375    vec2 values = vec2(rcurv, ndotv);\n\
00376    \n\
00377    vec2 ddx = dFdx(values);\n\
00378    vec2 ddy = dFdy(values);\n\
00379    vec2 grad_len = sqrt(ddx*ddx + ddy*ddy);\n\
00380    grad_len = grad_len*width + 1.0e-6;\n\
00381    vec2 dst_to_zero = abs(values)/grad_len;\n\
00382    \n\
00383    vec2 gaussian = exp(-(dst_to_zero*dst_to_zero));\n\
00384    \n\
00385    \n\
00386    float fade_out = max(((1.0/(0.008*abs(drcurv))) - 0.4), 0.0);\n\
00387    \n\
00388    gl_FragColor.r = 1.0;\n\
00389    gl_FragColor.b = 1.0 - gaussian[0] * max(fade_out, drcurv >= 0.0 ? 1.0 : 0.0);\n\
00390    gl_FragColor.g = 1.0 - gaussian[1];\n\
00391    gl_FragColor.a = 1.0;\n\
00392    \n\
00393 }\n\
00394 ";
00395 
00396 //----------------------------------------------------------------------------//
00397 
00398 /* Utility Function Prototypes */
00399 
00400 static GLuint load_ARB_program(const char *header, GLenum target,
00401                                const char *program_string);
00402 
00403 #ifdef GL_ARB_shader_objects
00404 
00405 GLhandleARB load_ARB_shader(const char *header, GLenum shader_type,
00406                             const char *shader_string);
00407 
00408 bool link_ARB_shader(const char *header, GLhandleARB prog_handle);
00409 
00410 void print_ARB_infolog(GLhandleARB object);
00411 
00412 #endif // GL_ARB_shader_objects
00413 
00414 void maketexture(double width, double fadeout=0.0);
00415 
00416 //----------------------------------------------------------------------------//
00417 
00418 /* Line Drawing Rendering Style Implementation */
00419 
00420 /*!
00421  *  \brief The abstract interface for a "Line Drawing" sytle rendering mode.
00422  *
00423  */
00424 class LineDrawingRenderingMode : public RenderingMode {
00425    
00426    public:
00427    
00428       class LineDrawingStripCB : public RenderingModeStripCB {
00429          
00430       };
00431       
00432       virtual ~LineDrawingRenderingMode() { }
00433    
00434 };
00435 
00436 //----------------------------------------------------------------------------//
00437 
00438 /*!
00439  *  \brief A rendering mode for the "Line Drawing" rendering style that uses
00440  *  OpenGL ARB vertex and fragment programs without screen space derivatives
00441  *  (multitexturing is used instead).
00442  *
00443  */
00444 class LineDrawingVprogFprogNoSSDMode : public LineDrawingRenderingMode {
00445    
00446    public:
00447    
00448       /*!
00449        *  \brief Handles callbacks for drawing triangle strips for the "Line Drawing"
00450        *  rendering style.
00451        *
00452        */
00453       class StripCB : public LineDrawingRenderingMode::LineDrawingStripCB {
00454          
00455          public:
00456          
00457             //! \brief "face" callback.
00458             virtual void faceCB(CBvert* v, CBface* f);
00459       
00460       };
00461    
00462       LineDrawingVprogFprogNoSSDMode();
00463       
00464       ~LineDrawingVprogFprogNoSSDMode();
00465    
00466       virtual void setup_for_drawing_outside_dl(const Patch *patch);
00467       virtual void setup_for_drawing_inside_dl(const Patch *patch);
00468       
00469       virtual GLStripCB *get_new_strip_cb() const
00470          { return new StripCB(); }
00471    
00472    private:
00473    
00474       LineDrawingVprogFprogNoSSDMode(const LineDrawingVprogFprogNoSSDMode &other);
00475       LineDrawingVprogFprogNoSSDMode &operator=(const LineDrawingVprogFprogNoSSDMode &rhs);
00476    
00477       GLuint vprog_name, fprog_name, c_texture_name, sc_texture_name;
00478    
00479 };
00480 
00481 LineDrawingVprogFprogNoSSDMode::LineDrawingVprogFprogNoSSDMode()
00482    : vprog_name(0), fprog_name(0), c_texture_name(0), sc_texture_name(0)
00483 {
00484    
00485    // Vertex Program Setup:
00486    
00487    if(GLExtensions::gl_arb_vertex_program_supported()){
00488       
00489       err_mesg(ERR_LEV_INFO, "LineDrawingTexture::init() - Can use ARB vertex programs!");
00490       
00491 #ifdef GL_ARB_vertex_program
00492 
00493       vprog_name = load_ARB_program("LineDrawingTexture::init() - ",
00494                                     GL_VERTEX_PROGRAM_ARB,
00495                                     LINE_DRAWING_VERTEX_PROGRAM_STR);
00496       
00497 #endif // GL_ARB_vertex_program
00498       
00499    }
00500    
00501    // Fragment Program Setup:
00502    
00503    if(GLExtensions::gl_arb_fragment_program_supported()){
00504       
00505       err_mesg(ERR_LEV_INFO, "LineDrawingTexture::init() - Can use ARB fragment programs!");
00506       
00507 #ifdef GL_ARB_fragment_program
00508 
00509       fprog_name = load_ARB_program("LineDrawingTexture::init() - ",
00510                                     GL_FRAGMENT_PROGRAM_ARB,
00511                                     LINE_DRAWING_FRAGMENT_PROGRAM_NO_SSD_STR);
00512       
00513 #endif // GL_ARB_fragment_program
00514       
00515    }
00516    
00517    if(GLExtensions::gl_arb_multitexture_supported()){
00518    
00519       glGenTextures(1, &c_texture_name);
00520       glBindTexture(GL_TEXTURE_2D, c_texture_name);
00521       maketexture(2.0);
00522       
00523       glGenTextures(1, &sc_texture_name);
00524       glBindTexture(GL_TEXTURE_2D, sc_texture_name);
00525       maketexture(1.0);
00526       
00527    }
00528    
00529 }
00530 
00531 LineDrawingVprogFprogNoSSDMode::~LineDrawingVprogFprogNoSSDMode()
00532 {
00533    
00534 #if defined(GL_ARB_vertex_program) || defined(GL_ARB_fragment_program)
00535 
00536    if(vprog_name)
00537       glDeleteProgramsARB(1, &vprog_name);
00538    
00539    if(fprog_name)
00540       glDeleteProgramsARB(1, &fprog_name);
00541       
00542 #endif
00543 
00544    if(c_texture_name)
00545       glDeleteTextures(1, &c_texture_name);
00546    
00547    if(sc_texture_name)
00548       glDeleteTextures(1, &sc_texture_name);
00549    
00550 }
00551 
00552 void
00553 LineDrawingVprogFprogNoSSDMode::setup_for_drawing_outside_dl(const Patch *patch)
00554 {
00555    
00556 #ifdef GL_ARB_vertex_program
00557    
00558    glEnable(GL_VERTEX_PROGRAM_ARB);
00559    glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vprog_name);
00560    
00561    bool draw_contours =
00562       LineDrawingTexture::get_draw_contours();
00563    bool draw_sugcontours =
00564       LineDrawingTexture::get_draw_sugcontours();
00565    
00566    // Enabling various features:
00567    glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 0,
00568                               draw_contours    ? 1.0f : 0.0f,
00569                               draw_contours    ? 0.0f : 1.0f,
00570                               draw_sugcontours ? 1.0f : 0.0f,
00571                               draw_sugcontours ? 0.0f : 1.0f);
00572    
00573    GLfloat sc_thresh = LineDrawingTexture::get_sugcontour_thresh();
00574    
00575    // Setting various parameters:
00576    glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 1,
00577                               sc_thresh,          // Suggestive Contour Threshold
00578                               1.0f,               // Bounding sphere radius (not used here)
00579                               static_cast<GLfloat>(patch->mesh()->avg_len()),
00580                               static_cast<GLfloat>(sqr(patch->mesh()->avg_len())) );
00581    
00582    Wpt eye = VIEW::eye();
00583                               
00584    glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 2,
00585                               static_cast<GLfloat>(eye[0]),
00586                               static_cast<GLfloat>(eye[1]),
00587                               static_cast<GLfloat>(eye[2]),
00588                               1.0f);
00589                               
00590 #endif // GL_ARB_vertex_program
00591 
00592 #ifdef GL_ARB_fragment_program
00593    
00594    glEnable(GL_FRAGMENT_PROGRAM_ARB);
00595    glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, fprog_name);
00596    
00597    bool draw_color = LineDrawingTexture::get_draw_in_color();
00598    
00599    // Enabling drawing in color of black and white:
00600    glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0,
00601                               draw_color ? -1.0f : 1.0f,
00602                               draw_color ? -1.0f : 1.0f,
00603                               draw_color ? -1.0f : 1.0f,
00604                               draw_color ? -1.0f : 1.0f);
00605    
00606 #endif // GL_ARB_fragment_program
00607    
00608 }
00609 
00610 void
00611 LineDrawingVprogFprogNoSSDMode::setup_for_drawing_inside_dl(const Patch *patch)
00612 {
00613    
00614 #ifdef GL_ARB_multitexture
00615    
00616    glActiveTextureARB(GL_TEXTURE0);
00617    glEnable(GL_TEXTURE_2D);
00618    glBindTexture(GL_TEXTURE_2D, c_texture_name);
00619    
00620    glActiveTextureARB(GL_TEXTURE1);
00621    glEnable(GL_TEXTURE_2D);
00622    glBindTexture(GL_TEXTURE_2D, sc_texture_name);
00623    
00624    glActiveTextureARB(GL_TEXTURE0);
00625                  
00626 #endif // GL_ARB_multitexture
00627       
00628 // #ifdef GL_ARB_vertex_program
00629 //       
00630 //    glEnable(GL_VERTEX_PROGRAM_ARB);
00631 //    glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vprog_name);
00632 //       
00633 // #endif // GL_ARB_vertex_program
00634 //       
00635 // #ifdef GL_ARB_fragment_program
00636 //       
00637 //    glEnable(GL_FRAGMENT_PROGRAM_ARB);
00638 //    glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, fprog_name);
00639 //       
00640 // #endif // GL_ARB_fragment_program
00641    
00642 }
00643 
00644 void
00645 LineDrawingVprogFprogNoSSDMode::StripCB::faceCB(CBvert* v, CBface* f)
00646 {
00647    
00648    using mlib::Wvec;
00649    
00650    // normal
00651    Wvec n;
00652    glNormal3dv(f->vert_normal(v,n).data());
00653 
00654    if (v->has_color())
00655       GL_COL(v->color(), alpha*v->alpha());
00656    
00657    Wvec pdir1 = v->pdir1();
00658    Wvec pdir2 = v->pdir2();
00659 
00660    // Send curvature data as vertex attributes:
00661    glVertexAttrib4dARB(6, pdir1[0], pdir1[1], pdir1[2], v->k1());
00662    glVertexAttrib4dARB(7, pdir2[0], pdir2[1], pdir2[2], v->k2());
00663    glVertexAttrib4dvARB(15, v->dcurv_tensor().dcurv);
00664 
00665    // vertex coords
00666    glVertex3dv(v->loc().data());
00667    
00668 }
00669 
00670 //----------------------------------------------------------------------------//
00671 
00672 /*!
00673  *  \brief A rendering mode for the "Line Drawing" rendering style that uses the
00674  *  OpenGL shading language.
00675  *
00676  */
00677 class LineDrawingGLSLMode : public LineDrawingRenderingMode {
00678    
00679    public:
00680    
00681       /*!
00682        *  \brief Handles callbacks for drawing triangle strips for the "Line Drawing"
00683        *  rendering style.
00684        *
00685        */
00686       class StripCB : public LineDrawingRenderingMode::LineDrawingStripCB {
00687          
00688          public:
00689          
00690             StripCB(const LineDrawingGLSLMode *mode_in)
00691                : LineDrawingRenderingMode::LineDrawingStripCB(), mode(mode_in) { }
00692          
00693             //! \brief "face" callback.
00694             virtual void faceCB(CBvert* v, CBface* f);
00695             
00696          private:
00697          
00698             const LineDrawingGLSLMode *mode;
00699       
00700       };
00701    
00702       LineDrawingGLSLMode();
00703       
00704       ~LineDrawingGLSLMode();
00705    
00706       virtual void setup_for_drawing_outside_dl(const Patch *patch);
00707       virtual void setup_for_drawing_inside_dl(const Patch *patch);
00708       
00709       virtual void after_drawing_outside_dl(const Patch *patch);
00710       
00711       virtual GLStripCB *get_new_strip_cb() const
00712          { return new StripCB(this); }
00713    
00714    private:
00715    
00716       LineDrawingGLSLMode(const LineDrawingGLSLMode &other);
00717       LineDrawingGLSLMode &operator=(const LineDrawingGLSLMode &rhs);
00718       
00719       GLint contours_on_uniform_loc;
00720       GLint sugcontours_on_uniform_loc;
00721       GLint scthresh_uniform_loc;
00722       GLint feature_size_uniform_loc;
00723       GLint eye_pos_uniform_loc;
00724       GLint width_uniform_loc;
00725       
00726       GLint pdir1_attrib_loc, pdir2_attrib_loc;
00727       GLint k1_attrib_loc, k2_attrib_loc;
00728       GLint dcurv_tensor_attrib_loc;
00729       
00730 #ifdef GL_ARB_shader_objects
00731    
00732       GLhandleARB vshader_handle, fshader_handle, prog_handle;
00733       
00734 #endif // GL_ARB_shader_objects
00735    
00736 };
00737 
00738 LineDrawingGLSLMode::LineDrawingGLSLMode()
00739    : contours_on_uniform_loc(-1), sugcontours_on_uniform_loc(-1),
00740      scthresh_uniform_loc(-1), feature_size_uniform_loc(-1),
00741      eye_pos_uniform_loc(-1), width_uniform_loc(-1),
00742    
00743 #ifdef GL_ARB_shader_objects
00744 
00745      vshader_handle(0), fshader_handle(0), prog_handle(0)
00746    
00747 #endif // GL_ARB_shader_objects
00748 
00749 {
00750    
00751    // Vertex Shader Setup:
00752    
00753    if(GLExtensions::gl_arb_vertex_shader_supported()){
00754       
00755       err_mesg(ERR_LEV_INFO, "LineDrawingTexture::init() - Can use ARB vertex shaders!");
00756       
00757 #if defined(GL_ARB_shader_objects) && defined(GL_ARB_vertex_shader) 
00758 
00759       vshader_handle = load_ARB_shader("LineDrawingTexture::init() - ",
00760                                        GL_VERTEX_SHADER_ARB,
00761                                        LINE_DRAWING_VERTEX_SHADER_STR);
00762       
00763 #endif // defined(GL_ARB_shader_objects) && defined(GL_ARB_vertex_shader) 
00764       
00765    }
00766    
00767    // Fragment Shader Setup:
00768    
00769    if(GLExtensions::gl_arb_fragment_shader_supported()){
00770       
00771       err_mesg(ERR_LEV_INFO, "LineDrawingTexture::init() - Can use ARB fragment shaders!");
00772       
00773 #if defined(GL_ARB_shader_objects) && defined(GL_ARB_fragment_shader) 
00774 
00775       fshader_handle = load_ARB_shader("LineDrawingTexture::init() - ",
00776                                        GL_FRAGMENT_SHADER_ARB,
00777                                        LINE_DRAWING_FRAGMENT_SHADER_STR);
00778       
00779 #endif // defined(GL_ARB_shader_objects) && defined(GL_ARB_fragment_shader) 
00780       
00781    }
00782    
00783    // Linking Shaders:
00784    
00785    if(GLExtensions::gl_arb_shader_objects_supported()){
00786       
00787 #ifdef GL_ARB_shader_objects
00788 
00789       prog_handle = glCreateProgramObjectARB();
00790       
00791       glAttachObjectARB(prog_handle, vshader_handle);
00792       glAttachObjectARB(prog_handle, fshader_handle);
00793       
00794       if(!link_ARB_shader("LineDrawingTexture::init() - ", prog_handle)){
00795          
00796          glDeleteObjectARB(prog_handle);
00797          glDeleteObjectARB(vshader_handle);
00798          glDeleteObjectARB(fshader_handle);
00799          
00800          prog_handle = vshader_handle = fshader_handle = 0;
00801          
00802       } else {
00803          
00804          glUseProgramObjectARB(prog_handle);
00805          
00806          // Retrieving uniform variable locations:
00807          
00808          contours_on_uniform_loc = glGetUniformLocationARB(prog_handle, "contours_on");
00809          sugcontours_on_uniform_loc = glGetUniformLocationARB(prog_handle, "sugcontours_on");
00810          scthresh_uniform_loc = glGetUniformLocationARB(prog_handle, "scthresh");
00811          feature_size_uniform_loc = glGetUniformLocationARB(prog_handle, "feature_size");
00812          eye_pos_uniform_loc = glGetUniformLocationARB(prog_handle, "eye_pos");
00813          width_uniform_loc = glGetUniformLocationARB(prog_handle, "width");
00814          
00815          // Retrieving attribute variable locations:
00816          
00817          pdir1_attrib_loc = glGetAttribLocationARB(prog_handle, "pdir1");
00818          pdir2_attrib_loc = glGetAttribLocationARB(prog_handle, "pdir2");
00819          k1_attrib_loc = glGetAttribLocationARB(prog_handle, "k1");
00820          k2_attrib_loc = glGetAttribLocationARB(prog_handle, "k2");
00821          dcurv_tensor_attrib_loc = glGetAttribLocationARB(prog_handle, "dcurv_tensor");
00822          
00823          glUseProgramObjectARB(0);
00824          
00825       }
00826 
00827 #endif // GL_ARB_shader_objects
00828       
00829    }
00830    
00831 }
00832 
00833 LineDrawingGLSLMode::~LineDrawingGLSLMode()
00834 {
00835    
00836 #ifdef GL_ARB_shader_objects
00837 
00838    glDeleteObjectARB(prog_handle);
00839    glDeleteObjectARB(vshader_handle);
00840    glDeleteObjectARB(fshader_handle);
00841       
00842 #endif // GL_ARB_shader_objects
00843    
00844 }
00845 
00846 void
00847 LineDrawingGLSLMode::setup_for_drawing_outside_dl(const Patch *path)
00848 {
00849    
00850 #ifdef GL_ARB_shader_objects
00851    
00852    glUseProgramObjectARB(prog_handle);
00853    
00854    Wpt eye = VIEW::eye();
00855                               
00856    glUniform3fARB(eye_pos_uniform_loc,
00857                   static_cast<GLfloat>(eye[0]),
00858                   static_cast<GLfloat>(eye[1]),
00859                   static_cast<GLfloat>(eye[2]));
00860    
00861    // Setting various parameters:
00862    glUniform1fARB(scthresh_uniform_loc,
00863                   LineDrawingTexture::get_sugcontour_thresh());
00864    
00865    // Enabling various features:
00866    glUniform1iARB(contours_on_uniform_loc,
00867                   LineDrawingTexture::get_draw_contours());
00868    glUniform1iARB(sugcontours_on_uniform_loc,
00869                   LineDrawingTexture::get_draw_sugcontours());
00870                               
00871 #endif // GL_ARB_shader_objects
00872    
00873 }
00874 
00875 void
00876 LineDrawingGLSLMode::setup_for_drawing_inside_dl(const Patch *patch)
00877 {
00878       
00879 #ifdef GL_ARB_shader_objects
00880    
00881    glUseProgramObjectARB(prog_handle);
00882    
00883    // Setting various parameters:
00884    glUniform1fARB(feature_size_uniform_loc,
00885                   static_cast<GLfloat>(patch->mesh()->avg_len()));
00886    glUniform1fARB(width_uniform_loc, 1.0f);
00887       
00888 #endif // GL_ARB_shader_objects
00889    
00890 }
00891 
00892 void
00893 LineDrawingGLSLMode::after_drawing_outside_dl(const Patch *patch)
00894 {
00895    
00896 #ifdef GL_ARB_shader_objects
00897    
00898    // Turn off shaders so that fixed functionality and ARB assembly programs
00899    // will work:
00900    glUseProgramObjectARB(0);
00901    
00902 #endif // GL_ARB_shader_objects
00903    
00904 }
00905 
00906 void
00907 LineDrawingGLSLMode::StripCB::faceCB(CBvert* v, CBface* f)
00908 {
00909    
00910    using mlib::Wvec;
00911    
00912    // normal
00913    Wvec n;
00914    glNormal3dv(f->vert_normal(v,n).data());
00915 
00916    if (v->has_color())
00917       GL_COL(v->color(), alpha*v->alpha());
00918 
00919    // Send curvature data as vertex attributes:
00920    
00921    Wvec pdir1 = v->pdir1();
00922    Wvec pdir2 = v->pdir2();
00923    
00924    glVertexAttrib3fARB(mode->pdir1_attrib_loc,
00925                        static_cast<GLfloat>(pdir1[0]),
00926                        static_cast<GLfloat>(pdir1[1]),
00927                        static_cast<GLfloat>(pdir1[2]));
00928    glVertexAttrib3fARB(mode->pdir2_attrib_loc,
00929                        static_cast<GLfloat>(pdir2[0]),
00930                        static_cast<GLfloat>(pdir2[1]),
00931                        static_cast<GLfloat>(pdir2[2]));
00932                        
00933    glVertexAttrib1fARB(mode->k1_attrib_loc, static_cast<GLfloat>(v->k1()));
00934    glVertexAttrib1fARB(mode->k2_attrib_loc, static_cast<GLfloat>(v->k2()));
00935    
00936    double *dcurv = &(v->dcurv_tensor().dcurv[0]);
00937    
00938    glVertexAttrib4fARB(mode->dcurv_tensor_attrib_loc,
00939                        static_cast<GLfloat>(dcurv[0]),
00940                        static_cast<GLfloat>(dcurv[1]),
00941                        static_cast<GLfloat>(dcurv[2]),
00942                        static_cast<GLfloat>(dcurv[3]));
00943 
00944    // vertex coords
00945    glVertex3dv(v->loc().data());
00946    
00947 }
00948 
00949 //----------------------------------------------------------------------------//
00950 
00951 class LineDrawingRenderingModeSelectionPolicy {
00952    
00953    public:
00954    
00955       inline static RenderingMode *SelectRenderingMode();
00956    
00957 };
00958 
00959 inline RenderingMode*
00960 LineDrawingRenderingModeSelectionPolicy::SelectRenderingMode()
00961 {
00962    
00963    RenderingMode *mode = 0;
00964    
00965    if(GLExtensions::gl_arb_shader_objects_supported() &&
00966       GLExtensions::gl_arb_vertex_shader_supported() &&
00967       GLExtensions::gl_arb_fragment_shader_supported() &&
00968       GLExtensions::gl_nv_fragment_program_option_supported()){
00969       
00970       mode = new LineDrawingGLSLMode();
00971       
00972    } else if(GLExtensions::gl_arb_vertex_program_supported()){
00973       
00974       if(GLExtensions::gl_arb_fragment_program_supported()){
00975          
00976          if(GLExtensions::gl_arb_multitexture_supported()){
00977             
00978             mode = new LineDrawingVprogFprogNoSSDMode();
00979             
00980          }
00981          
00982       }
00983       
00984    }
00985    
00986    return mode;
00987    
00988 }
00989 
00990 typedef RenderingModeSingleton<LineDrawingRenderingModeSelectionPolicy>
00991         LineDrawingModeSingleton;
00992 
00993 //----------------------------------------------------------------------------//
00994 
00995 bool LineDrawingTexture::draw_in_color = false;
00996 bool LineDrawingTexture::draw_contours = true;
00997 bool LineDrawingTexture::draw_sugcontours = true;
00998 float LineDrawingTexture::sugcontour_thresh = 0.0;
00999 
01000 LineDrawingTexture::LineDrawingTexture(Patch* patch, StripCB* cb)
01001    : BasicTexture(patch, cb), solid_color_texture(0)
01002 {
01003    
01004 //    if(!LineDrawingModeSingleton::Instance().line_drawing_supported()){
01005 //       
01006 //       solid_color_texture = new SolidColorTexture(patch);
01007 //       
01008 //    }
01009    
01010 }
01011 
01012 LineDrawingTexture::~LineDrawingTexture()
01013 {
01014    
01015    delete solid_color_texture;
01016    
01017 }
01018 
01019 int
01020 LineDrawingTexture::draw(CVIEWptr& v)
01021 {
01022    
01023    // Just draw a solid color if the "Line Drawing" style is not supported:
01024    if(!LineDrawingModeSingleton::Instance().supported()){
01025       
01026       // XXX - This is a temporary hack to remove use of the LineDrawingModeSingleton
01027       // from the LineDrawingTexture constructor due to static initialization
01028       // ordering problems.
01029       if(!solid_color_texture) solid_color_texture = new SolidColorTexture(_patch);
01030    
01031       return solid_color_texture->draw(v);
01032          
01033    }
01034    
01035    assert(cb() != 0);
01036    
01037    // XXX - This is a temporary hack to remove use of the LineDrawingModeSingleton
01038    // from the LineDrawingTexture constructor due to static initialization
01039    // ordering problems.
01040    if(!cb() || !dynamic_cast<LineDrawingRenderingMode::LineDrawingStripCB*>(cb()))
01041       set_cb(LineDrawingModeSingleton::Instance().get_new_strip_cb());
01042    
01043    if (_ctrl)
01044       return _ctrl->draw(v);
01045    cb()->alpha = alpha();
01046 
01047    // XXX - dumb hack
01048    check_patch_texture_map();
01049 
01050    // this is a no-op unless needed:
01051    // (don't put it inside display list creation):
01052    _patch->apply_texture();
01053 
01054    // set gl state (lighting, shade model)
01055    glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
01056 
01057    // set color (affects GL_CURRENT_BIT):
01058    GL_COL(_patch->color(), alpha()); // GL_CURRENT_BIT
01059    
01060    LineDrawingModeSingleton::Instance().setup_for_drawing_outside_dl(_patch);
01061       
01062    // Execute display list if it's valid:
01063    if (BasicTexture::dl_valid(v)) {
01064       
01065       BasicTexture::draw(v);
01066       
01067    } else { // Otherwise build a new display list:
01068 
01069       // Try to generate a display list:
01070       int dl = _dl.get_dl(v, 1, _patch->stamp());
01071       if (dl)
01072          glNewList(dl, GL_COMPILE);
01073       
01074       LineDrawingModeSingleton::Instance().setup_for_drawing_inside_dl(_patch);
01075    
01076       // draw the triangle strips
01077       _patch->draw_tri_strips(_cb);
01078       
01079       LineDrawingModeSingleton::Instance().after_drawing_inside_dl(_patch);
01080    
01081       // End the display list here:
01082       if(_dl.dl(v)){
01083          
01084          _dl.close_dl(v);
01085    
01086          // The display list is built; now execute it:
01087          BasicTexture::draw(v);
01088       }
01089    
01090    }
01091    
01092    LineDrawingModeSingleton::Instance().after_drawing_outside_dl(_patch);
01093 
01094    // Restore gl state:
01095    glPopAttrib();
01096 
01097    return _patch->num_faces();
01098 
01099 }
01100 
01101 //----------------------------------------------------------------------------//
01102 
01103 /*!
01104  *  \brief Create a texture with a black line of the given width.
01105  *
01106  *  Call this after binding a valid texture object.  That texture object will
01107  *  have its image data replaced with a 1024x1024 pixel image containing a black
01108  *  line of width \p width.
01109  *
01110  *  This function automatically computes mipmaps and turns on trilinear filtering
01111  *  (i.e. minification filter GL_LINEAR_MIPMAP_LINEAR).
01112  *
01113  */
01114 void
01115 maketexture(double width, double fadeout)
01116 {
01117    
01118    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
01119    
01120    int texsize = 1024;
01121    static unsigned char *texture = new unsigned char[texsize*texsize];
01122    
01123    int miplevel = 0;
01124    
01125    while (texsize) {
01126       
01127       for (int i = 0; i < texsize*texsize; i++) {
01128          
01129          double x = (double) (i%texsize) - 0.5 * texsize + 0.5;
01130          double y = (double) (i/texsize) - 0.5 * texsize + 0.5;
01131          double val = 1;
01132          
01133          if (texsize >= 4){
01134             
01135             if (fabs(x) < width && y > 0.0){
01136                
01137                val = sqr(max(1.0 - y, 0.0));
01138                val = (1.0*fadeout*miplevel + val)/(1.0 + fadeout*miplevel);
01139                
01140             }
01141             
01142          }
01143          
01144          texture[i] = min(max(int(256.0 * val), 0), 255);
01145          
01146       }
01147 
01148       /* test- write maketexture to file to edit
01149       char buf[256]; sprintf(buf, "mktex%d.ppm", texsize);
01150       FILE *f = fopen(buf, "wb");
01151       fprintf(f, "P6\n%d %d\n255\n", texsize, texsize);
01152       for(int i=0;i<texsize*texsize;i++){
01153         for(int j=0;j<3;j++) fwrite( &texture[i], 1, 1, f);
01154       }
01155       fclose(f);
01156        */
01157 
01158       glTexImage2D(GL_TEXTURE_2D, miplevel, GL_LUMINANCE, texsize, texsize, 0,
01159                    GL_LUMINANCE, GL_UNSIGNED_BYTE, texture);
01160               
01161       texsize >>= 1;
01162       ++miplevel;
01163       
01164    }
01165 
01166    float bgcolor[] = { 1, 1, 1, 1 };
01167    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, bgcolor);
01168    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
01169    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
01170 
01171    //alexni- try this extension
01172    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
01173    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
01174 
01175    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
01176    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
01177    
01178 #ifdef GL_EXT_texture_filter_anisotropic
01179    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
01180 #endif
01181 
01182 }
01183 
01184 //----------------------------------------------------------------------------//
01185 
01186 /* Utility Functions */
01187 
01188 GLuint
01189 load_ARB_program(const char *header, GLenum target, const char *program_string)
01190 {
01191    
01192    GLuint program_name = 0;
01193    
01194 #if defined(GL_ARB_vertex_program) || defined(GL_ARB_fragment_program)
01195 
01196    bool success = false;
01197    bool native;
01198    
01199    glGenProgramsARB(1, &program_name);
01200    glBindProgramARB(target, program_name);
01201    glProgramStringARB(target, GL_PROGRAM_FORMAT_ASCII_ARB,
01202                       strlen(program_string), program_string);
01203    
01204    if(target == GL_VERTEX_PROGRAM_ARB){
01205    
01206       success = GLExtensions::gl_arb_vertex_program_loaded(header, native,
01207                           reinterpret_cast<const unsigned char *>(program_string));
01208    
01209    } else if(target == GL_FRAGMENT_PROGRAM_ARB) {
01210       
01211       success = GLExtensions::gl_arb_fragment_program_loaded(header, native,
01212                           reinterpret_cast<const unsigned char *>(program_string));
01213       
01214    }
01215    
01216    if(!success){
01217       
01218       glDeleteProgramsARB(1, &program_name);
01219       program_name = 0;
01220       
01221    }
01222    
01223 #endif
01224 
01225    return program_name;
01226    
01227 }
01228 
01229 #ifdef GL_ARB_shader_objects
01230 
01231 GLhandleARB
01232 load_ARB_shader(const char *header, GLenum shader_type, const char *shader_string)
01233 {
01234    
01235    GLhandleARB shader_handle = glCreateShaderObjectARB(shader_type);
01236    
01237    glShaderSourceARB(shader_handle, 1, &shader_string, 0);
01238    
01239    glCompileShaderARB(shader_handle);
01240    
01241    GLint compile_status;
01242    
01243    glGetObjectParameterivARB(shader_handle, GL_OBJECT_COMPILE_STATUS_ARB, &compile_status);
01244    
01245    if(!compile_status){
01246       
01247       cerr << header
01248            << " Error while compiling shader.  Printing info log..." << endl;
01249       
01250       print_ARB_infolog(shader_handle);
01251       
01252       glDeleteObjectARB(shader_handle);
01253       
01254       shader_handle = 0;
01255       
01256    }
01257    
01258    return shader_handle;
01259    
01260 }
01261 
01262 bool
01263 link_ARB_shader(const char *header, GLhandleARB prog_handle)
01264 {
01265    
01266    glLinkProgramARB(prog_handle);
01267    
01268    GLint link_status;
01269    
01270    glGetObjectParameterivARB(prog_handle, GL_OBJECT_LINK_STATUS_ARB, &link_status);
01271    
01272    if(!link_status){
01273       
01274       cerr << header
01275            << " Error while linking shader program.  Printing info log..." << endl;
01276      
01277      print_ARB_infolog(prog_handle);
01278       
01279    }
01280    
01281    return link_status != 0;
01282    
01283 }
01284 
01285 void
01286 print_ARB_infolog(GLhandleARB object)
01287 {
01288    
01289    GLint infolog_length;
01290    
01291    glGetObjectParameterivARB(object, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infolog_length);
01292    
01293    char *infolog = new char[infolog_length + 1];
01294    
01295    GLint actual_infolog_length;
01296    
01297    glGetInfoLogARB(object, infolog_length, &actual_infolog_length, infolog);
01298    
01299    cerr << infolog << endl;
01300    
01301    delete [] infolog;
01302    
01303 }
01304 
01305 #endif // GL_ARB_shader_objects

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