forked from vixorien/D3D11Starter
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSky.cpp
More file actions
178 lines (154 loc) · 7.14 KB
/
Copy pathSky.cpp
File metadata and controls
178 lines (154 loc) · 7.14 KB
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#include "Sky.h"
#include <WICTextureLoader.h>
#include "Graphics.h"
Sky::Sky(
Microsoft::WRL::ComPtr<ID3D11SamplerState> sampler,
std::shared_ptr<Mesh> mesh,
std::wstring vsFilePath,
std::wstring psFilePath,
const wchar_t* right,
const wchar_t* left,
const wchar_t* up,
const wchar_t* down,
const wchar_t* front,
const wchar_t* back)
{
// initialize vsData
vsData = {};
DirectX::XMStoreFloat4x4(&vsData.view, DirectX::XMMatrixIdentity());
DirectX::XMStoreFloat4x4(&vsData.projection, DirectX::XMMatrixIdentity());
// set sampler and mesh
this->sampler = sampler;
this->mesh = mesh;
// Load vs and ps
vs = Graphics::LoadVertexShader(vsFilePath);
ps = Graphics::LoadPixelShader(psFilePath);
// create cube map
skySRV = CreateCubemap(right, left, up, down, front, back);
// fill and create rs and ds
D3D11_RASTERIZER_DESC rsDesc = {};
rsDesc.FillMode = D3D11_FILL_SOLID;
rsDesc.CullMode = D3D11_CULL_FRONT;
Graphics::Device->CreateRasterizerState(&rsDesc, rs.GetAddressOf());
D3D11_DEPTH_STENCIL_DESC dsDesc = {};
dsDesc.DepthEnable = true;
dsDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
Graphics::Device->CreateDepthStencilState(&dsDesc, depthState.GetAddressOf());
}
// --------------------------------------------------------
// Author: Chris Cascioli
// Purpose: Creates a cube map on the GPU from 6 individual textures
//
// - You are allowed to directly copy/paste this into your code base
// for assignments, given that you clearly cite that this is not
// code of your own design.
//
// - Note: This code assumes you’re putting the function in Sky.cpp,
// you’ve included WICTextureLoader.h and you have an ID3D11Device
// ComPtr called “device”. Make any adjustments necessary for
// your own implementation.
// --------------------------------------------------------
// --------------------------------------------------------
// Loads six individual textures (the six faces of a cube map), then
// creates a blank cube map and copies each of the six textures to
// another face. Afterwards, creates a shader resource view for
// the cube map and cleans up all of the temporary resources.
// --------------------------------------------------------
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> Sky::CreateCubemap(
const wchar_t* right,
const wchar_t* left,
const wchar_t* up,
const wchar_t* down,
const wchar_t* front,
const wchar_t* back)
{
// Load the 6 textures into an array.
// - We need references to the TEXTURES, not SHADER RESOURCE VIEWS!
// - Explicitly NOT generating mipmaps, as we don't need them for the sky!
// - Order matters here! +X, -X, +Y, -Y, +Z, -Z
Microsoft::WRL::ComPtr<ID3D11Texture2D> textures[6] = {};
DirectX::CreateWICTextureFromFile(Graphics::Device.Get(), right, (ID3D11Resource**)textures[0].GetAddressOf(), 0);
DirectX::CreateWICTextureFromFile(Graphics::Device.Get(), left, (ID3D11Resource**)textures[1].GetAddressOf(), 0);
DirectX::CreateWICTextureFromFile(Graphics::Device.Get(), up, (ID3D11Resource**)textures[2].GetAddressOf(), 0);
DirectX::CreateWICTextureFromFile(Graphics::Device.Get(), down, (ID3D11Resource**)textures[3].GetAddressOf(), 0);
DirectX::CreateWICTextureFromFile(Graphics::Device.Get(), front, (ID3D11Resource**)textures[4].GetAddressOf(), 0);
DirectX::CreateWICTextureFromFile(Graphics::Device.Get(), back, (ID3D11Resource**)textures[5].GetAddressOf(), 0);
// We'll assume all of the textures are the same color format and resolution,
// so get the description of the first texture
D3D11_TEXTURE2D_DESC faceDesc = {};
textures[0]->GetDesc(&faceDesc);
// Describe the resource for the cube map, which is simply
// a "texture 2d array" with the TEXTURECUBE flag set.
// This is a special GPU resource format, NOT just a
// C++ array of textures!!!
D3D11_TEXTURE2D_DESC cubeDesc = {};
cubeDesc.ArraySize = 6; // Cube map!
cubeDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; // We'll be using as a texture in a shader
cubeDesc.CPUAccessFlags = 0; // No read back
cubeDesc.Format = faceDesc.Format; // Match the loaded texture's color format
cubeDesc.Width = faceDesc.Width; // Match the size
cubeDesc.Height = faceDesc.Height; // Match the size
cubeDesc.MipLevels = 1; // Only need 1
cubeDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; // This should be treated as a CUBE, not 6 separate textures
cubeDesc.Usage = D3D11_USAGE_DEFAULT; // Standard usage
cubeDesc.SampleDesc.Count = 1;
cubeDesc.SampleDesc.Quality = 0;
// Create the final texture resource to hold the cube map
Microsoft::WRL::ComPtr<ID3D11Texture2D> cubeMapTexture;
Graphics::Device->CreateTexture2D(&cubeDesc, 0, cubeMapTexture.GetAddressOf());
// Loop through the individual face textures and copy them,
// one at a time, to the cube map texure
for (int i = 0; i < 6; i++)
{
// Calculate the subresource position to copy into
unsigned int subresource = D3D11CalcSubresource(
0, // Which mip (zero, since there's only one)
i, // Which array element?
1); // How many mip levels are in the texture?
// Copy from one resource (texture) to another
Graphics::Context->CopySubresourceRegion(
cubeMapTexture.Get(), // Destination resource
subresource, // Dest subresource index (one of the array elements)
0, 0, 0, // XYZ location of copy
textures[i].Get(), // Source resource
0, // Source subresource index (we're assuming there's only one)
0); // Source subresource "box" of data to copy (zero means the whole thing)
}
// At this point, all of the faces have been copied into the
// cube map texture, so we can describe a shader resource view for it
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.Format = cubeDesc.Format; // Same format as texture
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; // Treat this as a cube!
srvDesc.TextureCube.MipLevels = 1; // Only need access to 1 mip
srvDesc.TextureCube.MostDetailedMip = 0; // Index of the first mip we want to see
// Make the SRV
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> cubeSRV;
Graphics::Device->CreateShaderResourceView(cubeMapTexture.Get(), &srvDesc, cubeSRV.GetAddressOf());
// Send back the SRV, which is what we need for our shaders
return cubeSRV;
}
void Sky::Draw(std::shared_ptr<Camera> camera) {
// Change the necessary render states
Graphics::Context->RSSetState(rs.Get());
Graphics::Context->OMSetDepthStencilState(depthState.Get(), 0);
// Prepare the sky-specific shaders for drawing
Graphics::Context->VSSetShader(vs.Get(), 0, 0);
Graphics::Context->PSSetShader(ps.Get(), 0, 0);
// Bind the Sampler and SRV
Graphics::Context->PSSetSamplers(0, 1, sampler.GetAddressOf());
Graphics::Context->PSSetShaderResources(0, 1, skySRV.GetAddressOf());
// Copy the view and projection matrices into the constant buffer
vsData.view = camera->GetView();
vsData.projection = camera->GetProjection();
// Bind the constant buffer to the pipeline
Graphics::FillAndBindNextConstantBuffer(
&vsData,
sizeof(SkyVSConstantBuffer),
D3D11_VERTEX_SHADER,
0);
// Draw the mesh
mesh->Draw();
// Reset render states
Graphics::Context->RSSetState(0);
Graphics::Context->OMSetDepthStencilState(0, 0);
}