locked
Render Targets

    Question

  • I need to make a pixel shader that works across multiple sprites.  Of course that means I will need to render the sprites to a render target, then draw that render target to the screen using the pixel shader.  But, I'm using the SpriteBatch sample (modified a little) provided by the Dev Center.  I've seen the pixel shader work on each sprite individually, but I can't get a render target to even render without using the shader, so...  Any help?

    Here's the initialization of the render target:

    // Setup render target, used for black out shader.
    	D3D11_TEXTURE2D_DESC textureDesc;
    	HRESULT result;
    	D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
    	D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
    
    	// Initialize the render target texture description.
    	ZeroMemory(&textureDesc, sizeof(textureDesc));
    
    	// Setup the render target texture description.
    	textureDesc.Width = GameManager::m_screenManager->m_screenWidth;
    	textureDesc.Height = GameManager::m_screenManager->m_screenHeight;
    	textureDesc.MipLevels = 1;
    	textureDesc.ArraySize = 1;
    	textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
    	textureDesc.SampleDesc.Count = 1;
    	textureDesc.Usage = D3D11_USAGE_DEFAULT;
    	textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
    	textureDesc.CPUAccessFlags = 0;
    	textureDesc.MiscFlags = 0;
    
    	// Create the render target texture.
    	result = d3dDevice->CreateTexture2D(&textureDesc, NULL, &m_blackOutRenderTargetTexture);
    	if(FAILED(result))
    	{
    		int h = true;
    	}
    
    	// Setup the description of the render target view.
    	renderTargetViewDesc.Format = textureDesc.Format;
    	renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
    	renderTargetViewDesc.Texture2D.MipSlice = 0;
    
    	// Create the render target view.
    	result = d3dDevice->CreateRenderTargetView(m_blackOutRenderTargetTexture, &renderTargetViewDesc, &m_blackOutRenderTargetView);
    	if(FAILED(result))
    	{
    		int h = true;
    	}
    
    	// Setup the description of the shader resource view.
    	shaderResourceViewDesc.Format = textureDesc.Format;
    	shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
    	shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
    	shaderResourceViewDesc.Texture2D.MipLevels = 1;
    
    	// Create the shader resource view.
    	result = d3dDevice->CreateShaderResourceView(m_blackOutRenderTargetTexture, &shaderResourceViewDesc, &m_blackOutShaderResourceView);
    	if(FAILED(result))
    	{
    		int h = true;
    	}

    Then, the render to texture method, this is the method that actually renders to the render target:

    m_d3dContext->OMSetRenderTargets(1, &m_blackOutRenderTargetView, NULL);
    
    	m_spriteBatch->Begin();
    
    	// Draw blocks.
    	for (int i = 0; i < m_blocks.size(); i++)
    	{
    		if (m_blocks[i] == nullptr)
    			continue;
    
    		m_blocks[i]->Draw(m_spriteBatch, m_d3dContext, float4(1.0f, 1.0f, 1.0f, m_transitionPosition));
    	}
    	// Draw block explosions.
    	for (int i = 0; i < m_blocks.size(); i++)
    	{
    		if (m_blocks[i] == nullptr)
    			continue;
    
    		m_blocks[i]->DrawExplosion(m_spriteBatch, m_d3dContext);
    	}
    
    	m_spriteBatch->End();
    }

    Finally, the actual Render code, this calls the RenderToTexture method, then attemps to render the render target texture, please mind the commented out sections, I've done a lot of shearing simply to get this working:

    void GameScreen::Render()
    {
    	RenderToTexture();
    
    	m_d3dContext->OMSetRenderTargets(1, &m_renderTargetView, NULL);
    
    	//m_spriteBatch->SetPixelShaderParameters(m_d3dContext, 1.0f, 0.0f);
    
    	 m_spriteBatch->Begin();
    
    	 //XMFLOAT3 up = XMFLOAT3(0.0f, 1.0f, 0.0f);
    	 //XMVECTOR upCopy = XMLoadFloat3(&up);
    	 //XMFLOAT3 look = XMFLOAT3(0.0f, 0.0f, 1.0f);
    	 //XMVECTOR lookCopy = XMLoadFloat3(&look);
    	 //XMFLOAT3 pos = XMFLOAT3(0.0f, 0.0f, -10.0f);
    	 //XMVECTOR posCopy = XMLoadFloat3(&pos);
    
    	/*XMFLOAT4X4 world;
    	XMStoreFloat4x4(&world, XMMatrixIdentity());
    	XMFLOAT4X4 view;
    	XMStoreFloat4x4(&view, XMMatrixLookAtRH(posCopy, lookCopy, upCopy));
    	XMFLOAT4X4 projection;
    	XMStoreFloat4x4(&projection, XMMatrixOrthographicRH(1366, 768, 0.001f, 1000.0f));*/
    
    	//m_texShader->Render(m_d3dContext, 6, world, view, projection, m_background->GetView());
    
    	 Sprite* newSprite = new Sprite();
    	 newSprite->Initialize(m_d3dDevice, m_blackOutRenderTargetTexture, m_blackOutShaderResourceView, 1366, 768);
    
    	 m_spriteBatch->AddSprite(newSprite);
    	 m_spriteBatch->Draw(newSprite, 
    		 float2(GameManager::m_screenManager->m_screenCenter.x, GameManager::m_screenManager->m_screenCenter.y), 
    		 BasicSprites::PositionUnits::Pixels, float2(1.0f, 1.0f), BasicSprites::SizeUnits::Normalized, 
    		 float4(1.0f, 1.0f, 1.0f, 1.0f), 0.0f, BasicSprites::BlendMode::Alpha);
    
    	// Draw background.
    	//m_background->Draw(m_spriteBatch, GameManager::m_screenManager->m_screenCenter.x, GameManager::m_screenManager->m_screenCenter.y);
    
    	// Draw side bar.
    	//m_sideBar->Draw(m_spriteBatch);
    
    	// Draw pause button.
    	//m_pauseButton->Draw(m_spriteBatch);
    
    	// Draw title.
    	//m_title->Draw(m_spriteBatch);
    
    	// Draw blocks.
    	//for (int i = 0; i < m_blocks.size(); i++)
    	//{
    		//if (m_blocks[i] == nullptr)
    			//continue;
    
    		//m_blocks[i]->Draw(m_spriteBatch, m_d3dContext, float4(1.0f, 1.0f, 1.0f, m_transitionPosition));
    	//}
    	// Draw block explosions.
    	//for (int i = 0; i < m_blocks.size(); i++)
    	//{
    		//if (m_blocks[i] == nullptr)
    			//continue;
    
    		//m_blocks[i]->DrawExplosion(m_spriteBatch, m_d3dContext);
    	//}
    
    	// Lion behavior.
    	//if (dynamic_cast<LionGameScreenBehavior^>(m_currBehavior) != nullptr)  
    	//{
    		//LionGameScreenBehavior^ behavior = dynamic_cast<LionGameScreenBehavior^>(m_currBehavior);    // Create casted entry 'AS' a button.
    		//behavior->Draw(m_spriteBatch);		
    	//}
    
    	// Bonus behavior.
    	//if (dynamic_cast<BonusGameScreenBehavior^>(m_currBehavior) != nullptr)  
    	//{
    		//BonusGameScreenBehavior^ behavior = dynamic_cast<BonusGameScreenBehavior^>(m_currBehavior);    // Create casted entry 'AS' a button.
    		//behavior->Draw(m_spriteBatch);		
    	//}
    
    	//m_monkey->Draw(m_spriteBatch, float4(1.0f, 1.0f, 1.0f, m_transitionPosition));
    
    	//m_spriteBatch->End();
    
    	// Draw Text.
    	//m_d2dContext->BeginDraw();
    
    	// Score.
    	//m_text->Render(m_d2dContext, m_writeFactory, float4(0.0f, 0.0f, 0.0f, m_transitionPosition), GameData::m_score.ToString(), 
    		//-GameManager::m_screenManager->m_screenCenter.x + 1263, -GameManager::m_screenManager->m_screenCenter.y + 94);
    	// Level.
    	//m_text->Render(m_d2dContext, m_writeFactory, float4(0.0f, 0.0f, 0.0f, m_transitionPosition), GameData::m_level.ToString(), 
    		//-GameManager::m_screenManager->m_screenCenter.x + 1263, -GameManager::m_screenManager->m_screenCenter.y + 233);
    
    	// Bonus behavior.
    	//if (dynamic_cast<BonusGameScreenBehavior^>(m_currBehavior) != nullptr)  
    	//{
    	//	BonusGameScreenBehavior^ behavior = dynamic_cast<BonusGameScreenBehavior^>(m_currBehavior);    // Create casted entry 'AS' a button.
    	//	behavior->DrawText(m_spriteBatch);		
    	//}
    
    	//// Monkify timers.
    	//m_monkey->DrawTimers(float4(0.0f, 0.0f, 0.0f, m_transitionPosition));
    
     //   m_d2dContext->EndDraw();
    }

    Now, this uses the spritebatch sample downloaded here, slightly modified to support animation.

    I figure this is a longshot, but I am desparate.  I've tried many different things to try and get this render target rendered, it's quite important to get my shader working. 

    Thanks, Jeff.

    Monday, October 22, 2012 11:12 PM