$\begingroup$

Some possible things that might be the issue and could be explained by someone who is knowledgeable

Order of my indices, In all I've read, your array of indices for a triangle list is just clockwise order, see below how I ordered it for proof. EDIT - I have changed my indices according to Jason Allen's comment, no change

Keep in mind that my code runs fine, no errors, no warnings(that I know of) related to my issue.

Can these warnings be an issue?

I have been banging my head over this issue for far too long. I know the answer is going to be ridiculously simple but somehow it has successfully evaded me.

I've been implementing deferred rendering into my engine and my second pass, the one that actually renders to the swap chain buffer, is staying black (or whatever color I clear it to before rendering).

Now I know the issue has nothing to do with anything associated with the first pass/gBuffer because I am completely bypassing that part, literally commented out the call to it in the game loop.

My 2nd Pass Deferred Vertex Shader is as follows...

float4 main( float4 pos : POSITION ) : SV_POSITION { return pos; }

My 2nd Pass Pixel Shader is as follows... I have omitted the actual lighting code because it is all commented out until I fix the issue.

float4 main(in float4 screenPos : SV_Position) : SV_Target { return float4(1.0f,1.0f,1.0f, 1.0f); }

As you can see I am not doing anything related to lighting or anything, all I'm trying to do is set every pixel to white, I want to see it work.

Here is my renderSecondPass function. this is what I call every frame. Irrelevant code has been omitted.

void DirectX::renderSecondPass() { nullShaders(); d3d11DeviceContext->VSSetShader(deferredVertexShader, NULL, 0); d3d11DeviceContext->PSSetShader(deferredPixelShader, NULL, 0); HRESULT hr; float clear[] = { 1.0, 0.5, 0.0, 1.0 }; d3d11DeviceContext->OMSetRenderTargets(1, &d3d11RenderTargetView, NULL); d3d11DeviceContext->ClearRenderTargetView(d3d11RenderTargetView, clear); d3d11DeviceContext->IASetInputLayout(InputLayout::Deferred); d3d11DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); for (unsigned int i = 0; i < lightBuffer.size(); i++) { UINT stride = sizeof(Vertex::Deferred); UINT offset = 0; d3d11DeviceContext->IASetVertexBuffers(0, 1, &deferredQuadVB, &stride, &offset); d3d11DeviceContext->IASetIndexBuffer(deferredQuadIB, DXGI_FORMAT_R32_UINT, 0); d3d11DeviceContext->DrawIndexed(deferredQuadIndiceCount, 0, 0); } hr = swapChain->Present(0, 0); if (FAILED(hr)) { MessageBox(0, L"Swap Chain Present Error.", 0, 0); } }

Here is the Input Layout...

namespace Vertex { struct Deferred { VECTOR<float> Position; float Position_W; }; } // C++ side above // Shaderside below namespace InputLayout { static ID3D11InputLayout* Deferred; } const D3D11_INPUT_ELEMENT_DESC InputLayoutDesc::DEFERRED_VS_INPUTLAYOUT_DESC[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 } };

Creation of the Input Layouts and Loading of the shaders themselves from file. Irrelevant code has been omitted.

