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

OSGImageFunctions.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00008  *                                                                           *
00009 \*---------------------------------------------------------------------------*/
00010 /*---------------------------------------------------------------------------*\
00011  *                                License                                    *
00012  *                                                                           *
00013  * This library is free software; you can redistribute it and/or modify it   *
00014  * under the terms of the GNU Library General Public License as published    *
00015  * by the Free Software Foundation, version 2.                               *
00016  *                                                                           *
00017  * This library is distributed in the hope that it will be useful, but       *
00018  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00020  * Library General Public License for more details.                          *
00021  *                                                                           *
00022  * You should have received a copy of the GNU Library General Public         *
00023  * License along with this library; if not, write to the Free Software       *
00024  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00025  *                                                                           *
00026 \*---------------------------------------------------------------------------*/
00027 /*---------------------------------------------------------------------------*\
00028  *                                Changes                                    *
00029  *                                                                           *
00030  *                                                                           *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035 \*---------------------------------------------------------------------------*/
00036 //---------------------------------------------------------------------------
00037 //  Includes
00038 //---------------------------------------------------------------------------
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041 
00042 #include <OSGConfig.h>
00043 #include <OSGLog.h>
00044 #include <OSGImage.h>
00045 #include <OSGBaseFunctions.h>
00046 
00047 #include "OSGImageFunctions.h"
00048 
00049 
00050 OSG_USING_NAMESPACE
00051 
00052 #if defined(OSG_WIN32_ICL) && !defined(OSG_CHECK_FIELDSETARG)
00053 #pragma warning(disable : 383)
00054 #endif
00055 #ifdef __sgi
00056 #pragma set woff 1209
00057 #endif
00058 
00059 /***************************************************************************\
00060  *                            Description                                  *
00061 \***************************************************************************/
00062 
00063 
00064 //---------------------------------------------------------------------------//
00067 OSG_SYSTEMLIB_DLLMAPPING
00068 bool createComposedImage ( std::vector<ImagePtr> imageVec,
00069                            ImagePtr              image,
00070                            SliceDataType         sliceDataType )
00071 {
00072   UInt32 dataSize, i, n = imageVec.size();
00073   Int32 w, h;
00074   UInt8 *destData, *srcData;
00075   Image::PixelFormat pf;
00076   Image::Type        dt;
00077   bool needColor, needAlpha, needCopy = false;
00078   ImagePtr copy = Image::create();
00079   UInt32 depth, frameCount, sideCount;
00080 
00081   if (n) {
00082     for (i = 0; i < n; i++) {
00083       if ( i == 0 ) {
00084         pf = Image::PixelFormat(imageVec[0]->getPixelFormat());
00085         dt = Image::Type(imageVec[0]->getDataType());
00086         w = imageVec[0]->getWidth();
00087         h = imageVec[0]->getHeight();
00088         needAlpha = imageVec[0]->hasAlphaChannel();
00089         needColor = imageVec[0]->hasColorChannel();
00090       }
00091       else {
00092         needAlpha |= imageVec[i]->hasAlphaChannel();
00093         needColor |= imageVec[i]->hasColorChannel();
00094         if (Image::PixelFormat(imageVec[i]->getPixelFormat()) != pf) {
00095           needCopy = true;          
00096           FWARNING (( "Image has different PF while composing\n" ));
00097           pf = Image::OSG_INVALID_PF;
00098         }
00099         if (Image::Type(imageVec[i]->getDataType()) != dt) {
00100           needCopy = true;          
00101           FWARNING (( "Image has different DT while composing\n" ));
00102           dt = Image::OSG_INVALID_IMAGEDATATYPE;
00103         }
00104         if (imageVec[i]->getWidth() != w) {
00105           needCopy = true;          
00106           FWARNING (( "Image has different width while composing\n" ));
00107           w = osgMax ( w, imageVec[i]->getWidth());
00108         }
00109         if (imageVec[i]->getHeight() != h) {
00110           needCopy = true;          
00111           FWARNING (( "Image has different height while composing\n" ));
00112           h = osgMax ( h, imageVec[i]->getHeight());
00113         }
00114       }      
00115     }
00116 
00117     if (pf == Image::OSG_INVALID_PF) {
00118       if (needColor)
00119         if (needAlpha)
00120           pf = OSG::Image::OSG_RGBA_PF;
00121         else
00122           pf = OSG::Image::OSG_RGB_PF;
00123       else
00124         if (needAlpha)
00125           pf = OSG::Image::OSG_LA_PF;
00126         else
00127           pf = OSG::Image::OSG_L_PF;
00128     }
00129 
00130     if (dt == Image::OSG_INVALID_IMAGEDATATYPE)
00131       dt = Image::OSG_UINT8_IMAGEDATA;
00132 
00133     depth = frameCount = sideCount = 1;
00134     switch (sliceDataType) {
00135     case FRAME_SDT:
00136       frameCount = n;
00137       break;
00138     case SIDE_SDT:
00139       sideCount = n;
00140     case INVALID_SDT:
00141     case DEPTH_SDT:
00142     default:
00143       depth = n;
00144       break;
00145     }
00146       
00147     image->set( pf, w, h, depth, 1, frameCount, 0.0, 
00148                 0, dt, true, sideCount );
00149 
00150     destData = image->getData();
00151     dataSize = image->getSize() / n;
00152 
00153     if (needCopy) {
00154       FLOG (("Image data/type/size missmatch while composing\n"));
00155     }
00156 
00157     for (i = 0; i < n; i++) {
00158       if (needCopy) {
00159         copy->set(imageVec[i]);
00160         if ( Image::PixelFormat(copy->getPixelFormat()) != pf )
00161           copy->reformat(pf);
00162         if ( Image::Type(copy->getDataType()) != dt )
00163           copy->convertDataTypeTo(dt);
00164         if ( (w != copy->getWidth()) || (h != copy->getHeight()))
00165           copy->scale(w,h,copy->getDepth());
00166         srcData = copy->getData();
00167       }
00168       else 
00169         srcData = imageVec[i]->getData();
00170       
00171       memcpy ( destData, srcData, dataSize );
00172       destData += dataSize;
00173     }
00174   }
00175 
00176   subRefCP(copy);
00177 
00178   imageVec[0]->dump();
00179   image->dump();
00180 
00181   return true;
00182 }
00183 
00184 //---------------------------------------------------------------------------//
00187 OSG_SYSTEMLIB_DLLMAPPING
00188 bool OSG::createNormalMapFromBump ( ImagePtr image,
00189                                     ImagePtr dst,
00190                                     Vec3f    normalMapScale)
00191 {
00192     if (image == NullFC || image->getDepth() > 1 ||
00193         image->getPixelFormat() != Image::OSG_L_PF)
00194     {
00195         FFATAL(("No valid Normalmap given!\n"));
00196         return false;
00197     }
00198 
00199     bool cpImg = false;
00200 
00201     if (dst == NullFC)
00202     {
00203         dst = Image::create();
00204         cpImg = true;
00205     }
00206     
00207     Int32 w = image->getWidth();
00208     Int32 h = image->getHeight();
00209     
00210     unsigned char *srcData = image->getData();
00211 
00212     beginEditCP(dst);
00213     
00214     dst->set(Image::OSG_RGB_PF, w, h);
00215 
00216     unsigned char *dstData = dst->getData();
00217 
00218     Vec3f scale(normalMapScale);
00219     
00220     if (scale[0] == 0.0f || scale[1] == 0.0f || scale[2] == 0.0f)
00221     {
00222         Real32 a = Real32(w) / Real32(h);
00223         
00224         if(a < 1.0f)
00225         {
00226             scale[0] = 1.0f;
00227             scale[1] = 1.0f / a;
00228         }
00229         else
00230         {
00231             scale[0] = a;
00232             scale[1] = 1.0f;
00233         }
00234         scale[2] = 1.0f;
00235     }
00236 
00237     Int32 i, j;
00238 
00239     for (i=1; i<w-1; i++)
00240     {
00241         for (j=1; j<h-1; j++)
00242         {
00243             Vec3f dfdi(2.0f, 0.0f, (Real32)(srcData[(i+1) +     j*w] - srcData[(i-1) +     j*w]) / 255.0f);
00244             Vec3f dfdj(0.0f, 2.0f, (Real32)(srcData[    i + (j+1)*w] - srcData[    i + (j-1)*w]) / 255.0f);
00245             Vec3f n = dfdi.cross(dfdj);
00246             
00247             n[0] *= scale[0];
00248             n[1] *= scale[1];
00249             n[2] *= scale[2];
00250             n.normalize();
00251 
00252             dstData[(j*w+i)*3+0] = (unsigned char)((n[0]+1)*127.5);
00253             dstData[(j*w+i)*3+1] = (unsigned char)((n[1]+1)*127.5);
00254             dstData[(j*w+i)*3+2] = (unsigned char)((n[2]+1)*127.5);
00255         }
00256     }
00257 
00258     // handle image border
00259     for (i=0; i<w; i++)
00260     {
00261         dstData[i*3+0] = dstData[(w+i)*3+0];
00262         dstData[i*3+1] = dstData[(w+i)*3+1];
00263         dstData[i*3+2] = dstData[(w+i)*3+2];
00264         
00265         dstData[((h-1)*w+i)*3+0] = dstData[((h-2)*w+1)*3+0];
00266         dstData[((h-1)*w+i)*3+1] = dstData[((h-2)*w+1)*3+1];
00267         dstData[((h-1)*w+i)*3+2] = dstData[((h-2)*w+1)*3+2];
00268     }
00269     
00270     for (j=0; j<h; j++)
00271     {
00272         dstData[(j*w)*3+0] = dstData[(j*w+1)*3+0];
00273         dstData[(j*w)*3+1] = dstData[(j*w+1)*3+1];
00274         dstData[(j*w)*3+2] = dstData[(j*w+1)*3+2];
00275         
00276         dstData[(j*w+(w-1))*3+0] = dstData[(j*w+(w-2))*3+0];
00277         dstData[(j*w+(w-1))*3+1] = dstData[(j*w+(w-2))*3+1];
00278         dstData[(j*w+(w-1))*3+2] = dstData[(j*w+(w-2))*3+2];
00279     }
00280 
00281     endEditCP(dst);
00282 
00283     if (cpImg)
00284     {
00285         beginEditCP(image);
00286             image->set(dst);
00287         endEditCP(image);
00288     }
00289 
00290     //dst->dump();
00291     
00292     return true;
00293 }
00294 
00295 
00296 //---------------------------------------------------------------------------//
00299 OSG_SYSTEMLIB_DLLMAPPING
00300 void OSG::createNormalVolume ( ImagePtr inImage,
00301                                ImagePtr outImage,
00302                                AlphaValue alphaValue )
00303 {
00304   UInt8 *data = 0, *ds;
00305   Int32 w, h, d, x, y, z, md, ld, hd, xs, ys, zs, ps, ls, ss, os;
00306   Real32 g;
00307   const Real32 gMax = 441.67295593, gF = 255.0/gMax;
00308   Image::PixelFormat pf;
00309   ImagePtr copy;
00310 
00311   if ( (inImage->getPixelFormat() != Image::OSG_L_PF) ||
00312        (inImage->getDataType()    != Image::OSG_UINT8_IMAGEDATA) ) {
00313 
00314     copy = Image::create();
00315     FLOG (("Create copy to reformat/convert Image\n"));
00316 
00317     if (inImage->getPixelFormat() != Image::OSG_L_PF) 
00318       inImage->reformat(Image::OSG_L_PF,copy);      
00319     else 
00320       copy->set(inImage);    
00321     inImage = copy;
00322     
00323     if (inImage->getDataType() != Image::OSG_UINT8_IMAGEDATA) 
00324       inImage->convertDataTypeTo(Image::OSG_UINT8_IMAGEDATA);
00325   }
00326 
00327   pf   = (alphaValue == NONE_AVT) ? Image::OSG_RGB_PF : Image::OSG_RGBA_PF;
00328   w    = inImage->getWidth();
00329   h    = inImage->getHeight();
00330   d    = inImage->getDepth();
00331   data = inImage->getData();
00332   ps   = inImage->getBpp();
00333   ls   = ps * w;
00334   ss   = ls * h;
00335   os   = 0;
00336 
00337   beginEditCP(outImage);
00338 
00339   outImage->set( pf, w, h, d );
00340                       
00341   ds = outImage->getData();
00342 
00343   for (z = 0; z < d; z++) {
00344     for (y = 0; y < h; y++) {
00345       for (x = 0; x < w; x++) {
00346         md = data[(x*ps) + (y*ls) + (z*ss) + os];
00347 
00348         ld = (x > 0)     ? data[((x-1)*ps) + (y*ls) + (z*ss) + os] : 0;
00349         hd = (x < (w-1)) ? data[((x+1)*ps) + (y*ls) + (z*ss) + os] : 0;
00350         xs = (ld - hd);
00351 
00352         ld = (y > 0)     ? data[(x*ps) + ((y-1)*ls) + (z*ss) + os] : 0;
00353         hd = (y < (h-1)) ? data[(x*ps) + ((y+1)*ls) + (z*ss) + os] : 0;
00354         ys = (ld - hd);
00355 
00356         ld = (z > 0)     ? data[(x*ps) + (y*ls) + ((z-1)*ss) + os] : 0;
00357         hd = (z < (d-1)) ? data[(x*ps) + (y*ls) + ((z+1)*ss) + os] : 0;
00358         zs = (ld - hd);
00359 
00360         *ds++ = xs / 2 + 127;
00361         *ds++ = ys / 2 + 127;
00362         *ds++ = zs / 2 + 127;
00363 
00364         switch (alphaValue) {
00365         case NONE_AVT:
00366           break;
00367         case SOURCE_AVT:
00368           *ds++ = md;
00369           break;
00370         case GRADIENT_AVT:
00371           *ds++ = osgMax ( int(osgsqrt ( xs * xs + ys * ys + zs * zs ) * gF),
00372                            255 );        
00373           break;
00374         }
00375 
00376       }
00377     }
00378   }
00379 
00380   endEditCP(outImage);
00381 
00382   if (copy != osg::NullFC)
00383     subRefCP(copy);
00384 
00385   return;
00386 }
00387 
00388 
00389 //---------------------------------------------------------------------------//
00395 OSG_SYSTEMLIB_DLLMAPPING
00396 bool OSG::create2DPreIntegrationLUT ( ImagePtr dst,
00397                                       ImagePtr src,
00398                                       Real32   thickness)
00399 {
00400     if (src == NullFC || dst == NullFC ||
00401         src->getHeight() > 1 || src->getDepth() > 1 ||
00402         src->getPixelFormat() != Image::OSG_RGBA_PF)
00403     {
00404         FFATAL(("No appropriate image given!\n"));
00405         return false;
00406     }
00407 
00408     unsigned char *dataSrc = src->getData();
00409     UInt32 width = src->getWidth();
00410 
00411     beginEditCP( dst );
00412     {
00413         dst->set(Image::OSG_RGBA_PF, width, width);
00414 
00415         unsigned char *dataDst = dst->getData();
00416 
00417         for (Int32 x = 0; x < (Int32)width; x++)
00418         {
00419             for (Int32 y = 0; y < (Int32)width; y++)
00420             {
00421                 Int32 n = 10 + 2 * abs(x-y);
00422                 Real64 step = thickness / n;
00423                 
00424                 Real64 dr = 0.0,
00425                        dg = 0.0,
00426                        db = 0.0,
00427                        dtau = 0.0;
00428                 
00429                 for (Int32 i = 0; i < n; i++)
00430                 { 
00431                     Real64 w = x + (y-x) * (Real64)i/n;
00432                     
00433                     if ((Int32)(w + 1) >= (Int32)width)
00434                         w = (Real64)(width - 1) - 0.5/n;
00435 
00436                     Int32 pos = ((Int32)w) * 4;
00437                         
00438                     Real64 e = exp(-dtau), scale = step * (1.0 / 255.0),
00439                            f = w - floor(w), invF = 1 - f;
00440                         
00441                     Real64 tau =   scale * (dataSrc[pos + 3] * f + dataSrc[pos+4 + 3] * invF);
00442                     Real64 r = e * scale * (dataSrc[pos + 0] * f + dataSrc[pos+4 + 0] * invF);
00443                     Real64 g = e * scale * (dataSrc[pos + 1] * f + dataSrc[pos+4 + 1] * invF);
00444                     Real64 b = e * scale * (dataSrc[pos + 2] * f + dataSrc[pos+4 + 2] * invF);
00445 
00446                     dr += r; 
00447                     dg += g; 
00448                     db += b; 
00449                     dtau += tau;
00450                 }
00451                 
00452                 dataDst[(x*width+y)*4+0] = (unsigned char)((dr > 1.0 ? 1.0 : dr)*255);
00453                 dataDst[(x*width+y)*4+1] = (unsigned char)((dg > 1.0 ? 1.0 : dg)*255);
00454                 dataDst[(x*width+y)*4+2] = (unsigned char)((db > 1.0 ? 1.0 : db)*255);
00455                 dataDst[(x*width+y)*4+3] = (unsigned char)((1.0 - exp(-dtau))*255);
00456             }
00457         }
00458     }
00459     endEditCP( dst );
00460 
00461     //dst->dump();
00462     
00463     return true;
00464 }
00465 
00466 
00467 //---------------------------------------------------------------------------//
00470 OSG_SYSTEMLIB_DLLMAPPING
00471 bool OSG::splitRGBA(ImagePtr rgba,
00472                     ImagePtr rgb,
00473                     ImagePtr alpha)
00474 {
00475     if (rgba == NullFC || rgba->getDepth() > 1 ||
00476         rgba->getPixelFormat() != Image::OSG_RGBA_PF)
00477     {
00478         FFATAL(("No appropriate image given!\n"));
00479         return false;
00480     }
00481 
00482     if (rgb == NullFC)
00483         rgb = Image::create();
00484     if (alpha == NullFC)
00485         alpha = Image::create();
00486 
00487     Int32 w = rgba->getWidth();
00488     Int32 h = rgba->getHeight();
00489 
00490     beginEditCP( rgb );
00491     beginEditCP( alpha );
00492     {
00493         rgb->set(Image::OSG_RGB_PF, w, h);
00494         alpha->set(Image::OSG_L_PF, w, h);
00495         
00496         unsigned char *data = rgb->getData();
00497         unsigned char *dataRgba = rgba->getData();
00498         unsigned char *dataAlpha = alpha->getData();
00499         
00500         for (Int32 i=0; i<(w * h); i++)
00501         {    
00502             data[0] = dataRgba[0];
00503             data[1] = dataRgba[1];
00504             data[2] = dataRgba[2];
00505             dataAlpha[0] = dataRgba[3];
00506 
00507             data += 3;
00508             dataRgba += 4;
00509             dataAlpha++;
00510         }
00511     }
00512     endEditCP( alpha );
00513     endEditCP( rgb );
00514 
00515     //rgb->dump();
00516     //alpha->dump();
00517 
00518     return true;
00519 }
00520 
00521 //---------------------------------------------------------------------------//
00524 OSG_SYSTEMLIB_DLLMAPPING
00525 bool OSG::mergeRGBA(ImagePtr rgb,
00526                     ImagePtr alpha,
00527                     ImagePtr rgba)
00528 {
00529     if (rgb == NullFC || alpha == NullFC ||
00530         rgb->getDepth() > 1 || alpha->getDepth() > 1 || 
00531         rgb->getPixelFormat() != Image::OSG_RGB_PF ||
00532         alpha->getPixelFormat() != Image::OSG_L_PF)
00533     {
00534         FFATAL(("No appropriate images given!\n"));
00535         return false;
00536     }
00537 
00538     Int32 w = rgb->getWidth();
00539     Int32 h = rgb->getHeight();
00540 
00541     if (w != alpha->getWidth() || h != alpha->getHeight())
00542     {
00543         FFATAL(("Colour and Alpha Images must be of same size!\n"));
00544         return false;
00545     }
00546 
00547     if (rgba == NullFC)
00548         rgba = Image::create();
00549     
00550     beginEditCP( rgba );
00551     {
00552         rgba->set(Image::OSG_RGBA_PF, w, h);
00553         
00554         unsigned char *data = rgba->getData();
00555         unsigned char *dataRgb = rgb->getData();
00556         unsigned char *dataAlpha = alpha->getData();
00557         
00558         for (Int32 i=0; i<(w * h); i++)
00559         {
00560             data[0] = dataRgb[0];
00561             data[1] = dataRgb[1];
00562             data[2] = dataRgb[2];
00563             data[3] = *dataAlpha;
00564             data += 4;
00565             dataRgb += 3;
00566             dataAlpha++;
00567         }
00568     }    
00569     endEditCP( rgba );
00570  
00571     //rgba->dump();
00572 
00573     return true;
00574 }
00575 
00576 //---------------------------------------------------------------------------//
00579 OSG_SYSTEMLIB_DLLMAPPING
00580 bool OSG::createPhongTexture(ImagePtr image,
00581                              UInt32   size,
00582                              Real32   specular_exponent,
00583                              Real32   ka,
00584                              Real32   kd,
00585                              Real32   ks)
00586 {
00587     if (image == NullFC)
00588         image = Image::create();
00589     
00590     beginEditCP( image );
00591     {
00592         image->set(Image::OSG_L_PF, size, size);
00593         unsigned char *textureMap = image->getData();
00594         
00595         UInt32 i, j, index = 0;
00596         Real32 x = 0, y = 0;
00597         
00598         Real32 specular_factor, diffuse_factor;
00599         Real32 textureRadius = 0.95f;
00600         Real32 textureStep = (2.0 * textureRadius) / Real32(size-1);
00601     
00602         y = - textureRadius;
00603         for (j=0; j<size; j++)
00604         {
00605             x = -textureRadius;
00606             for (i=0; i<size; i++)
00607             {
00608                 diffuse_factor  = sqrt(1.0 - x * x);
00609                 specular_factor = pow( diffuse_factor * sqrt (1.0f - y * y) - x * y,
00610                                        specular_exponent );               
00611                 textureMap[index++] = (unsigned char)((ka + kd * diffuse_factor + ks * specular_factor) * 255);
00612                 x += textureStep;
00613             }
00614             y += textureStep;
00615         }
00616     }
00617     endEditCP( image );
00618 
00619     //image->dump();
00620 
00621     return true;
00622 }
00623 
00624 
00625 //---------------------------------------------------------------------------//
00628 OSG_SYSTEMLIB_DLLMAPPING
00629 bool OSG::createNormalizationCubeMap(std::vector<ImagePtr> imageVec,
00630                                      UInt32 size)
00631 {
00632     int i, j;
00633     
00634     if (imageVec.size() < 6)
00635     {
00636         FFATAL(("Only %d images given - need six\n", imageVec.size()));
00637         return false;
00638     }
00639 
00640     for (i=0; i<6; i++)
00641     {
00642         if (imageVec[i] == NullFC)
00643         {
00644             FFATAL(("Image[%d] is Null\n", i));
00645             return false;
00646         }
00647     }
00648     
00649     unsigned char *data = NULL;
00650     Vec3f n;
00651     
00652     size = osgnextpower2(size);
00653     
00654     float size2 = size / 2.0f;
00655     float offset = 0.5f;
00656 
00657     ImagePtr imagePosX = imageVec[0];
00658     
00659     // pos x  
00660     beginEditCP( imagePosX );
00661         imagePosX->set(Image::OSG_RGB_PF, size, size);
00662         data = imagePosX->getData();
00663                         
00664         for (j=0; j<size; j++) {        
00665             for (i=0; i<size; i++) {
00666                 
00667                 n[0] =  size2;  
00668                 n[1] = -((float)j + offset - size2);
00669                 n[2] = -((float)i + offset - size2);
00670                 n.normalize();
00671     
00672                 data[0] = (UInt8)(((n.x() + 1.f) / 2.f) * 255.f);
00673                 data[1] = (UInt8)(((n.y() + 1.f) / 2.f) * 255.f);
00674                 data[2] = (UInt8)(((n.z() + 1.f) / 2.f) * 255.f);
00675                 data += 3;
00676             }
00677         }
00678     endEditCP( imagePosX );
00679 
00680     ImagePtr imageNegX = imageVec[1];
00681     
00682     // neg x
00683     beginEditCP( imageNegX );
00684         imageNegX->set(Image::OSG_RGB_PF, size, size);
00685         data = imageNegX->getData();
00686                         
00687         for (j=0; j<size; j++) {        
00688             for (i=0; i<size; i++) {
00689                     
00690                 n[0] = -size2;
00691                 n[1] = -((float)j + offset - size2);
00692                 n[2] =  ((float)i + offset - size2);
00693                 n.normalize();
00694     
00695                 data[0]= (UInt8)(((n.x() + 1.f) / 2.f) * 255.f);
00696                 data[1]= (UInt8)(((n.y() + 1.f) / 2.f) * 255.f);
00697                 data[2]= (UInt8)(((n.z() + 1.f) / 2.f) * 255.f);
00698                 data += 3;
00699             }
00700         }
00701     endEditCP( imageNegX );
00702 
00703     ImagePtr imagePosY = imageVec[2];
00704             
00705     // pos y
00706     beginEditCP( imagePosY );
00707         imagePosY->set(Image::OSG_RGB_PF, size, size);
00708         data = imagePosY->getData();
00709                 
00710         for (j=0; j<size; j++) {        
00711             for (i=0; i<size; i++) {
00712                 
00713                 n[0] =  ((float)i + offset - size2);
00714                 n[1] =  size2;
00715                 n[2] =  ((float)j + offset - size2);
00716                 n.normalize();
00717     
00718                 data[0]= (UInt8)(((n.x() + 1.f) / 2.f) * 255.f);
00719                 data[1]= (UInt8)(((n.y() + 1.f) / 2.f) * 255.f);
00720                 data[2]= (UInt8)(((n.z() + 1.f) / 2.f) * 255.f);
00721                 data += 3;
00722             }
00723         }
00724     endEditCP( imagePosY );
00725 
00726     ImagePtr imageNegY = imageVec[3];
00727     
00728     // neg y
00729     beginEditCP( imageNegY );
00730         imageNegY->set(Image::OSG_RGB_PF, size, size);
00731         data = imageNegY->getData();
00732             
00733         for (j=0; j<size; j++) {        
00734             for (i=0; i<size; i++) {
00735                 
00736                 n[0]=  ((float)i + offset - size2);
00737                 n[1]= -size2;
00738                 n[2]= -((float)j + offset - size2);
00739                 n.normalize();
00740     
00741                 data[0] = (UInt8)(((n.x() + 1.f) / 2.f) * 255.f);
00742                 data[1] = (UInt8)(((n.y() + 1.f) / 2.f) * 255.f);
00743                 data[2] = (UInt8)(((n.z() + 1.f) / 2.f) * 255.f);
00744                 data += 3;
00745             }
00746         }
00747     endEditCP( imageNegY );
00748 
00749     ImagePtr imagePosZ = imageVec[4];
00750     
00751     // pos z    
00752     beginEditCP( imagePosZ );
00753         imagePosZ->set(Image::OSG_RGB_PF, size, size);
00754         data = imagePosZ->getData();
00755             
00756         for (j=0; j<size; j++) {        
00757             for (i=0; i<size; i++) {
00758                 
00759                 n[0] =  ((float)i + offset - size2);
00760                 n[1] = -((float)j + offset - size2);
00761                 n[2] =  size2;
00762                 n.normalize();
00763     
00764                 data[0] = (UInt8)(((n.x() + 1.f) / 2.f) * 255.f);
00765                 data[1] = (UInt8)(((n.y() + 1.f) / 2.f) * 255.f);
00766                 data[2] = (UInt8)(((n.z() + 1.f) / 2.f) * 255.f);
00767                 data += 3;
00768             }
00769         }
00770     endEditCP( imagePosZ );
00771 
00772     ImagePtr imageNegZ = imageVec[5];
00773     
00774     //negz
00775     beginEditCP( imageNegZ );
00776         imageNegZ->set(Image::OSG_RGB_PF, size, size);
00777         data = imageNegZ->getData();
00778         
00779         for (j=0; j<size; j++) {        
00780             for (i=0; i<size; i++) {
00781             
00782                 n[0] = -((float)i + offset - size2);
00783                 n[1] = -((float)j + offset - size2);
00784                 n[2] = -size2;
00785                 n.normalize();
00786     
00787                 data[0] = (UInt8)(((n.x() + 1.f) / 2.f) * 255.f);
00788                 data[1] = (UInt8)(((n.y() + 1.f) / 2.f) * 255.f);
00789                 data[2] = (UInt8)(((n.z() + 1.f) / 2.f) * 255.f);
00790                 data += 3;
00791             }
00792         }
00793     endEditCP( imageNegZ );
00794 
00795     return true;
00796 }
00797 
00798 
00799 //---------------------------------------------------------------------------//
00802 /************************************************************************
00803 *                                                                       *
00804 *               Copyright (C) 2002-2004  3Dlabs Inc. Ltd.               *
00805 *                                                                       *
00806 *                        All rights reserved.                           *
00807 *                                                                       *
00808 * Redistribution and use in source and binary forms, with or without    *
00809 * modification, are permitted provided that the following conditions    *
00810 * are met:                                                              *
00811 *                                                                       *
00812 *     Redistributions of source code must retain the above copyright    *
00813 *     notice, this list of conditions and the following disclaimer.     *
00814 *                                                                       *
00815 *     Redistributions in binary form must reproduce the above           *
00816 *     copyright notice, this list of conditions and the following       *
00817 *     disclaimer in the documentation and/or other materials provided   *
00818 *     with the distribution.                                            *
00819 *                                                                       *
00820 *     Neither the name of 3Dlabs Inc. Ltd. nor the names of its         *
00821 *     contributors may be used to endorse or promote products derived   *
00822 *     from this software without specific prior written permission.     *
00823 *                                                                       *
00824 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   *
00825 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     *
00826 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS     *
00827 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE        *
00828 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *
00829 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  *
00830 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      *
00831 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER      *
00832 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT    *
00833 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN     *
00834 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE       *
00835 * POSSIBILITY OF SUCH DAMAGE.                                           *
00836 *                                                                       *
00837 ************************************************************************/
00838 
00839 namespace
00840 {
00841 
00842 // globals
00843 #define MAXB 0x100
00844 
00845 Int32  p[MAXB + MAXB + 2];
00846 Real32 g3[MAXB + MAXB + 2][3];
00847 Real32 g2[MAXB + MAXB + 2][2];
00848 Real32 g1[MAXB + MAXB + 2];
00849 Int32  start = 1;
00850 Int32  B = 0x100;
00851 Int32  BM = 0xff;
00852 
00853 
00854 void setNoiseFrequency(Int32 frequency)
00855 {
00856     start = 1;
00857     B = frequency;
00858     BM = B-1;
00859 }
00860 
00861 Real32 lerp(Real32 t, Real32 a, Real32 b)
00862 {
00863     return (1 - t) * a + t * b;
00864 }
00865 
00866 Real32 sCurve(Real32 t)
00867 {
00868     return t * t * (3.0f - 2.0f * t);
00869 }
00870 
00871 Real32 at2(Real32 *q, Real32 rx, Real32 ry)
00872 {
00873     return rx * q[0] + ry * q[1];
00874 }
00875 
00876 Real32 at3(Real32 *q, Real32 rx, Real32 ry, Real32 rz)
00877 {
00878     return rx * q[0] + ry * q[1] + rz * q[2];
00879 }
00880 
00881 void setup(Real32 *vec, UInt8 i,
00882            Real32 &t,
00883            Int32 &b0, Int32 &b1,
00884            Real32 &r0, Real32 &r1)
00885 {
00886     t  = vec[i] + 0x1000;
00887     b0 = ((Int32)t) & BM;
00888     b1 = (b0 + 1) & BM;
00889     r0 = t - (Int32)t;
00890     r1 = r0 - 1.0f;
00891 }
00892 
00893 void normalize2(Real32 v[2])
00894 {
00895     Real32 s = sqrt(v[0] * v[0] + v[1] * v[1]);
00896     v[0] = v[0] / s;
00897     v[1] = v[1] / s;
00898 }
00899 
00900 void normalize3(Real32 v[3])
00901 {
00902     Real32 s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
00903     v[0] = v[0] / s;
00904     v[1] = v[1] / s;
00905     v[2] = v[2] / s;
00906 }
00907 
00908 void init(void)
00909 {
00910     Int32 i, j, k;
00911 
00912     srand(30757);
00913     for (i = 0 ; i < B ; i++)
00914     {
00915         p[i] = i;
00916         g1[i] = (Real32)((rand() % (B + B)) - B) / B;
00917 
00918         for (j = 0 ; j < 2 ; j++)
00919             g2[i][j] = (Real32)((rand() % (B + B)) - B) / B;
00920         normalize2(g2[i]);
00921 
00922         for (j = 0 ; j < 3 ; j++)
00923             g3[i][j] = (Real32)((rand() % (B + B)) - B) / B;
00924         normalize3(g3[i]);
00925     }
00926 
00927     while (--i)
00928     {
00929         k = p[i];
00930         p[i] = p[j = rand() % B];
00931         p[j] = k;
00932     }
00933 
00934     for (i = 0 ; i < B + 2 ; i++)
00935     {
00936         p[B + i] = p[i];
00937         g1[B + i] = g1[i];
00938         for (j = 0 ; j < 2 ; j++)
00939             g2[B + i][j] = g2[i][j];
00940         for (j = 0 ; j < 3 ; j++)
00941             g3[B + i][j] = g3[i][j];
00942     }
00943 }
00944     
00945 Real32 noise1(Real32 vec[1])
00946 {
00947     Int32 bx0, bx1;
00948     Real32 rx0, rx1, sx, t, u, v;
00949 
00950     if (start)
00951     {
00952         start = 0;
00953         init();
00954     }
00955 
00956     setup(vec, 0, t, bx0, bx1, rx0, rx1);
00957 
00958     sx = sCurve(rx0);
00959 
00960     u = rx0 * g1[ p[ bx0 ] ];
00961     v = rx1 * g1[ p[ bx1 ] ];
00962 
00963     return lerp(sx, u, v);
00964 }
00965 
00966 Real32 noise2(Real32 vec[2])
00967 {
00968     Int32 bx0, bx1, by0, by1, b00, b10, b01, b11;
00969     Real32 rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
00970     Int32 i, j;
00971 
00972     if (start)
00973     {
00974         start = 0;
00975         init();
00976     }
00977 
00978     setup(vec, 0, t, bx0, bx1, rx0, rx1);
00979     setup(vec, 1, t, by0, by1, ry0, ry1);
00980 
00981     i = p[ bx0 ];
00982     j = p[ bx1 ];
00983 
00984     b00 = p[ i + by0 ];
00985     b10 = p[ j + by0 ];
00986     b01 = p[ i + by1 ];
00987     b11 = p[ j + by1 ];
00988 
00989     sx = sCurve(rx0);
00990     sy = sCurve(ry0);
00991 
00992     q = g2[ b00 ] ; u = at2(q, rx0,ry0);
00993     q = g2[ b10 ] ; v = at2(q, rx1,ry0);
00994     a = lerp(sx, u, v);
00995 
00996     q = g2[ b01 ] ; u = at2(q, rx0,ry1);
00997     q = g2[ b11 ] ; v = at2(q, rx1,ry1);
00998     b = lerp(sx, u, v);
00999 
01000     return lerp(sy, a, b);
01001 }
01002 
01003 Real32 noise3(Real32 vec[3])
01004 {
01005     Int32 bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
01006     Real32 rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
01007     Int32 i, j;
01008 
01009     if (start)
01010     {
01011         start = 0;
01012         init();
01013     }
01014 
01015     setup(vec, 0, t, bx0, bx1, rx0, rx1);
01016     setup(vec, 1, t, by0, by1, ry0, ry1);
01017     setup(vec, 2, t, bz0, bz1, rz0, rz1);
01018 
01019     i = p[ bx0 ];
01020     j = p[ bx1 ];
01021 
01022     b00 = p[ i + by0 ];
01023     b10 = p[ j + by0 ];
01024     b01 = p[ i + by1 ];
01025     b11 = p[ j + by1 ];
01026 
01027     t  = sCurve(rx0);
01028     sy = sCurve(ry0);
01029     sz = sCurve(rz0);
01030 
01031     q = g3[ b00 + bz0 ] ; u = at3(q, rx0,ry0,rz0);
01032     q = g3[ b10 + bz0 ] ; v = at3(q, rx1,ry0,rz0);
01033     a = lerp(t, u, v);
01034 
01035     q = g3[ b01 + bz0 ] ; u = at3(q, rx0,ry1,rz0);
01036     q = g3[ b11 + bz0 ] ; v = at3(q, rx1,ry1,rz0);
01037     b = lerp(t, u, v);
01038 
01039     c = lerp(sy, a, b);
01040 
01041     q = g3[ b00 + bz1 ] ; u = at3(q, rx0,ry0,rz1);
01042     q = g3[ b10 + bz1 ] ; v = at3(q, rx1,ry0,rz1);
01043     a = lerp(t, u, v);
01044 
01045     q = g3[ b01 + bz1 ] ; u = at3(q, rx0,ry1,rz1);
01046     q = g3[ b11 + bz1 ] ; v = at3(q, rx1,ry1,rz1);
01047     b = lerp(t, u, v);
01048 
01049     d = lerp(sy, a, b);
01050 
01051     return lerp(sz, c, d);
01052 }
01053 
01054 Real32 noise(Real32 vec[], Int32 len)
01055 {
01056     // noise functions over 1, 2, and 3 dimensions 
01057     switch (len)
01058     {
01059       case 1: return noise1(vec);
01060       case 2: return noise2(vec);
01061       case 3: return noise3(vec);
01062       case 0:
01063       default: return 0.0f;
01064     }
01065 }
01066 
01067 };
01068 
01069 
01074 OSG_SYSTEMLIB_DLLMAPPING
01075 bool OSG::createNoise(ImagePtr image,
01076                       Image::PixelFormat pixelformat,
01077                       UInt16 numOctaves,
01078                       UInt16 size,
01079                       UInt8 dim,
01080                       bool splitOctaves)
01081 {
01082     Int32 f, i, j, k, c, w, h, mult = 1, frequency = 4;
01083     Real32 ni[3], amp = 0.5, inci, incj, inck;
01084     unsigned char  *data, *ptr = NULL;
01085     bool ok = true;
01086 
01087     if (image == NullFC)
01088     {
01089         FFATAL (("No output image given\n"));
01090         return false;
01091     }
01092 
01093     switch (dim)
01094     {
01095         case 1:
01096             ok = image->set(pixelformat, size);
01097             w = h = 1;
01098             break;
01099         case 2:
01100             ok = image->set(pixelformat, size, size);
01101             w = size; 
01102             h = 1;
01103             break;
01104         case 3:
01105             ok = image->set(pixelformat, size, size, size);
01106             w = h = size;
01107             break;
01108         default:
01109             ok = image->set(pixelformat, size, size); 
01110             dim = 2; 
01111             w = size; 
01112             h = 1;
01113             FWARNING(("createNoise: Use [1|2|3] for image dimension (default 2)\n"));
01114             break;
01115     }
01116 
01117     if ( ! (ok && (data = image->getData())) )
01118     { 
01119         FFATAL(("createNoise: Could not create image\n"));
01120         return false;
01121     }
01122 
01123     UInt16 ncomp = image->getComponents();
01124 
01125     if(splitOctaves && numOctaves > ncomp)
01126     {
01127         FWARNING(("createNoise: try to split %d octaves, but only have %d"
01128                     " components!\n", numOctaves, ncomp ));
01129         numOctaves = ncomp;
01130     }
01131 
01132     for (f=0; f<numOctaves; ++f, frequency*=2, amp*=0.5)
01133     {
01134         ptr = data;
01135 
01136         setNoiseFrequency(frequency);
01137         ni[0] = ni[1] = ni[2] = 0;
01138         inci = 1.0 / (size / (Real32)frequency);
01139         incj = 1.0 / (size / (Real32)frequency);
01140         inck = 1.0 / (size / (Real32)frequency);
01141 
01142         for (i=0; i<size; ++i, ni[0]+=inci)
01143         {
01144             for (j=0; j<w; ++j, ni[1]+=incj)
01145             {
01146                 for (k=0; k<h; ++k, ni[2]+=inck)
01147                 {
01148                     // calculate numOctaves of noise and scale to range [0;1]
01149                     if (splitOctaves)
01150                     {
01151                         *(ptr+f) = (UInt8)(((noise(ni, dim) + 1) * amp) * 128.0);
01152                     
01153                         ptr+=ncomp;
01154                     }
01155                     else 
01156                     {
01157                         for(c = 0; c < ncomp; ++c, ++ptr, ni[0] += 1)
01158                             (*ptr)  += (UInt8)(((noise(ni, dim) + 1) * amp) * 128.0);
01159                         
01160                         ni[0] -= ncomp;
01161                     }
01162                 }
01163             }
01164         }
01165         FNOTICE(("Generated %dD noise: octave %d/%d...\n", dim, f+1, numOctaves));
01166     }
01167 
01168     return true;
01169 }
01170 

Generated on Thu Aug 25 04:06:26 2005 for OpenSG by  doxygen 1.4.3