-
Notifications
You must be signed in to change notification settings - Fork 1
/
Shader.cpp
142 lines (116 loc) · 5.59 KB
/
Shader.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "pch.h"
#include "Shader.h"
Shader::Shader()
{
}
Shader::~Shader()
{
}
bool Shader::InitStandard(ID3D11Device * device, WCHAR * vsFilename, WCHAR * psFilename)
{
D3D11_BUFFER_DESC matrixBufferDesc;
D3D11_SAMPLER_DESC samplerDesc;
D3D11_BUFFER_DESC lightBufferDesc;
//LOAD SHADER: VERTEX
auto vertexShaderBuffer = DX::ReadData(vsFilename);
HRESULT result = device->CreateVertexShader(vertexShaderBuffer.data(), vertexShaderBuffer.size(), NULL, &m_vertexShader);
if (result != S_OK)
{
//if loading failed.
return false;
}
// Create the vertex input layout description.
// This setup needs to match the VertexType stucture in the MeshClass and in the shader.
D3D11_INPUT_ELEMENT_DESC polygonLayout[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
// Get a count of the elements in the layout.
unsigned int numElements;
numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]);
// Create the vertex input layout.
device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer.data(), vertexShaderBuffer.size(), &m_layout);
//LOAD SHADER: PIXEL
auto pixelShaderBuffer = DX::ReadData(psFilename);
result = device->CreatePixelShader(pixelShaderBuffer.data(), pixelShaderBuffer.size(), NULL, &m_pixelShader);
if (result != S_OK)
{
//if loading failed.
return false;
}
// Setup the description of the dynamic matrix constant buffer that is in the vertex shader.
matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
matrixBufferDesc.ByteWidth = sizeof(MatrixBufferType);
matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
matrixBufferDesc.MiscFlags = 0;
matrixBufferDesc.StructureByteStride = 0;
// Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class.
device->CreateBuffer(&matrixBufferDesc, NULL, &m_matrixBuffer);
// Setup light buffer
// Setup the description of the light dynamic constant buffer that is in the pixel shader.
// Note that ByteWidth always needs to be a multiple of 16 if using D3D11_BIND_CONSTANT_BUFFER or CreateBuffer will fail.
lightBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
lightBufferDesc.ByteWidth = sizeof(LightBufferType);
lightBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
lightBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
lightBufferDesc.MiscFlags = 0;
lightBufferDesc.StructureByteStride = 0;
// Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class.
device->CreateBuffer(&lightBufferDesc, NULL, &m_lightBuffer);
// Create a texture sampler state description.
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; // wrap
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; // wrap
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; // wrap
samplerDesc.MipLODBias = 0.0f;
samplerDesc.MaxAnisotropy = 1;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
samplerDesc.BorderColor[0] = 0;
samplerDesc.BorderColor[1] = 0;
samplerDesc.BorderColor[2] = 0;
samplerDesc.BorderColor[3] = 0;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
// Create the texture sampler state.
device->CreateSamplerState(&samplerDesc, &m_sampleState);
return true;
}
bool Shader::SetShaderParameters(ID3D11DeviceContext * context, DirectX::SimpleMath::Matrix * world, DirectX::SimpleMath::Matrix * view, DirectX::SimpleMath::Matrix * projection, Light *sceneLight1, ID3D11ShaderResourceView* texture1)
{
D3D11_MAPPED_SUBRESOURCE mappedResource;
MatrixBufferType* dataPtr;
LightBufferType* lightPtr;
DirectX::SimpleMath::Matrix tworld, tview, tproj;
// Transpose the matrices to prepare them for the shader.
tworld = world->Transpose();
tview = view->Transpose();
tproj = projection->Transpose();
context->Map(m_matrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
dataPtr = (MatrixBufferType*)mappedResource.pData;
dataPtr->world = tworld;// worldMatrix;
dataPtr->view = tview;
dataPtr->projection = tproj;
context->Unmap(m_matrixBuffer, 0);
context->VSSetConstantBuffers(0, 1, &m_matrixBuffer); //note the first variable is the mapped buffer ID. Corresponding to what you set in the VS
context->Map(m_lightBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
lightPtr = (LightBufferType*)mappedResource.pData;
lightPtr->ambient = sceneLight1->getAmbientColour();
lightPtr->diffuse = sceneLight1->getDiffuseColour();
lightPtr->position = sceneLight1->getPosition();
lightPtr->padding = 0.0f;
context->Unmap(m_lightBuffer, 0);
context->PSSetConstantBuffers(0, 1, &m_lightBuffer); //note the first variable is the mapped buffer ID. Corresponding to what you set in the PS
//pass the desired texture to the pixel shader.
context->PSSetShaderResources(0, 1, &texture1);
return false;
}
void Shader::EnableShader(ID3D11DeviceContext * context)
{
context->IASetInputLayout(m_layout); //set the input layout for the shader to match out geometry
context->VSSetShader(m_vertexShader.Get(), 0, 0); //turn on vertex shader
context->PSSetShader(m_pixelShader.Get(), 0, 0); //turn on pixel shader
// Set the sampler state in the pixel shader.
context->PSSetSamplers(0, 1, &m_sampleState);
}