DirectX 11 Render to Texture
In my code, i am making 2 rectangles, Rectangle1: Rendering On a Texture. Rectangle2: Rendering On Back Buffer. I am trying to do programmable blending,so need to access the destination pixel in pixel shader. In my code, I am creating a texture like below: d3d11Device->CreateTexture2D(&textureDesc, NULL, &renderTargetTextureMap); After this i am creating Render Target view of the texture. d3d11Device->CreateRenderTargetView(renderTargetTextureMap, &renderTargetViewDesc, &renderTargetViewMap); After this i am declaring vertex and pixel shader. Then in my draw call, i am performing following thing: float bgColor[4] = {0.0f, 0.0f,0.0f, 1.0f }; d3d11DevCon->ClearRenderTargetView(renderTargetViewMap, bgColor); float bgColor2[4] = { 0.0f, 1.0f, 0.0f, 1.0f }; ////////////////////////////////////////////////Buffer 1/////////////////////////////////////////////////////////////// //Set the vertex buffer UINT stride = sizeof(Vertex); UINT offset = 0; ///////////////////////////////////////////////////////////Buffer 2////////////////////////////////////////////////////////////////// d3d11DevCon->IASetIndexBuffer(d2dIndexBuffer, DXGI_FORMAT_R32_UINT, 0); d3d11DevCon->IASetVertexBuffers(0, 1, &triangleVertBuffer, &stride, &offset); ////Draw the triangle d3d11DevCon->DrawIndexed(6, 0, 0); I assume that since i have set my render target view as renderTargetViewMap, so my draw call will render to texture only. Now i am rendering to my backbuffer: //////////////////////////////////////////// d3d11DevCon->OMSetRenderTargets(1, &renderTargetView, NULL); d3d11DevCon->PSSetShaderResources(0, 1, &shaderResourceViewMap); //d3d11DevCon->ClearRenderTargetView(renderTargetView, bgColor2); d3d11DevCon->IASetIndexBuffer(d2dIndexBuffer2, DXGI_FORMAT_R32_UINT, 0); d3d11DevCon->IASetVertexBuffers(0, 1, &triangleVertBuffer2, &stride, &offset); ////Draw the triangle d3d11DevCon->DrawIndexed(6, 0, 0); //Present the backbuffer to the screen SwapChain->Present(0, 0); So, in this way my rendering is happening. Issue Face: In my pixel shader, VS_OUTPUT VS(float4 inPos : POSITION, float4 inColor : COLOR) { VS_OUTPUT output; output.Pos = inPos; output.Color = inColor; return output; } float4 PS(VS_OUTPUT input) : SV_TARGET { float2 temp; temp = input.Pos; float4 diffuse = ObjTexture.Sample(ObjSamplerState,0.5+0.5*temp); return input.Color + diffuse; } Here the diffuse is comming out to be equal to my bgcolor which i have set when rendering to texture float bgColor[4] = {0.0f, 0.0f,0.0f, 1.0f }; d3d11DevCon->ClearRenderTargetView(renderTargetViewMap, bgColor); I have also drawn a rectangle on it, but those pixels i am not able to access. How can i access the pixel of rectangle that i have drawn on rendering to texture. Issue Image: +[https://www.braynzarsoft.net/image/100316][Issue Image] Desired Results: +[https://www.braynzarsoft.net/image/100317][Desired Result] main.cpp //Include and link appropriate libraries and headers// #pragma comment(lib, "d3d11.lib") #pragma comment(lib, "d3dx11.lib") #pragma comment(lib, "d3dx10.lib") #include <windows.h> #include <d3d11.h> #include <d3dx11.h> #include <d3dx10.h> #include <xnamath.h> //Global Declarations - Interfaces// IDXGISwapChain* SwapChain; ID3D11Device* d3d11Device; ID3D11DeviceContext* d3d11DevCon; ID3D11RenderTargetView* renderTargetView; ID3D11Buffer* triangleVertBuffer; ID3D11Buffer* triangleVertBuffer2; ID3D11VertexShader* VS; ID3D11PixelShader* PS; ID3D10Blob* VS_Buffer; ID3D10Blob* PS_Buffer; ID3D11InputLayout* vertLayout; //Global Declarations - Others// LPCTSTR WndClassName = L"firstwindow"; HWND hwnd = NULL; HRESULT hr; const int Width = 800; const int Height = 600; //Function Prototypes// bool InitializeDirect3d11App(HINSTANCE hInstance); void CleanUp(); bool InitScene(); void UpdateScene(); void DrawScene(); bool InitializeWindow(HINSTANCE hInstance, int ShowWnd, int width, int height, bool windowed); int messageloop(); LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); ///////////////**************new**************//////////////////// //Vertex Structure and Vertex Layout (Input Layout)// struct Vertex //Overloaded Vertex Structure { Vertex() {} Vertex(float x, float y, float z, float cr, float cg, float cb, float ca) : pos(x, y, z), color(cr, cg, cb, ca) {} XMFLOAT3 pos; XMFLOAT4 color; }; ID3D11Texture2D* renderTargetTextureMap; ID3D11RenderTargetView* renderTargetViewMap; ID3D11ShaderResourceView* shaderResourceViewMap; ID3D11SamplerState* CubesTexSamplerState; ID3D11Buffer *d2dIndexBuffer; ID3D11Buffer *d2dIndexBuffer2; D3D11_TEXTURE2D_DESC textureDesc; D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc; D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc; D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; UINT numElements = ARRAYSIZE(layout); ///////////////**************new**************//////////////////// int WINAPI WinMain(HINSTANCE hInstance, //Main windows function HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { if (!InitializeWindow(hInstance, nShowCmd, Width, Height, true)) { MessageBox(0, L"Window Initialization - Failed", L"Error", MB_OK); return 0; } if (!InitializeDirect3d11App(hInstance)) //Initialize Direct3D { MessageBox(0, L"Direct3D Initialization - Failed", L"Error", MB_OK); return 0; } if (!InitScene()) //Initialize our scene { MessageBox(0, L"Scene Initialization - Failed", L"Error", MB_OK); return 0; } messageloop(); CleanUp(); return 0; } bool InitializeWindow(HINSTANCE hInstance, int ShowWnd, int width, int height, bool windowed) { typedef struct _WNDCLASS { UINT cbSize; UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HANDLE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; } WNDCLASS; WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = NULL; wc.cbWndExtra = NULL; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 2); wc.lpszMenuName = NULL; wc.lpszClassName = WndClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if (!RegisterClassEx(&wc)) { MessageBox(NULL, L"Error registering class", L"Error", MB_OK | MB_ICONERROR); return 1; } hwnd = CreateWindowEx( NULL, WndClassName, L"Lesson 4 - Begin Drawing", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, width, height, NULL, NULL, hInstance, NULL ); if (!hwnd) { MessageBox(NULL, L"Error creating window", L"Error", MB_OK | MB_ICONERROR); return 1; } ShowWindow(hwnd, ShowWnd); UpdateWindow(hwnd); return true; } bool InitializeDirect3d11App(HINSTANCE hInstance) { //Describe our Buffer DXGI_MODE_DESC bufferDesc; ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC)); bufferDesc.Width = Width; bufferDesc.Height = Height; bufferDesc.RefreshRate.Numerator = 60; bufferDesc.RefreshRate.Denominator = 1; bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; //Describe our SwapChain DXGI_SWAP_CHAIN_DESC swapChainDesc; ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC)); swapChainDesc.BufferDesc = bufferDesc; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = 1; swapChainDesc.OutputWindow = hwnd; swapChainDesc.Windowed = TRUE; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; //Create our SwapChain hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL, D3D11_SDK_VERSION, &swapChainDesc, &SwapChain, &d3d11Device, NULL, &d3d11DevCon); //Create our BackBuffer ID3D11Texture2D* BackBuffer; hr = SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&BackBuffer); //Create our Render Target hr = d3d11Device->CreateRenderTargetView(BackBuffer, NULL, &renderTargetView); BackBuffer->Release(); ////////////////////////////////////////////////////////////////////////EXPERIMENT AREA////////////////////////////////////////////////////////////////////////////////////// ZeroMemory(&textureDesc, sizeof(textureDesc)); // Setup the texture description. // We will have our map be a square // We will need to have this texture bound as a render target AND a shader resource textureDesc.Width = Width/2; textureDesc.Height = Height/2; 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; d3d11Device->CreateTexture2D(&textureDesc, NULL, &renderTargetTextureMap); // 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. d3d11Device->CreateRenderTargetView(renderTargetTextureMap, &renderTargetViewDesc, &renderTargetViewMap); /////////////////////// Map's Shader Resource View // 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. d3d11Device->CreateShaderResourceView(renderTargetTextureMap, &shaderResourceViewDesc, &shaderResourceViewMap); d3d11DevCon->OMSetRenderTargets(1, &renderTargetViewMap, NULL); return true; } void CleanUp() { //Release the COM Objects we created SwapChain->Release(); d3d11Device->Release(); d3d11DevCon->Release(); renderTargetView->Release(); triangleVertBuffer->Release(); VS->Release(); PS->Release(); VS_Buffer->Release(); PS_Buffer->Release(); vertLayout->Release(); } bool InitScene() { //Compile Shaders from shader file hr = D3DX11CompileFromFile(L"Effect.fx", 0, 0, "VS", "vs_5_0", 0, 0, 0, &VS_Buffer, 0, 0); hr = D3DX11CompileFromFile(L"Effect.fx", 0, 0, "PS", "ps_5_0", 0, 0, 0, &PS_Buffer, 0, 0); //Create the Shader Objects hr = d3d11Device->CreateVertexShader(VS_Buffer->GetBufferPointer(), VS_Buffer->GetBufferSize(), NULL, &VS); hr = d3d11Device->CreatePixelShader(PS_Buffer->GetBufferPointer(), PS_Buffer->GetBufferSize(), NULL, &PS); //Set Vertex and Pixel Shaders d3d11DevCon->VSSetShader(VS, 0, 0); d3d11DevCon->PSSetShader(PS, 0, 0); //Create the Input Layout hr = d3d11Device->CreateInputLayout(layout, numElements, VS_Buffer->GetBufferPointer(), VS_Buffer->GetBufferSize(), &vertLayout); //Set the Input Layout d3d11DevCon->IASetInputLayout(vertLayout); //Set Primitive Topology d3d11DevCon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); //Create the Viewport D3D11_VIEWPORT viewport; ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT)); viewport.TopLeftX = 0; viewport.TopLeftY = 0; viewport.Width = Width; viewport.Height = Height; //Set the Viewport d3d11DevCon->RSSetViewports(1, &viewport); Vertex v2[] = { // positions // colors // texture coords Vertex(1.0f, 1.0f, 0.0f,0.0f,1.0f,0.0f,1.0f), // top right Vertex(1.0f,0.0f, 0.0f,0.0f,1.0f,0.0f,1.0f), // bottom right Vertex(0.0f,0.0f, 0.0f,0.0f,1.0f,0.0f,1.0f), // bottom left Vertex(0.0f, 1.0, 0.0f,0.0f, 1.0f,0.0f,1.0f) // top left }; DWORD indices2[] = { // Front Face 0, 1, 2, 0, 2, 3, }; D3D11_BUFFER_DESC indexBufferDesc2; ZeroMemory(&indexBufferDesc2, sizeof(indexBufferDesc2)); indexBufferDesc2.Usage = D3D11_USAGE_DEFAULT; indexBufferDesc2.ByteWidth = sizeof(DWORD) * 2 * 3; indexBufferDesc2.BindFlags = D3D11_BIND_INDEX_BUFFER; indexBufferDesc2.CPUAccessFlags = 0; indexBufferDesc2.MiscFlags = 0; D3D11_SUBRESOURCE_DATA iinitData2; iinitData2.pSysMem = indices2; d3d11Device->CreateBuffer(&indexBufferDesc2, &iinitData2, &d2dIndexBuffer2); D3D11_BUFFER_DESC vertexBufferDesc2; ZeroMemory(&vertexBufferDesc2, sizeof(vertexBufferDesc2)); vertexBufferDesc2.Usage = D3D11_USAGE_DEFAULT; vertexBufferDesc2.ByteWidth = sizeof(Vertex) * 4; vertexBufferDesc2.BindFlags = D3D11_BIND_VERTEX_BUFFER; vertexBufferDesc2.CPUAccessFlags = 0; vertexBufferDesc2.MiscFlags = 0; D3D11_SUBRESOURCE_DATA vertexBufferData2; ZeroMemory(&vertexBufferData2, sizeof(vertexBufferData2)); vertexBufferData2.pSysMem = v2; hr = d3d11Device->CreateBuffer(&vertexBufferDesc2, &vertexBufferData2, &triangleVertBuffer2); ////////////////***********************First Texture Vertex Buffer *******************************///////////////////////////// //Create the vertex buffer Vertex v[] = { Vertex(-0.5f, -0.5f, 0.0f, 1.0f,0.0f,0.0f, 1.0f), Vertex(-0.5f, 0.5f, 0.0f, 1.0f,0.0f,0.0f, 1.0f), Vertex(0.5f, 0.5f, 0.0f, 1.0f, 0.0f,0.0f, 1.0f), Vertex(0.5f, -0.5f, 0.0f, 1.0f,0.0f, 0.0f, 1.0f), }; DWORD indices[] = { // Front Face 0, 1, 3, 1, 2, 3, }; D3D11_BUFFER_DESC indexBufferDesc; ZeroMemory(&indexBufferDesc, sizeof(indexBufferDesc)); indexBufferDesc.Usage = D3D11_USAGE_DEFAULT; indexBufferDesc.ByteWidth = sizeof(DWORD) * 2 * 3; indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; indexBufferDesc.CPUAccessFlags = 0; indexBufferDesc.MiscFlags = 0; D3D11_SUBRESOURCE_DATA iinitData; iinitData.pSysMem = indices; d3d11Device->CreateBuffer(&indexBufferDesc, &iinitData, &d2dIndexBuffer); D3D11_BUFFER_DESC vertexBufferDesc; ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc)); vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT; vertexBufferDesc.ByteWidth = sizeof(Vertex) * 4; vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; vertexBufferDesc.CPUAccessFlags = 0; vertexBufferDesc.MiscFlags = 0; D3D11_SUBRESOURCE_DATA vertexBufferData; ZeroMemory(&vertexBufferData, sizeof(vertexBufferData)); vertexBufferData.pSysMem = v; hr = d3d11Device->CreateBuffer(&vertexBufferDesc, &vertexBufferData, &triangleVertBuffer); UINT stride = sizeof(Vertex); UINT offset = 0; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// return true; } void UpdateScene() { } void DrawScene() { //////////////////////////////////////// CLEAR RENDER TARGET /////////////////////////////////////////////////////////// //d3d11DevCon->OMSetRenderTargets(1, &renderTargetViewMap, NULL); float bgColor[4] = {1.0f, 0.0f,0.0f, 1.0f }; d3d11DevCon->ClearRenderTargetView(renderTargetViewMap, bgColor); float bgColor2[4] = { 0.0f, 1.0f, 0.0f, 1.0f }; ////////////////////////////////////////////////Buffer 1/////////////////////////////////////////////////////////////// //Set the vertex buffer UINT stride = sizeof(Vertex); UINT offset = 0; ///////////////////////////////////////////////////////////Buffer 2////////////////////////////////////////////////////////////////// d3d11DevCon->IASetIndexBuffer(d2dIndexBuffer, DXGI_FORMAT_R32_UINT, 0); d3d11DevCon->IASetVertexBuffers(0, 1, &triangleVertBuffer, &stride, &offset); ////Draw the triangle d3d11DevCon->DrawIndexed(6, 0, 0); //////////////////////////////////////////// d3d11DevCon->OMSetRenderTargets(1, &renderTargetView, NULL); d3d11DevCon->PSSetShaderResources(0, 1, &shaderResourceViewMap); //d3d11DevCon->ClearRenderTargetView(renderTargetView, bgColor2); d3d11DevCon->IASetIndexBuffer(d2dIndexBuffer2, DXGI_FORMAT_R32_UINT, 0); d3d11DevCon->IASetVertexBuffers(0, 1, &triangleVertBuffer2, &stride, &offset); ////Draw the triangle d3d11DevCon->DrawIndexed(6, 0, 0); //Present the backbuffer to the screen SwapChain->Present(0, 0); } int messageloop() { MSG msg; ZeroMemory(&msg, sizeof(MSG)); while (true) { BOOL PeekMessageL( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg ); if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } else { // run game code UpdateScene(); DrawScene(); } } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_KEYDOWN: if (wParam == VK_ESCAPE) { DestroyWindow(hwnd); } return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, msg, wParam, lParam); } Shader FIle: Effect.fx struct VS_OUTPUT { float4 Pos : SV_POSITION; float4 Color : COLOR; }; Texture2D ObjTexture; SamplerState ObjSamplerState; VS_OUTPUT VS(float4 inPos : POSITION, float4 inColor : COLOR) { VS_OUTPUT output; output.Pos = inPos; output.Color = inColor; return output; } float4 PS(VS_OUTPUT input) : SV_TARGET { float2 temp; temp = input.Pos; float4 diffuse = ObjTexture.Sample(ObjSamplerState,0.5+0.5*temp); return input.Color + diffuse; }
please put a tab in front of all your lines of code, its hard to read the way it is now
on Oct 06 `17
iedoc
Added Tabs:
For more info : https://stackoverflow.com/questions/46606680/directx-11-render-to-texture-issue
on Oct 08 `17
AkshitVerma
Sign in to comment