Example #1
0
void CD3DCG::Render(LPDIRECT3DTEXTURE9 &origTex, D3DXVECTOR2 textureSize,
					D3DXVECTOR2 inputSize, D3DXVECTOR2 viewportSize, D3DXVECTOR2 windowSize)
{
	LPDIRECT3DSURFACE9 pRenderSurface = NULL,pBackBuffer = NULL;
	frameCnt++;

	if(!shaderLoaded)
		return;

	/* save back buffer render target
	*/
	pDevice->GetRenderTarget(0,&pBackBuffer);	

	/* pass 0 represents the original texture
	*/
	shaderPasses[0].tex = origTex;
	shaderPasses[0].outputSize = inputSize;
	shaderPasses[0].textureSize = textureSize;

	calculateMatrix();	

	for(int i=1;i<shaderPasses.size();i++) {
		switch(shaderPasses[i].scaleParams.scaleTypeX) {
			case CG_SCALE_ABSOLUTE:
				shaderPasses[i].outputSize.x = (double)shaderPasses[i].scaleParams.absX;
				break;
			case CG_SCALE_SOURCE:
				shaderPasses[i].outputSize.x = shaderPasses[i-1].outputSize.x * shaderPasses[i].scaleParams.scaleX;
				break;
			case CG_SCALE_VIEWPORT:
				shaderPasses[i].outputSize.x = viewportSize.x * shaderPasses[i].scaleParams.scaleX;
				break;
			default:
				shaderPasses[i].outputSize.x = viewportSize.x;
		}
		switch(shaderPasses[i].scaleParams.scaleTypeY) {
			case CG_SCALE_ABSOLUTE:
				shaderPasses[i].outputSize.y = (double)shaderPasses[i].scaleParams.absY;
				break;
			case CG_SCALE_SOURCE:
				shaderPasses[i].outputSize.y = shaderPasses[i-1].outputSize.y * shaderPasses[i].scaleParams.scaleY;
				break;
			case CG_SCALE_VIEWPORT:
				shaderPasses[i].outputSize.y = viewportSize.y * shaderPasses[i].scaleParams.scaleY;
				break;
			default:
				shaderPasses[i].outputSize.y = viewportSize.y;
		}
		float texSize = npot(max(shaderPasses[i].outputSize.x,shaderPasses[i].outputSize.y));
		
		/* make sure the render target exists and has an appropriate size,
		   then set as current render target with last pass as source
		*/
		ensureTextureSize(shaderPasses[i].tex,shaderPasses[i].textureSize,D3DXVECTOR2(texSize,texSize),true);
		shaderPasses[i].tex->GetSurfaceLevel(0,&pRenderSurface);
		pDevice->SetTexture(0, shaderPasses[i-1].tex);
		pDevice->SetRenderTarget(0,pRenderSurface);
		pRenderSurface->Release();

		/* set vertex declaration of current pass, update vertex
		   buffer and set base streams
		*/
		pDevice->SetVertexDeclaration(shaderPasses[i].vertexDeclaration);
		setVertexStream(shaderPasses[i].vertexBuffer,
			shaderPasses[i-1].outputSize,shaderPasses[i-1].textureSize,shaderPasses[i].outputSize);
		pDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
		pDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
		pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, shaderPasses[i].linearFilter?D3DTEXF_LINEAR:D3DTEXF_POINT);
		pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, shaderPasses[i].linearFilter?D3DTEXF_LINEAR:D3DTEXF_POINT);

		/* shader vars need to be set after the base vertex streams
		   have been set so they can override them
		*/
		setShaderVars(i);

		cgD3D9BindProgram(shaderPasses[i].cgVertexProgram);
		checkForCgError("Binding vertex program");
		cgD3D9BindProgram(shaderPasses[i].cgFragmentProgram);
		checkForCgError("Binding fragment program");
		
		/* viewport defines output size
		*/
		setViewport(0,0,shaderPasses[i].outputSize.x,shaderPasses[i].outputSize.y);

		pDevice->BeginScene();
		pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
		pDevice->EndScene();
	}

	/* take oldes PREV out of deque, make sure it has
	   the same size as the current texture and
	   then set it up as new original texture
	*/
	prevPass &oldestPrev = prevPasses.back();
	ensureTextureSize(oldestPrev.tex,oldestPrev.textureSize,textureSize,false);
	if(oldestPrev.vertexBuffer)
		oldestPrev.vertexBuffer->Release();
	origTex = oldestPrev.tex;
	prevPasses.pop_back();
	
	/* push current original with corresponding vertex
	   buffer to front of PREV deque
	*/
	shaderPasses[0].vertexBuffer = shaderPasses[1].vertexBuffer;
	prevPasses.push_front(prevPass(shaderPasses[0]));
	
	/* create new vertex buffer so that next render call
	   will not overwrite the PREV
	*/
	pDevice->CreateVertexBuffer(sizeof(VERTEX)*4,D3DUSAGE_WRITEONLY,0,D3DPOOL_MANAGED,&shaderPasses[1].vertexBuffer,NULL);
	
	/* set up last pass texture, backbuffer and viewport
	   for final display pass without shaders
	*/
	pDevice->SetTexture(0, shaderPasses.back().tex);
	pDevice->SetRenderTarget(0,pBackBuffer);
	pBackBuffer->Release();
	RECT displayRect=CalculateDisplayRect(shaderPasses.back().outputSize.x,shaderPasses.back().outputSize.y,windowSize.x,windowSize.y);
	setViewport(displayRect.left,displayRect.top,displayRect.right - displayRect.left,displayRect.bottom - displayRect.top);
	setVertexStream(shaderPasses.back().vertexBuffer,
		shaderPasses.back().outputSize,shaderPasses.back().textureSize,
		D3DXVECTOR2(displayRect.right - displayRect.left,displayRect.bottom - displayRect.top));
	pDevice->SetVertexShader(NULL);
	pDevice->SetPixelShader(NULL);
}
Example #2
0
void GFXDevice::updateStates(bool forceSetAll /*=false*/)
{
   PROFILE_SCOPE(GFXDevice_updateStates);

   if(forceSetAll)
   {
      bool rememberToEndScene = false;
      if(!canCurrentlyRender())
      {
         if (!beginScene())
         {
            AssertFatal(false, "GFXDevice::updateStates:  Unable to beginScene!");
         }
         rememberToEndScene = true;
      }

      setMatrix( GFXMatrixProjection, mProjectionMatrix );
      setMatrix( GFXMatrixWorld, mWorldMatrix[mWorldStackSize] );
      setMatrix( GFXMatrixView, mViewMatrix );

      setVertexDecl( mCurrVertexDecl );

      for ( U32 i=0; i < VERTEX_STREAM_COUNT; i++ )
      {
         setVertexStream( i, mCurrentVertexBuffer[i] );
         setVertexStreamFrequency( i, mVertexBufferFrequency[i] );
      }

      if( mCurrentPrimitiveBuffer.isValid() ) // This could be NULL when the device is initalizing
         mCurrentPrimitiveBuffer->prepare();

      /// Stateblocks
      if ( mNewStateBlock )
         setStateBlockInternal(mNewStateBlock, true);
      mCurrentStateBlock = mNewStateBlock;

      for(U32 i = 0; i < getNumSamplers(); i++)
      {
         switch (mTexType[i])
         {
            case GFXTDT_Normal :
               {
                  mCurrentTexture[i] = mNewTexture[i];
                  setTextureInternal(i, mCurrentTexture[i]);
               }  
               break;
            case GFXTDT_Cube :
               {
                  mCurrentCubemap[i] = mNewCubemap[i];
                  if (mCurrentCubemap[i])
                     mCurrentCubemap[i]->setToTexUnit(i);
                  else
                     setTextureInternal(i, NULL);
               }
               break;
            default:
               AssertFatal(false, "Unknown texture type!");
               break;
         }
      }

      // Set our material
      setLightMaterialInternal(mCurrentLightMaterial);

      // Set our lights
      for(U32 i = 0; i < LIGHT_STAGE_COUNT; i++)
      {
         setLightInternal(i, mCurrentLight[i], mCurrentLightEnable[i]);
      }

       _updateRenderTargets();

      if(rememberToEndScene)
         endScene();

      return;
   }

   if (!mStateDirty)
      return;

   // Normal update logic begins here.
   mStateDirty = false;

   // Update Projection Matrix
   if( mProjectionMatrixDirty )
   {
      setMatrix( GFXMatrixProjection, mProjectionMatrix );
      mProjectionMatrixDirty = false;
   }
   
   // Update World Matrix
   if( mWorldMatrixDirty )
   {
      setMatrix( GFXMatrixWorld, mWorldMatrix[mWorldStackSize] );
      mWorldMatrixDirty = false;
   }
   
   // Update View Matrix
   if( mViewMatrixDirty )
   {
      setMatrix( GFXMatrixView, mViewMatrix );
      mViewMatrixDirty = false;
   }


   if( mTextureMatrixCheckDirty )
   {
      for( S32 i = 0; i < getNumSamplers(); i++ )
      {
         if( mTextureMatrixDirty[i] )
         {
            mTextureMatrixDirty[i] = false;
            setMatrix( (GFXMatrixType)(GFXMatrixTexture + i), mTextureMatrix[i] );
         }
      }

      mTextureMatrixCheckDirty = false;
   }

   // Update the vertex declaration.
   if ( mVertexDeclDirty )
   {
      setVertexDecl( mCurrVertexDecl );
      mVertexDeclDirty = false;
   }

   // Update the vertex buffers.
   for ( U32 i=0; i < VERTEX_STREAM_COUNT; i++ )
   {
      if ( mVertexBufferDirty[i] )
      {
         setVertexStream( i, mCurrentVertexBuffer[i] );
         mVertexBufferDirty[i] = false;
      }

      if ( mVertexBufferFrequencyDirty[i] )
      {
         setVertexStreamFrequency( i, mVertexBufferFrequency[i] );
         mVertexBufferFrequencyDirty[i] = false;
      }
   }

   // Update primitive buffer
   //
   // NOTE: It is very important to set the primitive buffer AFTER the vertex buffer
   // because in order to draw indexed primitives in DX8, the call to SetIndicies
   // needs to include the base vertex offset, and the DX8 GFXDevice relies on
   // having mCurrentVB properly assigned before the call to setIndices -patw
   if( mPrimitiveBufferDirty )
   {
      if( mCurrentPrimitiveBuffer.isValid() ) // This could be NULL when the device is initalizing
         mCurrentPrimitiveBuffer->prepare();
      mPrimitiveBufferDirty = false;
   }

   // NOTE: With state blocks, it's now important to update state before setting textures
   // some devices (e.g. OpenGL) set states on the texture and we need that information before
   // the texture is activated.
   if (mStateBlockDirty)
   {
      setStateBlockInternal(mNewStateBlock, false);
      mCurrentStateBlock = mNewStateBlock;
      mStateBlockDirty = false;
   }

   if( mTexturesDirty )
   {
      mTexturesDirty = false;
      for(U32 i = 0; i < getNumSamplers(); i++)
      {
         if(!mTextureDirty[i])
            continue;
         mTextureDirty[i] = false;

         switch (mTexType[i])
         {
         case GFXTDT_Normal :
            {
               mCurrentTexture[i] = mNewTexture[i];
               setTextureInternal(i, mCurrentTexture[i]);
            }  
            break;
         case GFXTDT_Cube :
            {
               mCurrentCubemap[i] = mNewCubemap[i];
               if (mCurrentCubemap[i])
                  mCurrentCubemap[i]->setToTexUnit(i);
               else
                  setTextureInternal(i, NULL);
            }
            break;
         default:
            AssertFatal(false, "Unknown texture type!");
            break;
         }
      }
   }
   
   // Set light material
   if(mLightMaterialDirty)
   {
      setLightMaterialInternal(mCurrentLightMaterial);
      mLightMaterialDirty = false;
   }

   // Set our lights
   if(mLightsDirty)
   {
      mLightsDirty = false;
      for(U32 i = 0; i < LIGHT_STAGE_COUNT; i++)
      {
         if(!mLightDirty[i])
            continue;

         mLightDirty[i] = false;
         setLightInternal(i, mCurrentLight[i], mCurrentLightEnable[i]);
      }
   }

   _updateRenderTargets();

#ifdef TORQUE_DEBUG_RENDER
   doParanoidStateCheck();
#endif
}
void DeviceGraphicsDX11Geometry::syncToResource		(GeometryResource *geometry)
{
	if (geometry->getRecacheData()) {
        std::size_t num_vertices = geometry->getVertexStream()->size();
		
		std::size_t num_faces;
		if (geometry->getIndicesStream())
			num_faces = geometry->getIndicesStream()->size();
		else
			num_faces = geometry->getVertexStream()->size() / 3;
			
		_num_faces = (DTuint) num_faces;
		_num_vertices = (DTuint) num_vertices;
		
		DeviceGraphicsDX11DataStream *vertices_stream = NULL;
		DeviceGraphicsDX11DataStream *normals_stream = NULL;
		DeviceGraphicsDX11DataStream *texcoord0_stream = NULL;
		DeviceGraphicsDX11DataStream *texcoord1_stream = NULL;
		DeviceGraphicsDX11DataStream *tangents_stream = NULL;
		DeviceGraphicsDX11DataStream *colors_stream = NULL;
		DeviceGraphicsDX11DataStream *weights_index_stream = NULL;
		DeviceGraphicsDX11DataStream *weights_strength_stream = NULL;
		DeviceGraphicsDX11IndexStream *faces_stream = NULL;
		
		Vector3*		vertices = NULL;
		Vector3*		normals = NULL;
		Texcoord2*		texcoord0 = NULL;
		Texcoord2*		texcoord1 = NULL;
		Vector3*		tangents = NULL;
		Color*			colors = NULL;
		WeightsIndex*	weights_index = NULL;
		Texcoord4*		weights_strength = NULL;
		Triangle*		faces = NULL;

		if (geometry->getVertexStream()) {
			vertices_stream = DeviceGraphicsDX11DataStream::create();
			vertices = (Vector3*) vertices_stream->allocateData(sizeof(Vector3) * _num_vertices, DeviceGraphicsDX11DataStream::FMT_3_FLOAT, true);
			setVertexStream(vertices_stream);
			_size += sizeof(Vector3) * _num_vertices;
		}

		if (geometry->getNormalsStream()) {
			normals_stream = DeviceGraphicsDX11DataStream::create();
			normals = (Vector3*) normals_stream->allocateData(sizeof(Vector3) * _num_vertices, DeviceGraphicsDX11DataStream::FMT_3_FLOAT, false);
			setNormalStream(normals_stream);
			_size += sizeof(Vector3) * _num_vertices;
		}
		
		if (geometry->getUVsStream0()) {
			texcoord0_stream = DeviceGraphicsDX11DataStream::create();
			texcoord0 = (Texcoord2*) texcoord0_stream->allocateData(sizeof(Texcoord2) * _num_vertices, DeviceGraphicsDX11DataStream::FMT_2_FLOAT, false);
			setTexcoordStream(0, texcoord0_stream);
			_size += sizeof(Texcoord2) * _num_vertices;
		}
		
		if (geometry->getUVsStream1()) {
			texcoord1_stream = DeviceGraphicsDX11DataStream::create();
			texcoord1 = (Texcoord2*) texcoord1_stream->allocateData(sizeof(Texcoord2) * _num_vertices, DeviceGraphicsDX11DataStream::FMT_2_FLOAT, false);
			setTexcoordStream(1, texcoord1_stream);
			_size += sizeof(Texcoord2) * _num_vertices;
		}

		if (geometry->getTangentsStream()) {
			tangents_stream = DeviceGraphicsDX11DataStream::create();
			tangents = (Vector3*) tangents_stream->allocateData(sizeof(Vector3) * _num_vertices, DeviceGraphicsDX11DataStream::FMT_3_FLOAT, false);
			setTexcoordStream(2, tangents_stream);
			_size += sizeof(Vector3) * _num_vertices;
		}
		
		if (geometry->getColorsStream()) {
			colors_stream = DeviceGraphicsDX11DataStream::create();
			colors = (Color*) colors_stream->allocateData(sizeof(Color) * _num_vertices, DeviceGraphicsDX11DataStream::FMT_4_BYTE, false);
			setColorsStream(colors_stream);
			_size += sizeof(Color) * _num_vertices;
		}

		if (geometry->getWeightsIndexStream()) {
			weights_index_stream = DeviceGraphicsDX11DataStream::create();
			weights_index = (WeightsIndex*) weights_index_stream->allocateData(sizeof(WeightsIndex) * _num_vertices, DeviceGraphicsDX11DataStream::FMT_4_USHORT, false);
			setWeightsIndexStream(weights_index_stream);
			_size += sizeof(Texcoord4) * _num_vertices;
		}

		if (geometry->getWeightsStrengthStream()) {
			weights_strength_stream = DeviceGraphicsDX11DataStream::create();
			weights_strength = (Texcoord4*) weights_strength_stream->allocateData(sizeof(Texcoord4) * _num_vertices, DeviceGraphicsDX11DataStream::FMT_4_FLOAT, false);
			setWeightsStrengthStream(weights_strength_stream);
			_size += sizeof(Texcoord4) * _num_vertices;
		}

		if (geometry->getIndicesStream()) {
			faces_stream = DeviceGraphicsDX11IndexStream::create();
			faces = (Triangle*) faces_stream->allocateData(sizeof(Triangle) * _num_faces, false);
			setIndexStream(faces_stream);
			_size += sizeof(Triangle) * _num_faces;
		}
		
		
		// copy data
		for (DTuint v = 0; v < num_vertices; ++v) {
			if (vertices)			vertices[v] = geometry->getVertexStream()->get(v);
			if (normals)			normals[v] = geometry->getNormalsStream()->get(v);
			if (texcoord0)			texcoord0[v] = geometry->getUVsStream0()->get(v);
			if (texcoord1)			texcoord1[v] = geometry->getUVsStream1()->get(v);				
			if (tangents)			tangents[v] = geometry->getTangentsStream()->get(v);				
			if (colors)				colors[v] = geometry->getColorsStream()->get(v);				
			if (weights_index)		weights_index[v] = geometry->getWeightsIndexStream()->get(v);	
			if (weights_strength)	weights_strength[v] = geometry->getWeightsStrengthStream()->get(v);	
		}
		
		// copy FaceTri data
		for (DTuint f = 0; f < num_faces; ++f) {
			if (faces)				faces[f] = geometry->getIndicesStream()->get(f);	
		}

		if (vertices_stream)			vertices_stream->uploadData();
		if (normals_stream)				normals_stream->uploadData();
		if (texcoord0_stream)			texcoord0_stream->uploadData();
		if (texcoord1_stream)			texcoord1_stream->uploadData();
		if (tangents_stream)			tangents_stream->uploadData();
		if (colors_stream)				colors_stream->uploadData();
		if (weights_index_stream)		weights_index_stream->uploadData();
		if (weights_strength_stream)	weights_strength_stream->uploadData();
		if (faces_stream)				faces_stream->uploadData();
		
		RELEASE(vertices_stream);
		RELEASE(normals_stream);
		RELEASE(texcoord0_stream);
		RELEASE(texcoord1_stream);
		RELEASE(tangents_stream);
		RELEASE(colors_stream);
		RELEASE(weights_index_stream);
		RELEASE(weights_strength_stream);
		RELEASE(faces_stream);				
		
		geometry->setRecacheData(false);
	}
	
	if (geometry->getRecacheParameters()) {
		geometry->setRecacheParameters(false);
	}
	
}