Exemplo n.º 1
0
void ScatterSky::_debugRender( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat )
{
   GFXStateBlockDesc desc;
   desc.fillMode = GFXFillSolid;
   desc.setBlend( false, GFXBlendOne, GFXBlendZero );
   desc.setZReadWrite( false, false );
   GFXStateBlockRef sb = GFX->GFX->createStateBlock( desc );

   GFX->setStateBlock( sb );

   PrimBuild::begin( GFXLineStrip, mSkyPoints.size() );
   PrimBuild::color3i( 255, 0, 255 );

   for ( U32 i = 0; i < mSkyPoints.size(); i++ )
   {
      Point3F pnt = mSkyPoints[i];
      pnt.normalize();
      pnt *= 500;
      pnt += state->getCameraPosition();
      PrimBuild::vertex3fv( pnt );
   }

   PrimBuild::end();
}
Exemplo n.º 2
0
void Portal::_renderObject( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance* overrideMat )
{
   if( overrideMat )
      return;

   // Update geometry if necessary.

   if( mIsGeometryDirty )
      _updateGeometry();

   // Render portal polygon.

   GFXStateBlockDesc desc;
   desc.setBlend( true );
   desc.setZReadWrite( true, false );
   desc.setCullMode( GFXCullNone );

   PlaneF::Side viewSide = mPortalPlane.whichSide( state->getCameraPosition() );

   ColorI color;
   switch( mClassification )
   {
      case InvalidPortal:  color = ColorI( 255, 255, 255, 45 ); break;
      case ExteriorPortal: color = viewSide == PlaneF::Front ? ColorI( 0, 128, 128, 45 ) : ColorI( 0, 255, 255, 45 ); break;
      case InteriorPortal: color = viewSide == PlaneF::Front ? ColorI( 128, 128, 0, 45 ) : ColorI( 255, 255, 0, 45 ); break;
   }

   GFX->getDrawUtil()->drawPolygon( desc, mPortalPolygonWS.address(), mPortalPolygonWS.size(), color );

   desc.setFillModeWireframe();
   GFX->getDrawUtil()->drawPolygon( desc, mPortalPolygonWS.address(), mPortalPolygonWS.size(), ColorF::RED );

   // Render rest.

   Parent::_renderObject( ri, state, overrideMat );
}
Exemplo n.º 3
0
void EditTSCtrl::renderGrid()
{
   if( !isOrthoDisplayType() )
      return;

   GFXDEBUGEVENT_SCOPE( Editor_renderGrid, ColorI::WHITE );

   // Calculate the displayed grid size based on view
   F32 drawnGridSize = mGridPlaneSize;
   F32 gridPixelSize = projectRadius(1.0f, mGridPlaneSize);
   if(gridPixelSize < mGridPlaneSizePixelBias)
   {
      U32 counter = 1;
      while(gridPixelSize < mGridPlaneSizePixelBias)
      {
         drawnGridSize = mGridPlaneSize * counter * 10.0f;
         gridPixelSize = projectRadius(1.0f, drawnGridSize);

         ++counter;

         // No infinite loops here
         if(counter > 1000)
            break;
      }
   }

   F32 minorTickSize = 0;
   F32 gridSize = drawnGridSize;
   U32 minorTickMax = mGridPlaneMinorTicks + 1;
   if(minorTickMax > 0)
   {
      minorTickSize = drawnGridSize;
      gridSize = drawnGridSize * minorTickMax;
   }

   // Build the view-based origin
   VectorF dir;
   smCamMatrix.getColumn( 1, &dir );

   Point3F gridPlanePos = smCamPos + dir;
   Point2F size(mOrthoWidth + 2 * gridSize, mOrthoHeight + 2 * gridSize);

   GFXStateBlockDesc desc;
   desc.setBlend( true );
   desc.setZReadWrite( true, false );

   GFXDrawUtil::Plane plane = GFXDrawUtil::PlaneXY;
   switch( getDisplayType() )
   {
      case DisplayTypeTop:
      case DisplayTypeBottom:
         plane = GFXDrawUtil::PlaneXY;
         break;

      case DisplayTypeLeft:
      case DisplayTypeRight:
         plane = GFXDrawUtil::PlaneYZ;
         break;

      case DisplayTypeFront:
      case DisplayTypeBack:
         plane = GFXDrawUtil::PlaneXZ;
         break;
         
      default:
         break;
   }

   GFX->getDrawUtil()->drawPlaneGrid( desc, gridPlanePos, size, Point2F( minorTickSize, minorTickSize ), mGridPlaneMinorTickColor, plane );
   GFX->getDrawUtil()->drawPlaneGrid( desc, gridPlanePos, size, Point2F( gridSize, gridSize ), mGridPlaneColor, plane );
}
void ClipMapBlenderCache::initialize( ClipMap *cm )
{
	mOwningClipMap = cm;
	mClipMapSize = cm->mClipMapSize;

	mLightmapScratchTextures.push_back(GFXTexHandle( mClipMapSize, mClipMapSize, GFXFormatR8G8B8X8, &ClipMapTextureProfile, avar("%s() - mLightmapScratchTextures (line %d)", __FUNCTION__, __LINE__), 1 ));

	if (GFX->getPixelShaderVersion() == 0.0f)
	{
		mFixedfunction = true;

		// Fixed function stateblock
		GFXStateBlockDesc sbFF;
		sbFF.samplersDefined = true;
		sbFF.samplers[0] = GFXSamplerStateDesc::getClampLinear();
		sbFF.samplers[0].textureColorOp = GFXTOPSelectARG1;
		sbFF.samplers[0].colorArg1 = GFXTATexture;
		sbFF.samplers[1] = GFXSamplerStateDesc::getWrapLinear();      
		mFFBaseLayerSB = GFX->createStateBlock(sbFF);
		sbFF.setBlend(true, GFXBlendOne, GFXBlendOne);
		mFFAdditionalLayersSB = GFX->createStateBlock(sbFF);
		sbFF.setBlend(true, GFXBlendDestColor, GFXBlendSrcColor);
		sbFF.samplers[1].textureColorOp = GFXTOPDisable;
		mFFLightmapSB = GFX->createStateBlock(sbFF);
	}
	else
	{
		mFixedfunction = false;

		// Find and init shaders.
		ShaderData *sd = NULL;      
		if(GFX->getPixelShaderVersion() >= 2.0f)
		{
			if(!Sim::findObject( ( mLM1 ? "AtlasBlender20ShaderLM1" : "AtlasBlender20Shader" ), sd) || (sd->mShader == NULL))
			{
				Con::errorf("ClipMapBlenderCache::initialize - "
					"Couldn't find shader 'AtlasBlender20Shader'! Terrain will not blend properly on SM2.0 cards!");
			}
			else
			{
				mOnePass = sd->mShader;

				if (mOnePass)
					mShaderConsts = mOnePass->allocConstBuffer();

				if (mShaderConsts)
					sd->mapSamplerNames(mShaderConsts);
			}
		}
		else
		{
			if(!Sim::findObject( ( mLM1 ? "AtlasBlender11AShaderLM1" : "AtlasBlendeer11AShader" ), sd) || (sd->mShader == NULL))
			{
				Con::errorf("ClipMapBlenderCache::initialize - "
					"Couldn't find shader 'AtlasBlender11AShader'! Terrain will not blend properly on SM1.0 cards!");
			}
			else
			{
				mTwoPass[0] = sd->mShader;

				if (mTwoPass[0])
					mShaderConsts = mTwoPass[0]->allocConstBuffer();

				if (mShaderConsts)
					sd->mapSamplerNames(mShaderConsts);
			}

			if(!Sim::findObject( ( mLM1 ? "AtlasBlender11BShaderLM1" : "AtlasBlender11BShader" ), sd) || (sd->mShader == NULL))
			{
				Con::errorf("ClipMapBlenderCache::initialize - "
					"Couldn't find shader 'AtlasBlender11BShader'! Terrain will not blend properly on SM1.0 cards!");
			}
			else
			{
				mTwoPass[1] = sd->mShader;
			}
		}
		if (mShaderConsts)
		{
			mModelViewProjSC = mShaderConsts->getShader()->getShaderConstHandle(ShaderGenVars::modelview);
			mOpacityMapSC = mShaderConsts->getShader()->getShaderConstHandle("$opacity");
			mLightMapSC = mShaderConsts->getShader()->getShaderConstHandle("$lightMap");
			mTex1SC = mShaderConsts->getShader()->getShaderConstHandle("$tex1");
			mTex2SC = mShaderConsts->getShader()->getShaderConstHandle("$tex2");
			mTex3SC = mShaderConsts->getShader()->getShaderConstHandle("$tex3");
			mTex4SC = mShaderConsts->getShader()->getShaderConstHandle("$tex4");
			mSourceTexScalesSC = mShaderConsts->getShader()->getShaderConstHandle("$sourceTexScales");
		}

		// Init state blocks
		GFXStateBlockDesc sbd;
		sbd.setCullMode(GFXCullNone);
		sbd.setZEnable(false);
		sbd.zWriteEnable = false;
		sbd.samplersDefined = true;
		sbd.samplers[0] = GFXSamplerStateDesc::getClampLinear();
		sbd.samplers[1] = GFXSamplerStateDesc::getClampLinear();
		sbd.samplers[2] = GFXSamplerStateDesc::getWrapLinear();
		sbd.samplers[3] = GFXSamplerStateDesc::getWrapLinear();
		sbd.samplers[4] = GFXSamplerStateDesc::getWrapLinear();
		sbd.samplers[5] = GFXSamplerStateDesc::getWrapLinear();

		mOnePassSB = GFX->createStateBlock(sbd);

		sbd.setBlend(true, GFXBlendOne, GFXBlendOne);

		mTwoPassSB = GFX->createStateBlock(sbd);   
	}

	createOpacityScratchTextures();
}
Exemplo n.º 5
0
void ConvexShape::_renderDebug( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *mat )
{   
   GFXDrawUtil *drawer = GFX->getDrawUtil();

   GFX->setTexture( 0, NULL );

   // Render world box.
   if ( false )
   {
      Box3F wbox( mWorldBox );
      //if ( getServerObject() )      
      //   Box3F wbox = static_cast<ConvexShape*>( getServerObject() )->mWorldBox;      
      GFXStateBlockDesc desc;
      desc.setCullMode( GFXCullNone );
      desc.setFillModeWireframe();
      drawer->drawCube( desc, wbox, ColorI::RED );
   }


   const Vector< Point3F > &pointList = mGeometry.points;
	const Vector< ConvexShape::Face > &faceList = mGeometry.faces;

   // Render Edges.
   if ( false )
   {
      GFXTransformSaver saver;
      //GFXFrustumSaver fsaver;

      MatrixF xfm( getRenderTransform() );
      xfm.scale( getScale() );
      GFX->multWorld( xfm );

      GFXStateBlockDesc desc;
      desc.setZReadWrite( true, false );
      desc.setBlend( true );
      GFX->setStateBlockByDesc( desc );

      //MathUtils::getZBiasProjectionMatrix( 0.01f, state->getFrustum(), )

      const Point3F &camFvec = state->getCameraTransform().getForwardVector();



      for ( S32 i = 0; i < faceList.size(); i++ )
      {         
         const ConvexShape::Face &face = faceList[i];
         
         const Vector< ConvexShape::Edge > &edgeList = face.edges;

         const Vector< U32 > &facePntList = face.points;

         PrimBuild::begin( GFXLineList, edgeList.size() * 2 );
         
         PrimBuild::color( ColorI::WHITE * 0.8f );

         for ( S32 j = 0; j < edgeList.size(); j++ )         
         {
            PrimBuild::vertex3fv( pointList[ facePntList[ edgeList[j].p0 ] ] - camFvec * 0.001f );
            PrimBuild::vertex3fv( pointList[ facePntList[ edgeList[j].p1 ] ] - camFvec * 0.001f );
         }
         
         PrimBuild::end();
      }
   }

   ColorI faceColorsx[4] = 
   {
      ColorI( 255, 0, 0 ),
      ColorI( 0, 255, 0 ),
      ColorI( 0, 0, 255 ),
      ColorI( 255, 0, 255 )
   };

   MatrixF objToWorld( mObjToWorld );
   objToWorld.scale( mObjScale );

   // Render faces centers/colors.
   if ( false )
   {
      GFXStateBlockDesc desc;
      desc.setCullMode( GFXCullNone );
      
      Point3F size( 0.1f );

      for ( S32 i = 0; i < faceList.size(); i++ )
      {
         ColorI color = faceColorsx[ i % 4 ];
         S32 div = ( i / 4 ) * 4;
         if ( div > 0 )
            color /= div;
         color.alpha = 255;
         
         Point3F pnt;
         objToWorld.mulP( faceList[i].centroid, &pnt );
         drawer->drawCube( desc, size, pnt, color, NULL );
      }
   }

   // Render winding order.
   if ( false )
   {
      GFXStateBlockDesc desc;
      desc.setCullMode( GFXCullNone );
      desc.setZReadWrite( true, false );
      GFX->setStateBlockByDesc( desc );  

      U32 pointCount = 0;
      for ( S32 i = 0; i < faceList.size(); i++ )      
         pointCount += faceList[i].winding.size();      

      PrimBuild::begin( GFXLineList, pointCount * 2 );
      
      for ( S32 i = 0; i < faceList.size(); i++ )
      {
         for ( S32 j = 0; j < faceList[i].winding.size(); j++ )
         {
            Point3F p0 = pointList[ faceList[i].points[ faceList[i].winding[j] ] ];
            Point3F p1 = p0 + mSurfaces[ faceList[i].id ].getUpVector() * 0.75f * ( Point3F::One / mObjScale );

            objToWorld.mulP( p0 );
            objToWorld.mulP( p1 );

            ColorI color = faceColorsx[ j % 4 ];
            S32 div = ( j / 4 ) * 4;
            if ( div > 0 )
               color /= div;
            color.alpha = 255;
            
            PrimBuild::color( color );
            PrimBuild::vertex3fv( p0 );            
            PrimBuild::color( color );
            PrimBuild::vertex3fv( p1 );                        
         }
      }

      PrimBuild::end();
   }

   // Render Points.
   if ( false )
   {      
      /*
      GFXTransformSaver saver;

      MatrixF xfm( getRenderTransform() );
      xfm.scale( getScale() );
      GFX->multWorld( xfm );

      GFXStateBlockDesc desc;
      Point3F size( 0.05f );
      */
   }

   // Render surface transforms.
   if ( false )
   {
      GFXStateBlockDesc desc;
      desc.setBlend( false );
      desc.setZReadWrite( true, true );

      Point3F scale(mNormalLength);

      for ( S32 i = 0; i < mSurfaces.size(); i++ )
      {
         MatrixF objToWorld( mObjToWorld );
         objToWorld.scale( mObjScale );

         MatrixF renderMat;
         renderMat.mul( objToWorld, mSurfaces[i] );

         renderMat.setPosition( renderMat.getPosition() + renderMat.getUpVector() * 0.001f );
              
         drawer->drawTransform( desc, renderMat, &scale, NULL );
      }
   }
}
Exemplo n.º 6
0
void GuiColorPickerCtrl::onRender(Point2I offset, const RectI& updateRect)
{
   if (mStateBlock.isNull())
   {
      GFXStateBlockDesc desc;
      desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
      desc.setZReadWrite(false);
      desc.zWriteEnable = false;
      desc.setCullMode(GFXCullNone);
      mStateBlock = GFX->createStateBlock(desc);
   }

   RectI boundsRect(offset, getExtent());
   renderColorBox(boundsRect);

   if (mPositionChanged || mBitmap == NULL)
   {
      bool nullBitmap = false;

      if (mPositionChanged == false && mBitmap == NULL)
         nullBitmap = true;

      mPositionChanged = false;
      Point2I extent = getRoot()->getExtent();

      // If we are anything but a pallete, change the pick color
      if (mDisplayMode != pPallet)
      {
         Point2I resolution = getRoot()->getExtent();

         U32 buf_x = offset.x + mSelectorPos.x + 1;
         U32 buf_y = resolution.y - (extent.y - (offset.y + mSelectorPos.y + 1));

         GFXTexHandle bb( resolution.x, resolution.y, GFXFormatR8G8B8A8, &GFXDefaultRenderTargetProfile, avar("%s() - bb (line %d)", __FUNCTION__, __LINE__) );

         Point2I tmpPt(buf_x, buf_y);

         GFXTarget *targ = GFX->getActiveRenderTarget();
         targ->resolveTo(bb);

         if (mBitmap)
         {
            delete mBitmap;
            mBitmap = NULL;
         }

         mBitmap = new GBitmap(bb.getWidth(), bb.getHeight());

         bb.copyToBmp(mBitmap);

         if (!nullBitmap)
         {
            if (mSelectColor)
            {
               Point2I pos = findColor(mSetColor, offset, resolution, *mBitmap);
               mSetColor = mSetColor.BLACK;
               mSelectColor = false;
               setSelectorPos(pos);
            }
            else
            {
               ColorI tmp;
               mBitmap->getColor(buf_x, buf_y, tmp);

               mPickColor = (ColorF)tmp;

               // Now do onAction() if we are allowed
               if (mActionOnMove)
                  onAction();
            }
         }
      }
   }

   //render the children
   renderChildControls(offset, updateRect);
}
Exemplo n.º 7
0
bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials, 
                                       Pass *pass, 
                                       bool firstPass,
                                       bool prePassMat,
                                       bool reflectMat,
                                       bool baseOnly )
{
   if ( GFX->getPixelShaderVersion() < 3.0f )
      baseOnly = true;

   // NOTE: At maximum we only try to combine sgMaxTerrainMaterialsPerPass materials 
   // into a single pass.  This is sub-optimal for the simplest
   // cases, but the most common case results in much fewer
   // shader generation failures and permutations leading to
   // faster load time and less hiccups during gameplay.
   U32 matCount = getMin( sgMaxTerrainMaterialsPerPass, materials->size() );

   Vector<GFXTexHandle> normalMaps;

   // See if we're currently running under the
   // basic lighting manager.
   //
   // TODO: This seems ugly... we should trigger
   // features like this differently in the future.
   //
   bool useBLM = dStrcmp( LIGHTMGR->getId(), "BLM" ) == 0;

   // Do we need to disable normal mapping?
   const bool disableNormalMaps = MATMGR->getExclusionFeatures().hasFeature( MFT_NormalMap ) || useBLM;

   // How about parallax?
   const bool disableParallaxMaps = GFX->getPixelShaderVersion() < 3.0f || 
                                    MATMGR->getExclusionFeatures().hasFeature( MFT_Parallax );

   // Has advanced lightmap support been enabled for prepass.
   bool advancedLightmapSupport = false;
   if ( prePassMat )
   {
      // This sucks... but it works.
      AdvancedLightBinManager *lightBin;
      if ( Sim::findObject( "AL_LightBinMgr", lightBin ) )
         advancedLightmapSupport = lightBin->MRTLightmapsDuringPrePass();
   }

   // Loop till we create a valid shader!
   while( true )
   {
      FeatureSet features;
      features.addFeature( MFT_VertTransform );

      if ( prePassMat )
      {
         features.addFeature( MFT_EyeSpaceDepthOut );
         features.addFeature( MFT_PrePassConditioner );
         features.addFeature( MFT_DeferredTerrainBaseMap );
         features.addFeature(MFT_isDeferred);

         if ( advancedLightmapSupport )
            features.addFeature( MFT_RenderTarget3_Zero );
      }
      else
      {
         features.addFeature( MFT_TerrainBaseMap );
         features.addFeature( MFT_RTLighting );

         // The HDR feature is always added... it will compile out
         // if HDR is not enabled in the engine.
         features.addFeature( MFT_HDROut );
      }
      features.addFeature(MFT_DeferredTerrainBlankInfoMap);

      // Enable lightmaps and fogging if we're in BL.
      if ( reflectMat || useBLM )
      {
         features.addFeature( MFT_Fog );
         features.addFeature( MFT_ForwardShading );
      }
      if ( useBLM )
         features.addFeature( MFT_TerrainLightMap );

      // The additional passes need to be lerp blended into the
      // target to maintain the results of the previous passes.
      if ( !firstPass )
         features.addFeature( MFT_TerrainAdditive );

      normalMaps.clear();
      pass->materials.clear();

      // Now add all the material layer features.

      for ( U32 i=0; i < matCount && !baseOnly; i++ )
      {
         TerrainMaterial *mat = (*materials)[i]->mat;

         if ( mat == NULL )
            continue;

         // We only include materials that 
         // have more than a base texture.
         if (  mat->getDetailSize() <= 0 ||
               mat->getDetailDistance() <= 0 ||
               mat->getDetailMap().isEmpty() )
            continue;         

         S32 featureIndex = pass->materials.size();

		 // check for macro detail texture
         if (  !(mat->getMacroSize() <= 0 || mat->getMacroDistance() <= 0 || mat->getMacroMap().isEmpty() ) )
         {
            if(prePassMat)
               features.addFeature( MFT_DeferredTerrainMacroMap, featureIndex );
            else
	         features.addFeature( MFT_TerrainMacroMap, featureIndex );
         }

         if(prePassMat)
             features.addFeature( MFT_DeferredTerrainDetailMap, featureIndex );
         else
         features.addFeature( MFT_TerrainDetailMap, featureIndex );

         pass->materials.push_back( (*materials)[i] );
         normalMaps.increment();

         // Skip normal maps if we need to.
         if ( !disableNormalMaps && mat->getNormalMap().isNotEmpty() )
         {
            features.addFeature( MFT_TerrainNormalMap, featureIndex );

            normalMaps.last().set( mat->getNormalMap(), 
               &GFXDefaultStaticNormalMapProfile, "TerrainCellMaterial::_createPass() - NormalMap" );

            if ( normalMaps.last().getFormat() == GFXFormatDXT5 )
               features.addFeature( MFT_IsDXTnm, featureIndex );

            // Do we need and can we do parallax mapping?
            if (  !disableParallaxMaps &&
                  mat->getParallaxScale() > 0.0f &&
                  !mat->useSideProjection() )
               features.addFeature( MFT_TerrainParallaxMap, featureIndex );
         }

         // Is this layer got side projection?
         if ( mat->useSideProjection() )
            features.addFeature( MFT_TerrainSideProject, featureIndex );
      }

      MaterialFeatureData featureData;
      featureData.features = features;
      featureData.materialFeatures = features;

      // Check to see how many vertex shader output 
      // registers we're gonna need.
      U32 numTex = 0;
      U32 numTexReg = 0;
      for ( U32 i=0; i < features.getCount(); i++ )
      {
         S32 index;
         const FeatureType &type = features.getAt( i, &index );
         ShaderFeature* sf = FEATUREMGR->getByType( type );
         if ( !sf ) 
            continue;

         sf->setProcessIndex( index );
         ShaderFeature::Resources res = sf->getResources( featureData );

         numTex += res.numTex;
         numTexReg += res.numTexReg;
      }

      // Can we build the shader?
      //
      // NOTE: The 10 is sort of an abitrary SM 3.0 
      // limit.  Its really supposed to be 11, but that
      // always fails to compile so far.
      //
      if (  numTex < GFX->getNumSamplers() &&
            numTexReg <= 10 )
      {         
         // NOTE: We really shouldn't be getting errors building the shaders,
         // but we can generate more instructions than the ps_2_x will allow.
         //
         // There is no way to deal with this case that i know of other than
         // letting the compile fail then recovering by trying to build it
         // with fewer materials.
         //
         // We normally disable the shader error logging so that the user 
         // isn't fooled into thinking there is a real bug.  That is until
         // we get down to a single material.  If a single material case
         // fails it means it cannot generate any passes at all!
         const bool logErrors = matCount == 1;
         GFXShader::setLogging( logErrors, true );

         pass->shader = SHADERGEN->getShader( featureData, getGFXVertexFormat<TerrVertex>(), NULL, mSamplerNames );
      }

      // If we got a shader then we can continue.
      if ( pass->shader )
         break;

      // If the material count is already 1 then this
      // is a real shader error... give up!
      if ( matCount <= 1 )
         return false;

      // If we failed we next try half the input materials
      // so that we can more quickly arrive at a valid shader.
      matCount -= matCount / 2;
   }

   // Setup the constant buffer.
   pass->consts = pass->shader->allocConstBuffer();

   // Prepare the basic constants.
   pass->modelViewProjConst = pass->shader->getShaderConstHandle( "$modelview" );
   pass->worldViewOnly = pass->shader->getShaderConstHandle( "$worldViewOnly" );
   pass->viewToObj = pass->shader->getShaderConstHandle( "$viewToObj" );
   pass->eyePosWorldConst = pass->shader->getShaderConstHandle( "$eyePosWorld" );
   pass->eyePosConst = pass->shader->getShaderConstHandle( "$eyePos" );
   pass->vEyeConst = pass->shader->getShaderConstHandle( "$vEye" );
   pass->layerSizeConst = pass->shader->getShaderConstHandle( "$layerSize" );
   pass->objTransConst = pass->shader->getShaderConstHandle( "$objTrans" );
   pass->worldToObjConst = pass->shader->getShaderConstHandle( "$worldToObj" );  
   pass->lightInfoBufferConst = pass->shader->getShaderConstHandle( "$lightInfoBuffer" );   
   pass->baseTexMapConst = pass->shader->getShaderConstHandle( "$baseTexMap" );
   pass->layerTexConst = pass->shader->getShaderConstHandle( "$layerTex" );
   pass->fogDataConst = pass->shader->getShaderConstHandle( "$fogData" );
   pass->fogColorConst = pass->shader->getShaderConstHandle( "$fogColor" );
   pass->lightMapTexConst = pass->shader->getShaderConstHandle( "$lightMapTex" );
   pass->oneOverTerrainSize = pass->shader->getShaderConstHandle( "$oneOverTerrainSize" );
   pass->squareSize = pass->shader->getShaderConstHandle( "$squareSize" );

   pass->lightParamsConst = pass->shader->getShaderConstHandle( "$rtParamslightInfoBuffer" );

   // Now prepare the basic stateblock.
   GFXStateBlockDesc desc;
   if ( !firstPass )
   {
      desc.setBlend( true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha );

      // If this is the prepass then we don't want to
      // write to the last two color channels (where
      // depth is usually encoded).
      //
      // This trick works in combination with the 
      // MFT_TerrainAdditive feature to lerp the
      // output normal with the previous pass.
      //
      if ( prePassMat )
         desc.setColorWrites( true, true, true, false );
   }

   // We write to the zbuffer if this is a prepass
   // material or if the prepass is disabled.
   desc.setZReadWrite( true,  !MATMGR->getPrePassEnabled() || 
                              prePassMat ||
                              reflectMat );

   desc.samplersDefined = true;
   if ( pass->baseTexMapConst->isValid() )
      desc.samplers[pass->baseTexMapConst->getSamplerRegister()] = GFXSamplerStateDesc::getWrapLinear();

   if ( pass->layerTexConst->isValid() )
      desc.samplers[pass->layerTexConst->getSamplerRegister()] = GFXSamplerStateDesc::getClampPoint();

   if ( pass->lightInfoBufferConst->isValid() )
      desc.samplers[pass->lightInfoBufferConst->getSamplerRegister()] = GFXSamplerStateDesc::getClampPoint();

   if ( pass->lightMapTexConst->isValid() )
      desc.samplers[pass->lightMapTexConst->getSamplerRegister()] = GFXSamplerStateDesc::getWrapLinear();

   const U32 maxAnisotropy = MATMGR->getDefaultAnisotropy();

   // Finally setup the material specific shader 
   // constants and stateblock state.
   //
   // NOTE: If this changes be sure to check TerrainCellMaterial::_updateDefaultAnisotropy
   // to see if it needs the same changes.
   //
   for ( U32 i=0; i < pass->materials.size(); i++ )
   {
      MaterialInfo *matInfo = pass->materials[i];

      matInfo->detailInfoVConst = pass->shader->getShaderConstHandle( avar( "$detailScaleAndFade%d", i ) );
      matInfo->detailInfoPConst = pass->shader->getShaderConstHandle( avar( "$detailIdStrengthParallax%d", i ) );

      matInfo->detailTexConst = pass->shader->getShaderConstHandle( avar( "$detailMap%d", i ) );
      if ( matInfo->detailTexConst->isValid() )
      {
         const S32 sampler = matInfo->detailTexConst->getSamplerRegister();

         desc.samplers[sampler] = GFXSamplerStateDesc::getWrapLinear();
         desc.samplers[sampler].magFilter = GFXTextureFilterLinear;
         desc.samplers[sampler].mipFilter = GFXTextureFilterLinear;

         if ( maxAnisotropy > 1 )
         {
            desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic;
            desc.samplers[sampler].maxAnisotropy = maxAnisotropy;
         }
         else
            desc.samplers[sampler].minFilter = GFXTextureFilterLinear;

         matInfo->detailTex.set( matInfo->mat->getDetailMap(), 
            &GFXDefaultStaticDiffuseProfile, "TerrainCellMaterial::_createPass() - DetailMap" );
      }

      matInfo->macroInfoVConst = pass->shader->getShaderConstHandle( avar( "$macroScaleAndFade%d", i ) );
      matInfo->macroInfoPConst = pass->shader->getShaderConstHandle( avar( "$macroIdStrengthParallax%d", i ) );

      matInfo->macroTexConst = pass->shader->getShaderConstHandle( avar( "$macroMap%d", i ) );
      if ( matInfo->macroTexConst->isValid() )
      {
         const S32 sampler = matInfo->macroTexConst->getSamplerRegister();

         desc.samplers[sampler] = GFXSamplerStateDesc::getWrapLinear();
         desc.samplers[sampler].magFilter = GFXTextureFilterLinear;
         desc.samplers[sampler].mipFilter = GFXTextureFilterLinear;

         if ( maxAnisotropy > 1 )
         {
            desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic;
            desc.samplers[sampler].maxAnisotropy = maxAnisotropy;
         }
         else
            desc.samplers[sampler].minFilter = GFXTextureFilterLinear;

         matInfo->macroTex.set( matInfo->mat->getMacroMap(), 
            &GFXDefaultStaticDiffuseProfile, "TerrainCellMaterial::_createPass() - MacroMap" );
      }
	  //end macro texture

      matInfo->normalTexConst = pass->shader->getShaderConstHandle( avar( "$normalMap%d", i ) );
      if ( matInfo->normalTexConst->isValid() )
      {
         const S32 sampler = matInfo->normalTexConst->getSamplerRegister();

         desc.samplers[sampler] = GFXSamplerStateDesc::getWrapLinear();
         desc.samplers[sampler].magFilter = GFXTextureFilterLinear;
         desc.samplers[sampler].mipFilter = GFXTextureFilterLinear;

         if ( maxAnisotropy > 1 )
         {
            desc.samplers[sampler].minFilter = GFXTextureFilterAnisotropic;
            desc.samplers[sampler].maxAnisotropy = maxAnisotropy;
         }
         else
            desc.samplers[sampler].minFilter = GFXTextureFilterLinear;

         matInfo->normalTex = normalMaps[i];
      }
   }

   // Remove the materials we processed and leave the
   // ones that remain for the next pass.
   for ( U32 i=0; i < matCount; i++ )
   {
      MaterialInfo *matInfo = materials->first();
      if ( baseOnly || pass->materials.find_next( matInfo ) == -1 )
         delete matInfo;     
      materials->pop_front();
   }

   // If we're doing prepass it requires some 
   // special stencil settings for it to work.
   if ( prePassMat )
      desc.addDesc( RenderPrePassMgr::getOpaqueStenciWriteDesc( false ) );

   desc.setCullMode( GFXCullCCW );
   pass->stateBlock = GFX->createStateBlock(desc);

   //reflection stateblock
   desc.setCullMode( GFXCullCW );
   pass->reflectionStateBlock = GFX->createStateBlock(desc);

   // Create the wireframe state blocks.
   GFXStateBlockDesc wireframe( desc );
   wireframe.fillMode = GFXFillWireframe;
   wireframe.setCullMode( GFXCullCCW );
   pass->wireframeStateBlock = GFX->createStateBlock( wireframe );

   return true;
}
Exemplo n.º 8
0
void drawActor( NxActor *inActor )
{
   GFXDrawUtil *drawer = GFX->getDrawUtil();
   //drawer->setZRead( false );

   // Determine alpha we render shapes with.
   const U8 enabledAlpha = 255;
   const U8 disabledAlpha = 100;
   U8 renderAlpha = inActor->readActorFlag( NX_AF_DISABLE_COLLISION ) ? disabledAlpha : enabledAlpha;

   // Determine color we render actors and shapes with.
   ColorI actorColor( 0, 0, 255, 200 );   
   ColorI shapeColor = ( inActor->isSleeping() ? ColorI( 0, 0, 255, renderAlpha ) : ColorI( 255, 0, 255, renderAlpha ) );      

   MatrixF actorMat(true);
   inActor->getGlobalPose().getRowMajor44( actorMat );

   GFXStateBlockDesc desc;
   desc.setBlend( true );
   desc.setZReadWrite( true, false );
   desc.setCullMode( GFXCullNone );

   // Draw an xfm gizmo for the actor's globalPose...
   //drawer->drawTransform( desc, actorMat, Point3F::One, actorColor );
   
   // Loop through and render all the actor's shapes....

   NxShape *const*pShapeArray = inActor->getShapes();
   U32 numShapes = inActor->getNbShapes();

   for ( U32 i = 0; i < numShapes; i++ )
   {
      const NxShape *shape = pShapeArray[i];

      Point3F shapePos = pxCast<Point3F>( shape->getGlobalPosition() );
      MatrixF shapeMat(true);
      shape->getGlobalPose().getRowMajor44(shapeMat);
      shapeMat.setPosition( Point3F::Zero );

      switch ( shape->getType() )
      {
         case NX_SHAPE_SPHERE:
         {
            NxSphereShape *sphere = (NxSphereShape*)shape;     
            drawer->drawSphere( desc, sphere->getRadius(), shapePos, shapeColor );

            break;
         }
         case NX_SHAPE_BOX:
         {
            NxBoxShape *box = (NxBoxShape*)shape;
            Point3F size = pxCast<Point3F>( box->getDimensions() );            
            drawer->drawCube( desc, size*2, shapePos, shapeColor, &shapeMat );            
            break;
         }
         case NX_SHAPE_CAPSULE:
         {
            shapeMat.mul( MatrixF( EulerF( mDegToRad(90.0f), mDegToRad(90.0f), 0 ) ) );

            NxCapsuleShape *capsule = (NxCapsuleShape*)shape;
            drawer->drawCapsule( desc, shapePos, capsule->getRadius(), capsule->getHeight(), shapeColor, &shapeMat );

            break;
         }
         default:
         {
            break;
         }
      }
   }

   //drawer->clearZDefined();
}
Exemplo n.º 9
0
void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
{
	// Save the current transforms so we can restore
   // it for child control rendering below.
   GFXTransformSaver saver;
   bool renderingToTarget = false;

   if(!processCameraQuery(&mLastCameraQuery))
   {
      // We have no camera, but render the GUI children 
      // anyway.  This makes editing GuiTSCtrl derived
      // controls easier in the GuiEditor.
      renderChildControls( offset, updateRect );
      return;
   }

   GFXTargetRef origTarget = GFX->getActiveRenderTarget();

   // Set up the appropriate render style
   U32 prevRenderStyle = GFX->getCurrentRenderStyle();
   Point2F prevProjectionOffset = GFX->getCurrentProjectionOffset();
   Point2I renderSize = getExtent();

   if(mRenderStyle == RenderStyleStereoSideBySide)
   {
      GFX->setCurrentRenderStyle(GFXDevice::RS_StereoSideBySide);
      GFX->setCurrentProjectionOffset(mLastCameraQuery.projectionOffset);
      GFX->setStereoEyeOffsets(mLastCameraQuery.eyeOffset);

      if (!mLastCameraQuery.hasStereoTargets)
      {
         // Need to calculate our current viewport here
         mLastCameraQuery.stereoViewports[0] = updateRect;
         mLastCameraQuery.stereoViewports[0].extent.x /= 2;
         mLastCameraQuery.stereoViewports[1] = mLastCameraQuery.stereoViewports[0];
         mLastCameraQuery.stereoViewports[1].point.x += mLastCameraQuery.stereoViewports[1].extent.x;
      }

      if (!mLastCameraQuery.hasFovPort)
      {
         // Need to make our own fovPort
         mLastCameraQuery.fovPort[0] = CalculateFovPortForCanvas(mLastCameraQuery.stereoViewports[0], mLastCameraQuery);
         mLastCameraQuery.fovPort[1] = CalculateFovPortForCanvas(mLastCameraQuery.stereoViewports[1], mLastCameraQuery);
      }
         
      GFX->setStereoFovPort(mLastCameraQuery.fovPort); // NOTE: this specifies fov for BOTH eyes

      GFX->setSteroViewports(mLastCameraQuery.stereoViewports);
      GFX->setStereoTargets(mLastCameraQuery.stereoTargets);

      MatrixF myTransforms[2];

      if (smUseLatestDisplayTransform)
      {
         // Use the view matrix determined from the display device
         myTransforms[0] = mLastCameraQuery.eyeTransforms[0];
         myTransforms[1] = mLastCameraQuery.eyeTransforms[1];
      }
      else
      {
         // Use the view matrix determined from the control object
         myTransforms[0] = mLastCameraQuery.cameraMatrix;
         myTransforms[1] = mLastCameraQuery.cameraMatrix;

         QuatF qrot = mLastCameraQuery.cameraMatrix;
         Point3F pos = mLastCameraQuery.cameraMatrix.getPosition();
         Point3F rotEyePos;

         myTransforms[0].setPosition(pos + qrot.mulP(mLastCameraQuery.eyeOffset[0], &rotEyePos));
         myTransforms[1].setPosition(pos + qrot.mulP(mLastCameraQuery.eyeOffset[1], &rotEyePos));
      }

      GFX->setStereoEyeTransforms(myTransforms);

      // Allow render size to originate from the render target
      if (mLastCameraQuery.stereoTargets[0])
      {
         renderSize = mLastCameraQuery.stereoViewports[0].extent;
         renderingToTarget = true;
      }
   }
   else
   {
      GFX->setCurrentRenderStyle(GFXDevice::RS_Standard);
   }

   if ( mReflectPriority > 0 )
   {
      // Get the total reflection priority.
      F32 totalPriority = 0;
      for ( U32 i=0; i < smAwakeTSCtrls.size(); i++ )
         if ( smAwakeTSCtrls[i]->isVisible() )
            totalPriority += smAwakeTSCtrls[i]->mReflectPriority;

      REFLECTMGR->update(  mReflectPriority / totalPriority,
                           getExtent(),
                           mLastCameraQuery );
   }

   if(mForceFOV != 0)
      mLastCameraQuery.fov = mDegToRad(mForceFOV);

   if(mCameraZRot)
   {
      MatrixF rotMat(EulerF(0, 0, mDegToRad(mCameraZRot)));
      mLastCameraQuery.cameraMatrix.mul(rotMat);
   }

   Frustum frustum;
   if(mRenderStyle == RenderStyleStereoSideBySide)
   {
      // NOTE: these calculations are essentially overridden later by the fov port settings when rendering each eye.
      MathUtils::makeFovPortFrustum(&frustum, mLastCameraQuery.ortho,  mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane, mLastCameraQuery.fovPort[0]);
   }
   else
   {
      // set up the camera and viewport stuff:
      F32 wwidth;
      F32 wheight;
      F32 renderWidth = F32(renderSize.x);
      F32 renderHeight = F32(renderSize.y);
      F32 aspectRatio = renderWidth / renderHeight;
   
      // Use the FOV to calculate the viewport height scale
      // then generate the width scale from the aspect ratio.
      if(!mLastCameraQuery.ortho)
      {
         wheight = mLastCameraQuery.nearPlane * mTan(mLastCameraQuery.fov / 2.0f);
         wwidth = aspectRatio * wheight;
      }
      else
      {
         wheight = mLastCameraQuery.fov;
         wwidth = aspectRatio * wheight;
      }

      F32 hscale = wwidth * 2.0f / renderWidth;
      F32 vscale = wheight * 2.0f / renderHeight;

      F32 left = (updateRect.point.x - offset.x) * hscale - wwidth;
      F32 right = (updateRect.point.x + updateRect.extent.x - offset.x) * hscale - wwidth;
      F32 top = wheight - vscale * (updateRect.point.y - offset.y);
      F32 bottom = wheight - vscale * (updateRect.point.y + updateRect.extent.y - offset.y);

      frustum.set( mLastCameraQuery.ortho, left, right, top, bottom, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane );
   }

	// Manipulate the frustum for tiled screenshots
	const bool screenShotMode = gScreenShot && gScreenShot->isPending();
   if ( screenShotMode )
   {
      gScreenShot->tileFrustum( frustum );      
      GFX->setViewMatrix(MatrixF::Identity);
   }
      
   RectI tempRect = updateRect;
   
   if (!renderingToTarget)
   {
   #ifdef TORQUE_OS_MAC
      Point2I screensize = getRoot()->getWindowSize();
      tempRect.point.y = screensize.y - (tempRect.point.y + tempRect.extent.y);
   #endif

      GFX->setViewport( tempRect );
   }
   else
   {
      // Activate stereo RT
      GFX->activateStereoTarget(-1);
   }

   // Clear the zBuffer so GUI doesn't hose object rendering accidentally
   GFX->clear( GFXClearZBuffer , ColorI(20,20,20), 1.0f, 0 );
   //GFX->clear( GFXClearTarget, ColorI(255,0,0), 1.0f, 0);

   GFX->setFrustum( frustum );
   if(mLastCameraQuery.ortho)
   {
      mOrthoWidth = frustum.getWidth();
      mOrthoHeight = frustum.getHeight();
   }

   // We're going to be displaying this render at size of this control in
   // pixels - let the scene know so that it can calculate e.g. reflections
   // correctly for that final display result.
   gClientSceneGraph->setDisplayTargetResolution(renderSize);

   // Set the GFX world matrix to the world-to-camera transform, but don't 
   // change the cameraMatrix in mLastCameraQuery. This is because 
   // mLastCameraQuery.cameraMatrix is supposed to contain the camera-to-world
   // transform. In-place invert would save a copy but mess up any GUIs that
   // depend on that value.
   MatrixF worldToCamera = mLastCameraQuery.cameraMatrix;
   worldToCamera.inverse();
   GFX->setWorldMatrix( worldToCamera );

   mSaveProjection = GFX->getProjectionMatrix();
   mSaveModelview = GFX->getWorldMatrix();
   mSaveViewport = updateRect;
   mSaveWorldToScreenScale = GFX->getWorldToScreenScale();
   mSaveFrustum = GFX->getFrustum();
   mSaveFrustum.setTransform( mLastCameraQuery.cameraMatrix );

   // Set the default non-clip projection as some 
   // objects depend on this even in non-reflect cases.
   gClientSceneGraph->setNonClipProjection( mSaveProjection );

   // Give the post effect manager the worldToCamera, and cameraToScreen matrices
   PFXMGR->setFrameMatrices( mSaveModelview, mSaveProjection );

   renderWorld(updateRect);
   DebugDrawer::get()->render();

   // Render the canvas overlay if its available
   if (mRenderStyle == RenderStyleStereoSideBySide && mStereoGuiTarget.getPointer())
   {
      GFXDEBUGEVENT_SCOPE( StereoGui_Render, ColorI( 255, 0, 0 ) );
      MatrixF proj(1);
      
      Frustum originalFrustum = GFX->getFrustum();
      GFXTextureObject *texObject = mStereoGuiTarget->getTexture(0);
      const FovPort *currentFovPort = GFX->getStereoFovPort();
      const MatrixF *eyeTransforms = GFX->getStereoEyeTransforms();
      const Point3F *eyeOffset = GFX->getStereoEyeOffsets();
      Frustum gfxFrustum = originalFrustum;

      for (U32 i=0; i<2; i++)
      {
         GFX->activateStereoTarget(i);
         MathUtils::makeFovPortFrustum(&gfxFrustum, true, gfxFrustum.getNearDist(), gfxFrustum.getFarDist(), currentFovPort[i], eyeTransforms[i]);
         GFX->setFrustum(gfxFrustum);

         MatrixF eyeWorldTrans(1);
         eyeWorldTrans.setPosition(Point3F(eyeOffset[i].x,eyeOffset[i].y,eyeOffset[i].z));
         MatrixF eyeWorld(1);
         eyeWorld.mul(eyeWorldTrans);
         eyeWorld.inverse();
         
         GFX->setWorldMatrix(eyeWorld);
         GFX->setViewMatrix(MatrixF::Identity);

         if (!mStereoOverlayVB.getPointer())
         {
            mStereoOverlayVB.set(GFX, 4, GFXBufferTypeStatic);
            GFXVertexPCT *verts = mStereoOverlayVB.lock(0, 4);

            F32 texLeft   = 0.0f;
            F32 texRight  = 1.0f;
            F32 texTop    = 1.0f;
            F32 texBottom = 0.0f;

            F32 rectRatio = gfxFrustum.getWidth() / gfxFrustum.getHeight();
            F32 rectWidth = gfxFrustum.getWidth() * TS_OVERLAY_SCREEN_WIDTH;
            F32 rectHeight = rectWidth * rectRatio;

            F32 screenLeft   = -rectWidth * 0.5;
            F32 screenRight  = rectWidth * 0.5;
            F32 screenTop    = -rectHeight * 0.5;
            F32 screenBottom = rectHeight * 0.5;

            const F32 fillConv = 0.0f;
            const F32 frustumDepthAdjusted = gfxFrustum.getNearDist() + 0.012;
            verts[0].point.set( screenLeft  - fillConv, frustumDepthAdjusted, screenTop    - fillConv );
            verts[1].point.set( screenRight - fillConv, frustumDepthAdjusted, screenTop    - fillConv );
            verts[2].point.set( screenLeft  - fillConv, frustumDepthAdjusted, screenBottom - fillConv );
            verts[3].point.set( screenRight - fillConv, frustumDepthAdjusted, screenBottom - fillConv );

            verts[0].color = verts[1].color = verts[2].color = verts[3].color = ColorI(255,255,255,255);

            verts[0].texCoord.set( texLeft,  texTop );
            verts[1].texCoord.set( texRight, texTop );
            verts[2].texCoord.set( texLeft,  texBottom );
            verts[3].texCoord.set( texRight, texBottom );

            mStereoOverlayVB.unlock();
         }

         if (!mStereoGuiSB.getPointer())
         {
            // DrawBitmapStretchSR
            GFXStateBlockDesc bitmapStretchSR;
            bitmapStretchSR.setCullMode(GFXCullNone);
            bitmapStretchSR.setZReadWrite(false, false);
            bitmapStretchSR.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
            bitmapStretchSR.samplersDefined = true;

            bitmapStretchSR.samplers[0] = GFXSamplerStateDesc::getClampLinear();
            bitmapStretchSR.samplers[0].minFilter = GFXTextureFilterPoint;
            bitmapStretchSR.samplers[0].mipFilter = GFXTextureFilterPoint;
            bitmapStretchSR.samplers[0].magFilter = GFXTextureFilterPoint;

            mStereoGuiSB = GFX->createStateBlock(bitmapStretchSR);
         }

         GFX->setVertexBuffer(mStereoOverlayVB);
         GFX->setStateBlock(mStereoGuiSB);
         GFX->setTexture( 0, texObject );
         GFX->setupGenericShaders( GFXDevice::GSModColorTexture );
         GFX->drawPrimitive( GFXTriangleStrip, 0, 2 );
      }
   }

	// Restore the previous matrix state before
   // we begin rendering the child controls.
   saver.restore();

   // Restore the render style and any stereo parameters
   GFX->setActiveRenderTarget(origTarget);
   GFX->setCurrentRenderStyle(prevRenderStyle);
   GFX->setCurrentProjectionOffset(prevProjectionOffset);

   
   if(mRenderStyle == RenderStyleStereoSideBySide && gLastStereoTexture)
   {
      GFX->setClipRect(updateRect);
      GFX->getDrawUtil()->drawBitmapStretch(gLastStereoTexture, updateRect);
   }

   // Allow subclasses to render 2D elements.
   GFX->setClipRect(updateRect);
   renderGui( offset, updateRect );

   if (shouldRenderChildControls())
   {
      renderChildControls(offset, updateRect);
   }
   smFrameCount++;
}
Exemplo n.º 10
0
void SFXEmitter::_render3DVisualFeedback()
{
   GFXTransformSaver saver;
   
   GFX->multWorld( getRenderTransform() );
   
   GFXStateBlockDesc desc;
   desc.setZReadWrite( true, false );
   desc.setBlend( true );
   desc.setCullMode( GFXCullNone );

   if( mRenderSB == NULL )
      mRenderSB = GFX->createStateBlock( desc );
   
   GFX->setStateBlock( mRenderSB );
   
   // Render the max range sphere.
   
   if( smRenderColorRangeSphere.alpha > 0 )
      GFX->getDrawUtil()->drawSphere( desc, mDescription.mMaxDistance, Point3F( 0.f, 0.f, 0.f ), smRenderColorRangeSphere );
   
   //TODO: some point size support in GFX would be nice

   // Prepare primitive list.  Make sure we stay within limits.
   
   F32 radialIncrements = smRenderRadialIncrements;
   F32 sweepIncrements = smRenderSweepIncrements;
   F32 pointDistance = smRenderPointDistance;
   
   F32 numPoints;
   while( 1 )
   {
      numPoints = mCeil( 360.f / radialIncrements ) *
                  mCeil( 360.f / sweepIncrements ) *
                  ( mDescription.mMaxDistance / pointDistance );
                  
      if( numPoints < 65536 )
         break;
         
      radialIncrements *= 1.1f;
      sweepIncrements *= 1.1f;
      pointDistance *= 1.5;
   }
                           
   PrimBuild::begin( GFXPointList, numPoints );

   // Render inner cone.
   
   _renderCone(
      radialIncrements,
      sweepIncrements,
      pointDistance,
      mDescription.mConeInsideAngle, 0.f,
      mDescription.mVolume, mDescription.mVolume,
      smRenderColorInnerCone );

   // Outer Cone and Outside volume only get rendered if mConeOutsideVolume > 0
   
   if( mDescription.mConeOutsideVolume > 0.f )
   {
      const F32 outsideVolume = mDescription.mVolume * mDescription.mConeOutsideVolume;
      
      // Render outer cone.
      
      _renderCone(
         radialIncrements,
         sweepIncrements,
         pointDistance,
         mDescription.mConeOutsideAngle, mDescription.mConeInsideAngle,
         outsideVolume, mDescription.mVolume,
         smRenderColorOuterCone );
      
      // Render outside volume.
      
      _renderCone(
         radialIncrements,
         sweepIncrements,
         pointDistance,
         360.f, mDescription.mConeOutsideAngle,
         outsideVolume, outsideVolume,
         smRenderColorOutsideVolume );
   }
   
   // Commit primitive list.
   
   PrimBuild::end();
}
void ShadowMaterialHook::init( BaseMatInstance *inMat )
{
   if( !inMat->isValid() )
      return;

   // Tweak the feature data to include just what we need.
   FeatureSet features;
   features.addFeature( MFT_VertTransform );
   features.addFeature( MFT_DiffuseMap );
   features.addFeature( MFT_TexAnim );
   features.addFeature( MFT_AlphaTest );
   features.addFeature( MFT_Visibility );

   // Actually we want to include features from the inMat
   // if they operate on the preTransform verts so things
   // like wind/deformation effects will also affect the shadow.
   const FeatureSet &inFeatures = inMat->getFeatures();
   for ( U32 i = 0; i < inFeatures.getCount(); i++ )
   {      
      const FeatureType& ft = inFeatures.getAt(i);
      
      if ( ft.getGroup() == MFG_PreTransform )
         features.addFeature( ft );
   }

   // Do instancing in shadows if we can.
   if ( inFeatures.hasFeature( MFT_UseInstancing ) )
      features.addFeature( MFT_UseInstancing );

   Material *shadowMat = (Material*)inMat->getMaterial();
   if ( dynamic_cast<CustomMaterial*>( shadowMat ) )
   {
      // This is a custom material... who knows what it really does, but
      // if it wasn't already filtered out of the shadow render then just
      // give it some default depth out material.
      shadowMat = MATMGR->getMaterialDefinitionByName( "AL_DefaultShadowMaterial" );
   }

   // By default we want to disable some states
   // that the material might enable for us.
   GFXStateBlockDesc forced;
   forced.setBlend( false );
   forced.setAlphaTest( false );

   // We should force on zwrite as the prepass
   // will disable it by default.
   forced.setZReadWrite( true, true );
   
   // TODO: Should we render backfaces for 
   // shadows or does the ESM take care of 
   // all our acne issues?
   //forced.setCullMode( GFXCullCW );

   // Vector, and spotlights use the same shadow material.
   BaseMatInstance *newMat = new ShadowMatInstance( shadowMat );
   newMat->setUserObject( inMat->getUserObject() );
   newMat->getFeaturesDelegate().bind( &ShadowMaterialHook::_overrideFeatures );
   newMat->addStateBlockDesc( forced );
   if( !newMat->init( features, inMat->getVertexFormat() ) )
   {
      SAFE_DELETE( newMat );
      newMat = MATMGR->createWarningMatInstance();
   }
   
   mShadowMat[ShadowType_Spot] = newMat;

   newMat = new ShadowMatInstance( shadowMat );
   newMat->setUserObject( inMat->getUserObject() );
   newMat->getFeaturesDelegate().bind( &ShadowMaterialHook::_overrideFeatures );
   forced.setCullMode( GFXCullCW );   
   newMat->addStateBlockDesc( forced );
   forced.cullDefined = false;
   newMat->addShaderMacro( "CUBE_SHADOW_MAP", "" );
   newMat->init( features, inMat->getVertexFormat() );
   mShadowMat[ShadowType_CubeMap] = newMat;
   
   // A dual paraboloid shadow rendered in a single draw call.
   features.addFeature( MFT_ParaboloidVertTransform );
   features.addFeature( MFT_IsSinglePassParaboloid );
   features.removeFeature( MFT_VertTransform );
   newMat = new ShadowMatInstance( shadowMat );
   newMat->setUserObject( inMat->getUserObject() );
   GFXStateBlockDesc noCull( forced );
   noCull.setCullMode( GFXCullNone );
   newMat->addStateBlockDesc( noCull );
   newMat->getFeaturesDelegate().bind( &ShadowMaterialHook::_overrideFeatures );
   newMat->init( features, inMat->getVertexFormat() );
   mShadowMat[ShadowType_DualParaboloidSinglePass] = newMat;

   // Regular dual paraboloid shadow.
   features.addFeature( MFT_ParaboloidVertTransform );
   features.removeFeature( MFT_IsSinglePassParaboloid );
   features.removeFeature( MFT_VertTransform );
   newMat = new ShadowMatInstance( shadowMat );
   newMat->setUserObject( inMat->getUserObject() );
   newMat->addStateBlockDesc( forced );
   newMat->getFeaturesDelegate().bind( &ShadowMaterialHook::_overrideFeatures );
   newMat->init( features, inMat->getVertexFormat() );
   mShadowMat[ShadowType_DualParaboloid] = newMat;

   /*
   // A single paraboloid shadow.
   newMat = new ShadowMatInstance( startMatInstance );
   GFXStateBlockDesc noCull;
   noCull.setCullMode( GFXCullNone );
   newMat->addStateBlockDesc( noCull );
   newMat->getFeaturesDelegate().bind( &ShadowMaterialHook::_overrideFeatures );
   newMat->init( features, globalFeatures, inMat->getVertexFormat() );
   mShadowMat[ShadowType_DualParaboloidSinglePass] = newMat;
   */
}
Exemplo n.º 12
0
void GuiGraphCtrl::onRender(Point2I offset, const RectI &updateRect)
{   
   if (mBlendSB.isNull())
   {
      GFXStateBlockDesc desc;

      desc.setBlend(true, GFXBlendSrcColor, GFXBlendInvSrcColor);
      mBlendSB = GFX->createStateBlock(desc);

      desc.setBlend(false, GFXBlendOne, GFXBlendZero);
      mSolidSB = GFX->createStateBlock(desc);

   }

   GFX->setStateBlock( mBlendSB );
   
	GFX->getDrawUtil()->drawRectFill( updateRect, mProfile->mFillColor );
   
   GFX->setStateBlock( mSolidSB );

   const Point2I globalPos = getGlobalBounds().point;
   const F32 midPointY = F32( globalPos.y ) + F32( getExtent().y ) * mCenterY;

	for( S32 k = 0; k < MaxPlots; ++ k )
	{
		// Check if there is an autoplot and the proper amount of time has passed, if so add datum.
		if( mAutoPlot[ k ] && mAutoPlotDelay[ k ] < (Sim::getCurrentTime() - mAutoPlotLastDisplay[ k ] ) )
		{
         mAutoPlotLastDisplay[ k ] = Sim::getCurrentTime();
         addDatum( k, Con::getFloatVariable( mAutoPlot[ k ] ) );
		}

		// Nothing to graph
		if( mGraphData[ k ].size() == 0 )
			continue;

		// Adjust scale to max value + 5% so we can see high values
		F32 Scale = F32( getExtent().y ) / F32( mGraphMax[ k ] * 1.05 );
      
      const S32 numSamples = mGraphData[ k ].size();

      switch( mGraphType[ k ] )
      {
         case Bar:
         {
            F32 prevOffset = 0;

            for( S32 sample = 0; sample < numSamples; ++ sample )
            {                  
               PrimBuild::begin( GFXTriangleFan, 4 );
               PrimBuild::color( mGraphColor[ k ] );

               F32 offset = F32( getExtent().x ) / F32( MaxDataPoints ) * F32( sample + 1 );

               PrimBuild::vertex2f( globalPos.x + prevOffset,
                  midPointY - ( getDatum( k, sample ) * Scale ) );

               PrimBuild::vertex2f( globalPos.x + offset,
                  midPointY - ( getDatum( k, sample ) * Scale ) );

               PrimBuild::vertex2f( globalPos.x + offset,
                  midPointY );

               PrimBuild::vertex2f( globalPos.x + prevOffset,
                  midPointY );

               prevOffset = offset;

               PrimBuild::end();
            }

            break;
         }
         
         case Filled:
         {
            PrimBuild::begin( GFXTriangleStrip, numSamples * 2 ); // Max size correct? -pw
            PrimBuild::color( mGraphColor[ k ] );

            for( S32 sample = 0; sample < numSamples; ++ sample )
            {
               F32 offset = F32( getExtent().x ) / F32( MaxDataPoints - 1 ) * F32( sample );

               PrimBuild::vertex2f( globalPos.x + offset,
                  midPointY );

               PrimBuild::vertex2f( globalPos.x + offset,
                  midPointY - ( getDatum( k, sample ) * Scale ) );
            }

            PrimBuild::end();
            break;
         }

         case Point:
         case Polyline:
         {
            if( mGraphType[ k ] == Point )
               PrimBuild::begin( GFXPointList, numSamples ); // Max size correct? -pw
            else
               PrimBuild::begin( GFXLineStrip, numSamples );

            PrimBuild::color( mGraphColor[ k ] );

            for( S32 sample = 0; sample < numSamples; ++ sample )
            {
               F32 offset = F32( getExtent().x ) / F32( MaxDataPoints - 1 ) * F32( sample );

               PrimBuild::vertex2f( globalPos.x + offset,
                  midPointY - ( getDatum( k, sample ) * Scale ) );
            }

            PrimBuild::end();
            break;
         }
      }
	}

	if( mProfile->mBorder )
	{
		RectI rect( offset.x, offset.y, getWidth(), getHeight() );
		GFX->getDrawUtil()->drawRect( rect, mProfile->mBorderColor );
	}
   
   renderChildControls( offset, updateRect );
}