bool DirectX::initShaders() { std::vector<char> shaderBuffer; std::string filename; HRESULT hr; // deferredVS filename = "Shaders\\deferredVS.cso"; if (!shaderFileToMemory(filename, shaderBuffer)) { MessageBox(0, L"Load defaultVS Shader Into Memory Error.", 0, 0); return false; } hr = d3d11Device->CreateVertexShader(&shaderBuffer[0], shaderBuffer.size(), NULL, &deferredVertexShader); hr = d3d11Device->CreateInputLayout(InputLayoutDesc::DEFERRED_VS_INPUTLAYOUT_DESC, 1, &shaderBuffer[0], shaderBuffer.size(), &InputLayout::Deferred); // deferredPS filename = "Shaders\\deferredPS.cso"; if (!shaderFileToMemory(filename, shaderBuffer)) { MessageBox(0, L"Load deferredPS Shader Into Memory Error.", 0, 0); return false; } hr = d3d11Device->CreatePixelShader(&shaderBuffer[0], shaderBuffer.size(), NULL, &deferredPixelShader); return true; }

The Vertex and Index Buffer were created using the following...

bool DirectX::initDeferredQuad() { std::vector<Vertex::Deferred> deferredQuadVertices; std::vector<unsigned int> deferredQuadIndices; Vertex::Deferred quadVertices[4]; Vertex::Deferred quadVertice; quadVertice.Position_W = 1.0; quadVertice.Position = VECTOR<float>(-1.0, 1.0, 0.0); quadVertices[0] = quadVertice; quadVertice.Position = VECTOR<float>(1.0, 1.0, 0.0); quadVertices[1] = quadVertice; quadVertice.Position = VECTOR<float>(-1.0, -1.0, 0.0); quadVertices[2] = quadVertice; quadVertice.Position = VECTOR<float>(1.0, -1.0, 0.0); quadVertices[3] = quadVertice; D3D11_BUFFER_DESC vbd; D3D11_SUBRESOURCE_DATA vinitData; HRESULT hr; vbd.Usage = D3D11_USAGE_IMMUTABLE; vbd.ByteWidth = sizeof(Vertex::Deferred) * 4; vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER; vbd.CPUAccessFlags = 0; vbd.MiscFlags = 0; vbd.StructureByteStride = 0; vinitData.pSysMem = &quadVertices; hr = d3d11Device->CreateBuffer(&vbd, &vinitData, &deferredQuadVB); if (FAILED(hr)) { MessageBox(0, L"Quad Vertex Buffer Creation Error.", 0, 0); return false; } unsigned int quadIndices[] = { 0, 1, 2, 2, 1, 3 }; deferredQuadIndiceCount = 6; D3D11_BUFFER_DESC ibd; D3D11_SUBRESOURCE_DATA iinitData; ibd.Usage = D3D11_USAGE_IMMUTABLE; ibd.ByteWidth = sizeof(unsigned int) * 6; ibd.BindFlags = D3D11_BIND_INDEX_BUFFER; ibd.CPUAccessFlags = 0; ibd.MiscFlags = 0; iinitData.pSysMem = &deferredQuadIndices; hr = d3d11Device->CreateBuffer(&ibd, &iinitData, &deferredQuadIB); if (FAILED(hr)) { MessageBox(0, L"QuadIndex Buffer Creation Error.", 0, 0); return false; } return true; }

I thought the issue was here. Since my Vertex Shader is feeding the Rasterizer data directly, the Vertex Shader has to output SV_Position in Clip Space. Wouldn't the coordinates I've made for my vertices be correct for a quad composed of 2 triangles that would take up the entire screen? (I've tried changing the z values, no change)

Here is resizeSwapChain, I've been bulding/rebuild the viewport in here. This function is called at initialization and whenever the window size changes after the window adjustment has been released (WM_EXITSIZEMOVE). Irrelevant code has been omitted.

void DirectX::resizeSwapChain() { const unsigned int clientWidth = uClient->getAppScreenWidth(); const unsigned int clientHeight = uClient->getAppScreenHeight(); HRESULT hr; if (!(d3d11RenderTargetView == NULL)) { d3d11RenderTargetView->Release(); d3d11RenderTargetView = 0; } if (!(d3d11DepthStencilView) == NULL) { d3d11DepthStencilView->Release(); d3d11DepthStencilView = 0; } if (!(d3d11StencilBuffer) == NULL) { d3d11StencilBuffer->Release(); d3d11StencilBuffer = 0; } hr = swapChain->ResizeBuffers(1, clientWidth, clientHeight, DXGI_FORMAT_R8G8B8A8_UNORM, 0); ID3D11Texture2D* backBuffer; hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBuffer)); hr = d3d11Device->CreateRenderTargetView(backBuffer, 0, &d3d11RenderTargetView); backBuffer->Release(); backBuffer = 0; D3D11_TEXTURE2D_DESC depthStencilDesc; depthStencilDesc.Width = clientWidth; depthStencilDesc.Height = clientHeight; depthStencilDesc.MipLevels = 1; depthStencilDesc.ArraySize = 1; depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; if (msaaEnabled) { depthStencilDesc.SampleDesc.Count = 4; depthStencilDesc.SampleDesc.Quality = msaaQuality - 1; } else { depthStencilDesc.SampleDesc.Count = 1; depthStencilDesc.SampleDesc.Quality = 0; } depthStencilDesc.Usage = D3D11_USAGE_DEFAULT; depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthStencilDesc.CPUAccessFlags = 0; depthStencilDesc.MiscFlags = 0; hr = d3d11Device->CreateTexture2D(&depthStencilDesc, 0, &d3d11StencilBuffer); hr = d3d11Device->CreateDepthStencilView(d3d11StencilBuffer, 0, &d3d11DepthStencilView); d3d11ScreenViewport.TopLeftX = 0; d3d11ScreenViewport.TopLeftY = 0; d3d11ScreenViewport.Width = static_cast<float>(clientWidth); d3d11ScreenViewport.Height = static_cast<float>(clientHeight); d3d11ScreenViewport.MinDepth = 0.0f; d3d11ScreenViewport.MaxDepth = 1.0f; d3d11DeviceContext->RSSetViewports(1, &d3d11ScreenViewport); mainCamera->setProjectionMatrix(MATRIX4X4<float>::perspectiveFieldOfViewLeftHandMatrix(0.25 * GenericMath::PI, GenericMath::aspectRatio(clientWidth, clientHeight), 0.001, 1000.0)); }

