I started learning Direct3D a week ago and I've been following many tutorials but after I got to the point where I had to create a Constant Buffer I got stuck, the creation of the buffer seems to be working correctly but the UpdateSubresourceUpdateSubresource function doesn't seem to update it, the value I'm trying to put in the buffer has no purpose apart from being a proof of concept, the value is the float brightness inside the struct VS_CONSTANT_BUFFER.
It is set to 1.0 during the buffer creation, then it is set 0.5 when the frame is redrawn but it doesn't update the buffer on the shader sideVS_CONSTANT_BUFFER.
Here is the code, I put all of the Direct3D stuff in one place so there is nothing you don't see:
It is set to 1.0 during the buffer creation, then it is set 0.5 when the frame is redrawn but it doesn't update the buffer on the shader side.
Here is the code, I put all of the Direct3D stuff in one place so there is nothing you don't see:
#include "GraphicsInit.h"
#include"Window.h"
float red = 0.0f;
int angle = 0;
struct Vertex
{
float x, y, z;
float r, g, b, a;
};
Vertex triangle[] = {
{-0.5f,-0.5f,0.5f, 1.0f,0.0f,0.0f,1.0f},
{-0.5f, 0.5f,0.5f, 0.0f,1.0f,0.0f,1.0f},
{ 0.5f, 0.5f,0.5f, 0.0f,0.0f,1.0f,1.0f},
{ 0.5f,-0.5f,0.5f, 0.0f,1.0f,0.0f,1.0f},
{-0.6f, 0.7,0.4f, 1.0f,1.0f,1.0f,1.0f},
{ 0.4f, 0.3f,0.9f, 1.0f,1.0f,1.0f,1.0f},
{ 0.9f,-0.8f,0.6f, 1.0f,1.0f,1.0f,1.0f}
};
unsigned int indices[] = {
0, 1, 2,
0, 2, 3,
4,5,6
};
ID3D11VertexShader* vs;
ID3D11PixelShader* ps;
ID3D11InputLayout* InputLayout;
ID3D11Buffer* VertexBuffer;
ID3D11Buffer* IndexBuffer;
ID3D11Buffer* VSConstantBuffer = NULL;
//Struct needs to be equal to the one in the shaders
struct VS_CONSTANT_BUFFER
{
float brightness;
};
VS_CONSTANT_BUFFER VSCBdata;
//CBStruct CBDat = {
// {
// std::cos(angle), std::sin(angle), 0.0f, 0.0f,
// -std::sin(angle), std::cos(angle), 0.0f, 0.0f,
// 0.0f, 0.0f, 0.0f, 0.0f,
// 0.0f, 0.0f, 0.0f, 0.0f
// }
//};
void InitD3D(HWND hWnd)
{
//////////////////DEVICE AND SWAPCHAIN//////////////////
DXGI_SWAP_CHAIN_DESC scd;
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));
scd.BufferCount = 1; // one back buffer
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // use 32-bit color
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
D3D11CreateDeviceAndSwapChain(
NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
NULL,
NULL,
NULL,
D3D11_SDK_VERSION,
&scd,
&swapchain,
&dev,
NULL,
&devcon);
/////////////////////////////////////////////////////////
//////////////////SET THE RENDER TARGET//////////////////
// get the address of the back buffer
ID3D11Texture2D* pBackBuffer;
swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
// use the back buffer address to create the render target
dev->CreateRenderTargetView(pBackBuffer, NULL, &backbuffer);
pBackBuffer->Release();
// set the render target as the back buffer
devcon->OMSetRenderTargets(1, &backbuffer, NULL);
/////////////////////////////////////////////////////////
//////////////////SET THE VIEW PORT//////////////////
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = sizeX;
viewport.Height = sizeY;
devcon->RSSetViewports(1, &viewport);
/////////////////////////////////////////////////////////
InitBuffers();
InitPipeline();
}
void InitPipeline()
{
//////////////////SHADERS COMPILING//////////////////
ID3D10Blob* blobvs, * blobps;
D3DX11CompileFromFile(L"Shaders.hlsl", 0, 0, "VS", "vs_4_0", 0, 0, 0, &blobvs, 0, 0);
D3DX11CompileFromFile(L"Shaders.hlsl", 0, 0, "PS", "ps_4_0", 0, 0, 0, &blobps, 0, 0);
dev->CreateVertexShader(blobvs->GetBufferPointer(), blobvs->GetBufferSize(), NULL, &vs);
dev->CreatePixelShader(blobps->GetBufferPointer(), blobps->GetBufferSize(), NULL, &ps);
devcon->VSSetShader(vs, 0, 0);
devcon->PSSetShader(ps, 0, 0);
/////////////////////////////////////////////////////////
//////////////////INPUT LAYOUT//////////////////
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 },
};
dev->CreateInputLayout(layout, 2, blobvs->GetBufferPointer(), blobvs->GetBufferSize(), &InputLayout);
devcon->IASetInputLayout(InputLayout);
/////////////////////////////////////////////////////////
blobvs->Release();
blobps->Release();
//////////////////IA//////////////////
// select which vertex buffer to display
UINT stride = sizeof(Vertex);
UINT offset = 0;
devcon->IASetVertexBuffers(0, 1, &VertexBuffer, &stride, &offset);
devcon->IASetIndexBuffer(IndexBuffer, DXGI_FORMAT_R32_UINT, 0);
// select which primtive type we are using
devcon->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
/////////////////////////////////////////////////////////
}
// this is the function used to render a single frame
void RenderFrame(void)
{
VSCBdata.brightness = 0.5f;
// clear the back buffer to a deep blue
devcon->ClearRenderTargetView(backbuffer, D3DXCOLOR(red, 0.2f, 0.4f, 1.0f));
devcon->UpdateSubresource(VSConstantBuffer, 0, NULL, &VSCBdata, 0, 0);
devcon->VSSetConstantBuffers(0, 1, &VSConstantBuffer);
// draw the vertex buffer to the back buffer
devcon->DrawIndexed(9, 0,0);
// do 3D rendering on the back buffer here
// switch the back buffer and the front buffer
swapchain->Present(0, 0);
}
void InitBuffers()
{
//////////////////VERTEX BUFFER//////////////////
D3D11_BUFFER_DESC buffer_desc = { 0 };
buffer_desc.ByteWidth = sizeof(Vertex) * ARRAYSIZE(triangle);
buffer_desc.Usage = D3D11_USAGE_DEFAULT;
buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
buffer_desc.CPUAccessFlags = 0;
buffer_desc.MiscFlags = 0;
buffer_desc.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA sub = { 0 };
sub.pSysMem = triangle;
sub.SysMemPitch = 0;
sub.SysMemSlicePitch = 0;
dev->CreateBuffer(&buffer_desc, &sub, &VertexBuffer);
/////////////////////////////////////////////////////////
//////////////////INDEX BUFFER//////////////////
D3D11_BUFFER_DESC index_desc = { 0 };
index_desc.Usage = D3D11_USAGE_DEFAULT;
index_desc.ByteWidth = sizeof(unsigned int) * ARRAYSIZE(indices);
index_desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
index_desc.CPUAccessFlags = 0;
index_desc.MiscFlags = 0;
// Define the resource data.
D3D11_SUBRESOURCE_DATA index_data;
index_data.pSysMem = indices;
index_data.SysMemPitch = 0;
index_data.SysMemSlicePitch = 0;
dev->CreateBuffer(&index_desc, &index_data, &IndexBuffer);
/////////////////////////////////////////////////////////
//////////////////CONSTANT BUFFER//////////////////
// Define the constant data used to communicate with shaders.
// Supply the vertex shader constant data.
VSCBdata.brightness = 1.0f;
// Fill in a buffer description.
D3D11_BUFFER_DESC CBDesc;
/////VERY STRANGÊ BEHAVIOUR
CBDesc.ByteWidth = 16;
//////
CBDesc.Usage = D3D11_USAGE_DYNAMIC;
CBDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
CBDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
CBDesc.MiscFlags = 0;
CBDesc.StructureByteStride = 0;
// Fill in the subresource data.
D3D11_SUBRESOURCE_DATA CBInitData;
CBInitData.pSysMem = &VSCBdata;
CBInitData.SysMemPitch = 0;
CBInitData.SysMemSlicePitch = 0;
// Create the buffer.
dev->CreateBuffer(&CBDesc, &CBInitData,&VSConstantBuffer);
// Set the buffer.
devcon->VSSetConstantBuffers(0, 1, &VSConstantBuffer);
/////////////////////////////////////////////////////////
}
void CleanD3D(void)
{
//Device
dev->Release();
devcon->Release();
/////////
//Swapchain
swapchain->Release();
backbuffer->Release();
/////////
//Pipeline
vs->Release();
ps->Release();
InputLayout->Release();
/////////
//Buffers
VertexBuffer->Release();
IndexBuffer->Release();
VSConstantBuffer->Release();
/////////
}