void Update(SActivationInfo * pActInfo)
	{
		float timeOfDay = GetPortFloat(pActInfo, eIP_TimeOfDay);
		float longitude = timeOfDay / 24.0f * gf_PI * 2.0f;
		float latitude = -45.0f * gf_PI / 180.0f;
		Vec3 sunDir( sinf(longitude) * cosf(latitude), sinf(longitude) * sinf(latitude), cosf(longitude) );

		CRY_ASSERT(!"Direct call of I3DEngine::SetSunDir() is not supported anymore. Use Time of day featue instead.");
//		gEnv->p3DEngine->SetSunDir(sunDir);
		ActivateOutput(pActInfo, eOP_SunDirection, sunDir);
	}
Ejemplo n.º 2
0
void RenderImposterMgr::_innerRender( const SceneState *state, ShaderState &shaderState )
{
   PROFILE_SCOPE( RenderImposterMgr_InnerRender );

   // Capture the GFX stats for this render.
   GFXDeviceStatistics stats;
   stats.start( GFX->getDeviceStatistics() );

   GFXTransformSaver saver;

   // Init the shader.
   GFX->setShader( shaderState.mShader );
   GFX->setShaderConstBuffer( shaderState.mConsts );
   GFX->setStateBlock( shaderState.mSB );

   // Set the projection and world transform info.
   MatrixF proj = GFX->getProjectionMatrix() * GFX->getWorldMatrix();
   shaderState.mConsts->set( shaderState.mWorldViewProjectSC, proj );

   if (  shaderState.mSunDirSC ||
         shaderState.mLightColorSC ||
         shaderState.mAmbientSC )
   {
      // Pass the lighting consts.
      const LightInfo *sunlight = state->getLightManager()->getSpecialLight( LightManager::slSunLightType );
      VectorF sunDir( sunlight->getDirection() );
      sunDir.normalize();

      shaderState.mConsts->set( shaderState.mSunDirSC, sunDir );
      shaderState.mConsts->set( shaderState.mLightColorSC, sunlight->getColor() );
      shaderState.mConsts->set( shaderState.mAmbientSC, sunlight->getAmbient() );
   }

   // Get the data we need from the camera matrix.
   const MatrixF &camMat = state->getCameraTransform();
   Point3F camPos; 
   VectorF camRight, camUp, camDir;
   camMat.getColumn( 0, &camRight );
   camMat.getColumn( 1, &camDir );
   camMat.getColumn( 2, &camUp );
   camMat.getColumn( 3, &camPos );
   shaderState.mConsts->set( shaderState.mCamPosSC, camPos );
   shaderState.mConsts->set( shaderState.mCamRightSC, camRight );
   shaderState.mConsts->set( shaderState.mCamUpSC, camUp );

   if ( shaderState.mLightTexRT && shaderState.mLightTarget )
   {
      GFXTextureObject *texObject = shaderState.mLightTarget->getTargetTexture( 0 );
      GFX->setTexture( 2, texObject );
   
      // TODO: This normally shouldn't be NULL, but can be on the
      // first render... not sure why... we should investigate and
      // fix that rather than protect against it.
      if ( texObject )
      {
         const Point3I &targetSz = texObject->getSize();
         const RectI &targetVp = shaderState.mLightTarget->getTargetViewport();
         Point4F rtParams;

         ScreenSpace::RenderTargetParameters(targetSz, targetVp, rtParams);

         shaderState.mConsts->set( shaderState.mLightTexRT, rtParams ); 
      }
   }

   // Setup a fairly large dynamic vb to hold a bunch of imposters.
   if ( !mVB.isValid() )
   {
      // Setup the vb to hold a bunch of imposters at once.
      mVB.set( GFX, mImposterBatchSize * 4, GFXBufferTypeDynamic );
      
      // Setup a static index buffer for rendering.
      mIB.set( GFX, mImposterBatchSize * 6, 0, GFXBufferTypeStatic );
      U16 *idxBuff;
      mIB.lock(&idxBuff, NULL, NULL, NULL);
      for ( U32 i=0; i < mImposterBatchSize; i++ )
      {
         //
         // The vertex pattern in the VB for each 
         // imposter is as follows...
         //
         //     0----1
         //     |\   |
         //     | \  |
         //     |  \ |
         //     |   \|
         //     3----2
         //
         // We setup the index order below to ensure
         // sequental, cache friendly, access.
         //
         U32 offset = i * 4;
         idxBuff[i*6+0] = 0 + offset;
         idxBuff[i*6+1] = 1 + offset;
         idxBuff[i*6+2] = 2 + offset;
         idxBuff[i*6+3] = 2 + offset;
         idxBuff[i*6+4] = 3 + offset;
         idxBuff[i*6+5] = 0 + offset;
      }
      mIB.unlock();
   }

   // Set the buffers here once.
   GFX->setPrimitiveBuffer( mIB );
   GFX->setVertexBuffer( mVB );

   // Batch up the imposters into the buffer.  These
   // are already sorted by texture, to minimize switches
   // so just batch them up and render as they come.

   ImposterVertex* vertPtr = NULL;
   U32 vertCount = 0;
   F32 halfSize, fade, scale;
   Point3F center;
   QuatF rotQuat;

   const U32 binSize = mElementList.size();
   for( U32 i=0; i < binSize; )
   {
      ImposterRenderInst *ri = static_cast<ImposterRenderInst*>( mElementList[i].inst );

      TSLastDetail* detail = ri->detail;

      // Setup the textures.
      GFX->setTexture( 0, detail->getTextureMap() );
      GFX->setTexture( 1, detail->getNormalMap() );

      // Setup the constants for this batch.
      Point4F params( (detail->getNumPolarSteps() * 2) + 1, detail->getNumEquatorSteps(), detail->getPolarAngle(), detail->getIncludePoles() );
      shaderState.mConsts->set( shaderState.mParamsSC, params );

      U32 uvCount = getMin( detail->getTextureUVs().size(), 64 );
      AlignedArray<Point4F> rectData( uvCount, sizeof( Point4F ), (U8*)detail->getTextureUVs().address(), false );
      shaderState.mConsts->set( shaderState.mUVsSC, rectData );

      vertPtr = mVB.lock();
      vertCount = 0;

      for ( ; i < binSize; i++ )
      {
         ri = static_cast<ImposterRenderInst*>( mElementList[i].inst );

         // Stop the loop if the detail changed.
         if ( ri->detail != detail )
            break;

         ++smRendered;

         // If we're out of vb space then draw what we got.
         if ( vertCount + 4 >= mVB->mNumVerts )
         {
            mVB.unlock();
            GFX->drawIndexedPrimitive( GFXTriangleList, 0, 0, vertCount, 0, vertCount / 2 );
            vertPtr = mVB.lock();
            vertCount = 0;
         }

         center   = ri->center;
         halfSize = ri->halfSize;
         fade     = ri->alpha;
         scale    = ri->scale;
         rotQuat  = ri->rotQuat;

         // Fill in the points for this instance.
         vertPtr->center = center;
         vertPtr->center.w = 0;
         vertPtr->miscParams.set( halfSize, fade, scale );
         vertPtr->rotQuat.set( rotQuat.x, rotQuat.y, rotQuat.z, rotQuat.w );
         vertPtr++;

         vertPtr->center = center;
         vertPtr->center.w = 1;
         vertPtr->miscParams.set( halfSize, fade, scale );
         vertPtr->rotQuat.set( rotQuat.x, rotQuat.y, rotQuat.z, rotQuat.w );
         vertPtr++;

         vertPtr->center = center;
         vertPtr->center.w = 2;
         vertPtr->miscParams.set( halfSize, fade, scale );
         vertPtr->rotQuat.set( rotQuat.x, rotQuat.y, rotQuat.z, rotQuat.w );
         vertPtr++;

         vertPtr->center = center;
         vertPtr->center.w = 3;
         vertPtr->miscParams.set( halfSize, fade, scale );
         vertPtr->rotQuat.set( rotQuat.x, rotQuat.y, rotQuat.z, rotQuat.w );
         vertPtr++;

         vertCount += 4;
      }

      // Any remainder to dump?
      if ( vertCount > 0 )
      {
         smBatches++;
         mVB.unlock();
         GFX->drawIndexedPrimitive( GFXTriangleList, 0, 0, vertCount, 0, vertCount / 2 );
      }
   }

   // Capture the GFX stats for this render.
   stats.end( GFX->getDeviceStatistics() );
   smDrawCalls += stats.mDrawCalls;
   smPolyCount += stats.mPolyCount;
   smRTChanges += stats.mRenderTargetChanges;
}