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

paper_effect.C

Go to the documentation of this file.
00001 
00002 
00003 #include "gtex/gl_extensions.H"
00004 #include "paper_effect.H"
00005 #include "geom/texturegl.H"
00006 #include "geom/gl_util.H"
00007 #include "geom/gl_view.H"
00008 
00009 /*****************************************************************
00010  * Paper Texture Remapping
00011  *****************************************************************/
00012 
00013 char *paper_remap_base = "nprdata/paper_textures/";
00014 char *paper_remap_fnames[][2] = 
00015 {
00016    {"pube.png",                  "p-combed-1.png"},
00017    {"basic_paper.png",           "p-noisy-1.png"},
00018    {"big_canvas.png",            "p-rough-2.png"},
00019    {"big_rough.png",             "p-cement-1.png"},
00020    {"blacktop.png",              "p-cement-2.png"},
00021    {"blobby2.png",               "p-blobby-1.png"},
00022    {"brushed_and_teased.png",    "p-brushed-1.png"},
00023    {"brushed_paper.png",         "p-brushed-2.png"},
00024    {"burlap.png",                "p-weave-1.png"},
00025    {"cane.png",                   "p-fabric-1.png"},
00026 //   {"canvas.png",                x
00027 //   {"canvas_inv.png",            x
00028    {"cold_press_water_color.png","p-noisy-2.png"},
00029    {"combs.png",                 "p-combed-1.png"},
00030    {"craqulure.png",             "p-blobby-2.png"},
00031    {"cross_fibre.png",           "p-fiber-4.png"},
00032    {"crusty_src.png",            "p-rough-1.png"},
00033    {"eroded_pavement.png",       "p-cement-3.png"},
00034    {"fine_grain.png",            "p-fine-1.png"},
00035    {"fine_paper.png",            "p-noisy-3.png"},
00036    {"finger_print.png",          "p-finger-1.png"},
00037    {"furry_bark.png",            "p-brushed-3.png"},
00038    {"gnarly12.png",              "p-ridged-1.png"},
00039 //   {"half_tone_small.png",       x
00040 //   {"halftone.png",              x
00041    {"handmade_paper_stock.png",  "p-fabric-2.png"},
00042    {"harsh.png",                 "p-cement-4.png"},
00043    {"hot_press_water_color.png", "p-fine-2.png"},
00044 //   {"laid_pastel_paper.png",     x
00045    {"loom_woven.png",            "p-weave-2.png"},
00046 //   {"marble.png",                x
00047    {"mini_glyphs.png",           "p-weird-1.png"},
00048    {"old_angora.png",            "p-rough-3.png"},
00049    {"paper.png",                 "p-noisy-4.png"},
00050    {"paper1.png",                "p-noisy-4.png"},
00051 //   {"paper2.png",                x
00052    {"paper3.png",                "p-ridged-1.png"},
00053 //   {"paper4.png",                x
00054    {"paper5.png",                "p-rough-4.png"},
00055    {"plaid.png",                 "p-weave-3.png"},
00056    {"pulpy_handmade.png",        "p-cement-5.png"},
00057    {"raw_silk.png",              "p-fabric-3.png"},
00058    {"ribbed_dreckle.png",        "p-ridged-2.png"},
00059    {"ribbed_pastel.png",         "p-ridged-3.png"},
00060    {"rice_contrast.png",         "p-fiber-1.png"},
00061    {"rice_src.png",              "p-fiber-2.png"},
00062    {"rough_src.png",             "p-rough-5.png"},
00063    {"rough_tooth.png",           "p-brushed-4.png"},
00064    {"sanded_pastel_board.png",   "p-fine-3.png"},
00065    {"sandy_watercolor.png",      "p-cement-6.png"},
00066    {"sandy_watercolor2.png",     "p-cement-6a.png"},
00067    {"scratchy_textile.png",      "p-fabric-4.png"},
00068    {"sidewalk.png",              "p-cement-7.png"},
00069    {"silk_fine.png",             "p-fine-4.png"},
00070    {"silk_fine2.png",            "p-fine-4a.png"},
00071    {"silk_high.png",             "p-fabric-5.png"},
00072    {"small_canvas.png",          "p-fine-5.png"},
00073    {"smooth_water_color.png",    "p-fabric-3.png"},
00074    {"string_paper.png",          "p-fiber-3.png"},
00075    {"super_fine.png",            "p-fine-6.png"},
00076    {"tissue.png",                "p-cement-8.png"},
00077    {"turbulent.png",             "p-weird-2.png"},
00078    {"vertical_stringy.png",      "p-weird-3.png"},
00079    {"water_color_pad.png",       "p-ridged-4.png"},
00080    {"watercolor2.png",           "p-cement-9.png"},
00081    {"watercolor_big_bumpy.png",  "p-rough-6.png"},
00082    {"watercolor_bumpy.png",      "p-rough-6a.png"},
00083    {"wool.png",                  "p-weird-4.png"},
00084    { NULL,                        NULL}
00085 };
00086 
00087 
00088 /*****************************************************************
00089  * PaperEffect
00090  *****************************************************************/
00091 
00092 int               PaperEffect::_implementation = PaperEffect::IMPLEMENTATION__NONE;
00093 
00094 TEXTUREptr        PaperEffect::_paper_texture;
00095 
00096 LIST<str_ptr>*    PaperEffect::_paper_texture_names = 0;
00097 LIST<TEXTUREptr>* PaperEffect::_paper_texture_ptrs = 0;
00098 LIST<str_ptr>*    PaperEffect::_paper_texture_remap_orig_names = 0;
00099 LIST<str_ptr>*    PaperEffect::_paper_texture_remap_new_names = 0;
00100 
00101 GLuint            PaperEffect::_disabled_no_frag_prog_arb;
00102 GLuint            PaperEffect::_disabled_1d_frag_prog_arb;
00103 GLuint            PaperEffect::_disabled_2d_frag_prog_arb;
00104 GLuint            PaperEffect::_paper_with_no_frag_prog_arb;
00105 GLuint            PaperEffect::_paper_with_1d_frag_prog_arb;
00106 GLuint            PaperEffect::_paper_with_2d_frag_prog_arb;
00107 
00108 GLuint            PaperEffect::_paper_frag_shader_ati;
00109 
00110 const char *      PaperEffect::_DisabledNoFragProgARB = 
00111 {
00112 "!!ARBfp1.0\n\
00113 \
00114 ATTRIB   iCol  = fragment.color;\
00115 \
00116 OUTPUT   oCol  = result.color;\
00117 \
00118 TEMP     tResult;\
00119 \
00120 \
00121 \
00122 MOV      tResult, iCol;\
00123 \
00124 MUL      tResult.rgb, tResult, tResult.a;\
00125 \
00126 MOV      oCol, tResult;\
00127 \
00128 END"
00129 };
00130 
00131 const char *      PaperEffect::_Disabled1DFragProgARB = 
00132 {
00133 "!!ARBfp1.0\n\
00134 \
00135 ATTRIB   iCol  = fragment.color;\
00136 ATTRIB   iTex0 = fragment.texcoord[0];\
00137 \
00138 OUTPUT   oCol  = result.color;\
00139 \
00140 TEMP     tResult;\
00141 \
00142 \
00143 \
00144 TXP      tResult, iTex0, texture[0], 1D;\
00145 \
00146 MUL      tResult, iCol, tResult;\
00147 \
00148 MUL      tResult.rgb, tResult, tResult.a;\
00149 \
00150 MOV      oCol, tResult;\
00151 \
00152 END"
00153 };
00154 
00155 const char *      PaperEffect::_Disabled2DFragProgARB = 
00156 {
00157 "!!ARBfp1.0\n\
00158 \
00159 ATTRIB   iCol  = fragment.color;\
00160 ATTRIB   iTex0 = fragment.texcoord[0];\
00161 \
00162 OUTPUT   oCol  = result.color;\
00163 \
00164 TEMP     tResult;\
00165 \
00166 \
00167 \
00168 TXP      tResult, iTex0, texture[0], 2D;\
00169 \
00170 MUL      tResult, iCol, tResult;\
00171 \
00172 MUL      tResult.rgb, tResult, tResult.a;\
00173 \
00174 MOV      oCol, tResult;\
00175 \
00176 END"
00177 };
00178 
00179 const char *      PaperEffect::_PaperWithNoFragProgARB = 
00180 {
00181 "!!ARBfp1.0\n\
00182 \
00183 ATTRIB   iCol  = fragment.color;\
00184 ATTRIB   iTex0 = fragment.texcoord[0];\
00185 ATTRIB   iTex1 = fragment.texcoord[1];\
00186 \
00187 OUTPUT   oCol  = result.color;\
00188 \
00189 PARAM    cHalf = { 0.5, 0.5, 0.5, 0.5 };\
00190 PARAM    cOne  = { 1.0, 1.0, 1.0, 1.0 };\
00191 PARAM    cTwo  = { 2.0, 2.0, 2.0, 2.0 };\
00192 \
00193 PARAM    c2Cont = program.env[1];\
00194 PARAM    c2Brig = program.env[2];\
00195 \
00196 TEMP     tResult;\
00197 TEMP     tPeak;\
00198 TEMP     tValley;\
00199 \
00200 \
00201 \
00202 MOV      tResult, iCol;\
00203 \
00204 \
00205 \
00206 MUL_SAT  tPeak.a,   cTwo,  tResult;\
00207 \
00208 MAD_SAT  tValley.a, cTwo,  tResult, -cOne;\
00209 \
00210 \
00211 \
00212 TXP      tResult.a, iTex1, texture[1], 2D;\
00213 \
00214 MUL_SAT  tResult.a, c2Brig, tResult;\
00215 ADD      tResult.a, tResult, -cHalf;\
00216 MAD_SAT  tResult.a, c2Cont, tResult,  cHalf;\
00217 \
00218 LRP      tResult.a, tResult, tPeak, tValley;\
00219 \
00220 \
00221 \
00222 MUL      tResult.rgb, tResult, tResult.a;\
00223 \
00224 MOV      oCol, tResult;\
00225 \
00226 END"
00227 };
00228 
00229 const char *      PaperEffect::_PaperWith1DFragProgARB = 
00230 {
00231 "!!ARBfp1.0\n\
00232 \
00233 ATTRIB   iCol  = fragment.color;\
00234 ATTRIB   iTex0 = fragment.texcoord[0];\
00235 ATTRIB   iTex1 = fragment.texcoord[1];\
00236 \
00237 OUTPUT   oCol  = result.color;\
00238 \
00239 PARAM    cHalf = { 0.5, 0.5, 0.5, 0.5 };\
00240 PARAM    cOne  = { 1.0, 1.0, 1.0, 1.0 };\
00241 PARAM    cTwo  = { 2.0, 2.0, 2.0, 2.0 };\
00242 \
00243 PARAM    c2Cont = program.env[1];\
00244 PARAM    c2Brig = program.env[2];\
00245 \
00246 TEMP     tResult;\
00247 TEMP     tPeak;\
00248 TEMP     tValley;\
00249 \
00250 \
00251 \
00252 TXP      tResult, iTex0, texture[0], 1D;\
00253 \
00254 MUL      tResult, iCol,  tResult;\
00255 \
00256 \
00257 \
00258 MUL_SAT  tPeak.a,   cTwo,  tResult;\
00259 \
00260 MAD_SAT  tValley.a, cTwo,  tResult, -cOne;\
00261 \
00262 \
00263 \
00264 TXP      tResult.a, iTex1, texture[1], 2D;\
00265 \
00266 MUL_SAT  tResult.a, c2Brig, tResult;\
00267 ADD      tResult.a, tResult, -cHalf;\
00268 MAD_SAT  tResult.a, c2Cont, tResult,  cHalf;\
00269 \
00270 LRP      tResult.a, tResult, tPeak, tValley;\
00271 \
00272 \
00273 \
00274 MUL      tResult.rgb, tResult, tResult.a;\
00275 \
00276 MOV      oCol, tResult;\
00277 \
00278 END"
00279 };
00280 
00281 const char *      PaperEffect::_PaperWith2DFragProgARB = 
00282 {
00283 "!!ARBfp1.0\n\
00284 \
00285 ATTRIB   iCol  = fragment.color;\
00286 ATTRIB   iTex0 = fragment.texcoord[0];\
00287 ATTRIB   iTex1 = fragment.texcoord[1];\
00288 \
00289 OUTPUT   oCol  = result.color;\
00290 \
00291 PARAM    cHalf = { 0.5, 0.5, 0.5, 0.5 };\
00292 PARAM    cOne  = { 1.0, 1.0, 1.0, 1.0 };\
00293 PARAM    cTwo  = { 2.0, 2.0, 2.0, 2.0 };\
00294 \
00295 PARAM    c2Cont = program.env[1];\
00296 PARAM    c2Brig = program.env[2];\
00297 \
00298 TEMP     tResult;\
00299 TEMP     tPeak;\
00300 TEMP     tValley;\
00301 \
00302 \
00303 \
00304 TXP      tResult, iTex0, texture[0], 2D;\
00305 \
00306 MUL      tResult, iCol,  tResult;\
00307 \
00308 \
00309 \
00310 MUL_SAT  tPeak.a,   cTwo,  tResult;\
00311 \
00312 MAD_SAT  tValley.a, cTwo,  tResult, -cOne;\
00313 \
00314 \
00315 \
00316 TXP      tResult.a, iTex1, texture[1], 2D;\
00317 \
00318 MUL_SAT  tResult.a, c2Brig, tResult;\
00319 ADD      tResult.a, tResult, -cHalf;\
00320 MAD_SAT  tResult.a, c2Cont, tResult,  cHalf;\
00321 \
00322 LRP      tResult.a, tResult, tPeak, tValley;\
00323 \
00324 \
00325 \
00326 MUL      tResult.rgb, tResult, tResult.a;\
00327 \
00328 MOV      oCol, tResult;\
00329 \
00330 END"
00331 };
00332 
00333 /*****************************************************************
00334  * gl_multi_tex_coord_2dv function pointer
00335  *****************************************************************/
00336 
00337 // Calling to paper_coord just calls glMultiTexCood2dv through
00338 // this pointer.  However, if postprocess=true, we'd like to
00339 // quietly, and quickly ignore the calls, so we change to a no_op
00340 // on this pointer when postprocess=true (which is default)
00341 
00342 #ifndef APICALLCONVENTION
00343 #ifdef WIN32
00344 #define APICALLCONVENTION __stdcall
00345 #else
00346 #define APICALLCONVENTION
00347 #endif //WIN32
00348 #endif //APICALLCONVENTION
00349 
00350 void  APICALLCONVENTION   no_op(GLenum, const GLdouble *) {}
00351 void (APICALLCONVENTION * gl_multi_tex_coord_2dv) (GLenum, const GLdouble *) = &no_op;
00352 
00353 /////////////////////////////////////
00354 // Static Variable Initialization
00355 /////////////////////////////////////
00356 
00357 static str_ptr paper_filename_default = "/nprdata/paper_textures/paper.png";
00358 
00359 ////////////////////////////////////////////////////////////////////////////////
00360 // PaperEffect Methods
00361 ////////////////////////////////////////////////////////////////////////////////
00362 
00363 /////////////////////////////////////
00364 // The no-op texture coord to use in post process mode
00365 /////////////////////////////////////
00366 
00367 /////////////////////////////////////
00368 // Constructor
00369 /////////////////////////////////////
00370 
00371 PaperEffect::PaperEffect()
00372 {
00373 }
00374 
00375 /////////////////////////////////////
00376 // Destructor
00377 /////////////////////////////////////
00378 
00379 PaperEffect::~PaperEffect()
00380 {
00381 }
00382 
00383 /////////////////////////////////////
00384 // paper_coord()
00385 /////////////////////////////////////
00386 // Calls through the function pointer.
00387 // This is either a no-op or the real gl call
00388 // This pointer is set when the postprocess flag is toggled
00389 void    
00390 PaperEffect::paper_coord(const double *v)
00391 {
00392 #ifdef GL_ARB_multitexture
00393    gl_multi_tex_coord_2dv(GL_TEXTURE1_ARB, v); 
00394 #endif
00395 }
00396 
00397 
00398 /////////////////////////////////////
00399 // toggle_active
00400 /////////////////////////////////////
00401 
00402 void
00403 PaperEffect::toggle_active()
00404 {
00405    if (!_is_inited) init();
00406 
00407    if (!_is_supported)
00408    {
00409       assert(!_is_active);
00410       err_mesg(ERR_LEV_INFO, "PaperEffect::toggle_active() - **SORRY!** Can't activate -- no hardware support.");
00411       return;
00412    }
00413 
00414    if(_is_active)
00415    {
00416       _is_active = false;
00417       gl_multi_tex_coord_2dv = no_op;
00418       err_mesg(ERR_LEV_INFO, "PaperEffect::toggle_active() - Now inactive.");
00419    }
00420    else
00421    {
00422       _is_active = true;
00423 #ifdef GL_ARB_multitexture
00424       gl_multi_tex_coord_2dv = glMultiTexCoord2dvARB;
00425 #endif
00426       err_mesg(ERR_LEV_INFO, "PaperEffect::toggle_active() - Now active.");
00427    }
00428    notify_usage_toggled();
00429 }
00430 
00431 /////////////////////////////////////
00432 //  begin_paper_effect()
00433 /////////////////////////////////////
00434 void    
00435 PaperEffect::begin_paper_effect(bool apply, double x, double y)
00436 {
00437    check_new_paper(); 
00438    begin_paper_effect(((apply)?(_paper_texture):(NULL)), _cont, _brig, x, y);
00439 }
00440 
00441 /////////////////////////////////////
00442 //  end_paper_effect()
00443 /////////////////////////////////////
00444    
00445 void
00446 PaperEffect::end_paper_effect(bool apply)
00447 { 
00448    //XXX - Check again?
00449    check_new_paper(); 
00450    end_paper_effect(((apply)?(_paper_texture):(NULL)));
00451 }
00452 
00453 /////////////////////////////////////
00454 //  begin_paper_effect()
00455 /////////////////////////////////////
00456 void
00457 PaperEffect::begin_paper_effect(TEXTUREptr t, float cont, float brig, double orig_x, double orig_y)
00458 {
00459 
00460    GL_VIEW::print_gl_errors("PaperEffect::begin_paper_effect() [Start] - ");
00461 
00462    if (!_is_inited) init();
00463 
00464    if (!_is_supported) return;
00465 
00466    if ((_implementation & IMPLEMENTATION__GL_ARB) && !GLExtensions::get_debug())
00467    {
00468       begin_paper_effect_arb(t, cont, brig, orig_x, orig_y);
00469    }
00470    else if (_implementation & IMPLEMENTATION__GL_NV)
00471    {
00472       begin_paper_effect_nv(t, cont, brig, orig_x, orig_y);
00473    }
00474    else if (_implementation & IMPLEMENTATION__GL_ATI)
00475    {
00476       begin_paper_effect_ati(t, cont, brig, orig_x, orig_y);
00477    }
00478    else
00479    {
00480       assert(_implementation == IMPLEMENTATION__NONE);
00481    }
00482 
00483    GL_VIEW::print_gl_errors("PaperEffect::begin_paper_effect() [End] - ");
00484 }
00485 
00486 /////////////////////////////////////
00487 //  end_paper_effect()
00488 /////////////////////////////////////
00489 void
00490 PaperEffect::end_paper_effect(TEXTUREptr t)
00491 {
00492    GL_VIEW::print_gl_errors("PaperEffect::end_paper_effect() [Start] - ");
00493 
00494    assert(_is_inited);
00495 
00496    if (!_is_supported) return;
00497 
00498    if ((_implementation & IMPLEMENTATION__GL_ARB) && !GLExtensions::get_debug())
00499    {
00500       end_paper_effect_arb(t);
00501    }
00502    else if (_implementation & IMPLEMENTATION__GL_NV)
00503    {
00504       end_paper_effect_nv(t);
00505    }
00506    else if (_implementation & IMPLEMENTATION__GL_ATI)
00507    {
00508       end_paper_effect_ati(t);
00509    }
00510    else
00511    {
00512       assert(_implementation == IMPLEMENTATION__NONE);
00513    }
00514 
00515    GL_VIEW::print_gl_errors("PaperEffect::end_paper_effect() [End] - ");
00516 }
00517 
00518 /////////////////////////////////////
00519 //  begin_paper_effect_nv()
00520 /////////////////////////////////////
00521 void
00522 PaperEffect::begin_paper_effect_nv(TEXTUREptr t, float cont, float brig, double orig_x, double orig_y)
00523 {
00524    assert(_is_inited);
00525    assert(_is_supported);
00526    assert(_implementation & IMPLEMENTATION__GL_NV);
00527 
00528    //If not active, or no texture, then just premultiply alpha...
00529    if (!_is_active || t==NULL) 
00530    {
00531 #ifdef GL_NV_register_combiners
00532 
00533    GLint query;
00534 
00535    assert(!glIsEnabled(GL_REGISTER_COMBINERS_NV));
00536 
00537    //Check if were actually applying the texture
00538    //We need this to combine the diffuse color and texture properly
00539    GLboolean using_texture0 = glIsEnabled(GL_TEXTURE_2D) || glIsEnabled(GL_TEXTURE_1D);
00540 
00541    //XXX - Assume that if it's enabled, we're using MODULATE
00542    //If this not good enough, we must modify the register combiner
00543    //state below to implement the desired texture environment given by query
00544    if (using_texture0)
00545    {
00546       glGetTexEnviv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &query);
00547       assert(query == GL_MODULATE);
00548    }
00549 
00550    //XXX - Now setup the reg. comb. state, stomping the old state
00551    // We use 1 stage of general combiners.
00552    glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, 1);
00553 
00554    // A,B(RGB) <-- Primary(RGB), Tex0(RGB) [or (1,1,1)  if (using_texture0 == false).]
00555    glCombinerInputNV(GL_COMBINER0_NV,
00556                      GL_RGB,              GL_VARIABLE_A_NV,
00557                      GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV,   GL_RGB);
00558    if (using_texture0)
00559    {
00560       glCombinerInputNV(GL_COMBINER0_NV,
00561                         GL_RGB,           GL_VARIABLE_B_NV,
00562                         GL_TEXTURE0_ARB,  GL_UNSIGNED_IDENTITY_NV,   GL_RGB);
00563    }
00564    else
00565    {
00566       glCombinerInputNV(GL_COMBINER0_NV,
00567                         GL_RGB,           GL_VARIABLE_B_NV,
00568                         GL_ZERO,          GL_UNSIGNED_INVERT_NV,     GL_RGB);
00569    }
00570    // AB(RGB) --> SPARE0(RGB)  ['pigment color'] (via GL_MODULATE!!)
00571    glCombinerOutputNV(GL_COMBINER0_NV, GL_RGB,             
00572                       GL_SPARE0_NV,    GL_DISCARD_NV,   GL_DISCARD_NV,
00573                       GL_NONE,         GL_NONE,
00574                       GL_FALSE,        GL_FALSE,        GL_FALSE);
00575 
00576 
00577    // A,B(ALPHA) <-- Primary(ALPHA), Tex0(ALPHA) [or (1) if (using_texture0 == false).]
00578    glCombinerInputNV(GL_COMBINER0_NV,
00579                      GL_ALPHA,            GL_VARIABLE_A_NV,          
00580                      GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV,   GL_ALPHA);
00581    if (using_texture0)
00582    {
00583       glCombinerInputNV(GL_COMBINER0_NV,
00584                         GL_ALPHA,         GL_VARIABLE_B_NV,          
00585                         GL_TEXTURE0_ARB,  GL_UNSIGNED_IDENTITY_NV,   GL_ALPHA);
00586    }
00587    else
00588    {
00589       glCombinerInputNV(GL_COMBINER0_NV,
00590                         GL_ALPHA,         GL_VARIABLE_B_NV,          
00591                         GL_ZERO,          GL_UNSIGNED_INVERT_NV,     GL_ALPHA);
00592    }
00593 
00594    // (AB)(ALPHA) --> SPARE0(ALPHA) 
00595    glCombinerOutputNV(GL_COMBINER0_NV,    GL_ALPHA,             
00596                       GL_SPARE0_NV,       GL_DISCARD_NV,   GL_DISCARD_NV,
00597                       GL_NONE,   GL_NONE,
00598                       GL_FALSE,           GL_FALSE,        GL_FALSE);
00599 
00600    //Final stage:
00601    //Outgoing RGB,ALPHA <-- SPARE0(RGB),SPARE0(ALPHA)
00602    glFinalCombinerInputNV(GL_VARIABLE_A_NV,
00603                           GL_ZERO,      GL_UNSIGNED_IDENTITY_NV,   GL_RGB);
00604    glFinalCombinerInputNV(GL_VARIABLE_C_NV,
00605                           GL_E_TIMES_F_NV,   GL_UNSIGNED_IDENTITY_NV,   GL_RGB);
00606    glFinalCombinerInputNV(GL_VARIABLE_D_NV,
00607                           GL_ZERO,      GL_UNSIGNED_IDENTITY_NV,   GL_RGB);
00608    glFinalCombinerInputNV(GL_VARIABLE_E_NV,
00609                           GL_SPARE0_NV,   GL_UNSIGNED_IDENTITY_NV,   GL_RGB);
00610    glFinalCombinerInputNV(GL_VARIABLE_F_NV,
00611                           GL_SPARE0_NV,   GL_UNSIGNED_IDENTITY_NV,   GL_ALPHA);
00612    glFinalCombinerInputNV(GL_VARIABLE_G_NV,
00613                           GL_SPARE0_NV,   GL_UNSIGNED_IDENTITY_NV,   GL_ALPHA);
00614 
00615 
00616    glEnable(GL_REGISTER_COMBINERS_NV);
00617 
00618 #endif
00619    }
00620    else
00621    {
00622 #if defined(GL_NV_register_combiners) && defined(GL_ARB_multitexture)
00623 
00624       GLint query;
00625       double uscale, vscale, uoff, voff, aspect;
00626       int w, h;
00627       VIEW_SIZE(w,h);
00628 
00629       if (w >= h)
00630       {
00631          aspect = (double)w/(double)h;
00632          uscale = (double)w/(2.0*aspect*(double)t->image().width());
00633          vscale = (double)h/(2.0*(double)t->image().height());
00634          uoff = aspect;
00635          voff = 1.0;
00636       }
00637       else
00638       {
00639          aspect = (double)h/(double)w;
00640          uscale = (double)w/(2.0*(double)t->image().width());
00641          vscale = (double)h/(2.0*aspect*(double)t->image().height());
00642          uoff = 1.0;
00643          voff = aspect;
00644       }
00645 
00646       //We should push texture state to save the old reg. combiner
00647       //state and texture state for both units, but we're going to assume that only
00648       //PaperEffect plays with the 2nd texture unit and reg. combiners,
00649       //so we just go ahead and stomp all over this state. 
00650       //The texture state is local to the current active unit, so
00651       //we just change to the 2nd unit, and go crazy:
00652 
00653       //First, since we assume nobody else is using reg. combiners
00654       //let's be sure that this is true.
00655       assert(!glIsEnabled(GL_REGISTER_COMBINERS_NV));
00656 
00657       //Now, let's just be sure that TEXTURE0 was the
00658       //active unit to start with since this should
00659       //be true is we're the only guys using multitex.
00660    
00661       glGetIntegerv ( GL_ACTIVE_TEXTURE_ARB, &query); 
00662       assert(query == GL_TEXTURE0_ARB);
00663 
00664       //Check if were actually applying the texture
00665       //We need this to combine the diffuse color and texture properly
00666       GLboolean using_texture0 = glIsEnabled(GL_TEXTURE_2D) || glIsEnabled(GL_TEXTURE_1D);
00667 
00668       //XXX - Assume that if it's enabled, we're using MODULATE
00669       //If this not good enough, we must modify the register combiner
00670       //state below to implement the desired texture environment given by query
00671       if (using_texture0)
00672       {
00673          glGetTexEnviv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &query);
00674          assert(query == GL_MODULATE);
00675       }
00676 
00677       //XXX - Now setup the reg. comb. state, stomping the old state
00678       // We use 2 stages of general combiners.
00679       glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, 2);
00680 
00681       //1st stage:
00682       // Computes brightness/contrast adjustment to height field.
00683       // Evaluates. 'peak' and 'trough' basis functions at the 'pressure'(ALPHA).
00684 
00685       // Contrast ranges 0-1 with 0.5 meaning no effect
00686       // Brightness ranges 0-1 with 0.5 meaning no effect
00687       // Due to the limits of using a single combiner for 
00688       // both effects, brightening becomes less dramatic
00689       // as contrast is increased
00690 
00691       GLfloat constant0[4] = {0.0, 0.0, 0.0, 0.0};
00692       GLfloat constant1[4] = {0.0, 0.0, 0.0, 0.0};
00693 
00694       assert(cont>=0.0); assert(cont<=1.0f);
00695       assert(brig>=0.0); assert(brig<=1.0f);
00696       constant0[3] = cont;
00697       constant1[3] = (brig<=0.5f)?(cont*brig/0.5f):(cont+(1.0f-cont)*(brig-0.5f)/0.5f);
00698 
00699       glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, constant0);
00700       glCombinerParameterfvNV(GL_CONSTANT_COLOR1_NV, constant1);
00701 
00702       // A,B(RGB) <-- 0.5-CONST0(ALPHA), 0.5 [ (0.5-contrast)*0.5 ]
00703       // C,D(RGB) <-- CONST1(ALPHA), (TEX1)(ALPHA) [brightness adjusted contrast*height]
00704       glCombinerInputNV(GL_COMBINER0_NV,
00705                         GL_RGB,                 GL_VARIABLE_A_NV,          
00706                         GL_CONSTANT_COLOR0_NV,  GL_HALF_BIAS_NEGATE_NV,    GL_ALPHA);
00707       glCombinerInputNV(GL_COMBINER0_NV,
00708                         GL_RGB,                 GL_VARIABLE_B_NV,          
00709                         GL_ZERO,                GL_HALF_BIAS_NEGATE_NV,    GL_ALPHA);
00710       glCombinerInputNV(GL_COMBINER0_NV,
00711                         GL_RGB,                 GL_VARIABLE_C_NV,          
00712                         GL_CONSTANT_COLOR1_NV,  GL_UNSIGNED_IDENTITY_NV,   GL_ALPHA);
00713       glCombinerInputNV(GL_COMBINER0_NV,
00714                         GL_RGB,                 GL_VARIABLE_D_NV,          
00715                         GL_TEXTURE1_ARB,        GL_UNSIGNED_IDENTITY_NV,   GL_ALPHA);
00716 
00717       //(AB+CD)(RGB) --> SPARE1(RGB)  [brightness and contrast adjusted height]
00718       glCombinerOutputNV(GL_COMBINER0_NV,    GL_RGB,             
00719                          GL_DISCARD_NV,      GL_DISCARD_NV,   GL_SPARE1_NV,
00720                          GL_SCALE_BY_TWO_NV, GL_NONE,
00721                          GL_FALSE,           GL_FALSE,        GL_FALSE);
00722 
00723       // A,B(ALPHA) <-- Primary(ALPHA), Tex0(ALPHA) [or (1) if (using_texture0 == false).]
00724       glCombinerInputNV(GL_COMBINER0_NV,
00725                         GL_ALPHA,            GL_VARIABLE_A_NV,          
00726                         GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV,   GL_ALPHA);
00727       if (using_texture0)
00728       {
00729          glCombinerInputNV(GL_COMBINER0_NV,
00730                            GL_ALPHA,         GL_VARIABLE_B_NV,          
00731                            GL_TEXTURE0_ARB,  GL_UNSIGNED_IDENTITY_NV,   GL_ALPHA);
00732       }
00733       else
00734       {
00735          glCombinerInputNV(GL_COMBINER0_NV,
00736                            GL_ALPHA,         GL_VARIABLE_B_NV,          
00737                            GL_ZERO,          GL_UNSIGNED_INVERT_NV,     GL_ALPHA);
00738       }
00739 
00740       // C,D(ALPHA) <-- (+1),(-0.5) [for use as a bias, CD=-0.5, in trough transfer function]
00741       glCombinerInputNV(GL_COMBINER0_NV,
00742                         GL_ALPHA,            GL_VARIABLE_C_NV,          
00743                         GL_ZERO,             GL_UNSIGNED_INVERT_NV,   GL_ALPHA);
00744       glCombinerInputNV(GL_COMBINER0_NV,
00745                         GL_ALPHA,            GL_VARIABLE_D_NV,          
00746                         GL_ZERO,             GL_HALF_BIAS_NORMAL_NV,  GL_ALPHA);
00747 
00748       //   2x(AB)(ALPHA) --> SPARE0(ALPHA)  [peak transfer function at incoming alpha (as GL_MODULATE)]
00749       //2x(AB+CD)(ALPHA) --> SPARE1(ALPHA)  [trough tranfer function at incoming alpha (as GL_MODULATE)]
00750       glCombinerOutputNV(GL_COMBINER0_NV,    GL_ALPHA,             
00751                          GL_SPARE0_NV,       GL_DISCARD_NV,   GL_SPARE1_NV,
00752                          GL_SCALE_BY_TWO_NV, GL_NONE,
00753                          GL_FALSE,           GL_FALSE,        GL_FALSE);
00754 
00755 
00756       // 2nd stage:
00757       // Computes the 'pigment color'(RGB) and 'pressure'(ALPHA) via a GL_MODULATE style multiply
00758       // Computes the 'deposited pigment fraction'(ALPHA)
00759       //   as weighted sum of 'peak' and 'trough' using 'height' (TEX1ALPHA)
00760 
00761       // A,B(RGB) <-- Primary(RGB), Tex0(RGB) [or (1,1,1)  if (using_texture0 == false).]
00762       glCombinerInputNV(GL_COMBINER1_NV,
00763                         GL_RGB,              GL_VARIABLE_A_NV,
00764                         GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV,   GL_RGB);
00765       if (using_texture0)
00766       {
00767          glCombinerInputNV(GL_COMBINER1_NV,
00768                            GL_RGB,           GL_VARIABLE_B_NV,
00769                            GL_TEXTURE0_ARB,  GL_UNSIGNED_IDENTITY_NV,   GL_RGB);
00770       }
00771       else
00772       {
00773          glCombinerInputNV(GL_COMBINER1_NV,
00774                            GL_RGB,           GL_VARIABLE_B_NV,
00775                            GL_ZERO,          GL_UNSIGNED_INVERT_NV,     GL_RGB);
00776       }
00777       // AB(RGB) --> SPARE0(RGB)  ['pigment color'] (via GL_MODULATE!!)
00778       glCombinerOutputNV(GL_COMBINER1_NV, GL_RGB,             
00779                          GL_SPARE0_NV,    GL_DISCARD_NV,   GL_DISCARD_NV,
00780                          GL_NONE,         GL_NONE,
00781                          GL_FALSE,        GL_FALSE,        GL_FALSE);
00782 
00783       // A,C(ALPHA) <-- SPARE0(ALPHA), SPARE1(ALPHA) ['peak' and 'trough']
00784       // B,D(ALPHA) <-- TEX1(ALPHA), (1-TEX1)(ALPHA) ['peak', 'trough' weights in linear combo]
00785       // B,D(ALPHA) <-- SPARE1(BLUE), (1-SPARE1)(BLUE) ['peak', 'trough' weights in linear combo]
00786       glCombinerInputNV(GL_COMBINER1_NV,
00787                         GL_ALPHA,            GL_VARIABLE_A_NV,          
00788                         GL_SPARE0_NV,        GL_UNSIGNED_IDENTITY_NV,   GL_ALPHA);
00789       glCombinerInputNV(GL_COMBINER1_NV,
00790                         GL_ALPHA,            GL_VARIABLE_C_NV,          
00791                         GL_SPARE1_NV,        GL_UNSIGNED_IDENTITY_NV,   GL_ALPHA);
00792       glCombinerInputNV(GL_COMBINER1_NV,
00793                         GL_ALPHA,            GL_VARIABLE_B_NV,          
00794                         GL_SPARE1_NV,        GL_UNSIGNED_IDENTITY_NV,   GL_BLUE);
00795       glCombinerInputNV(GL_COMBINER1_NV,
00796                         GL_ALPHA,            GL_VARIABLE_D_NV,          
00797                         GL_SPARE1_NV,        GL_UNSIGNED_INVERT_NV,     GL_BLUE);
00798 
00799       //(AB+CD)(ALPHA) --> SPARE0(ALPHA)  ['deposited pigment fraction' as (h)'peak'+(1-h)'trough']
00800       glCombinerOutputNV(GL_COMBINER1_NV,    GL_ALPHA,             
00801                          GL_DISCARD_NV,      GL_DISCARD_NV,   GL_SPARE0_NV,
00802                          GL_NONE,            GL_NONE,
00803                          GL_FALSE,           GL_FALSE,        GL_FALSE);
00804 
00805       // XXX - Newer version premultiplies by alpha!!!!!!!
00806 
00807    /*
00808       //Final stage:
00809       //Outgoing RGB,ALPHA <-- SPARE0(RGB),SPARE0(ALPHA)
00810       glFinalCombinerInputNV(GL_VARIABLE_A_NV,
00811                              GL_ZERO,        GL_UNSIGNED_IDENTITY_NV,   GL_RGB);
00812       glFinalCombinerInputNV(GL_VARIABLE_C_NV,
00813                              GL_SPARE0_NV,   GL_UNSIGNED_IDENTITY_NV,   GL_RGB);
00814       glFinalCombinerInputNV(GL_VARIABLE_D_NV,
00815                              GL_ZERO,        GL_UNSIGNED_IDENTITY_NV,   GL_RGB);
00816       glFinalCombinerInputNV(GL_VARIABLE_G_NV,
00817                              GL_SPARE0_NV,   GL_UNSIGNED_IDENTITY_NV,   GL_ALPHA);
00818    */
00819 
00820       //Final stage:
00821       //Outgoing RGB,ALPHA <-- SPARE0(RGB),SPARE0(ALPHA)
00822       glFinalCombinerInputNV(GL_VARIABLE_A_NV,
00823                              GL_ZERO,      GL_UNSIGNED_IDENTITY_NV,   GL_RGB);
00824       glFinalCombinerInputNV(GL_VARIABLE_C_NV,
00825                              GL_E_TIMES_F_NV,  GL_UNSIGNED_IDENTITY_NV,   GL_RGB);
00826       glFinalCombinerInputNV(GL_VARIABLE_D_NV,
00827                              GL_ZERO,      GL_UNSIGNED_IDENTITY_NV,   GL_RGB);
00828       glFinalCombinerInputNV(GL_VARIABLE_E_NV,
00829                              GL_SPARE0_NV,   GL_UNSIGNED_IDENTITY_NV,   GL_RGB);
00830       glFinalCombinerInputNV(GL_VARIABLE_F_NV,
00831                              GL_SPARE0_NV,   GL_UNSIGNED_IDENTITY_NV,   GL_ALPHA);
00832       glFinalCombinerInputNV(GL_VARIABLE_G_NV,
00833                              GL_SPARE0_NV,   GL_UNSIGNED_IDENTITY_NV,   GL_ALPHA);
00834 
00835 
00836       //Now switch to TEXTURE1 and stomp all over the old state
00837       glActiveTextureARB(GL_TEXTURE1_ARB);
00838 
00839       t->apply_texture();              //calls glBindTexture and sets state
00840    
00841       //Setup the scale matrix to convert from NDC -> UV
00842       glGetIntegerv ( GL_MATRIX_MODE, &query); 
00843       glMatrixMode( GL_TEXTURE );
00844       glLoadIdentity();
00845       glScaled( uscale, vscale, 1.0 );
00846       glTranslated( uoff - orig_x, voff - orig_y, 0.0 );
00847       glMatrixMode( query );
00848 
00849       glEnable(GL_TEXTURE_2D);
00850 
00851       //Turn on the combiners
00852       glEnable(GL_REGISTER_COMBINERS_NV);
00853 
00854       //And return to the 1st texturing unit
00855       glActiveTextureARB(GL_TEXTURE0_ARB);
00856 
00857 #endif
00858    
00859    }
00860 }
00861 
00862 /////////////////////////////////////
00863 //  begin_paper_effect_ati()
00864 /////////////////////////////////////
00865 void
00866 PaperEffect::begin_paper_effect_ati(TEXTUREptr t, float cont, float brig, double orig_x, double orig_y)
00867 {
00868    assert(_is_inited);
00869    assert(_is_supported);
00870    assert(_implementation & IMPLEMENTATION__GL_ATI);
00871 
00872 
00873 #if defined(GL_ATI_fragment_shader) && defined(GL_ARB_multitexture) && !defined(NON_ATI_GFX)
00874 
00875    GLint query;
00876 
00877    //We should push texture state to save the state for both units, 
00878    //but we're going to assume that only PaperEffect plays with the 
00879    //2nd texture unit, so we just go ahead and stomp all over this state. 
00880 
00881    //First, since we assume nobody else is using fragment programs...
00882    //Let's be sure that this is true.
00883    assert(!glIsEnabled(GL_FRAGMENT_SHADER_ATI));
00884 
00885    //Now, let's just be sure that TEXTURE0 was the
00886    //active unit to start with since this should
00887    //be true if we're the only guys using multitex.
00888    glGetIntegerv ( GL_ACTIVE_TEXTURE_ARB, &query); 
00889    assert(query == GL_TEXTURE0_ARB);
00890 
00891    //Check if were actually applying the texture.
00892    //We need this to combine the diffuse color and texture properly
00893    GLboolean using_texture0 = glIsEnabled(GL_TEXTURE_2D) || glIsEnabled(GL_TEXTURE_1D);
00894 
00895    //XXX - Assume that if it's enabled, we're using MODULATE
00896    //If this not good enough, we must modify the programs to
00897    //implement the desired texturing scheme given by the query...
00898    if (using_texture0)
00899    {
00900       glGetTexEnviv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &query);
00901       assert(query == GL_MODULATE);
00902    }
00903 
00904    // See if we're actually doing ye olde paper effect...
00905    bool using_texture1 = _is_active && (t != NULL);
00906 
00907    if (using_texture1)
00908    {
00909       //Compute stuff for the ndc->uv conversion matrix
00910       double uscale, vscale, uoff, voff, aspect;
00911       int w, h;   VIEW_SIZE(w,h);
00912       if (w >= h)
00913       {
00914          aspect = (double)w/(double)h;
00915          uscale = (double)w/(2.0*aspect*(double)t->image().width());
00916          vscale = (double)h/(2.0*(double)t->image().height());
00917          uoff = aspect;
00918          voff = 1.0;
00919       }
00920       else
00921       {
00922          aspect = (double)h/(double)w;
00923          uscale = (double)w/(2.0*(double)t->image().width());
00924          vscale = (double)h/(2.0*aspect*(double)t->image().height());
00925          uoff = 1.0;
00926          voff = aspect;
00927       }
00928 
00929       //Now switch to TEXTURE1 and stomp all over the old state
00930       glActiveTextureARB(GL_TEXTURE1_ARB);
00931 
00932       t->apply_texture(); //calls glBindTexture and sets state
00933 
00934       //Setup the scale matrix to convert from NDC -> UV
00935       glGetIntegerv ( GL_MATRIX_MODE, &query); 
00936       glMatrixMode( GL_TEXTURE );
00937       glLoadIdentity();
00938       glScaled( uscale, vscale, 1.0 );
00939       glTranslated( uoff - orig_x, voff - orig_y, 0.0 );
00940       glMatrixMode( query );
00941 
00942       glEnable(GL_TEXTURE_2D);
00943 
00944       //And return to the 1st texturing unit
00945       glActiveTextureARB(GL_TEXTURE0_ARB);
00946    }
00947 
00948 
00949    //Now setup the fragment program...
00950 
00951    GLfloat c0[4], c1[4], c2[4];
00952 
00953    c0[0]=c0[1]=c0[2]=c0[3]=((using_texture0)?(1.0f):(0.0f));
00954 
00955    assert(cont>=0.0); assert(cont<=1.0f);
00956    assert(brig>=0.0); assert(brig<=1.0f);
00957 
00958    if (using_texture1)
00959    {
00960       c1[0]=c1[1]=c1[2]=c1[3] = 0.5f - cont;
00961       c2[0]=c2[1]=c2[2]=c2[3] = (brig<=0.5f)?(2.0f*cont*brig):(cont+(1.0f-cont)*(brig-0.5f)/0.5f);
00962    }
00963    else
00964    {
00965       c1[0]=c1[1]=c1[2]=c1[3] = 0.5f;
00966       c2[0]=c2[1]=c2[2]=c2[3] = 0.0f;
00967    }
00968    glBindFragmentShaderATI(_paper_frag_shader_ati); 
00969 
00970    glSetFragmentShaderConstantATI (GL_CON_0_ATI, c0);
00971    glSetFragmentShaderConstantATI (GL_CON_1_ATI, c1);
00972    glSetFragmentShaderConstantATI (GL_CON_2_ATI, c2);
00973    
00974    glEnable(GL_FRAGMENT_SHADER_ATI);  //GL_ENABLE_BIT
00975 
00976 #endif
00977    
00978 }
00979 
00980 /////////////////////////////////////
00981 //  begin_paper_effect_arb()
00982 /////////////////////////////////////
00983 void
00984 PaperEffect::begin_paper_effect_arb(TEXTUREptr t, float cont, float brig, double orig_x, double orig_y)
00985 {
00986    assert(_is_inited);
00987    assert(_is_supported);
00988    assert(_implementation & IMPLEMENTATION__GL_ARB);
00989 
00990 #if defined(GL_ARB_fragment_program) && defined(GL_ARB_multitexture)
00991 
00992    GLint query;
00993 
00994    //We should push texture state to save the state for both units, 
00995    //but we're going to assume that only PaperEffect plays with the 
00996    //2nd texture unit, so we just go ahead and stomp all over this state. 
00997 
00998    //First, since we assume nobody else is using fragment programs...
00999    //Let's be sure that this is true.
01000    assert(!glIsEnabled(GL_FRAGMENT_PROGRAM_ARB));
01001 
01002    //Now, let's just be sure that TEXTURE0 was the
01003    //active unit to start with since this should
01004    //be true if we're the only guys using multitex.
01005    glGetIntegerv ( GL_ACTIVE_TEXTURE_ARB, &query); 
01006    assert(query == GL_TEXTURE0_ARB);
01007 
01008    //Check if were actually applying the texture.
01009    //We need this to combine the diffuse color and texture properly
01010    GLboolean using_texture0 = glIsEnabled(GL_TEXTURE_2D) || glIsEnabled(GL_TEXTURE_1D);
01011 
01012    //XXX - Assume that if it's enabled, we're using MODULATE
01013    //If this not good enough, we must modify the programs to
01014    //implement the desired texturing scheme given by the query...
01015    if (using_texture0)
01016    {
01017       glGetTexEnviv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &query);
01018       assert(query == GL_MODULATE);
01019    }
01020 
01021    // See if we're actually doing ye olde paper effect...
01022    bool using_texture1 = _is_active && (t != NULL);
01023 
01024    if (using_texture1)
01025    {
01026       //Compute stuff for the ndc->uv conversion matrix
01027       double uscale, vscale, uoff, voff, aspect;
01028       int w, h;   VIEW_SIZE(w,h);
01029       if (w >= h)
01030       {
01031          aspect = (double)w/(double)h;
01032          uscale = (double)w/(2.0*aspect*(double)t->image().width());
01033          vscale = (double)h/(2.0*(double)t->image().height());
01034          uoff = aspect;
01035          voff = 1.0;
01036       }
01037       else
01038       {
01039          aspect = (double)h/(double)w;
01040          uscale = (double)w/(2.0*(double)t->image().width());
01041          vscale = (double)h/(2.0*aspect*(double)t->image().height());
01042          uoff = 1.0;
01043          voff = aspect;
01044       }
01045 
01046       //Now switch to TEXTURE1 and stomp all over the old state
01047       glActiveTextureARB(GL_TEXTURE1_ARB);
01048 
01049       t->apply_texture(); //calls glBindTexture and sets state
01050 
01051       //Setup the scale matrix to convert from NDC -> UV
01052       glGetIntegerv ( GL_MATRIX_MODE, &query); 
01053       glMatrixMode( GL_TEXTURE );
01054       glLoadIdentity();
01055       glScaled( uscale, vscale, 1.0 );
01056       glTranslated( uoff - orig_x, voff - orig_y, 0.0 );
01057       glMatrixMode( query );
01058 
01059       glEnable(GL_TEXTURE_2D);
01060 
01061       //And return to the 1st texturing unit
01062       glActiveTextureARB(GL_TEXTURE0_ARB);
01063    }
01064 
01065 
01066    //Now setup the fragment program...
01067    GLuint prog;
01068    if (using_texture1)
01069    {
01070       if (glIsEnabled(GL_TEXTURE_1D)) 
01071       {
01072          prog = _paper_with_1d_frag_prog_arb;
01073       }
01074       else if (glIsEnabled(GL_TEXTURE_2D)) 
01075       {
01076          prog = _paper_with_2d_frag_prog_arb;
01077       }
01078       else 
01079       {
01080          prog = _paper_with_no_frag_prog_arb;
01081       }
01082    }
01083    else
01084    {
01085       if (glIsEnabled(GL_TEXTURE_1D)) 
01086       {
01087          prog = _disabled_1d_frag_prog_arb;
01088       }
01089       else if (glIsEnabled(GL_TEXTURE_2D)) 
01090       {
01091          prog = _disabled_2d_frag_prog_arb;
01092       }
01093       else 
01094       {
01095          prog = _disabled_no_frag_prog_arb;
01096       }
01097    }
01098 
01099    glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prog); 
01100 
01101    float c = 2.0f * cont;
01102    float b = 2.0f * ((brig<=0.5f)?(brig):(1.0f-brig+(brig-0.5f)/cont));
01103 
01104    glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, c, c, c, c);
01105    glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, b, b, b, b);
01106 
01107    glEnable(GL_FRAGMENT_PROGRAM_ARB);  //GL_ENABLE_BIT
01108 
01109 #endif
01110 
01111 }
01112 
01113 
01114 /////////////////////////////////////
01115 //  end_paper_effect_nv()
01116 /////////////////////////////////////
01117 void
01118 PaperEffect::end_paper_effect_nv(TEXTUREptr t)
01119 {
01120    assert(_is_inited);
01121    assert(_is_supported);
01122    assert(_implementation & IMPLEMENTATION__GL_NV);
01123 
01124    //If not active, or no texture, then just premultiply alpha...
01125    if (!_is_active || t==NULL) 
01126    {
01127 #ifdef GL_NV_register_combiners
01128 
01129    // Make sure these are still turned on
01130    assert(glIsEnabled(GL_REGISTER_COMBINERS_NV));
01131   
01132    // Kill the combiners
01133    glDisable(GL_REGISTER_COMBINERS_NV);
01134 
01135 #endif
01136    }
01137    else
01138    {
01139 #if defined(GL_NV_register_combiners) && defined(GL_ARB_multitexture)
01140 
01141    GLint query;
01142 
01143    // Make sure these are still turned on
01144    assert(glIsEnabled(GL_REGISTER_COMBINERS_NV));
01145   
01146    // Since nobody else should be playing with
01147    // multitexturing, we should be using the 1st unit
01148    glGetIntegerv ( GL_ACTIVE_TEXTURE_ARB, &query); 
01149    assert(query == GL_TEXTURE0_ARB);
01150 
01151    // Now change to 2nd unit
01152    glActiveTextureARB(GL_TEXTURE1_ARB);
01153    // Kill the combiners
01154    glDisable(GL_REGISTER_COMBINERS_NV);
01155    // Kill the 2nd texture
01156    glDisable(GL_TEXTURE_2D);
01157    // Return to the 1st unit
01158    glActiveTextureARB(GL_TEXTURE0_ARB);
01159 
01160 #endif
01161    }   
01162 }
01163 
01164 /////////////////////////////////////
01165 //  end_paper_effect_ati()
01166 /////////////////////////////////////
01167 void 
01168 PaperEffect::end_paper_effect_ati(TEXTUREptr t)
01169 {
01170    assert(_is_inited);
01171    assert(_is_supported);
01172    assert(_implementation & IMPLEMENTATION__GL_ATI);
01173 
01174 #if defined(GL_ATI_fragment_shader) && defined(GL_ARB_multitexture) && !defined(NON_ATI_GFX)
01175 
01176    GLint query;
01177 
01178    // Make sure that fragment shader is enabled
01179    // XXX - Could even check that the shader has
01180    // an identifier that belongs to the set of
01181    // used by this effect, but that's just totally anal...
01182    assert(glIsEnabled(GL_FRAGMENT_SHADER_ATI));
01183    glDisable(GL_FRAGMENT_SHADER_ATI);
01184 
01185    // Since nobody else should be playing with
01186    // multitexturing, we should still be using the 1st unit...
01187    glGetIntegerv ( GL_ACTIVE_TEXTURE_ARB, &query); 
01188    assert(query == GL_TEXTURE0_ARB);
01189 
01190    // Turn off paper texture...
01191    bool using_texture1 = _is_active && (t != NULL);
01192    if (using_texture1)
01193    {
01194       // Now change to 2nd unit
01195       glActiveTextureARB(GL_TEXTURE1_ARB);
01196 
01197       // Sanity check
01198       assert(glIsEnabled(GL_TEXTURE_2D));
01199 
01200       // Kill the 2nd texture
01201       glDisable(GL_TEXTURE_2D);
01202 
01203       // Return to the 1st unit
01204       glActiveTextureARB(GL_TEXTURE0_ARB);
01205    }
01206 
01207 #endif
01208  
01209 }
01210 
01211 /////////////////////////////////////
01212 //  end_paper_effect_arb()
01213 /////////////////////////////////////
01214 void
01215 PaperEffect::end_paper_effect_arb(TEXTUREptr t)
01216 {
01217    assert(_is_inited);
01218    assert(_is_supported);
01219    assert(_implementation & IMPLEMENTATION__GL_ARB);
01220 
01221    GL_VIEW::print_gl_errors("PaperEffect::end_paper_effect_arb() [Start] - ");
01222 
01223 #if defined(GL_ARB_fragment_program) && defined(GL_ARB_multitexture)
01224 
01225    GLint query;
01226 
01227    // Make sure that fragment program is enabled
01228    // XXX - Could even check that the program has
01229    // an identifier that belongs to the set of
01230    // prgrams used by this effect, but that's
01231    // just totally anal...
01232    assert(glIsEnabled(GL_FRAGMENT_PROGRAM_ARB));
01233    glDisable(GL_FRAGMENT_PROGRAM_ARB);
01234 
01235    // Since nobody else should be playing with
01236    // multitexturing, we should still be using the 1st unit...
01237    glGetIntegerv ( GL_ACTIVE_TEXTURE_ARB, &query); 
01238    assert(query == GL_TEXTURE0_ARB);
01239 
01240    // Turn off paper texture...
01241    bool using_texture1 = _is_active && (t != NULL);
01242    if (using_texture1)
01243    {
01244       // Now change to 2nd unit
01245       glActiveTextureARB(GL_TEXTURE1_ARB);
01246 
01247       // Sanity check
01248       assert(glIsEnabled(GL_TEXTURE_2D));
01249 
01250       // Kill the 2nd texture
01251       glDisable(GL_TEXTURE_2D);
01252 
01253       // Return to the 1st unit
01254       glActiveTextureARB(GL_TEXTURE0_ARB);
01255    }
01256 
01257 #endif
01258    GL_VIEW::print_gl_errors("PaperEffect::end_paper_effect_arb() [End] - ");
01259 }
01260 
01261 /////////////////////////////////////
01262 //  is_alpha_premult()
01263 /////////////////////////////////////
01264 bool
01265 PaperEffect::is_alpha_premult()
01266 {
01267    if (!_is_inited) init();
01268 
01269    return _is_supported;
01270 }
01271 
01272 
01273 /////////////////////////////////////
01274 // get_texture() 
01275 /////////////////////////////////////
01276 TEXTUREptr
01277 PaperEffect::get_texture(Cstr_ptr &in_tf, str_ptr &tf)
01278 {
01279    int ind;
01280 
01281    tf = in_tf;
01282 
01283    //Do lazy initialization...
01284    if (!_paper_texture_names)
01285    {
01286       _paper_texture_names = new LIST<str_ptr>; assert(_paper_texture_names);
01287       _paper_texture_ptrs = new LIST<TEXTUREptr>; assert(_paper_texture_ptrs);
01288 
01289       _paper_texture_remap_orig_names = new LIST<str_ptr>; assert(_paper_texture_remap_orig_names);
01290       _paper_texture_remap_new_names = new LIST<str_ptr>; assert(_paper_texture_remap_new_names);
01291 
01292       int i = 0;
01293       while (paper_remap_fnames[i][0] != NULL)
01294       {
01295          _paper_texture_remap_orig_names->add(Config::JOT_ROOT() + paper_remap_base + paper_remap_fnames[i][0]);
01296          _paper_texture_remap_new_names->add(Config::JOT_ROOT() + paper_remap_base + paper_remap_fnames[i][1]);
01297          i++;
01298       }
01299    }
01300 
01301    //No paper
01302    if (tf == NULL_STR)
01303    {
01304       tf = NULL_STR;
01305    return NULL;
01306    }
01307    else if ((ind = _paper_texture_names->get_index(tf)) != BAD_IND)
01308    {
01309       //Finding original name in cache...
01310 
01311       //If it's a failed texture...
01312       if ((*_paper_texture_ptrs)[ind] == NULL)
01313       {
01314          //...see if it was remapped...
01315          int ii = _paper_texture_remap_orig_names->get_index(tf);
01316          //...and change to looking up the remapped name            
01317          if (ii != BAD_IND)
01318          {
01319             str_ptr old_tf = tf;
01320             tf = (*_paper_texture_remap_new_names)[ii];
01321 
01322             ind = _paper_texture_names->get_index(tf);
01323 
01324             err_mesg(ERR_LEV_SPAM, 
01325                "PaperEffect::get_texture() - Previously remapped -=<[{ (%s) ---> (%s) }]>=-", 
01326                   **old_tf, **tf );
01327          }
01328       }
01329 
01330       //Now see if the final name yields a good texture...
01331       if ((*_paper_texture_ptrs)[ind] != NULL)
01332       {
01333          err_mesg(ERR_LEV_SPAM, "PaperEffect::get_texture() - Using cached copy of texture.");
01334          tf = tf;
01335          return (*_paper_texture_ptrs)[ind];
01336       }
01337       else
01338       {
01339          err_mesg(ERR_LEV_INFO, "PaperEffect::get_texture() - **ERROR** Previous caching failure: '%s'...", **tf);
01340          tf = NULL_STR;
01341          return NULL;
01342       }
01343    }
01344    //Haven't seen this name before...
01345    else
01346    {
01347       err_mesg(ERR_LEV_SPAM, "PaperEffect::get_texture() - Not in cache: '%s'", **tf);
01348 
01349       Image i(**tf);
01350 
01351       //Can't load the texture?
01352       if (i.empty())
01353       {
01354          //...check for a remapped file...
01355          int ii = _paper_texture_remap_orig_names->get_index(tf);
01356 
01357          //...and use that name instead....
01358          if (ii != BAD_IND)
01359          {
01360             //...but also indicate that the original name is bad...
01361 
01362             _paper_texture_names->add(tf);
01363             _paper_texture_ptrs->add(NULL);
01364 
01365             str_ptr old_tf = tf;
01366             tf = (*_paper_texture_remap_new_names)[ii];
01367 
01368             err_mesg(ERR_LEV_ERROR, 
01369                "PaperEffect::get_texture() - Remapping --===<<[[{{ (%s) ---> (%s) }}]]>>===--", 
01370                   **old_tf, **tf );
01371 
01372             i.load_file(**tf);
01373          }
01374       }
01375 
01376       //If the final name loads, store the cached texture...
01377       if (!i.empty())
01378       {
01379       TEXTUREglptr t = new TEXTUREgl("");
01380          
01381          t->set_save_img(true);
01382          t->set_mipmap(false);
01383       t->set_image(i.copy(),i.width(),i.height(),i.bpp());
01384 
01385          _paper_texture_names->add(tf);
01386          _paper_texture_ptrs->add(t);
01387 
01388          err_mesg(ERR_LEV_INFO, 
01389             "PaperEffect::get_texture() - Cached: (w=%d h=%d bpp=%u) %s", 
01390                i.width(), i.height(), i.bpp(), **tf);
01391 
01392          tf = tf;
01393       return t;
01394       }
01395       //Otherwise insert a failed NULL...
01396       else
01397       {
01398          err_mesg(ERR_LEV_ERROR, "PaperEffect::get_texture() - *****ERROR***** Failed loading to cache: '%s'", **tf);
01399 
01400          _paper_texture_names->add(tf);
01401          _paper_texture_ptrs->add(NULL);
01402 
01403          tf = NULL_STR;
01404          return NULL;
01405       }
01406    }
01407    // g++ 4.0 on macosx needs the following:
01408    return NULL;
01409 }
01410 
01411 /*
01412 TEXTUREptr
01413 PaperEffect::get_texture(Cstr_ptr &tf)
01414 {
01415    int index;
01416    
01417    if (tf == NULL_STR)
01418    {
01419    return 0;
01420    }
01421    else if ((index = _paper_names.get_index(tf)) != BAD_IND)
01422    {
01423       err_mesg(ERR_LEV_INFO, "PaperEffect::get_texture() - Using cached copy of texture.");
01424       return _paper_textures[index];
01425    }
01426    else
01427    {
01428       err_mesg(ERR_LEV_INFO, "PaperEffect::get_texture() - Not in cache: %s", **tf);
01429 
01430       Image image(**tf);
01431 
01432       if (!image.empty())
01433       {
01434       TEXTUREglptr t = new TEXTUREgl("");
01435          t->set_save_img(true);
01436          t->set_mipmap(false);
01437       t->set_image(image.copy(),image.width(),image.height(),image.bpp());
01438 
01439          err_mesg(ERR_LEV_INFO, "PaperEffect::get_texture() - Cached: w=%d h=%d bpp=%d", image.width(), image.height(), image.bpp());
01440 
01441          _paper_names.add(tf);
01442          _paper_textures.add(t);
01443 
01444       return t;
01445       }
01446       else
01447       {
01448          err_mesg(ERR_LEV_ERROR, "PaperEffect::get_texture() - Error loading to cache: %s", **tf);
01449          return 0;
01450       }
01451    }   
01452 }
01453 */
01454 
01455 /////////////////////////////////////
01456 // check_new_paper() 
01457 /////////////////////////////////////
01458 bool
01459 PaperEffect::check_new_paper()
01460 {
01461    //XXX - Since mipmapping is NOT on, these textures must have 2^n dimensions? (REALLY?)
01462 
01463    str_ptr new_paper_filename = (_paper_tex)?(Config::JOT_ROOT() + _paper_tex):(NULL_STR);
01464 
01465    if (new_paper_filename != _paper_filename)        
01466    {
01467       str_ptr ret_filename;
01468       
01469       _paper_texture = get_texture(new_paper_filename, ret_filename);
01470       _paper_filename = ret_filename;
01471 
01472       if (ret_filename == NULL_STR)
01473       {
01474          _paper_tex = NULL_STR;         
01475       }
01476       else
01477       {
01478          //JOT_ROOT should be at start of this filename...
01479          assert(strstr(**_paper_filename,**Config::JOT_ROOT()) == **_paper_filename );
01480 
01481          //Now strip it off...
01482          _paper_tex = &((**_paper_filename)[Config::JOT_ROOT().len()]);
01483       }
01484 
01485 
01486       notify_paper_changed();
01487 
01488       return true;
01489    }
01490    return false;
01491 }
01492 
01493 /////////////////////////////////////
01494 // init()
01495 /////////////////////////////////////
01496 void
01497 PaperEffect::init()
01498 {
01499    GL_VIEW::print_gl_errors("PaperEffect::init() [Start] - ");
01500 
01501    assert(!_is_inited);
01502 
01503    _is_inited = true;
01504 
01505    GLExtensions::init();
01506 
01507    _is_supported = false;
01508 
01509    _implementation = IMPLEMENTATION__NONE;
01510 
01511    err_mesg(ERR_LEV_INFO, "\nPaperEffect::init() - Querying hardware support...");      
01512 
01513    // Check for GL_ARB_multitexture...
01514    err_mesg(ERR_LEV_INFO, "PaperEffect::init() - Trying for GL_ARB_multitexture...");      
01515    
01516    if (init_tex())
01517    {
01518       err_mesg(ERR_LEV_INFO, "PaperEffect::init() - ...GL_ARB_multitexture is available.");      
01519 
01520       // Check for GL_ARB_fragement_program...
01521       err_mesg(ERR_LEV_INFO, "PaperEffect::init() - Trying for GL_ARB_fragement_program...");      
01522       if (init_arb())
01523       {
01524          err_mesg(ERR_LEV_INFO, "PaperEffect::init() - ...GL_ARB_fragement_program is available.");      
01525          
01526          _is_supported = true;
01527          _implementation |= IMPLEMENTATION__GL_ARB;
01528       }
01529       else
01530       {
01531          err_mesg(ERR_LEV_INFO, "PaperEffect::init() - ...GL_ARB_fragement_program is *NOT* available.");      
01532       }   
01533 
01534       // Check for GL_NV_register_combiners...
01535       err_mesg(ERR_LEV_INFO, "PaperEffect::init() - Trying for GL_NV_register_combiners...");      
01536       
01537       if (init_nv())
01538       {
01539          err_mesg(ERR_LEV_INFO, "PaperEffect::init() - ...GL_NV_register_combiners is available.");      
01540          
01541          _is_supported = true;
01542          _implementation |= IMPLEMENTATION__GL_NV;
01543       }
01544       else
01545       {
01546          err_mesg(ERR_LEV_INFO, "PaperEffect::init() - ...GL_NV_register_combiners is *NOT* available."); 
01547       }
01548 
01549       // Check for GL_ATI_fragment_shader...
01550       err_mesg(ERR_LEV_INFO, "PaperEffect::init() - Trying for GL_ATI_fragment_shader...");      
01551       
01552       if (init_ati())
01553       {
01554          err_mesg(ERR_LEV_INFO, "PaperEffect::init() - ...GL_ATI_fragment_shader is available.");      
01555          
01556          _is_supported = true;
01557          _implementation |= IMPLEMENTATION__GL_ATI;
01558       }
01559       else
01560       {
01561          err_mesg(ERR_LEV_INFO, "PaperEffect::init() - ...GL_ATI_fragment_shader is *NOT* available."); 
01562       }
01563    }
01564    else
01565    {
01566       err_mesg(ERR_LEV_INFO, "PaperEffect::init() - ...GL_ARB_multitexture is *NOT* available.");      
01567    }
01568 
01569    if (_is_supported)
01570    {
01571       err_mesg(ERR_LEV_INFO, "PaperEffect::init() - ...hardware support available!");
01572    }
01573    else
01574    {
01575       err_mesg(ERR_LEV_INFO, "PaperEffect::init() - ...hardware support *NOT* available! **SORRY**");
01576    }
01577 
01578    GL_VIEW::print_gl_errors("PaperEffect::init() [End] - ");
01579 
01580 }
01581 
01582 /////////////////////////////////////
01583 // init_tex()
01584 /////////////////////////////////////
01585 bool
01586 PaperEffect::init_tex()
01587 {
01588    bool ret = false;
01589 
01590    if (GLExtensions::gl_arb_multitexture_supported()) 
01591    {
01592 #ifdef GL_ARB_multitexture
01593       GLint num_texture = 0;
01594       glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &num_texture);
01595       if (num_texture >= 2)
01596       {
01597          ret = true;
01598          err_mesg(ERR_LEV_INFO, "PaperEffect::init_tex() - Need 2 TEX units, found %d.", num_texture);
01599       }
01600       else 
01601          err_mesg(ERR_LEV_INFO, "PaperEffect::init_tex() - Need 2 TEX units, *ONLY* found %d!", num_texture);
01602 #endif
01603    }
01604    else
01605    {
01606       err_mesg(ERR_LEV_INFO, "PaperEffect::init_nv() - GL_ARB_multitexture is NOT supported by hardware!");
01607    }
01608 
01609    return ret;
01610 }
01611 
01612 /////////////////////////////////////
01613 // init_nv()
01614 /////////////////////////////////////
01615 bool
01616 PaperEffect::init_nv()
01617 {
01618    bool ret = false;
01619 
01620    if (GLExtensions::gl_nv_register_combiners_supported()) 
01621    {
01622 #ifdef GL_NV_register_combiners
01623       GLint num_stage = 0;
01624       glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV,&num_stage);
01625       if (num_stage >= 2) 
01626       {
01627          err_mesg(ERR_LEV_INFO, "PaperEffect::init_nv() - Need 2 general combiner stages, found %d.", num_stage);
01628          ret = true;
01629       }
01630       else 
01631          err_mesg(ERR_LEV_INFO, "PaperEffect::init_nv() - Need 2 general combiner stages, *ONLY* found %d!", num_stage);
01632 #endif
01633    }
01634    else
01635    {
01636       err_mesg(ERR_LEV_INFO, "PaperEffect::init_nv() - GL_NV_register_combiners is NOT supported by hardware!");
01637    }
01638 
01639    return ret;
01640 }
01641 
01642 /////////////////////////////////////
01643 // init_ati()
01644 /////////////////////////////////////
01645 bool
01646 PaperEffect::init_ati()
01647 {
01648    bool ret = false;
01649 
01650    if (GLExtensions::gl_ati_fragment_shader_supported()) 
01651    {
01652    
01653 #if !defined(NON_ATI_GFX)
01654 #ifdef GL_ATI_fragment_shader
01655 
01656       GL_VIEW::print_gl_errors("PaperEffect::init_ati() [Start] - ");
01657 
01658       ret = true;
01659 
01660       err_mesg(ERR_LEV_INFO, "PaperEffect::init_ati() - Compiling fragment shader...");
01661 
01662       _paper_frag_shader_ati = glGenFragmentShadersATI(1); 
01663       glBindFragmentShaderATI(_paper_frag_shader_ati); 
01664 
01665       glBeginFragmentShaderATI();
01666 
01667       glSampleMapATI(GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STQ_DQ_ATI); 
01668       glSampleMapATI(GL_REG_1_ATI, GL_TEXTURE1_ARB, GL_SWIZZLE_STQ_DQ_ATI); 
01669 
01670       //Pass 1 - Instruction Pair 1
01671       //R0[rgb] <- R0[rgb] * PRIM[rgb] {modulate by TEX0}
01672       //R0[a] <-   R0[a]   * PRIM[a]
01673       glColorFragmentOp2ATI( GL_MUL_ATI,                         
01674                                  GL_REG_0_ATI,           GL_NONE,    GL_NONE,  
01675                                  GL_REG_0_ATI,           GL_NONE,    GL_NONE,  
01676                                  GL_PRIMARY_COLOR_ARB,   GL_NONE,    GL_NONE); 
01677 
01678       glAlphaFragmentOp2ATI( GL_MUL_ATI, 
01679                                  GL_REG_0_ATI,                       GL_NONE,
01680                                  GL_REG_0_ATI,           GL_NONE,    GL_NONE,
01681                                  GL_PRIMARY_COLOR_ARB,   GL_NONE,    GL_NONE);
01682 
01683 
01684       //Pass 1 - Instruction Pair 2
01685       //R4[rgb] <- (C0[rgb]>0.5) ? R0[rgb] : PRIM[rgb] {load PRIM or PRIM*TEX0 into R0 depending on C0}
01686       //R4[a]   <- (C0[a]>0.5)   ? R0[a]   : PRIM[a]
01687       glColorFragmentOp3ATI( GL_CND_ATI,                         
01688                                  GL_REG_0_ATI,           GL_NONE,    GL_NONE,  
01689                                  GL_REG_0_ATI,           GL_NONE,    GL_NONE,  
01690                                  GL_PRIMARY_COLOR_ARB,   GL_NONE,    GL_NONE,                                   
01691                                  GL_CON_0_ATI,           GL_NONE,    GL_NONE); 
01692       glAlphaFragmentOp3ATI( GL_CND_ATI, 
01693                                  GL_REG_0_ATI,                       GL_NONE,  
01694                                  GL_REG_0_ATI,           GL_NONE,    GL_NONE,  
01695                                  GL_PRIMARY_COLOR_ARB,   GL_NONE,    GL_NONE,                                   
01696                                  GL_CON_0_ATI,           GL_NONE,    GL_NONE); 
01697 
01698       //Pass 1 - Instruction Pair 4
01699       //R2[a] <- clamp(2*R0[a])
01700       glAlphaFragmentOp1ATI( GL_MOV_ATI, 
01701                                  GL_REG_2_ATI,                       GL_SATURATE_BIT_ATI,
01702                                  GL_REG_0_ATI,           GL_NONE,    GL_2X_BIT_ATI);
01703 
01704 
01705       //Pass 1 - Instruction Pair 5
01706       //R3[a] <- clamp(2*(R0[a]-.5))
01707       glAlphaFragmentOp1ATI( GL_MOV_ATI, 
01708                                  GL_REG_3_ATI,                       GL_SATURATE_BIT_ATI,
01709                                  GL_REG_0_ATI,           GL_NONE,    GL_BIAS_BIT_ATI | GL_2X_BIT_ATI);
01710       
01711       
01712       //Pass 1 - Instruction Pair 6
01713       //R1[a] <- C1[a] + 2*C2[a]*R1[a] {(0.5-cont)+2(2*brig'*cont)*h}
01714       glAlphaFragmentOp3ATI( GL_MAD_ATI, 
01715                                  GL_REG_1_ATI,                       GL_SATURATE_BIT_ATI,
01716                                  GL_CON_2_ATI,           GL_NONE,    GL_2X_BIT_ATI,
01717                                  GL_REG_1_ATI,           GL_NONE,    GL_NONE,
01718                                  GL_CON_1_ATI,           GL_NONE,    GL_NONE);
01719 
01720       //Pass 1 - Instruction Pair 7
01721       //R0[a] <- R1[a]*R2[a] + (1-R1[a])*R3[a]
01722       glAlphaFragmentOp3ATI( GL_LERP_ATI, 
01723                                  GL_REG_0_ATI,                       GL_NONE,
01724                                  GL_REG_1_ATI,           GL_NONE,    GL_NONE,
01725                                  GL_REG_2_ATI,           GL_NONE,    GL_NONE,
01726                                  GL_REG_3_ATI,           GL_NONE,    GL_NONE);
01727 
01728       //Pass 1 - Instruction Pair 8
01729       //R0[rgb] <- R0[rgb] * R0[aaa]
01730 
01731       glColorFragmentOp2ATI( GL_MUL_ATI,                           //ADD,SUB,MUL,MAD,LERP,MOV,CND,CND0,DOTn
01732                                  GL_REG_0_ATI, GL_NONE,  GL_NONE,  //NONE = RED | GREEN | BLUE
01733                                                                    //EIGHTH, QUARTH, HALF, 2X, 4X, 8X | SATURATE
01734                                  GL_REG_0_ATI, GL_NONE,  GL_NONE,  //RED , GREEN , BLUE, ALPHA, NONE
01735                                                                    //NEGATE | COMP |BIAS | 2X [-(2*((1.0-s)-0.5))]
01736                                  GL_REG_0_ATI, GL_ALPHA, GL_NONE); 
01737 
01738 
01739       glEndFragmentShaderATI();
01740 
01741       ret = !GL_VIEW::print_gl_errors("PaperEffect::init_ati() [End] - ") && ret;
01742 
01743       if (ret)
01744       {
01745          err_mesg(ERR_LEV_INFO, "PaperEffect::init_ati() - ...done.");
01746       }
01747       else
01748       {
01749          err_mesg(ERR_LEV_INFO, "PaperEffect::init_ati() - ...failed!!");
01750       }
01751 #endif
01752 #endif
01753    }
01754    else
01755    {
01756       err_mesg(ERR_LEV_INFO, "PaperEffect::init_ati() - GL_ATI_fragment_shader is NOT supported by hardware!");
01757    }
01758 
01759    return ret;
01760 }
01761 
01762 /////////////////////////////////////
01763 // init_arb()
01764 /////////////////////////////////////
01765 bool
01766 PaperEffect::init_arb()
01767 {
01768    bool ret = false;
01769 
01770    //XXX - Make sure we're not getting here with pending errors...
01771    GL_VIEW::print_gl_errors("PaperEffect::init_arb() [Start] - ");
01772 
01773    if (GLExtensions::gl_arb_fragment_program_supported())
01774    {
01775       err_mesg(ERR_LEV_INFO, "PaperEffect::init_arb() - GL_ARB_fragment_program supported. Trying programs...");
01776 #ifdef GL_ARB_fragment_program
01777 
01778       bool n, native = true;
01779 
01780       ret = true; 
01781 
01782       glGenProgramsARB(1, &_disabled_no_frag_prog_arb); 
01783       glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, _disabled_no_frag_prog_arb); 
01784       glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
01785                            strlen(_DisabledNoFragProgARB), _DisabledNoFragProgARB);
01786       ret = ret && GLExtensions::gl_arb_fragment_program_loaded("PaperEffect::init_arb() (Off - No Tex) - ", n, (const unsigned char *)_DisabledNoFragProgARB);
01787       native = native && n;
01788       
01789       glGenProgramsARB(1, &_disabled_1d_frag_prog_arb); 
01790       glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, _disabled_1d_frag_prog_arb); 
01791       glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
01792                            strlen(_Disabled1DFragProgARB), _Disabled1DFragProgARB);
01793       ret = ret && GLExtensions::gl_arb_fragment_program_loaded("PaperEffect::init_arb() (Off - 1D Tex) - ", n, (const unsigned char *)_Disabled1DFragProgARB);
01794       native = native && n;
01795 
01796       glGenProgramsARB(1, &_disabled_2d_frag_prog_arb); 
01797       glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, _disabled_2d_frag_prog_arb); 
01798       glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
01799                            strlen(_Disabled2DFragProgARB), _Disabled2DFragProgARB);
01800       ret = ret && GLExtensions::gl_arb_fragment_program_loaded("PaperEffect::init_arb() (Off - 2D Tex) - ", n, (const unsigned char *)_Disabled2DFragProgARB);
01801       native = native && n;
01802 
01803       glGenProgramsARB(1, &_paper_with_no_frag_prog_arb); 
01804       glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, _paper_with_no_frag_prog_arb); 
01805       glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
01806                            strlen(_PaperWithNoFragProgARB), _PaperWithNoFragProgARB);
01807       ret = ret && GLExtensions::gl_arb_fragment_program_loaded("PaperEffect::init_arb() (On - No Tex) - ", n, (const unsigned char *)_PaperWithNoFragProgARB);
01808       native = native && n;
01809       
01810       glGenProgramsARB(1, &_paper_with_1d_frag_prog_arb); 
01811       glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, _paper_with_1d_frag_prog_arb); 
01812       glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
01813                            strlen(_PaperWith1DFragProgARB), _PaperWith1DFragProgARB);
01814       ret = ret && GLExtensions::gl_arb_fragment_program_loaded("PaperEffect::init_arb() (On - 1D Tex) - ", n, (const unsigned char *)_PaperWith1DFragProgARB);
01815       native = native && n;
01816 
01817       glGenProgramsARB(1, &_paper_with_2d_frag_prog_arb); 
01818       glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, _paper_with_2d_frag_prog_arb); 
01819       glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
01820                            strlen(_PaperWith2DFragProgARB), _PaperWith2DFragProgARB);
01821       ret = ret && GLExtensions::gl_arb_fragment_program_loaded("PaperEffect::init_arb() (On - 2D Tex) - ", n, (const unsigned char *)_PaperWith2DFragProgARB);
01822       native = native && n;
01823 
01824       if (ret)
01825       {
01826          err_mesg(ERR_LEV_INFO, "PaperEffect::init_arb() - ...all programs loaded successfully, ");
01827          if (native)
01828          {
01829             err_mesg(ERR_LEV_INFO, "PaperEffect::init_arb() - ...and will run native in hardware!");
01830          }
01831          else
01832          {
01833             err_mesg(ERR_LEV_INFO, "PaperEffect::init_arb() - ...but all will *NOT* run native in hardware!");
01834          }
01835       }
01836       else
01837       {
01838          err_mesg(ERR_LEV_INFO, "PaperEffect::init_arb() - ...all programs *NOT* loaded successfully.");
01839       }
01840       
01841 #endif
01842    }
01843    else
01844    {
01845       err_mesg(ERR_LEV_INFO, "PaperEffect::init_arb() - GL_ARB_fragment_program is NOT supported by hardware!");
01846    }
01847 
01848    GL_VIEW::print_gl_errors("PaperEffect::init_arb() [End] - ");
01849 
01850    return ret;
01851 }

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