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

OSGDisplayCalibration.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *               Copyright (C) 2000-2002 by the OpenSG Forum                 *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00039 //---------------------------------------------------------------------------
00040 //  Includes
00041 //---------------------------------------------------------------------------
00042 
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045 
00046 #include <OSGConfig.h>
00047 #include <OSGSimpleGeometry.h>
00048 #include <OSGMaterialChunk.h>
00049 
00050 #include "OSGDisplayCalibration.h"
00051 
00052 OSG_USING_NAMESPACE
00053 
00054 /***************************************************************************\
00055  *                            Description                                  *
00056 \***************************************************************************/
00057 
00062 /***************************************************************************\
00063  *                           Class variables                               *
00064 \***************************************************************************/
00065 
00066 /***************************************************************************\
00067  *                           Class methods                                 *
00068 \***************************************************************************/
00069 
00070 void DisplayCalibration::initMethod (void)
00071 {
00072 }
00073 
00074 
00075 /***************************************************************************\
00076  *                           Instance methods                              *
00077 \***************************************************************************/
00078 
00079 /*-------------------------------------------------------------------------*\
00080  -  private                                                                 -
00081 \*-------------------------------------------------------------------------*/
00082 
00083 /*----------------------- constructors & destructors ----------------------*/
00084 
00085 DisplayCalibration::DisplayCalibration(void) :
00086     Inherited(),
00087     _changed(true),
00088     _cmPort(NullFC),
00089     _dsPort(NullFC),
00090     _dsPort2(NullFC)
00091 {
00092 }
00093 
00094 DisplayCalibration::DisplayCalibration(const DisplayCalibration &source) :
00095     Inherited(source),
00096     _changed(true),
00097     _cmPort(NullFC),
00098     _dsPort(NullFC),
00099     _dsPort2(NullFC)
00100 {
00101 }
00102 
00103 DisplayCalibration::~DisplayCalibration(void)
00104 {
00105     if(_cmPort != osg::NullFC) 
00106     {
00107         subRefCP(_cmPort);
00108         subRefCP(_dsPort);
00109         subRefCP(_dsPort2);
00110         subRefCP(_cmRoot);
00111         subRefCP(_dsRoot);
00112         subRefCP(_ds2Root);
00113         subRefCP(_cam);
00114         subRefCP(_dsBack);
00115         subRefCP(_ds2Back);
00116     }
00117 }
00118 
00119 /*----------------------------- class specific ----------------------------*/
00120 
00123 void DisplayCalibration::calibrate(WindowPtr window,RenderActionBase *ract)
00124 {
00125     if(!getEnabled())
00126         return;
00127 
00128     createCMViewports(window);
00129 
00130     window->addPort(_cmPort);
00131     _cmPort->render(ract);
00132     window->subPort(_cmPort);
00133 
00134     if(getScaleDown() < 1.0f)
00135     {
00136         window->addPort(_dsPort);
00137         _dsPort->render(ract);
00138         window->subPort(_dsPort);
00139         window->addPort(_dsPort2);
00140         _dsPort2->render(ract);
00141         window->subPort(_dsPort2);
00142     }
00143 
00144 }
00145 
00146 void DisplayCalibration::changed(BitVector whichField, UInt32 origin)
00147 {
00148     _changed = true;
00149     Inherited::changed(whichField, origin);
00150 }
00151 
00152 void DisplayCalibration::dump(      UInt32    , 
00153                          const BitVector ) const
00154 {
00155     SLOG << "Dump DisplayCalibration NI" << std::endl;
00156 }
00157 
00158 void DisplayCalibration::createCMViewports(WindowPtr window)
00159 {
00160     // create color management structures
00161     if(_cmPort != osg::NullFC &&
00162        !_changed &&
00163        _winWidth == window->getWidth() &&
00164        _winHeight == window->getHeight())
00165         return;
00166 
00167     if(getScaleDown()>1.0)
00168         setScaleDown(1.0);
00169 
00170     _changed = false;
00171     _winWidth = window->getWidth();
00172     _winHeight = window->getHeight();
00173 
00174     // reset
00175     if(_cmPort != osg::NullFC) {
00176         subRefCP(_cmPort);
00177         subRefCP(_dsPort);
00178         subRefCP(_dsPort2);
00179         subRefCP(_cmRoot);
00180         subRefCP(_dsRoot);
00181         subRefCP(_ds2Root);
00182         subRefCP(_cam);
00183         subRefCP(_dsBack);
00184         subRefCP(_ds2Back);
00185     }
00186 
00187     Matrix m;
00188     ImagePtr img = Image::create();
00189     beginEditCP(img);
00190     img->set(GL_RGB,1,1);
00191     endEditCP(img);
00192 
00193     int extension = osg::Window::registerExtension("GL_ARB_fragment_program");
00194     if(window->hasExtension(extension))
00195     {
00196         SINFO << "Use fragment program for color crrection" << std::endl;
00197         _useFragmentProgram = true;
00198     }
00199     else
00200     {
00201         SINFO << "Use reg combiner for color crrection" << std::endl;
00202         _useFragmentProgram = false;
00203     }
00204     
00205     TextureChunkPtr tex = TextureChunk::create();    
00206 
00207     if(_useFragmentProgram)
00208     {
00209         // Step 1: The texture from the GrabBackground
00210 
00211         beginEditCP(tex);
00212         tex->setImage(img);
00213         tex->setMinFilter(GL_NEAREST);
00214         tex->setScale(false);
00215         tex->setEnvMode(GL_REPLACE);
00216         endEditCP  (tex);
00217 
00218         // Step 2: The textures for the initial gamma mapping
00219         
00220         // Texture Chunks for gamma mapping
00221         
00222         UChar8 rgammadata[] =
00223             {  0, 80, 160, 255 };
00224         
00225         _rgammaimg = Image::create();
00226         beginEditCP(_rgammaimg);
00227         _rgammaimg->set(Image::OSG_L_PF,4,1,1,1,1,0,rgammadata);
00228         endEditCP(_rgammaimg);
00229         
00230         _rgammachunk = TextureChunk::create();    
00231         beginEditCP(_rgammachunk);
00232         _rgammachunk->setImage(_rgammaimg);
00233         _rgammachunk->setMinFilter(GL_LINEAR);
00234         _rgammachunk->setMagFilter(GL_LINEAR);
00235         _rgammachunk->setWrapS(GL_CLAMP_TO_EDGE);
00236         _rgammachunk->setWrapT(GL_CLAMP_TO_EDGE);
00237         endEditCP  (_rgammachunk);
00238         
00239         UChar8 ggammadata[] =
00240             {  0, 80, 160, 255 };
00241         
00242         _ggammaimg = Image::create();
00243         beginEditCP(_ggammaimg);
00244         _ggammaimg->set(Image::OSG_L_PF,4,1,1,1,1,0,ggammadata);
00245         endEditCP(_ggammaimg);
00246         
00247         _ggammachunk = TextureChunk::create();    
00248         beginEditCP(_ggammachunk);
00249         _ggammachunk->setImage(_ggammaimg);
00250         _ggammachunk->setMinFilter(GL_LINEAR);
00251         _ggammachunk->setMagFilter(GL_LINEAR);
00252         _ggammachunk->setWrapS(GL_CLAMP_TO_EDGE);
00253         _ggammachunk->setWrapT(GL_CLAMP_TO_EDGE);
00254         endEditCP  (_ggammachunk);
00255 
00256         UChar8 bgammadata[] =
00257             {  0, 80, 160, 255 };
00258         
00259         _bgammaimg = Image::create();
00260         beginEditCP(_bgammaimg);
00261         _bgammaimg->set(Image::OSG_L_PF,4,1,1,1,1,0,bgammadata);
00262         endEditCP(_bgammaimg);
00263     
00264         _bgammachunk = TextureChunk::create();    
00265         beginEditCP(_bgammachunk);
00266         _bgammachunk->setImage(_bgammaimg);
00267         _bgammachunk->setMinFilter(GL_LINEAR);
00268         _bgammachunk->setMagFilter(GL_LINEAR);
00269         _bgammachunk->setWrapS(GL_CLAMP_TO_EDGE);
00270         _bgammachunk->setWrapT(GL_CLAMP_TO_EDGE);
00271         endEditCP  (_bgammachunk);
00272 
00273         // set gamma table
00274         for(int j=0; j < 3; ++j)
00275         {
00276             ImagePtr img;
00277             switch(j)
00278             {
00279                 case 0: img = _rgammaimg; break;
00280                 case 1: img = _ggammaimg; break;
00281                 case 2: img = _bgammaimg; break;
00282             }
00283             beginEditCP(img);
00284             if(getGammaRamp().size() == 0)
00285             {
00286                 img->set(Image::OSG_L_PF, 256, 1);
00287                 UInt8 *data = img->getData();
00288                 for(int i=0; i < 256; i++)
00289                 {
00290                     data[i] = (UInt8)(pow(i/255.0,1.0)*255);
00291                 }
00292             }
00293             else
00294             {
00295                 img->set(Image::OSG_L_PF, getGammaRamp().size(), 1);
00296                 UInt8 *data = img->getData();
00297                 for(int i=0; i < getGammaRamp().size(); i++)
00298                 {
00299                     data[i] = (UInt8)(getGammaRamp()[i][j] * 255);
00300                 }
00301             }
00302             endEditCP(img);
00303         }
00304 
00305         // Step 3: FragmentProgram Chunk for color matrix multiply
00306         m.setValue(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1);     
00307         
00308         _fragProgram = FragmentProgramChunk::create();
00309         std::string prog(
00310             "!!ARBfp1.0\n"
00311             "PARAM mat0 = program.local[1];\n"
00312             "PARAM mat1 = program.local[2];\n"
00313             "PARAM mat2 = program.local[3];\n"
00314             "PARAM mat3 = program.local[4];\n"
00315             "PARAM gamma = program.local[5];\n"
00316             "TEMP source;\n"
00317             "TEMP target;\n"
00318             "\n"
00319             "# get the grabbed texture's color\n"
00320             "TEX source, fragment.texcoord[0], texture[0], 2D;\n"
00321             "\n"
00322             "# gamma map it\n"
00323             "POW source.r, source.r, gamma.r;\n"
00324             "POW source.g, source.g, gamma.r;\n"
00325             "POW source.b, source.b, gamma.r;\n"
00326             "\n"
00327             "# do the matrix transform\n"
00328             "DP4 target.x, mat0, source;\n"
00329             "DP4 target.y, mat1, source;\n"
00330             "DP4 target.z, mat2, source;\n"
00331             "\n"
00332             "# map it through the target gamma\n"
00333             "TEX target.r, target.r, texture[1], 1D;\n"
00334             "TEX target.g, target.g, texture[2], 1D;\n"
00335             "TEX target.b, target.b, texture[3], 1D;\n"
00336             "\n"
00337             "# mov it to the output\n"
00338             "MOV result.color, target;\n"
00339             "END\n");
00340         
00341         beginEditCP(_fragProgram);
00342         _fragProgram->setProgram(prog);
00343         endEditCP(_fragProgram);
00344     }   
00345     else
00346     {
00347         // Step 1: The texture from the GrabBackground
00348 
00349         beginEditCP(tex);
00350         tex->setImage(img);
00351         tex->setMinFilter(GL_NEAREST);
00352         tex->setScale(false);
00353         tex->setEnvMode(GL_REPLACE);
00354         tex->setShaderOperation(GL_TEXTURE_2D);
00355         tex->setInternalFormat(GL_RGB8);
00356         endEditCP  (tex);
00357 
00358         // Step 2: The textures for the initial gamma mapping
00359   
00360         // Texture Chunks for gamma mapping
00361 
00362         UChar8 _argammadata[] =
00363             {  0,  0,  0,    0,  0,  0,    0,  0,  0,    0,  0,  0,    
00364                80,  0,  0,   80,  0,  0,   80,  0,  0,   80,  0,  0,    
00365                160,  0,  0,  160,  0,  0,  160,  0,  0,  160,  0,  0,    
00366                255,  0,  0,  255,  0,  0,  255,  0,  0,  255,  0,  0  
00367             };
00368     
00369         _argammaimg = Image::create();
00370         beginEditCP(_argammaimg);
00371         _argammaimg->set(GL_RGB,4,4,1,1,1,0,_argammadata);
00372         endEditCP(_argammaimg);
00373     
00374         _argammachunk = TextureChunk::create();    
00375         beginEditCP(_argammachunk);
00376         _argammachunk->setImage(_argammaimg);
00377         _argammachunk->setMinFilter(GL_NEAREST);
00378         _argammachunk->setMagFilter(GL_NEAREST);
00379         _argammachunk->setWrapS(GL_CLAMP_TO_EDGE);
00380         _argammachunk->setWrapT(GL_CLAMP_TO_EDGE);
00381         _argammachunk->setShaderOperation(GL_DEPENDENT_AR_TEXTURE_2D_NV);
00382         _argammachunk->setShaderInput    (GL_TEXTURE0_ARB);
00383         _argammachunk->setInternalFormat(GL_RGB8);
00384         endEditCP  (_argammachunk);
00385 
00386         UChar8 _gbgammadata[] =
00387             {  0,  0,  0,     0, 80,  0,     0,160,  0,    0,255,  0,
00388                0,  0, 80,     0, 80, 80,     0,160, 80,    0,255, 80,
00389                0,  0,160,     0, 80,160,     0,160,160,    0,255,160,
00390                0,  0,255,     0, 80,255,     0,160,255,    0,255,255
00391             };
00392     
00393         _gbgammaimg = Image::create();
00394         beginEditCP(_gbgammaimg);
00395         _gbgammaimg->set(GL_RGB,4,4,1,1,1,0,_gbgammadata);
00396         endEditCP(_gbgammaimg);
00397     
00398         _gbgammachunk = TextureChunk::create();    
00399         beginEditCP(_gbgammachunk);
00400         _gbgammachunk->setImage(_gbgammaimg);
00401         _gbgammachunk->setMinFilter(GL_NEAREST);
00402         _gbgammachunk->setMagFilter(GL_NEAREST);
00403         _gbgammachunk->setWrapS(GL_CLAMP_TO_EDGE);
00404         _gbgammachunk->setWrapT(GL_CLAMP_TO_EDGE);
00405         _gbgammachunk->setShaderOperation(GL_DEPENDENT_GB_TEXTURE_2D_NV);
00406         _gbgammachunk->setShaderInput    (GL_TEXTURE0_ARB);
00407         _gbgammachunk->setInternalFormat(GL_RGB8);
00408         endEditCP  (_gbgammachunk);
00409 
00410         // Step 3: RegisterCombiners Chunk for color matrix multiply
00411 
00412         m.setValue(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1);     
00413         m.setValue(1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1);
00414         
00415         _regCombiner = RegisterCombinersChunk::create();
00416     }
00417 
00418     // putting it all together
00419         
00420     ChunkMaterialPtr mat = ChunkMaterial::create();
00421     beginEditCP(mat);
00422     mat->addChunk(tex);
00423     if(_useFragmentProgram)
00424     {
00425         mat->addChunk(_rgammachunk);
00426         mat->addChunk(_ggammachunk);
00427         mat->addChunk(_bgammachunk);
00428         mat->addChunk(_fragProgram);
00429     }
00430     else
00431     {
00432         mat->addChunk(_argammachunk);
00433         mat->addChunk(_gbgammachunk);
00434         mat->addChunk(_regCombiner);
00435     }
00436     endEditCP(mat);
00437 
00438     // add the second viewport
00439      
00440     GeoPTypesUI8Ptr  types = GeoPTypesUI8::create();
00441     GeoPLengthsPtr lens = GeoPLengthsUI32::create();    
00442     beginEditCP(types);
00443     types->addValue(GL_QUADS);
00444     endEditCP(types);
00445 
00446     beginEditCP(lens);
00447     lens->addValue(4);
00448     endEditCP(lens);
00449     
00450     GeoPositions3fPtr pos = GeoPositions3f::create();
00451     beginEditCP(pos);
00452     pos->addValue(Pnt3f(-1, -1, -0.5));
00453     pos->addValue(Pnt3f( 1, -1, -0.5));
00454     pos->addValue(Pnt3f( 1,  1, -0.5));
00455     pos->addValue(Pnt3f(-1,  1, -0.5));
00456     endEditCP(pos);
00457     _positions=pos;
00458     
00459     _texcoords = GeoTexCoords2f::create();
00460     beginEditCP(_texcoords);
00461     _texcoords->addValue(Vec2f(0,0));
00462     _texcoords->addValue(Vec2f(1,0));
00463     _texcoords->addValue(Vec2f(1,1));
00464     _texcoords->addValue(Vec2f(0,1));
00465     endEditCP(_texcoords);
00466    
00467     GeometryPtr geo = Geometry::create();
00468     beginEditCP(geo);
00469     geo->setMaterial(mat);
00470     geo->setPositions(pos);
00471     geo->setTypes(types);
00472     geo->setTexCoords(_texcoords);
00473     geo->setLengths(lens);
00474     endEditCP  (geo);
00475     
00476     NodePtr cube = Node::create();
00477     beginEditCP(cube);
00478     cube->setCore(geo);
00479     endEditCP(cube);
00480    
00481     ComponentTransformPtr trans = ComponentTransform::create();
00482     beginEditCP(trans);
00483     trans->setTranslation(Vec3f(getScaleDown()-1, getScaleDown()-1, 0));
00484     trans->setScale(Vec3f(getScaleDown(), getScaleDown(), 1.0));
00485     endEditCP(trans);
00486     
00487     _cmRoot = Node::create();
00488     addRefCP(_cmRoot);
00489     beginEditCP(_cmRoot);
00490     _cmRoot->setCore(trans);
00491     _cmRoot->addChild(cube);
00492     endEditCP(_cmRoot);
00493  
00494     GroupPtr group = Group::create();
00495     NodePtr gr = Node::create();
00496     beginEditCP(gr);
00497     gr->setCore(group);
00498     gr->addChild(_cmRoot);
00499     endEditCP(gr);
00500    
00501     _cam = MatrixCamera::create();
00502     addRefCP(_cam);
00503     beginEditCP(_cam);
00504     _cam->setNear(0.1);
00505     _cam->setFar(10);
00506     _cam->setModelviewMatrix(Matrix::identity());
00507     _cam->setProjectionMatrix(Matrix::identity());   
00508     endEditCP(_cam);
00509     
00510     // create a dummy geometry
00511     _dsRoot = makePlane(1, 1, 1, 1);
00512     addRefCP(_dsRoot);
00513     beginEditCP(_dsRoot);
00514       _dsRoot->setActive(false);
00515     endEditCP(_dsRoot);
00516     
00517     // Add the grab background
00518     
00519     _cmBack = TextureGrabBackground::create();
00520     addRefCP(_cmBack);
00521     
00522     beginEditCP(_cmBack);
00523         _cmBack->setTexture(tex);
00524         _cmBack->setColor(Color3f(0,0,0));
00525     endEditCP(_cmBack);
00526     
00527     _cmPort = Viewport::create();
00528     addRefCP(_cmPort);
00529 
00530     beginEditCP(_cmPort);
00531         _cmPort->setCamera(_cam);
00532         _cmPort->setRoot(_cmRoot);
00533         _cmPort->setBackground(_cmBack);
00534         _cmPort->setLeft(0);
00535         _cmPort->setRight(1);
00536         _cmPort->setBottom(0);
00537         _cmPort->setTop(1);
00538     endEditCP(_cmPort);
00539 
00540     // create down scale viewport
00541 
00542     ImagePtr img2 = Image::create();
00543     beginEditCP(img2);
00544         img2->set(GL_RGB,1,1);
00545     endEditCP(img2);
00546     
00547     TextureChunkPtr tex2 = TextureChunk::create();
00548     beginEditCP(tex2);
00549         tex2->setImage(img2);
00550         tex2->setMinFilter(GL_NEAREST);
00551         tex2->setMagFilter(GL_NEAREST);
00552         tex2->setScale(false);
00553         tex2->setEnvMode(GL_REPLACE);
00554     endEditCP(tex2);
00555     
00556     _dsBack = TextureGrabBackground::create();
00557     addRefCP(_dsBack);
00558     beginEditCP(_dsBack);
00559         _dsBack->setTexture(tex2);
00560         _dsBack->setColor(Color3f(1,0,0));
00561     endEditCP(_dsBack);
00562     
00563     // create the down scale viewport
00564     _dsPort = Viewport::create();
00565     addRefCP(_dsPort);
00566     beginEditCP(_dsPort);
00567         _dsPort->setCamera(_cam);
00568         _dsPort->setRoot(_dsRoot);
00569         _dsPort->setBackground(_dsBack);
00570         _dsPort->setLeft(0);
00571         _dsPort->setRight(1);
00572         _dsPort->setBottom(0);
00573         _dsPort->setTop(1);
00574     endEditCP(_dsPort);
00575 
00576     // vp2
00577     
00578     _ds2Back = SolidBackground::create();
00579     addRefCP(_ds2Back);
00580     beginEditCP(_ds2Back);
00581         _ds2Back->setColor(Color3f(1,0,0));
00582     endEditCP(_ds2Back);
00583 
00584     ChunkMaterialPtr mat2 = ChunkMaterial::create();
00585     MaterialChunkPtr matc = MaterialChunk::create();
00586     
00587     beginEditCP(mat2);
00588         mat2->addChunk(tex2);
00589     endEditCP(mat2);
00590 
00591     GeometryPtr geo2 = Geometry::create();
00592 
00593     GeoPLengthsPtr lens2 = GeoPLengthsUI32::create();    
00594     beginEditCP(lens2);
00595     lens->addValue(4);
00596     endEditCP(lens2);
00597 
00598     _positionsScale = GeoPositions3f::create();
00599     beginEditCP(_positionsScale);
00600     _positionsScale->addValue(Pnt3f(-1, -1, -0.5));
00601     _positionsScale->addValue(Pnt3f( 1, -1, -0.5));
00602     _positionsScale->addValue(Pnt3f( 1,  1, -0.5));
00603     _positionsScale->addValue(Pnt3f(-1,  1, -0.5));
00604     endEditCP(_positionsScale);
00605     
00606     _texcoordsScale = GeoTexCoords2f::create();
00607     beginEditCP(_texcoordsScale);
00608     _texcoordsScale->addValue(Vec2f(0,0));
00609     _texcoordsScale->addValue(Vec2f(1,0));
00610     _texcoordsScale->addValue(Vec2f(1,1));
00611     _texcoordsScale->addValue(Vec2f(0,1));
00612     endEditCP(_texcoordsScale);
00613 
00614     beginEditCP(geo2);
00615     geo2->setMaterial(mat2);
00616     geo2->setPositions(_positionsScale);
00617     geo2->setTypes(types);
00618     geo2->setTexCoords(_texcoordsScale);
00619     geo2->setLengths(lens2);
00620     endEditCP(geo2);
00621  
00622     _ds2Root = Node::create();
00623     beginEditCP(_ds2Root);
00624     _ds2Root->setCore(geo2);
00625     endEditCP(_ds2Root);
00626 
00627     _dsPort2 = Viewport::create();
00628     addRefCP(_dsPort2);
00629     beginEditCP(_dsPort2);
00630         _dsPort2->setCamera(_cam);
00631         _dsPort2->setRoot(_ds2Root);
00632         _dsPort2->setBackground(_ds2Back);
00633         _dsPort2->setLeft(0);
00634         _dsPort2->setRight(1);
00635         _dsPort2->setBottom(0);
00636         _dsPort2->setTop(1);
00637     endEditCP(_dsPort2);
00638 
00639     updateMatrix();
00640     updateGamma();
00641 
00642 
00643     // ---------------------------------------------------------------
00644     // set projection grid
00645     // ---------------------------------------------------------------
00646 
00647     UInt32 x,y;
00648     Int32 left=0,top=1,bottom=0,right=1;
00649     left   = 0;
00650     right  = window->getWidth() - 1;
00651     bottom = 0;
00652     top    = window->getHeight() - 1;
00653 
00654     Real32 h=top-bottom+1;
00655     Real32 w=right-left+1;
00656     Real32 
00657         tw = osgnextpower2((UInt32)w), 
00658         th = osgnextpower2((UInt32)h);
00659 
00660     beginEditCP(_texcoords);
00661     beginEditCP(_positions);
00662     _positions->clear();
00663     _texcoords->clear();
00664 
00665     if(getGrid().size() == 0 ||
00666        getGrid().size() != getGridWidth() * getGridHeight() ||
00667        getGridWidth() < 2 ||
00668        getGridHeight() < 2)
00669     {
00670         _texcoords->addValue(Vec2f(0,0));
00671         _texcoords->addValue(Vec2f(w/tw,0));
00672         _texcoords->addValue(Vec2f(w/tw,h/th));
00673         _texcoords->addValue(Vec2f(0,h/th));
00674         _positions->addValue(Pnt3f(-1, -1, -0.5));
00675         _positions->addValue(Pnt3f( 1, -1, -0.5));
00676         _positions->addValue(Pnt3f( 1,  1, -0.5));
00677         _positions->addValue(Pnt3f(-1,  1, -0.5));
00678     }
00679     else
00680     {
00681         UInt32 i;
00682         bool   absolute=false;
00683         for(i=0;i<getGrid().size();++i)
00684             if(getGrid()[i][0]>1 ||
00685                getGrid()[i][1]>1)
00686             {
00687                 absolute=true;
00688                 break;
00689             }
00690         for(int y=0 ; y<getGridHeight()-1 ; ++y)
00691         {
00692             for(int x=0 ; x<getGridWidth()-1 ; ++x)
00693             {
00694                 // calculate texture coordinates
00695                 Vec2f tex[4];
00696                 tex[0] = Vec2f(  x,  y);
00697                 tex[1] = Vec2f(x+1,  y);
00698                 tex[2] = Vec2f(x+1,y+1);
00699                 tex[3] = Vec2f(  x,y+1);
00700 
00701                 // get position
00702                 Vec2f pos[4];
00703                 pos[0] = getGrid()[y*getGridWidth()+x];
00704                 pos[1] = getGrid()[y*getGridWidth()+x+1];
00705                 pos[2] = getGrid()[(y+1)*getGridWidth()+x+1];
00706                 pos[3] = getGrid()[(y+1)*getGridWidth()+x];
00707                 for(i=0 ; i<4 ; ++i)
00708                 {
00709                     // scale to 0 - 1
00710                     tex[i][0] /= getGridWidth() - 1;
00711                     tex[i][1] /= getGridHeight() - 1;
00712                     // scale to ^2 texture size
00713                     tex[i][0] *= w/(float)tw;
00714                     tex[i][1] *= h/(float)th;
00715                     if(absolute) 
00716                     {
00717                         pos[i][0] /= (w-1);
00718                         pos[i][1] /= (h-1);
00719                     }
00720                     _texcoords->addValue(tex[i]);
00721                     Pnt3f p(pos[i][0],pos[i][1],0);
00722                     _positions->addValue(p*2-Vec3f(1,1,1));
00723                 }
00724             }
00725         }
00726     }
00727     endEditCP(_texcoords);
00728 
00729     beginEditCP(lens);
00730     lens->clear();
00731     lens->addValue(_positions->getSize());
00732     endEditCP(lens);
00733 
00734     endEditCP(_positions);
00735 
00736     // ---------------------------------------------------------------
00737     // set downscale params
00738     // ---------------------------------------------------------------
00739 
00740     UInt32 w2 = UInt32(((right - left) + 1) * getScaleDown());
00741     UInt32 h2 = UInt32(((top - bottom) + 1) * getScaleDown());
00742     UInt32 lefts = Int32(left * getScaleDown());
00743     UInt32 rights = w2 - 1;
00744     UInt32 bottoms = Int32(bottom * getScaleDown());
00745     UInt32 tops = h2 - 1;
00746     
00747     _dsPort->setSize(lefts,bottoms,rights,tops);
00748     _dsPort2->setSize(left,bottom,right,top);
00749                     
00750     Real32 h3= tops - bottoms + 1;
00751     Real32 w3= rights - lefts + 1;
00752     Real32 tw2 = osgnextpower2((UInt32) w2);
00753     Real32 th2 = osgnextpower2((UInt32) h2);
00754     
00755     beginEditCP(_texcoordsScale);
00756     _texcoordsScale->clear();
00757     _texcoordsScale->addValue(Vec2f(0,0));
00758     _texcoordsScale->addValue(Vec2f(w3/tw2,0));
00759     _texcoordsScale->addValue(Vec2f(w3/tw2,h3/th2));
00760     _texcoordsScale->addValue(Vec2f(0,h3/th2));
00761     endEditCP(_texcoordsScale);
00762     
00763     beginEditCP(_positionsScale);
00764     _positionsScale->clear();
00765     _positionsScale->addValue(Pnt3f(-1, -1, -0.5));
00766     _positionsScale->addValue(Pnt3f( 1, -1, -0.5));
00767     _positionsScale->addValue(Pnt3f( 1,  1, -0.5));
00768     _positionsScale->addValue(Pnt3f(-1,  1, -0.5));
00769     endEditCP(_positionsScale);
00770 
00771 }
00772 
00773 void DisplayCalibration::updateGamma()
00774 {
00775     UInt16 x,y;
00776     UInt8 *data;
00777     UInt32 res = getGammaRamp().size();
00778 
00779     if(res == 0)
00780         res = 256;
00781 
00782     if(_useFragmentProgram)
00783     {
00784         beginEditCP(_fragProgram, FragmentProgramChunk::ParamValuesFieldMask);
00785 
00786         _fragProgram->setParameter(5, Vec4f(getGamma(),getGamma(),getGamma(),0));   
00787 
00788         endEditCP(_fragProgram, FragmentProgramChunk::ParamValuesFieldMask);
00789     }
00790     else
00791     {
00792         _argammaimg->set(GL_RGB,res,res);
00793 
00794         beginEditCP(_argammaimg);
00795         data = _argammaimg->getData();
00796     
00797         memset(data, 0, res * res * 3);
00798     
00799         for(y = 0; y < res; ++y)
00800         {
00801             UInt8 v = (int)(pow(y/(Real32)(res-1),getGamma())*255+0.5);
00802             for(x = 0; x < res; ++x)
00803             {
00804                 *data++ = v;
00805                 *data++ = 0;
00806                 *data++ = 0;           
00807             }
00808         }
00809         endEditCP(_argammaimg);
00810 
00811         beginEditCP(_argammachunk);
00812         _argammachunk->setImage(_argammaimg);
00813         endEditCP(_argammachunk);
00814 
00815         _gbgammaimg->set(GL_RGB,res,res);
00816 
00817         beginEditCP(_gbgammaimg);
00818         data = _gbgammaimg->getData();
00819     
00820         memset(data, 0, res * res * 3);
00821     
00822         for(y = 0; y < res; ++y)
00823         {
00824             UInt8 vy = (int)(pow(y/(Real32)(res-1),getGamma())*255+0.5);
00825             for(x = 0; x < res; ++x)
00826             {
00827                 UInt8 vx = (int)(pow(x/(Real32)(res-1),getGamma())*255+0.5);
00828                 *data++ = 0;
00829                 *data++ = vx;
00830                 *data++ = vy;           
00831             }
00832         }
00833         endEditCP(_gbgammaimg);
00834 
00835         beginEditCP(_gbgammachunk);
00836         _gbgammachunk->setImage(_gbgammaimg);
00837         endEditCP(_gbgammachunk);
00838     }
00839 }
00840 
00841 void DisplayCalibration::updateMatrix()
00842 {
00843     if(_useFragmentProgram)
00844     {
00845         beginEditCP(_fragProgram, FragmentProgramChunk::ParamValuesFieldMask);
00846     
00847         _fragProgram->setParameter(1, getColorMatrix()[0]);
00848         _fragProgram->setParameter(2, getColorMatrix()[1]);
00849         _fragProgram->setParameter(3, getColorMatrix()[2]);
00850         _fragProgram->setParameter(4, getColorMatrix()[3]);
00851     
00852         endEditCP(_fragProgram, FragmentProgramChunk::ParamValuesFieldMask);
00853 
00854     }
00855     else
00856     {
00857 #if 0
00858         Color4f 
00859             m1(m[0][0]/2+.5,m[0][1]/2+.5,m[0][2]/2+.5,0),
00860             m2(m[1][0]/2+.5,m[1][1]/2+.5,m[1][2]/2+.5,0),
00861             m3(m[2][0]/2+.5,m[2][1]/2+.5,m[2][2]/2+.5,0),
00862             m4(m[3][0]/2+.5,m[3][1]/2+.5,m[3][2]/2+.5,0);
00863 #endif
00864         Color4f 
00865             m1(getColorMatrix()[0][0]/2+.5,
00866             getColorMatrix()[0][1]/2+.5,
00867             getColorMatrix()[0][2]/2+.5,0),
00868             m2(getColorMatrix()[1][0]/2+.5,
00869             getColorMatrix()[1][1]/2+.5,
00870             getColorMatrix()[1][2]/2+.5,0),
00871             m3(getColorMatrix()[2][0]/2+.5,
00872             getColorMatrix()[2][1]/2+.5,
00873             getColorMatrix()[2][2]/2+.5,0),
00874             m4(getColorMatrix()[3][0]/2+.5,
00875             getColorMatrix()[3][1]/2+.5,
00876             getColorMatrix()[3][2]/2+.5,0);
00877     
00878         Color4f selectR(1,0,0,0), selectG(0,1,0,0), selectB(0,0,1,0);
00879 
00880         UInt16 ncomb = 0;
00881     
00882         beginEditCP(_regCombiner);
00883 
00884         _regCombiner->setCombinerRGB(ncomb,
00885                             GL_TEXTURE1_ARB,       GL_UNSIGNED_IDENTITY_NV, GL_RGB, // variable A
00886                             GL_ZERO,               GL_UNSIGNED_INVERT_NV,   GL_RGB, // variable B
00887                             GL_TEXTURE2_ARB,       GL_UNSIGNED_IDENTITY_NV, GL_RGB, // variable C
00888                             GL_ZERO,               GL_UNSIGNED_INVERT_NV,   GL_RGB, // variable D
00889                             GL_DISCARD_NV, GL_DISCARD_NV, GL_TEXTURE0_ARB,   // ABout, CDout, Sumout
00890                             GL_NONE, GL_NONE,                            // scale, bias
00891                             GL_FALSE, GL_FALSE, GL_FALSE );                // ABdot, CDdot, muxSum
00892 
00893         ncomb++;
00894 
00895         // first combiner: spare0 = dot(col, m1), spare1 = dot(col,m2)      
00896         
00897         _regCombiner->setCombinerColors(ncomb, m1, m2);
00898 
00899         _regCombiner->setCombinerRGB(
00900             ncomb,
00901             GL_TEXTURE0_ARB,       GL_UNSIGNED_IDENTITY_NV, GL_RGB, // variable A
00902             GL_CONSTANT_COLOR0_NV, GL_EXPAND_NORMAL_NV,     GL_RGB, // variable B
00903             GL_TEXTURE0_ARB,       GL_UNSIGNED_IDENTITY_NV, GL_RGB, // variable C
00904             GL_CONSTANT_COLOR1_NV, GL_EXPAND_NORMAL_NV,     GL_RGB, // variable D
00905             GL_SPARE0_NV, GL_SPARE1_NV, GL_DISCARD_NV,   // ABout, CDout, Sumout
00906             GL_NONE, GL_NONE,                            // scale, bias
00907             GL_TRUE, GL_TRUE, GL_FALSE );                // ABdot, CDdot, muxSum
00908         
00909         ncomb++;
00910     
00911         // second combiner: tex0 = dot(col, m3), spare0 = spare0.r   
00912     
00913         _regCombiner->setCombinerColors(ncomb, m3, selectR);
00914 
00915         _regCombiner->setCombinerRGB(ncomb,
00916                             GL_TEXTURE0_ARB,       GL_UNSIGNED_IDENTITY_NV, GL_RGB, // variable A
00917                             GL_CONSTANT_COLOR0_NV, GL_EXPAND_NORMAL_NV,     GL_RGB, // variable B
00918                             GL_SPARE0_NV,          GL_UNSIGNED_IDENTITY_NV, GL_RGB, // variable C
00919                             GL_CONSTANT_COLOR1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB, // variable D
00920                             GL_TEXTURE3_ARB, GL_SPARE0_NV, GL_DISCARD_NV, // ABout, CDout, Sumout
00921                             GL_NONE, GL_NONE,                             // scale, bias
00922                             GL_TRUE, GL_FALSE, GL_FALSE );                 // ABdot, CDdot, muxSum
00923 
00924         ncomb++;
00925     
00926         // final combiner 
00927     
00928         _regCombiner->setColor0(selectG);
00929         _regCombiner->setColor1(selectB);
00930     
00931         // RGB = D + AB + (1-A)C
00932         _regCombiner->setFinalCombiner( 
00933             GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB, // variable A
00934             GL_SPARE1_NV,          GL_UNSIGNED_IDENTITY_NV, GL_RGB, // variable B
00935             GL_E_TIMES_F_NV,       GL_UNSIGNED_IDENTITY_NV, GL_RGB, // variable C
00936             GL_SPARE0_NV,          GL_UNSIGNED_IDENTITY_NV, GL_RGB, // variable D
00937             GL_CONSTANT_COLOR1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB, // variable E
00938             GL_TEXTURE3_ARB,       GL_UNSIGNED_IDENTITY_NV, GL_RGB, // variable F
00939             GL_PRIMARY_COLOR_NV,   GL_UNSIGNED_IDENTITY_NV, GL_ALPHA );// variable G
00940 
00941         endEditCP(_regCombiner);
00942     }
00943 }
00944 
00945 /*------------------------------------------------------------------------*/
00946 /*                              cvs id's                                  */
00947 
00948 #ifdef OSG_SGI_CC
00949 #pragma set woff 1174
00950 #endif
00951 
00952 #ifdef OSG_LINUX_ICC
00953 #pragma warning( disable : 177 )
00954 #endif
00955 
00956 namespace
00957 {
00958     static Char8 cvsid_cpp       [] = "@(#)$Id: $";
00959     static Char8 cvsid_hpp       [] = OSGDISPLAYCALIBRATIONBASE_HEADER_CVSID;
00960     static Char8 cvsid_inl       [] = OSGDISPLAYCALIBRATIONBASE_INLINE_CVSID;
00961 
00962     static Char8 cvsid_fields_hpp[] = OSGDISPLAYCALIBRATION