Here is my D3D11 Initialization function, this is where I create my Rasterization states. Irrelevant code has been omitted.

bool DirectX::initDirectX() { D3D_FEATURE_LEVEL featureLevel; HRESULT hr = D3D11CreateDevice(NULL, driverType, NULL, NULL, NULL, 0, D3D11_SDK_VERSION, &d3d11Device, &featureLevel, &d3d11DeviceContext); hr = d3d11Device->CheckMultisampleQualityLevels( DXGI_FORMAT_R8G8B8A8_UNORM, 4, &msaaQuality); DXGI_SWAP_CHAIN_DESC swapChainDesc; swapChainDesc.BufferDesc.Width = uClient->getAppScreenWidth(); swapChainDesc.BufferDesc.Height = uClient->getAppScreenHeight(); swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; if (msaaEnabled) { swapChainDesc.SampleDesc.Count = 4; swapChainDesc.SampleDesc.Quality = msaaQuality - 1; } else { swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; } swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = 1; swapChainDesc.OutputWindow = *windowsHandle; swapChainDesc.Windowed = true; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.Flags = 0; IDXGIDevice* dxgiDevice = 0; hr = d3d11Device->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); IDXGIAdapter* dxgiAdapter = 0; hr = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter); IDXGIFactory* dxgiFactory = 0; hr = dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory); hr = dxgiFactory->CreateSwapChain(d3d11Device, &swapChainDesc, &swapChain); dxgiDevice->Release(); dxgiDevice = 0; dxgiAdapter->Release(); dxgiAdapter = 0; dxgiFactory->Release(); dxgiFactory = 0; resizeGBuffers(); resizeSwapChain(); D3D11_RASTERIZER_DESC rasterizerDesc; ZeroMemory(&rasterizerDesc, sizeof(D3D11_RASTERIZER_DESC)); rasterizerDesc.FillMode = D3D11_FILL_SOLID; rasterizerDesc.CullMode = D3D11_CULL_BACK; rasterizerDesc.FrontCounterClockwise = false; rasterizerDesc.DepthClipEnable = true; hr = d3d11Device->CreateRasterizerState( &rasterizerDesc, &d3d11SolidRS);\ ZeroMemory(&rasterizerDesc, sizeof(D3D11_RASTERIZER_DESC)); rasterizerDesc.FillMode = D3D11_FILL_WIREFRAME; rasterizerDesc.CullMode = D3D11_CULL_BACK; rasterizerDesc.FrontCounterClockwise = false; rasterizerDesc.DepthClipEnable = true; hr = d3d11Device->CreateRasterizerState( &rasterizerDesc, &d3d11WireframeRS); d3d11DeviceContext->RSSetState(d3d11SolidRS); return true; }

If anyone needs more info, just ask. Thanks