forked from vixorien/D3D11Starter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSky.cpp
169 lines (141 loc) · 6.54 KB
/
Sky.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
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
#include "Sky.h"
#include "Helpers.h"
#pragma comment(lib, "d3dcompiler.lib")
#include <d3dcompiler.h>
#include <WICTextureLoader.h>
#include <cstring>
using namespace DirectX;
// --------------------------------------------------------
// 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] = {};
CreateWICTextureFromFile(device.Get(), right, (ID3D11Resource**)textures[0].GetAddressOf(), 0);
CreateWICTextureFromFile(device.Get(), left, (ID3D11Resource**)textures[1].GetAddressOf(), 0);
CreateWICTextureFromFile(device.Get(), up, (ID3D11Resource**)textures[2].GetAddressOf(), 0);
CreateWICTextureFromFile(device.Get(), down, (ID3D11Resource**)textures[3].GetAddressOf(), 0);
CreateWICTextureFromFile(device.Get(), front, (ID3D11Resource**)textures[4].GetAddressOf(), 0);
CreateWICTextureFromFile(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;
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
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;
device->CreateShaderResourceView(cubeMapTexture.Get(), &srvDesc, cubeSRV.GetAddressOf());
// Send back the SRV, which is what we need for our shaders
return cubeSRV;
}
Sky::Sky(
std::shared_ptr<Mesh> mesh,
Microsoft::WRL::ComPtr<ID3D11SamplerState> samplerState,
Microsoft::WRL::ComPtr<ID3D11Device> device,
Microsoft::WRL::ComPtr<ID3D11DeviceContext> context,
std::shared_ptr<SimpleVertexShader> vs,
std::shared_ptr<SimplePixelShader> ps,
std::vector<std::wstring> filesToLoad
) :
skyMesh(mesh),
samplerOptions(samplerState),
device(device),
context(context),
vertexShader(vs),
pixelShader(ps) {
//Create the Cube Map SRV
textureSRV = CreateCubemap(
filesToLoad[0].c_str(),
filesToLoad[1].c_str(),
filesToLoad[2].c_str(),
filesToLoad[3].c_str(),
filesToLoad[4].c_str(),
filesToLoad[5].c_str()
);
//Create the Rasterizer State
D3D11_RASTERIZER_DESC rasterizerDesc = {};
rasterizerDesc.FillMode = D3D11_FILL_SOLID;
rasterizerDesc.CullMode = D3D11_CULL_FRONT;
device->CreateRasterizerState(&rasterizerDesc, rasterizerState.GetAddressOf());
//Create the Depth-Stencil State
D3D11_DEPTH_STENCIL_DESC depthStencilDesc = {};
depthStencilDesc.DepthEnable = true;
//depthStencilDesc.StencilWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
device->CreateDepthStencilState(&depthStencilDesc, depthStencilState.GetAddressOf());
}
Sky::~Sky() {
}
void Sky::Draw(std::shared_ptr<Camera> camera) {
//Set the render states
context->RSSetState(rasterizerState.Get());
context->OMSetDepthStencilState(depthStencilState.Get(), 0);
//Prepare sky-specific shaders for drawing
vertexShader->SetShader();
pixelShader->SetShader();
vertexShader->SetMatrix4x4("view", camera->GetView());
vertexShader->SetMatrix4x4("projection", camera->GetProjection());
pixelShader->SetShaderResourceView("CubeMap", textureSRV);
pixelShader->SetSamplerState("SkySampler", samplerOptions);
vertexShader->CopyAllBufferData();
pixelShader->CopyAllBufferData();
//Draw the mesh
skyMesh->Draw();
//Reset render states
context->RSSetState(0);
context->OMSetDepthStencilState(0, 0);
}