I am learning HLSL and having trouble understanding how to pass matrices into the shaders to be able to perform the necessary operations within the shader to have the position values sent to the shaders placed in the correct place according to the view and projection matrices. I was going to place the viewMatrix and projMatrix data into the INPUT_ELEMENT_DESC array but then found that there is not a DXGI_FORMAT value to support a 4x4 float matrix. What is the correct way to pass the values of projMatrix and viewMatrix into the shader?
Thanks in advance
windowSource.cpp
void BuildD3D(HWND hWnd){
// create a struct to hold information about the swap chain
DXGI_SWAP_CHAIN_DESC scd;
// clear out the struct for use
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));
// fill the swap chain description struct
scd.BufferCount = 1; // one back buffer
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // use 32-bit color
scd.BufferDesc.Width = 800;
scd.BufferDesc.Height = 600;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // how swap chain is to be used
scd.OutputWindow = hWnd; // the window to be used
scd.SampleDesc.Count = 4; // how many multisamples
scd.Windowed = TRUE; // windowed/full-screen mode
scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
// create a device, device context and swap chain using the information in the scd struct
D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL, D3D11_SDK_VERSION, &scd, &swapchain, &dev, NULL, &devContext);
// Get Back Buffer information
ID3D11Texture2D *pBackbuffer;
swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackbuffer);
// Target rendering to the backbuffer that was just defined
dev->CreateRenderTargetView(pBackbuffer, NULL, &backbuffer);
// Release the data that was rendered to the backbuffer.
pBackbuffer->Release();
// Define the backbuffer as the rendering target
devContext->OMSetRenderTargets(1, &backbuffer, NULL);
// Define Viewport
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = 800;
viewport.Height = 600;
devContext->RSSetViewports(1, &viewport);
// Set Up Projection Matrix
projMatrix = DirectX::XMMatrixPerspectiveFovLH(DirectX::XMConvertToRadians(45.0f), 1920.0f, 1.0f, 200.0f);
// Set Up View Matrix
DirectX::XMVECTOR eyePos = {0.0f, 10.0f, 0.0f};
DirectX::XMVECTOR focusPos = {0.0f, 0.0f, 0.0f};
DirectX::XMVECTOR upPos = { 0.0f, 1.0f, 0.0f };
// Bind LookAt matrix to viewmatrix
viewMatrix = DirectX::XMMatrixLookAtLH(eyePos, focusPos, upPos);
BuildPipeline();
ParseGraphics();
}
void RenderFrame(void) {
// Clear BackBuffer to a color
devContext->ClearRenderTargetView(backbuffer, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));
// select which vertex buffer to display
UINT stride = sizeof(Vertex);
UINT offset = 0;
devContext->IASetVertexBuffers(0, 1, &pVBuffer, &stride, &offset);
// select which primtive type we are using
devContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// draw the vertex buffer to the back buffer
devContext->Draw(6, 0);
// swap buffers
swapchain->Present(0, 0);
}
void ParseGraphics() {
// Create Vertex Buffer
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.ByteWidth = sizeof(Vertex) * 6;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
dev->CreateBuffer(&bd, NULL, &pVBuffer);
// copy vertices into buffer
D3D11_MAPPED_SUBRESOURCE msr;
devContext->Map(pVBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &msr);
memcpy(msr.pData, square, sizeof(square));
devContext->Unmap(pVBuffer, NULL);
}
void BuildPipeline() {
// Load and Compile Shaders
ID3D10Blob *VS, *PS;
D3DX11CompileFromFile(L"shaders.shader", 0, 0, "VShader", "vs_5_0", 0, 0, 0, &VS, 0, 0);
D3DX11CompileFromFile(L"shaders.shader", 0, 0, "PShader", "ps_5_0", 0, 0, 0, &PS, 0, 0);
// Create shaders from the data in the Blobs Buffer
dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);
// Apply Shaders to the device context
devContext->VSSetShader(pVS, 0, 0);
devContext->PSSetShader(pPS, 0, 0);
// Define the layout of the input given to the shaders
D3D11_INPUT_ELEMENT_DESC ied[] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 3 * sizeof(float), D3D11_INPUT_PER_VERTEX_DATA, 0},
// Maybe pass projection matrix into shader here???
};
dev->CreateInputLayout(ied, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &pLayout);
devContext->IASetInputLayout(pLayout);
}
shader.shaders
struct VOut
{
float4 position : SV_POSITION;
float4 color : COLOR;
float4x4 fMatrix;
};
VOut VShader(float4 position : POSITION, float4 color : COLOR)
{
VOut output;
output.position = position;
output.color = color;
return output;
}
float4 PShader(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
{
return color;
}