Exemple #1
0
void ClipMap::ClipStackEntry::initDebugTexture(U32 level)
{
   static U8 colors[10][3] = 
   {
      {0xFF, 0x00, 0x00},
      {0xFF, 0xFF, 0x00},
      {0x00, 0xFF, 0x00},
      {0x00, 0xFF, 0xFF},
      {0x00, 0x00, 0xFF},
      {0xFF, 0x00, 0xFF},
      {0xFF, 0xFF, 0xFF},
      {0xaa, 0x00, 0xaa},
      {0xaa, 0xaa, 0x00},
      {0x00, 0xaa, 0xaa},
   };

   GBitmap *debugBmp = new GBitmap(4, 4);

   ColorI debugClr(colors[level][0], colors[level][1], colors[level][2]);
   ColorI edgeClr(colors[level][2], colors[level][1], colors[level][0]);

   for(S32 i=0; i<4; i++)
   {
      for(S32 j=0; j<4; j++)
      {
         bool edge = i==0 || j==0 || i==3 || j==3;
         debugBmp->setColor(i,j, edge ? edgeClr : debugClr);
      }
   }

   mDebugTex.set(debugBmp, &GDefaultStaticDiffuseProfile, true, "Clipmap Debug Tex");
}
void blInteriorProxy::addToShadowVolume(ShadowVolumeBSP * shadowVolume, LightInfo * light, S32 level)
{
    if(light->getType() != LightInfo::Vector)
        return;

    ColorF ambient = light->getAmbient();

    bool shadowedTree = true;

    InteriorInstance* interior = dynamic_cast<InteriorInstance*>(getObject());
    if (!interior)
        return;
    Resource<InteriorResource> mInteriorRes = interior->getResource();

    // check if just getting shadow detail
    if(level == SceneLighting::SHADOW_DETAIL)
    {
        shadowedTree = false;
        level = mInteriorRes->getNumDetailLevels() - 1;
    }

    Interior * detail = mInteriorRes->getDetailLevel(level);
    bool hasAlarm = detail->hasAlarmState();

    // make sure surfaces do not get processed more than once
    BitVector surfaceProcessed;
    surfaceProcessed.setSize(detail->mSurfaces.size());
    surfaceProcessed.clear();

    ColorI color = light->getAmbient();

    // go through the zones of the interior and grab outside visible surfaces
    for(U32 i = 0; i < detail->getNumZones(); i++)
    {
        Interior::Zone & zone = detail->mZones[i];
        for(U32 j = 0; j < zone.surfaceCount; j++)
        {
            U32 surfaceIndex = detail->mZoneSurfaces[zone.surfaceStart + j];

            // dont reprocess a surface
            if(surfaceProcessed.test(surfaceIndex))
                continue;
            surfaceProcessed.set(surfaceIndex);

            Interior::Surface & surface = detail->mSurfaces[surfaceIndex];

            // outside visible?
            if(!(surface.surfaceFlags & Interior::SurfaceOutsideVisible))
                continue;

            // good surface?
            PlaneF plane = detail->getPlane(surface.planeIndex);
            if(Interior::planeIsFlipped(surface.planeIndex))
                plane.neg();

            // project the plane
            PlaneF projPlane;
            mTransformPlane(interior->getTransform(), interior->getScale(), plane, &projPlane);

            // fill with ambient? (need to do here, because surface will not be
            // added to the SVBSP tree)
            F32 dot = mDot(projPlane, light->getDirection());
            if(dot > -gParellelVectorThresh)// && !(GFX->getPixelShaderVersion() > 0.0) )
            {
                if(shadowedTree)
                {
                    // alarm lighting
                    GFXTexHandle normHandle = gInteriorLMManager.duplicateBaseLightmap(detail->getLMHandle(), interior->getLMHandle(), detail->getNormalLMapIndex(surfaceIndex));
                    GFXTexHandle alarmHandle;

                    GBitmap * normLightmap = normHandle->getBitmap();
                    GBitmap * alarmLightmap = 0;

                    // check if they share the lightmap
                    if(hasAlarm)
                    {
                        if(detail->getNormalLMapIndex(surfaceIndex) != detail->getAlarmLMapIndex(surfaceIndex))
                        {
                            alarmHandle = gInteriorLMManager.duplicateBaseLightmap(detail->getLMHandle(), interior->getLMHandle(), detail->getAlarmLMapIndex(surfaceIndex));
                            alarmLightmap = alarmHandle->getBitmap();
                        }
                    }

                    //
                    // Support for interior light map border sizes.
                    //
                    U32 xlen, ylen, xoff, yoff;
                    U32 lmborder = detail->getLightMapBorderSize();
                    xlen = surface.mapSizeX + (lmborder * 2);
                    ylen = surface.mapSizeY + (lmborder * 2);
                    xoff = surface.mapOffsetX - lmborder;
                    yoff = surface.mapOffsetY - lmborder;

                    // attemp to light normal and alarm lighting
                    for(U32 c = 0; c < 2; c++)
                    {
                        GBitmap * lightmap = (c == 0) ? normLightmap : alarmLightmap;
                        if(!lightmap)
                            continue;

                        // fill it
                        for(U32 y = 0; y < ylen; y++)
                        {
                            for(U32 x = 0; x < xlen; x++)
                            {
                                ColorI outColor(255, 0, 0, 255);

#ifndef SET_COLORS
                                ColorI lmColor(0, 0, 0, 255);
                                lightmap->getColor(xoff + x, yoff + y, lmColor);

                                U32 _r = static_cast<U32>( color.red ) + static_cast<U32>( lmColor.red );
                                U32 _g = static_cast<U32>( color.green ) + static_cast<U32>( lmColor.green );
                                U32 _b = static_cast<U32>( color.blue ) + static_cast<U32>( lmColor.blue );

                                outColor.red   = mClamp(_r, 0, 255);
                                outColor.green = mClamp(_g, 0, 255);
                                outColor.blue  = mClamp(_b, 0, 255);
#endif

                                lightmap->setColor(xoff + x, yoff + y, outColor);
                            }
                        }
                    }
                }
                continue;
            }

            ShadowVolumeBSP::SVPoly * poly = buildInteriorPoly(shadowVolume, detail,
                                             surfaceIndex, light, shadowedTree);

            // insert it into the SVBSP tree
            shadowVolume->insertPoly(poly);
        }
    }
}
void blTerrainProxy::light(LightInfo * light)
{
   // If we don't have terrain or its not a directional
   // light then skip processing.
   TerrainBlock * terrain = getObject();
   if ( !terrain || light->getType() != LightInfo::Vector )
      return;

   S32 time = Platform::getRealMilliseconds();

   // reset
   mShadowVolume = new ShadowVolumeBSP;

   // build interior shadow volume
   for(ObjectProxy ** itr = gLighting->mLitObjects.begin(); itr != gLighting->mLitObjects.end(); itr++)
   {
      ObjectProxy* objproxy = *itr;
      if (markObjectShadow(objproxy))
         objproxy->addToShadowVolume(mShadowVolume, light, SceneLighting::SHADOW_DETAIL);
   }

   lightVector(light);

   // set the lightmap...
   terrain->clearLightMap();

   // Blur...
   F32 kernel[3][3] = { {1, 2, 1},
                        {2, 3, 2},
                        {1, 2, 1} };

   F32 modifier = 1;
   F32 divisor = 0;


   for( U32 i=0; i<3; i++ )
   {
      for( U32 j=0; j<3; j++ )
      {
         if( i==1 && j==1 )
         {
            kernel[i][j] = 1 + kernel[i][j] * modifier;
         }
         else
         {
            kernel[i][j] = kernel[i][j] * modifier;
         }

         divisor += kernel[i][j];
      }
   }

   for( U32 i=0; i < mLightMapSize; i++ )
   {
      for( U32 j=0; j < mLightMapSize; j++ )
      {

         ColorF val;
         val  = _getValue( i-1, j-1  ) * kernel[0][0];
         val += _getValue( i-1, j    ) * kernel[0][1];
         val += _getValue( i-1, j+1  ) * kernel[0][2];
         val += _getValue(   i, j-1  ) * kernel[1][0];
         val += _getValue(   i, j    ) * kernel[1][1];
         val += _getValue(   i, j+1  ) * kernel[1][2];
         val += _getValue( i+1, j-1  ) * kernel[2][0];
         val += _getValue( i+1, j    ) * kernel[2][1];
         val += _getValue( i+1, j+1  ) * kernel[2][2];

         U32 edge = 0;

         if( j == 0 || j == mLightMapSize - 1 )
            edge++;

         if( i == 0 || i == mLightMapSize - 1 )
            edge++;

         if( !edge )
            val = val / divisor;
         else
            val = mLightmap[ i * mLightMapSize + j ];

         // clamp values
         mLightmap[ i * mLightMapSize + j ]= val;
      }
   }

   // And stuff it into the texture...
   GBitmap *terrLightMap = terrain->getLightMap();
   for(U32 y = 0; y < mLightMapSize; y++)
   {
      for(U32 x = 0; x < mLightMapSize; x++)
      {
         ColorI color(255, 255, 255, 255);
         
         color.red   = mLightmap[x + y * mLightMapSize].red   * 255;
         color.green = mLightmap[x + y * mLightMapSize].green * 255;
         color.blue  = mLightmap[x + y * mLightMapSize].blue  * 255;

         terrLightMap->setColor(x, y, color);
      }
   }

   /*
   // This handles matching up the outer edges of the terrain
   // lightmap when it has neighbors
   if (!terrain->isTiling())
   {
      for (S32 y = 0; y < terrLightMap->getHeight(); y++)
      {
         ColorI c;
         if (terrain->getFile()->mEdgeTerrainFiles[0])
         {
            terrLightMap->getColor(terrLightMap->getWidth()-1,y,c);
            terrLightMap->setColor(0,y,c);
            terrLightMap->setColor(1,y,c);
         }
         else
         {
            terrLightMap->getColor(0,y,c);
            terrLightMap->setColor(terrLightMap->getWidth()-1,y,c);
            terrLightMap->setColor(terrLightMap->getWidth()-2,y,c);
         }
      }

      for (S32 x = 0; x < terrLightMap->getHeight(); x++)
      {
         ColorI c;
         if (terrain->getFile()->mEdgeTerrainFiles[1])
         {
            terrLightMap->getColor(x,terrLightMap->getHeight()-1,c);
            terrLightMap->setColor(x,0,c);
            terrLightMap->setColor(x,1,c);
         }
         else
         {
            terrLightMap->getColor(x,0,c);
            terrLightMap->setColor(x,terrLightMap->getHeight()-1,c);
            terrLightMap->setColor(x,terrLightMap->getHeight()-2,c);
         }
      }
   }
   */

   delete mShadowVolume;

   Con::printf("    = terrain lit in %3.3f seconds", (Platform::getRealMilliseconds()-time)/1000.f);
}