void TextureWave::BuildShaders() { HRESULT result = S_FALSE; #if defined(DEBUG) || defined(_DEBUG) result = D3DReadFileToBlob(L"../X64/Debug/VertexShader.cso", &m_vertexBlob); #else if defined(RELEASE) || defined(_RELEASE) result = D3DReadFileToBlob(L"../X64/Release/VertexShader.cso", &m_vertexBlob); #endif result = m_d3dDevice->CreateVertexShader(m_vertexBlob->GetBufferPointer(), m_vertexBlob->GetBufferSize(), nullptr, &m_vertexShader); D3DHelper::ThrowIfFailed(result); #if defined(DEBUG) || defined(_DEBUG) result = D3DReadFileToBlob(L"../x64/Debug/PixelShader.cso", &m_pixelBlob); #else if defined(RELEASE) || defined(_RELEASE) result = D3DReadFileToBlob(L"../X64/Release/PixelShader.cso", &m_pixelBlob); #endif result = m_d3dDevice->CreatePixelShader(m_pixelBlob->GetBufferPointer(), m_pixelBlob->GetBufferSize(), nullptr, &m_pixelShader); D3DHelper::ThrowIfFailed(result); }
void TextureDemo::BuildShader() { HRESULT result = S_FALSE; DWORD shaderFlags = 0; #if defined(DEBUG) || defined(_DEBUG) shaderFlags |= D3D10_SHADER_DEBUG; shaderFlags |= D3D10_SHADER_SKIP_OPTIMIZATION; #endif #if defined(DEBUG) || defined(_DEBUG) result = D3DReadFileToBlob(L"../X64/Debug/VertexShader.cso", &m_vertexBlob); #else if defined(RELEASE) || defined(_RELEASE) result = D3DReadFileToBlob(L"../X64/Release/VertexShader.cso", &m_vertexBlob); #endif result = m_d3dDevice->CreateVertexShader(m_vertexBlob->GetBufferPointer(), m_vertexBlob->GetBufferSize(), nullptr, &m_vertexShader); D3DHelper::ThrowIfFailed(result); #if defined(DEBUG) || defined(_DEBUG) result = D3DReadFileToBlob(L"../X64/Debug/PixelShader.cso", &m_pixelBlob); #else if defined(RELEASE) || defined(_RELEASE) result = D3DReadFileToBlob(L"../X64/Release/PixelShader.cso", &m_pixelBlob); #endif result = m_d3dDevice->CreatePixelShader(m_pixelBlob->GetBufferPointer(), m_pixelBlob->GetBufferSize(), nullptr, &m_pixelShader); D3DHelper::ThrowIfFailed(result); m_constBuffer.Create(m_d3dDevice); m_constDiffuseLight.Create(m_d3dDevice); }
HRESULT Box::BuildShaders() { DWORD shaderFlags = 0; #if defined(DEBUG) || defined(_DEBUG) shaderFlags |= D3D10_SHADER_DEBUG; shaderFlags |= D3D10_SHADER_SKIP_OPTIMIZATION; #endif HRESULT result; result = D3DReadFileToBlob(L"../Debug/BoxPixelShader.cso", &m_pixelBlob); if (FAILED(result)) { return result; } result = D3DReadFileToBlob(L"../Debug/BoxVertexShader.cso", &m_vertexBlob); if (FAILED(result)) { return result; } result = m_d3dDevice->CreateVertexShader(m_vertexBlob->GetBufferPointer(), m_vertexBlob->GetBufferSize(), nullptr, &m_vertexShader); if (FAILED(result)) { return result; } result = m_d3dDevice->CreatePixelShader(m_pixelBlob->GetBufferPointer(), m_pixelBlob->GetBufferSize(), nullptr, &m_pixelShader); return result; }
HRESULT LightSkull::BuildShaders() { HRESULT result; DWORD shaderFlags = 0; #if defined(DEBUG) || defined(_DEBUG) shaderFlags |= D3D10_SHADER_DEBUG; shaderFlags |= D3D10_SHADER_SKIP_OPTIMIZATION; #endif #if defined(DEBUG) || defined(_DEBUG) result = D3DReadFileToBlob(L"../X64/Debug/VertexShader.cso", &m_vertexBlob); #else if defined(RELEASE) || defined(_RELEASE) result = D3DReadFileToBlob(L"../X64/Release/VertexShader.cso", &m_vertexBlob); #endif D3DHelper::ThrowIfFailed(result); #if defined(DEBUG) || defined(_DEBUG) result = D3DReadFileToBlob(L"../X64/Debug/PixelShader.cso", &m_pixelBlob); #else if defined(RELEASE) || defined(_RELEASE) result = D3DReadFileToBlob(L"../X64/Release/PixelShader.cso", &m_pixelBlob); #endif D3DHelper::ThrowIfFailed(result); result = m_d3dDevice->CreateVertexShader(m_vertexBlob->GetBufferPointer(), m_vertexBlob->GetBufferSize(), nullptr, &m_vertexShader); D3DHelper::ThrowIfFailed(result); result = m_d3dDevice->CreatePixelShader(m_pixelBlob->GetBufferPointer(), m_pixelBlob->GetBufferSize(), nullptr, &m_pixelShader); D3DHelper::ThrowIfFailed(result); D3D11_RASTERIZER_DESC wireframeDesc; ZeroMemory(&wireframeDesc, sizeof(D3D11_RASTERIZER_DESC)); wireframeDesc.FillMode = D3D11_FILL_WIREFRAME; wireframeDesc.CullMode = D3D11_CULL_BACK; wireframeDesc.FrontCounterClockwise = false; wireframeDesc.DepthClipEnable = true; result = m_d3dDevice->CreateRasterizerState(&wireframeDesc, &m_frameRenderState); D3DHelper::ThrowIfFailed(result); D3D11_RASTERIZER_DESC solidDesc; ZeroMemory(&solidDesc, sizeof(D3D11_RASTERIZER_DESC)); solidDesc.FillMode = D3D11_FILL_SOLID; solidDesc.CullMode = D3D11_CULL_BACK; solidDesc.FrontCounterClockwise = false; solidDesc.DepthClipEnable = true; result = m_d3dDevice->CreateRasterizerState(&solidDesc, &m_solidRenderState); D3DHelper::ThrowIfFailed(result); m_currentRenderState = m_solidRenderState; return result; }
Shader::Shader(const std::wstring& vShaderPath, const std::wstring& pShaderPath) { UINT flags = D3DCOMPILE_ENABLE_STRICTNESS; #if _DEBUG flags |= D3DCOMPILE_DEBUG; #endif HRESULT hrv = D3DReadFileToBlob(vShaderPath.c_str(), &m_vByteCode); HRESULT hrp = D3DReadFileToBlob(pShaderPath.c_str(), &m_pByteCode); // encapsulate both shaders into shader objects dev->CreateVertexShader(m_vByteCode->GetBufferPointer(), m_vByteCode->GetBufferSize(), NULL, &m_vertexShader); dev->CreatePixelShader(m_pByteCode->GetBufferPointer(), m_pByteCode->GetBufferSize(), NULL, &m_pixelShader); }
HRESULT ShaderPS::init(ID3D11Device* device, LPCWSTR shaderPath) { HRESULT hr = S_OK; hr = D3DReadFileToBlob(shaderPath, &blob_); std::wstring location = L"ShaderPS::init D3DReadFileToBlob "; std::wstring failed = L" Failed!"; std::wstring errorMsg = location + static_cast<std::wstring>(shaderPath) + failed; if(FAILED(hr)) ERROR_MSG(errorMsg.c_str()); else { hr = device->CreatePixelShader( blob_->GetBufferPointer(), blob_->GetBufferSize(), nullptr, &pixelShader_); location = L"ShaderVS::init CreateVertexShader "; errorMsg = location + static_cast<std::wstring>(shaderPath) + failed; if(FAILED(hr)) ERROR_MSG(errorMsg.c_str()); } return hr; }
void Pipeline::loadShader(ShaderType type, std::wstring path) { ID3DBlob* shader; D3DReadFileToBlob(path.data(), &shader); m_shadersMap.erase(type); m_shadersMap.insert(std::pair<ShaderType, std::shared_ptr<ID3DBlob>>(type, std::shared_ptr<ID3DBlob>(shader))); switch (type) { case ShaderType::VERTEX_SHADER : m_pipelineDesc.VS = { shader->GetBufferPointer(), shader->GetBufferSize() }; break; case ShaderType::HULL_SHADER : m_pipelineDesc.HS = { shader->GetBufferPointer(), shader->GetBufferSize() }; break; case ShaderType::DOMAIN_SHADER: m_pipelineDesc.DS = { shader->GetBufferPointer(), shader->GetBufferSize() }; break; case ShaderType::PIXEL_SHADER: m_pipelineDesc.PS = { shader->GetBufferPointer(), shader->GetBufferSize() }; break; } }
bool CD3DVertexShader::Create(const std::wstring& vertexFile, D3D11_INPUT_ELEMENT_DESC* vertexLayout, unsigned int vertexLayoutSize) { ReleaseShader(); ID3D11Device* pDevice = g_Windowing.Get3D11Device(); if (!pDevice) return false; if (FAILED(D3DReadFileToBlob(vertexFile.c_str(), &m_VSBuffer))) { CLog::Log(LOGERROR, __FUNCTION__ " - Failed to load the vertex shader."); return false; } if (vertexLayout && vertexLayoutSize) { m_vertexLayoutSize = vertexLayoutSize; m_vertexLayout = new D3D11_INPUT_ELEMENT_DESC[vertexLayoutSize]; for (unsigned int i = 0; i < vertexLayoutSize; ++i) m_vertexLayout[i] = vertexLayout[i]; } else return false; m_inited = CreateInternal(); if (m_inited) g_Windowing.Register(this); return m_inited; }
HRESULT ShaderBase::loadFromFile( const std::string &filename ) { std::string shaderFile = filesystem::getFile( filename ); std::wstring wShaderFile = std::wstring( shaderFile.begin(), shaderFile.end() ); //load shader file ID3DBlob *shaderSource; HRESULT res = D3DReadFileToBlob( wShaderFile.c_str(), &shaderSource ); if ( FAILED(res) ) { std::cout << "Error (ShaderBase::loadFromFile): Error loading shader source " << wShaderFile.c_str() << std::endl; return res; } res = processLoadedShaderBlob( shaderSource ); if ( FAILED(res) ) { std::cout << "Error (ShaderBase::loadFromFile): Error processing shader source " << wShaderFile.c_str() << std::endl; shaderSource->Release(); return res; } shaderSource->Release(); return S_OK; }
bool beShaderTexture::Init(beRenderInterface* ri, const beWString& pixelFilename, const beWString& vertexFilename) { ID3D11Device* device = ri->GetDevice(); D3D11_SAMPLER_DESC samplerDesc; //ID3D10Blob* errorMessage = nullptr; ID3D10Blob* vBuffer = nullptr; ID3D10Blob* pBuffer = nullptr; //HRESULT res = D3DCompileFromFile(vertexFilename.c_str(), nullptr, nullptr, "main", "vs_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, &vBuffer, &errorMessage); //if (FAILED(res)) //{ // if (errorMessage) // { // LOG("%s\n Filename:%s, res:0x%08x", errorMessage->GetBufferPointer(), vertexFilename.c_str(), res); // } // BE_ASSERT(false); // return false; //} //res = D3DCompileFromFile(pixelFilename.c_str(), nullptr, nullptr, "main", "ps_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, &pBuffer, &errorMessage); //if (FAILED(res)) //{ // if (errorMessage) // { // bePrintf::bePrintf(false, "", "%s\n Filename:%s, res:0x%08x", errorMessage->GetBufferPointer(), pixelFilename.c_str(), res); // } // BE_ASSERT(false); // return false; //} D3DReadFileToBlob(vertexFilename.c_str(), &vBuffer); D3DReadFileToBlob(pixelFilename.c_str(), &pBuffer); defer({BE_SAFE_RELEASE(vBuffer);});
HRESULT ManagementShader::initPixelShader(ID3D11Device* device, std::wstring filePath, std::wstring fileName, ID3D11PixelShader** shader, ID3DBlob** blob) { HRESULT hr = S_OK; std::wstring completePath = filePath + fileName; hr = D3DReadFileToBlob(completePath.c_str(), blob); if(FAILED(hr)) MessageBox(NULL, L"ManagmenetShader::initPixelShader() | D3DReadFileToBlob() | Failed", completePath.c_str(), MB_OK | MB_ICONEXCLAMATION); else { hr = device->CreatePixelShader((*blob)->GetBufferPointer(), (*blob)->GetBufferSize(), NULL, shader); if(FAILED(hr)) MessageBox(NULL, L"ManagementShader::initPixelShader() | device->CreatePixelShader() | Failed", completePath.c_str(), MB_OK | MB_ICONEXCLAMATION); } return hr; }
bool CD3DPixelShader::Create(const std::wstring& wstrFile) { ReleaseShader(); ID3D11Device* pDevice = g_Windowing.Get3D11Device(); if (!pDevice) return false; if (FAILED(D3DReadFileToBlob(wstrFile.c_str(), &m_PSBuffer))) { CLog::Log(LOGERROR, __FUNCTION__ " - Failed to load the vertex shader."); return false; } m_inited = CreateInternal(); if (m_inited) g_Windowing.Register(this); return m_inited; }
void Blob::Load(std::wstring path) { Graphouny::Framework::ThrowOnFailed( D3DReadFileToBlob(path.c_str(), &m_pBlob), L"Failed to load blob '" + path + L"'"); }
void Simulation::InitializePipeline() { D3D11_INPUT_ELEMENT_DESC vDesc[] = { { "POSITION", NULL, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, NULL }, { "COLOR", NULL, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, NULL }, { "TEXCOORD", NULL, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, NULL }, { "NORMAL", NULL, DXGI_FORMAT_R32G32B32_FLOAT, 0, 36, D3D11_INPUT_PER_VERTEX_DATA, NULL }, { "TANGENT", NULL, DXGI_FORMAT_R32G32B32_FLOAT, 0, 44, D3D11_INPUT_PER_VERTEX_DATA, NULL } }; ID3DBlob* vertexByte; D3DReadFileToBlob(L"Default.cso", &vertexByte); dev->CreateInputLayout(vDesc, ARRAYSIZE(vDesc), vertexByte->GetBufferPointer(), vertexByte->GetBufferSize(), &inputLayout); ReleaseMacro(vertexByte); D3D11_BUFFER_DESC cd; ZeroMemory(&cd, sizeof(D3D11_BUFFER_DESC)); cd.ByteWidth = sizeof(matrixBufferData); cd.Usage = D3D11_USAGE_DEFAULT; cd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; cd.CPUAccessFlags = 0; cd.MiscFlags = 0; cd.StructureByteStride = 0; dev->CreateBuffer(&cd, NULL, &matrixBuffer); D3D11_BLEND_DESC bd; ZeroMemory(&bd, sizeof(D3D11_BLEND_DESC)); bd.AlphaToCoverageEnable = false; bd.IndependentBlendEnable = false; bd.RenderTarget[0].BlendEnable = true; bd.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; bd.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; bd.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; bd.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; bd.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; bd.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; bd.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; dev->CreateBlendState(&bd, &blendState); D3D11_RASTERIZER_DESC rd; ZeroMemory(&rd, sizeof(D3D11_RASTERIZER_DESC)); rd.FillMode = D3D11_FILL_WIREFRAME; rd.CullMode = D3D11_CULL_BACK; rd.FrontCounterClockwise = false; rd.DepthBias = 0; rd.DepthBiasClamp = 0; rd.SlopeScaledDepthBias = 0; rd.DepthClipEnable = true; rd.ScissorEnable = false; rd.MultisampleEnable = false; rd.AntialiasedLineEnable = false; dev->CreateRasterizerState(&rd, &wireframe); rd.FillMode = D3D11_FILL_SOLID; dev->CreateRasterizerState(&rd, &solid); D3D11_DEPTH_STENCIL_DESC dsd; ZeroMemory(&dsd, sizeof(D3D11_DEPTH_STENCIL_DESC)); dsd.DepthEnable = true; dsd.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; dsd.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; dsd.StencilEnable = false; dsd.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; dsd.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; dsd.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; dsd.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; dsd.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; dsd.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsd.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; dsd.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; dsd.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; dsd.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dev->CreateDepthStencilState(&dsd, &depthStencilState); }
// -------------------------------------------------------- // Loads the specified shader and builds the variable table using shader // reflection. This must be a separate step from the constructor since // we can't invoke derived class overrides in the base class constructor. // // shaderFile - A "wide string" specifying the compiled shader to load // // Returns true if shader is loaded properly, false otherwise // -------------------------------------------------------- bool ISimpleShader::LoadShaderFile(LPCWSTR shaderFile) { // Load the shader to a blob and ensure it worked ID3DBlob* shaderBlob = 0; HRESULT hr = D3DReadFileToBlob(shaderFile, &shaderBlob); if (hr != S_OK) { return false; } // Create the shader - Calls an overloaded version of this abstract // method in the appropriate child class shaderValid = CreateShader(shaderBlob); if (!shaderValid) { shaderBlob->Release(); return false; } // Set up shader reflection to get information about // this shader and its variables, buffers, etc. ID3D11ShaderReflection* refl; D3DReflect( shaderBlob->GetBufferPointer(), shaderBlob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&refl); // Get the description of the shader D3D11_SHADER_DESC shaderDesc; refl->GetDesc(&shaderDesc); // Create an array of constant buffers constantBufferCount = shaderDesc.ConstantBuffers; constantBuffers = new SimpleConstantBuffer[constantBufferCount]; // Handle bound resources (like shaders and samplers) unsigned int resourceCount = shaderDesc.BoundResources; for (unsigned int r = 0; r < resourceCount; r++) { // Get this resource's description D3D11_SHADER_INPUT_BIND_DESC resourceDesc; refl->GetResourceBindingDesc(r, &resourceDesc); // Check the type switch (resourceDesc.Type) { case D3D_SIT_TEXTURE: // A texture resource textureTable.insert(std::pair<std::string, unsigned int>(resourceDesc.Name, resourceDesc.BindPoint)); break; case D3D_SIT_SAMPLER: // A sampler resource samplerTable.insert(std::pair<std::string, unsigned int>(resourceDesc.Name, resourceDesc.BindPoint)); break; } } // Loop through all constant buffers for (unsigned int b = 0; b < constantBufferCount; b++) { // Get this buffer ID3D11ShaderReflectionConstantBuffer* cb = refl->GetConstantBufferByIndex(b); // Get the description of this buffer D3D11_SHADER_BUFFER_DESC bufferDesc; cb->GetDesc(&bufferDesc); // Get the description of the resource binding, so // we know exactly how it's bound in the shader D3D11_SHADER_INPUT_BIND_DESC bindDesc; refl->GetResourceBindingDescByName(bufferDesc.Name, &bindDesc); // Set up the buffer and put its pointer in the table constantBuffers[b].BindIndex = bindDesc.BindPoint; cbTable.insert(std::pair<std::string, SimpleConstantBuffer*>(bufferDesc.Name, &constantBuffers[b])); // Create this constant buffer D3D11_BUFFER_DESC newBuffDesc; newBuffDesc.Usage = D3D11_USAGE_DEFAULT; newBuffDesc.ByteWidth = bufferDesc.Size; newBuffDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; newBuffDesc.CPUAccessFlags = 0; newBuffDesc.MiscFlags = 0; newBuffDesc.StructureByteStride = 0; device->CreateBuffer(&newBuffDesc, 0, &constantBuffers[b].ConstantBuffer); // Set up the data buffer for this constant buffer constantBuffers[b].LocalDataBuffer = new unsigned char[bufferDesc.Size]; ZeroMemory(constantBuffers[b].LocalDataBuffer, bufferDesc.Size); // Loop through all variables in this buffer for (unsigned int v = 0; v < bufferDesc.Variables; v++) { // Get this variable ID3D11ShaderReflectionVariable* var = cb->GetVariableByIndex(v); // Get the description of the variable D3D11_SHADER_VARIABLE_DESC varDesc; var->GetDesc(&varDesc); // Create the variable struct SimpleShaderVariable varStruct; varStruct.ConstantBufferIndex = b; varStruct.ByteOffset = varDesc.StartOffset; varStruct.Size = varDesc.Size; // Get a string version std::string varName(varDesc.Name); // Add this variable to the table varTable.insert(std::pair<std::string, SimpleShaderVariable>(varName, varStruct)); } } // All set refl->Release(); shaderBlob->Release(); return true; }
HRESULT InitDevice() { HRESULT hr = S_OK; RECT rc; GetClientRect(g_hWnd, &rc); UINT width = rc.right - rc.left; UINT height = rc.bottom - rc.top; UINT createDeviceFlags = 0; #ifdef _DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_DRIVER_TYPE driverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, }; UINT numDriverTypes = ARRAYSIZE(driverTypes); D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0, }; UINT numFeatureLevels = ARRAYSIZE(featureLevels); DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(sd)); sd.BufferCount = 1; sd.BufferDesc.Width = width; sd.BufferDesc.Height = height; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = g_hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++) { g_driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDeviceAndSwapChain(nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext); if (SUCCEEDED(hr)) break; } if (FAILED(hr)) return hr; // Create a render target view ID3D11Texture2D* pBackBuffer = nullptr; hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); if (FAILED(hr)) return hr; hr = g_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &g_pRenderTargetView); pBackBuffer->Release(); if (FAILED(hr)) return hr; // Create depth stencil texture D3D11_TEXTURE2D_DESC descDepth; ZeroMemory(&descDepth, sizeof(descDepth)); descDepth.Width = width; descDepth.Height = height; descDepth.MipLevels = 1; descDepth.ArraySize = 1; descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; descDepth.SampleDesc.Count = 1; descDepth.SampleDesc.Quality = 0; descDepth.Usage = D3D11_USAGE_DEFAULT; descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; descDepth.CPUAccessFlags = 0; descDepth.MiscFlags = 0; hr = g_pd3dDevice->CreateTexture2D(&descDepth, nullptr, &g_pDepthStencil); if (FAILED(hr)) return hr; // Create the depth stencil view D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; ZeroMemory(&descDSV, sizeof(descDSV)); descDSV.Format = descDepth.Format; descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; descDSV.Texture2D.MipSlice = 0; hr = g_pd3dDevice->CreateDepthStencilView(g_pDepthStencil, &descDSV, &g_pDepthStencilView); if (FAILED(hr)) return hr; g_pImmediateContext->OMSetRenderTargets(1, &g_pRenderTargetView, g_pDepthStencilView); // Setup the viewport D3D11_VIEWPORT vp; vp.Width = (FLOAT)width; vp.Height = (FLOAT)height; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; g_pImmediateContext->RSSetViewports(1, &vp); // If PREBUILD_SHADER is defined, then the shaders are compiled at build time. // If PREBUILD_SHADER is not defined, the shaders are compiled at run time. #pragma region Shader compilation logic // Vertex shader ID3DBlob* pVSBlob = nullptr; #ifdef PREBUILD_SHADER // Create the vertex shader from precompiled cso file. hr = D3DReadFileToBlob(L"vs.cso", &pVSBlob); if (SUCCEEDED(hr)) g_pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &g_pVertexShader); #else // Compile the vertex shader hr = CompileShaderFromFile(L"vs.fx", "VS", "vs_4_0", &pVSBlob); if (FAILED(hr)) { MessageBox(nullptr, L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK); return hr; } // Create the vertex shader hr = g_pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &g_pVertexShader); #endif if (FAILED(hr)) { if (pVSBlob) pVSBlob->Release(); return hr; } // Define the 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 }, }; UINT numElements = ARRAYSIZE(layout); // Create the input layout hr = g_pd3dDevice->CreateInputLayout(layout, numElements, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &g_pVertexLayout); pVSBlob->Release(); if (FAILED(hr)) return hr; // Set the input layout g_pImmediateContext->IASetInputLayout(g_pVertexLayout); // Compile the pixel shader ID3DBlob* pPSBlob = nullptr; #ifdef PREBUILD_SHADER // Create the vertex shader from precompiled cso file. hr = D3DReadFileToBlob(L"ps.cso", &pPSBlob); if (SUCCEEDED(hr)) g_pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &g_pPixelShader); #else hr = CompileShaderFromFile(L"ps.fx", "PS", "ps_4_0", &pPSBlob); if (FAILED(hr)) { MessageBox(nullptr, L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK); return hr; } // Create the pixel shader hr = g_pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &g_pPixelShader); #endif pPSBlob->Release(); if (FAILED(hr)) return hr; #pragma endregion // Create vertex buffer SimpleVertex vertices[] = { { XMFLOAT3(-1.0f, 1.0f, -1.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) }, { XMFLOAT3(1.0f, 1.0f, -1.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) }, { XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) }, { XMFLOAT3(-1.0f, 1.0f, 1.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) }, { XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f) }, { XMFLOAT3(1.0f, -1.0f, -1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) }, { XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) }, { XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f) }, }; D3D11_BUFFER_DESC bd; ZeroMemory(&bd, sizeof(bd)); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof(SimpleVertex) * 8; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA InitData; ZeroMemory(&InitData, sizeof(InitData)); InitData.pSysMem = vertices; hr = g_pd3dDevice->CreateBuffer(&bd, &InitData, &g_pVertexBuffer); if (FAILED(hr)) return hr; // Set vertex buffer UINT stride = sizeof(SimpleVertex); UINT offset = 0; g_pImmediateContext->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset); // Create index buffer WORD indices[] = { 3, 1, 0, 2, 1, 3, 0, 5, 4, 1, 5, 0, 3, 4, 7, 0, 4, 3, 1, 6, 5, 2, 6, 1, 2, 7, 6, 3, 7, 2, 6, 4, 5, 7, 4, 6, }; bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof(WORD) * 36; // 36 vertices needed for 12 triangles in a triangle list bd.BindFlags = D3D11_BIND_INDEX_BUFFER; bd.CPUAccessFlags = 0; InitData.pSysMem = indices; hr = g_pd3dDevice->CreateBuffer(&bd, &InitData, &g_pIndexBuffer); if (FAILED(hr)) return hr; // Set index buffer g_pImmediateContext->IASetIndexBuffer(g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0); // Set primitive topology g_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // Create the constant buffer bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof(ConstantBuffer); bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bd.CPUAccessFlags = 0; hr = g_pd3dDevice->CreateBuffer(&bd, nullptr, &g_pConstantBuffer); if (FAILED(hr)) return hr; // Initialize the world matrix g_World = XMMatrixIdentity(); // Initialize the view matrix XMVECTOR Eye = XMVectorSet(0.0f, 0.0f, -3.0f, 0.0f); XMVECTOR At = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f); XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); g_View = XMMatrixLookAtLH(Eye, At, Up); // Initialize the projection matrix g_Projection = XMMatrixPerspectiveFovLH(XM_PIDIV2, width / (FLOAT)height, 0.01f, 100.0f); return S_OK; }
bool RendererDX11::LoadContent(HWND windowHandle) { assert(m_d3dDevice); InitFractalCube(startSize, DirectX::XMFLOAT3(0.0f, 0.0f, 0.0f), DirectX::XMFLOAT3(0.0f, 0.0f, 0.0f), 0); for (auto i = 0; i < m_meshes.size(); ++i) { m_meshes[i]->InitializeBuffers(m_d3dDevice); } m_camera = Camera(); HRESULT hr; // Load the compiled vertex shader. ID3DBlob* vertexShaderBlob; LPCWSTR compiledVertexShaderObject = L"SimpleVertexShader.cso"; // Load the compiled pixel shader. ID3DBlob* pixelShaderBlob; LPCWSTR compiledPixelShaderObject = L"SimplePixelShader.cso"; hr = D3DReadFileToBlob(compiledVertexShaderObject, &vertexShaderBlob); if (FAILED(hr)) { return false; } hr = D3DReadFileToBlob(compiledPixelShaderObject, &pixelShaderBlob); if (FAILED(hr)) { return false; } hr = m_d3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, &m_d3dVertexShader); if (FAILED(hr)) { return false; } hr = m_d3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), nullptr, &m_d3dPixelShader); if (FAILED(hr)) { return false; } // Create the input layout for the vertex shader. D3D11_INPUT_ELEMENT_DESC vertexLayoutDesc[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(VertexPosColor,Position), D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(VertexPosColor,Color), D3D11_INPUT_PER_VERTEX_DATA, 0 } }; hr = m_d3dDevice->CreateInputLayout(vertexLayoutDesc, _countof(vertexLayoutDesc), vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &m_d3dInputLayout); if (FAILED(hr)) { return false; } SafeRelease(vertexShaderBlob); SafeRelease(pixelShaderBlob); // Create the constant buffers for the variables defined in the vertex shader. D3D11_BUFFER_DESC constantBufferDesc; ZeroMemory(&constantBufferDesc, sizeof(D3D11_BUFFER_DESC)); constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; constantBufferDesc.ByteWidth = sizeof(DirectX::XMMATRIX); constantBufferDesc.CPUAccessFlags = 0; constantBufferDesc.Usage = D3D11_USAGE_DEFAULT; hr = m_d3dDevice->CreateBuffer(&constantBufferDesc, nullptr, &m_d3dConstantBuffers[CB_Appliation]); if (FAILED(hr)) { return false; } hr = m_d3dDevice->CreateBuffer(&constantBufferDesc, nullptr, &m_d3dConstantBuffers[CB_Frame]); if (FAILED(hr)) { return false; } hr = m_d3dDevice->CreateBuffer(&constantBufferDesc, nullptr, &m_d3dConstantBuffers[CB_Object]); if (FAILED(hr)) { return false; } // Setup the projection matrix. RECT clientRect; GetClientRect(windowHandle, &clientRect); // Compute the exact client dimensions. // This is required for a correct projection matrix. float clientWidth = static_cast<float>(clientRect.right - clientRect.left); float clientHeight = static_cast<float>(clientRect.bottom - clientRect.top); m_projectionMatrix = DirectX::XMMatrixPerspectiveFovLH(DirectX::XMConvertToRadians(45.0f), clientWidth / clientHeight, 0.1f, 100.0f); m_d3dDeviceContext->UpdateSubresource(m_d3dConstantBuffers[CB_Appliation], 0, nullptr, &m_projectionMatrix, 0, 0); return true; }
bool D3DClass::Initialize(int screenHeight, int screenWidth, HWND hwnd, bool vsync, bool fullscreen) { D3D_FEATURE_LEVEL featureLevel; HRESULT result; D3D12_COMMAND_QUEUE_DESC commandQueueDesc; IDXGIFactory4* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator, renderTargetViewDescriptorSize; unsigned long long stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; DXGI_SWAP_CHAIN_DESC swapChainDesc; IDXGISwapChain* swapChain; D3D12_DESCRIPTOR_HEAP_DESC renderTargetViewHeapDesc; D3D12_CPU_DESCRIPTOR_HANDLE renderTargetViewHandle; // Store the vsync setting. m_vsync_enabled = vsync; // Set the feature level to DirectX 12.1 to enable using all the DirectX 12 features. // Note: Not all cards support full DirectX 12, this feature level may need to be reduced on some cards to 12.0. featureLevel = D3D_FEATURE_LEVEL_11_0; // Create the Direct3D 12 device. result = D3D12CreateDevice(NULL, featureLevel, __uuidof(ID3D12Device), (void**)&m_device); if (FAILED(result)) { MessageBox(hwnd, L"Could not create a DirectX 12.1 device. The default video card does not support DirectX 12.1.", L"DirectX Device Failure", MB_OK); return false; } // Initialize the description of the command queue. ZeroMemory(&commandQueueDesc, sizeof(commandQueueDesc)); // Set up the description of the command queue. commandQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; commandQueueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL; commandQueueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; commandQueueDesc.NodeMask = 0; // Create the command queue. m_device->CreateCommandQueue(&commandQueueDesc, __uuidof(ID3D12CommandQueue), (void**)&m_commandQueue); // Create a DirectX graphics interface factory. CreateDXGIFactory1(__uuidof(IDXGIFactory4), (void**)&factory); // Use the factory to create an adapter for the primary graphics interface (video card). factory->EnumAdapters(0, &adapter); // Enumerate the primary adapter output (monitor). adapter->EnumOutputs(0, &adapterOutput); // Get the number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor). adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); // Create a list to hold all the possible display modes for this monitor/video card combination. displayModeList = new DXGI_MODE_DESC[numModes]; // Now fill the display mode list structures. adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); // Now go through all the display modes and find the one that matches the screen height and width. // When a match is found store the numerator and denominator of the refresh rate for that monitor. for (i = 0; i<numModes; i++) { if (displayModeList[i].Height == (unsigned int)screenHeight) { if (displayModeList[i].Width == (unsigned int)screenWidth) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } // Get the adapter (video card) description. adapter->GetDesc(&adapterDesc); // Store the dedicated video card memory in megabytes. m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // Convert the name of the video card to a character array and store it. wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); // Release the display mode list. delete[] displayModeList; displayModeList = nullptr; // Release the adapter output. adapterOutput->Release(); adapterOutput = nullptr; // Release the adapter. adapter->Release(); adapter = nullptr; // Initialize the swap chain description. ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); // Set the swap chain to use double buffering. swapChainDesc.BufferCount = 2; // Set the height and width of the back buffers in the swap chain. swapChainDesc.BufferDesc.Height = screenHeight; swapChainDesc.BufferDesc.Width = screenWidth; // Set a regular 32-bit surface for the back buffers. swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Set the usage of the back buffers to be render target outputs. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // Set the swap effect to discard the previous buffer contents after swapping. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; // Set the handle for the window to render to. swapChainDesc.OutputWindow = hwnd; // Set to full screen or windowed mode. swapChainDesc.Windowed = !fullscreen; // Set the refresh rate of the back buffer. if (m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } // Turn multisampling off. swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; // Set the scan line ordering and scaling to unspecified. swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // Don't set the advanced flags. swapChainDesc.Flags = 0; // Finally create the swap chain using the swap chain description. factory->CreateSwapChain(m_commandQueue, &swapChainDesc, &swapChain); // Next upgrade the IDXGISwapChain to a IDXGISwapChain3 interface and store it in a private member variable named m_swapChain. // This will allow us to use the newer functionality such as getting the current back buffer index. swapChain->QueryInterface(__uuidof(IDXGISwapChain3), (void**)&m_swapChain); // Clear pointer to original swap chain interface since we are using version 3 instead (m_swapChain). swapChain = nullptr; // Release the factory now that the swap chain has been created. factory->Release(); factory = nullptr; // Initialize the render target view heap description for the two back buffers. ZeroMemory(&renderTargetViewHeapDesc, sizeof(renderTargetViewHeapDesc)); // Set the number of descriptors to two for our two back buffers. Also set the heap tyupe to render target views. renderTargetViewHeapDesc.NumDescriptors = 2; renderTargetViewHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; renderTargetViewHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; // Create the render target view heap for the back buffers. m_device->CreateDescriptorHeap(&renderTargetViewHeapDesc, __uuidof(ID3D12DescriptorHeap), (void**)&m_renderTargetViewHeap); // Get a handle to the starting memory location in the render target view heap to identify where the render target views will be located for the two back buffers. renderTargetViewHandle = m_renderTargetViewHeap->GetCPUDescriptorHandleForHeapStart(); // Get the size of the memory location for the render target view descriptors. renderTargetViewDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); // Get a pointer to the first back buffer from the swap chain. m_swapChain->GetBuffer(0, __uuidof(ID3D12Resource), (void**)&m_backBufferRenderTarget[0]); // Create a render target view for the first back buffer. m_device->CreateRenderTargetView(m_backBufferRenderTarget[0], NULL, renderTargetViewHandle); // Increment the view handle to the next descriptor location in the render target view heap. renderTargetViewHandle.ptr += renderTargetViewDescriptorSize; // Get a pointer to the second back buffer from the swap chain. m_swapChain->GetBuffer(1, __uuidof(ID3D12Resource), (void**)&m_backBufferRenderTarget[1]); // Create a render target view for the second back buffer. m_device->CreateRenderTargetView(m_backBufferRenderTarget[1], NULL, renderTargetViewHandle); // Finally get the initial index to which buffer is the current back buffer. m_bufferIndex = m_swapChain->GetCurrentBackBufferIndex(); // Create a command allocator. m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(ID3D12CommandAllocator), (void**)&m_commandAllocator); // Create a fence for GPU synchronization. m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence), (void**)&m_fence); // Create an event object for the fence. m_fenceEvent = CreateEvent(nullptr, false, false, nullptr); // Initialize the starting fence value. m_fenceValue = 1; CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc; rootSignatureDesc.Init(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); ID3DBlob* signature; ID3DBlob* error; D3D12SerializeRootSignature( &rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error); m_device->CreateRootSignature( 0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature)); //Create pipeline state, load and compiler shaders. //Note here to change D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION for debug UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; D3DReadFileToBlob(L"DefaultVS.cso", &m_vertexShader); D3DReadFileToBlob(L"DefaultHS.cso", &m_hullShader); D3DReadFileToBlob(L"DefaultDS.cso", &m_domainShader); D3DReadFileToBlob(L"DefaultPS.cso", &m_pixelShader); std::array<D3D12_INPUT_ELEMENT_DESC, 2> inputElementDescs = { D3D12_INPUT_ELEMENT_DESC{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, D3D12_INPUT_ELEMENT_DESC{ "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } }; D3D12_GRAPHICS_PIPELINE_STATE_DESC pipelineDesc = {}; pipelineDesc.InputLayout = { inputElementDescs.data() , (UINT)inputElementDescs.size() }; pipelineDesc.pRootSignature = m_rootSignature; pipelineDesc.VS = { m_vertexShader->GetBufferPointer(), m_vertexShader->GetBufferSize() }; pipelineDesc.PS = { m_pixelShader->GetBufferPointer(), m_pixelShader->GetBufferSize() }; pipelineDesc.HS = { m_hullShader->GetBufferPointer(), m_hullShader->GetBufferSize() }; pipelineDesc.DS = { m_domainShader->GetBufferPointer(), m_domainShader->GetBufferSize() }; pipelineDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT_WIREFRAME); pipelineDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); pipelineDesc.DepthStencilState.DepthEnable = false; pipelineDesc.DepthStencilState.StencilEnable = false; pipelineDesc.SampleMask = UINT_MAX; pipelineDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH; pipelineDesc.NumRenderTargets = 1; pipelineDesc.RTVFormats[0] = DXGI_FORMAT_B8G8R8A8_UNORM; pipelineDesc.SampleDesc.Count = 1; m_device->CreateGraphicsPipelineState(&pipelineDesc, IID_PPV_ARGS(&m_pipelineState)); // Create a basic command list. m_device->CreateCommandList( 0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator, m_pipelineState, IID_PPV_ARGS(&m_commandList)); // Initially we need to close the command list during initialization as it is created in a recording state. m_commandList->Close(); Vertex triangleVertices[] = { { { 0.0f, 0.5f, 0.f }, { 1.f, 0.f, 0.f, 1.f } }, { { 0.5f, -0.5f, 0.f },{ 0.f, 1.f, 0.f, 1.f } }, { { -0.5f, -0.5f, 0.f },{ 0.f, 0.f, 1.f, 1.f } }, }; const UINT vertexBufferSize = sizeof(triangleVertices); m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_vertexBuffer)); UINT8* pVertexDataBegin; CD3DX12_RANGE readRange(0, 0); m_vertexBuffer->Map(0, &readRange, reinterpret_cast<void**>(&pVertexDataBegin)); memcpy(pVertexDataBegin, triangleVertices, vertexBufferSize); m_vertexBuffer->Unmap(0, nullptr); m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress(); m_vertexBufferView.StrideInBytes = sizeof(Vertex); m_vertexBufferView.SizeInBytes = vertexBufferSize; m_viewport.Height = screenHeight; m_viewport.Width = screenWidth; m_viewport.MaxDepth = 1000.f; m_viewport.MinDepth = 0.1f; m_viewport.TopLeftX = 0.f; m_viewport.TopLeftY = 0.f; m_scissorRect.left = 0; m_scissorRect.right = screenWidth; m_scissorRect.top = 0; m_scissorRect.bottom = screenHeight; unsigned long long fenceToWaitFor = m_fenceValue; m_commandQueue->Signal(m_fence, fenceToWaitFor); m_fenceValue++; // Wait until the GPU is done rendering. if (m_fence->GetCompletedValue() < fenceToWaitFor) { m_fence->SetEventOnCompletion(fenceToWaitFor, m_fenceEvent); WaitForSingleObject(m_fenceEvent, INFINITE); } return true; }
HRESULT Shader::CreateFromFile(const ShaderDesc& shaderDesc, const std::wstring& filename) { m_shaderDesc = shaderDesc; std::wstring filename_sourceCode = filename + L".hlsl"; std::wstring filename_byteCode = filename + L".csa"; UINT compilerFlags = 0; #if defined(_DEBUG) compilerFlags |= D3DCOMPILE_DEBUG; #endif const Renderer* pRenderer = Renderer::Get(); // Ladda källkoden. std::ifstream file(filename_sourceCode); if (!file.is_open()) { MessageBox(nullptr, L"Could not open shader file.", nullptr, MB_ICONERROR); return EXIT_FAILURE; } std::string buffer, data; while (std::getline(file, buffer)) data += buffer + "\n"; file.close(); //MessageBoxA(nullptr, data.c_str(), nullptr, MB_ICONINFORMATION); // // Kompilera vertex-shadern. // CComPtr<ID3DBlob> pVSBlob = nullptr; //if (!FileSystem::FileExists("AmbientOcclusion\\Shader.vs")) if (true) { std::cout << "Compiling vertex shader..." << std::endl; // Kompilera vertex-shadern. CComPtr<ID3DBlob> pErrors = nullptr; HRESULT hr = D3DCompile2(data.c_str(), data.length(), nullptr, nullptr, nullptr, "VS", "vs_5_0", compilerFlags, 0, 0, nullptr, 0, &pVSBlob, &pErrors); if (pErrors) { std::stringstream ss; ss << "Shader errors:\n\n"; ss << (const char*)pErrors->GetBufferPointer(); MessageBoxA(nullptr, ss.str().c_str(), nullptr, MB_ICONERROR); return EXIT_FAILURE; } if (pVSBlob == nullptr) { MessageBox(nullptr, L"Could not compile vertex shader. Dunno why.", nullptr, MB_ICONERROR); return EXIT_FAILURE; } // Spara maskinkoden till en fil så vi slipper kompilera om och om och om och om och om och om och om och om igen. D3DWriteBlobToFile(pVSBlob, L"AmbientOcclusion\\Shader.vs", TRUE); CComPtr<ID3DBlob> pVSDebugInfo = nullptr; D3DGetDebugInfo(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &pVSDebugInfo); if (pVSDebugInfo) { std::cout << "Vertex shader debug info:" << std::endl << (const char*)pVSDebugInfo->GetBufferPointer() << std::endl; } } else { std::cout << "Loading vertex shader from file..." << std::endl; // Ladda maskinkoden till blobben. D3DReadFileToBlob(L"AmbientOcclusion\\Shader.vs", &pVSBlob); } // Skapa vertex-shadern. HR(pRenderer->GetD3DDevice()->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &m_pVS)); // Skapa input-layouten. HRESULT hr = pRenderer->GetD3DDevice()->CreateInputLayout(&m_shaderDesc.vertexElementDescs[0], (UINT)m_shaderDesc.vertexElementDescs.size(), pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &m_pInputLayout); if (hr == E_INVALIDARG) { MessageBox(nullptr, L"Din vertex-layout ser inte ut som den gör i shaderfilen.", nullptr, MB_ICONERROR); return hr; } HR(hr); // // Kompilera pixel-shadern. // CComPtr<ID3DBlob> pPSBlob = nullptr; //if (!FileSystem::FileExists("AmbientOcclusion\\Shader.ps")) if (true) { std::cout << "Compiling pixel shader..." << std::endl; CComPtr<ID3DBlob> pErrors = nullptr; HRESULT hr = D3DCompile2(data.c_str(), data.length(), nullptr, nullptr, nullptr, "PS", "ps_5_0", compilerFlags, 0, 0, nullptr, 0, &pPSBlob, &pErrors); if (pErrors) { std::stringstream ss; ss << "Shader errors:\n\n"; ss << (const char*)pErrors->GetBufferPointer(); MessageBoxA(nullptr, ss.str().c_str(), nullptr, MB_ICONERROR); return EXIT_FAILURE; } if (pPSBlob == nullptr) { MessageBox(nullptr, L"Could not compile pixel shader. Dunno why.", nullptr, MB_ICONERROR); return EXIT_FAILURE; } // Spara maskinkoden till en fil så vi slipper kompilera om och om igen. D3DWriteBlobToFile(pPSBlob, L"AmbientOcclusion\\Shader.ps", TRUE); CComPtr<ID3DBlob> pPSDebugInfo = nullptr; D3DGetDebugInfo(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), &pPSDebugInfo); if (pPSDebugInfo) { std::cout << "Pixel shader debug info:" << std::endl << (const char*)pPSDebugInfo->GetBufferPointer() << std::endl; pPSDebugInfo = nullptr; } } else { std::cout << "Loading pixel shader from file..." << std::endl; // Ladda maskinkoden till blobben. D3DReadFileToBlob(L"AmbientOcclusion\\Shader.ps", &pPSBlob); } HR(pRenderer->GetD3DDevice()->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &m_pPS)); // Skapa pixel-shadern. pPSBlob = nullptr; // Skapa konstantbuffertarna. m_constantBufferCount = (UINT)m_shaderDesc.constantBufferDescs.size(); m_pConstantBuffers = new ID3D11Buffer*[m_constantBufferCount]; for (unsigned int i = 0; i < m_constantBufferCount; i++) { D3D11_BUFFER_DESC cbd = { }; cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; cbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; cbd.ByteWidth = Singe::Math::RoundUp(m_shaderDesc.constantBufferDescs[i].constantBufferSize, 16); cbd.Usage = D3D11_USAGE_DYNAMIC; HR(pRenderer->GetD3DDevice()->CreateBuffer(&cbd, nullptr, &m_pConstantBuffers[i])); D3D11_MAPPED_SUBRESOURCE ms = { }; HR(pRenderer->GetD3DImmediateContext()->Map(m_pConstantBuffers[i], 0, D3D11_MAP_WRITE_DISCARD, 0, &ms)); pRenderer->GetD3DImmediateContext()->Unmap(m_pConstantBuffers[i], 0); } static const unsigned int MAX_VERTICES = 10000; static const unsigned int MAX_INDICES = 10000; m_pVertexData = new unsigned char[MAX_VERTICES * m_shaderDesc.vertexDataStride]; // Skapa vertexbufferten. D3D11_BUFFER_DESC vbd = { }; vbd.Usage = D3D11_USAGE_DEFAULT; vbd.ByteWidth = sizeof(m_shaderDesc.vertexDataStride) * MAX_VERTICES; vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER; HR(pRenderer->GetD3DDevice()->CreateBuffer(&vbd, nullptr, &m_pVertexBuffer)); // Skapa den sekundära vertexbufferten. D3D11_BUFFER_DESC vbsd = { }; vbsd.Usage = D3D11_USAGE_STAGING; vbsd.ByteWidth = sizeof(m_shaderDesc.vertexDataStride) * MAX_VERTICES; vbsd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; HR(pRenderer->GetD3DDevice()->CreateBuffer(&vbsd, nullptr, &m_pVertexBufferStaging)); // Skapa indexbufferten. D3D11_BUFFER_DESC ibd = { }; ibd.Usage = D3D11_USAGE_DEFAULT; ibd.ByteWidth = sizeof(UINT) * MAX_INDICES; ibd.BindFlags = D3D11_BIND_INDEX_BUFFER; HR(pRenderer->GetD3DDevice()->CreateBuffer(&ibd, nullptr, &m_pIndexBuffer)); // Skapa den sekundära indexbufferten. D3D11_BUFFER_DESC ibsd = { }; ibsd.Usage = D3D11_USAGE_STAGING; ibsd.ByteWidth = sizeof(UINT) * MAX_VERTICES; ibsd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; HR(pRenderer->GetD3DDevice()->CreateBuffer(&ibsd, nullptr, &m_pIndexBufferStaging)); return EXIT_SUCCESS; }
// // Load unique Content. // bool DirectXClass::LoadContent() { HRESULT hr = S_OK; // // Create the shared vertex buffer // D3D11_BUFFER_DESC sbd; ZeroMemory(&sbd, sizeof(D3D11_BUFFER_DESC)); sbd.Usage = D3D11_USAGE_DEFAULT; sbd.ByteWidth = sizeof(TerrainVertex) * TOTAL_GRID_POINTS; sbd.BindFlags = D3D11_BIND_VERTEX_BUFFER; sbd.CPUAccessFlags = 0; sbd.MiscFlags = 0; hr = m_3dDevice->CreateBuffer(&sbd, NULL, &m_VertexBuffer); //Empty buffer, no data if (FAILED(hr)) return false; // // Create the shared index buffer. // D3D11_BUFFER_DESC indexBufferDesc; ZeroMemory(&indexBufferDesc, sizeof(D3D11_BUFFER_DESC)); indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; indexBufferDesc.ByteWidth = sizeof(int) * NUM_INDICES; indexBufferDesc.CPUAccessFlags = 0; indexBufferDesc.Usage = D3D11_USAGE_DEFAULT; hr = m_3dDevice->CreateBuffer(&indexBufferDesc, NULL, &m_IndexBuffer); //Empty buffer, no data if (FAILED(hr)) return false; // // Create Constant buffers // D3D11_BUFFER_DESC constantBufferDesc; ZeroMemory(&constantBufferDesc, sizeof(D3D11_BUFFER_DESC)); constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; constantBufferDesc.ByteWidth = sizeof(XMMATRIX); constantBufferDesc.CPUAccessFlags = 0; constantBufferDesc.Usage = D3D11_USAGE_DEFAULT; hr = m_3dDevice->CreateBuffer(&constantBufferDesc, nullptr, &g_d3dConstantBuffers[CB_Application]); if (FAILED(hr)) return false; hr = m_3dDevice->CreateBuffer(&constantBufferDesc, nullptr, &g_d3dConstantBuffers[CB_Frame]); if (FAILED(hr)) return false; hr = m_3dDevice->CreateBuffer(&constantBufferDesc, nullptr, &g_d3dConstantBuffers[CB_Object]); if (FAILED(hr)) return false; // // Load the compiled vertex shader. // ID3DBlob* vertexShaderBlob; #if _DEBUG LPCWSTR compiledVertexShaderObject = L"VertexShader_d.cso"; #else LPCWSTR compiledVertexShaderObject = L"VertexShader.cso"; #endif hr = D3DReadFileToBlob(compiledVertexShaderObject, &vertexShaderBlob); if (FAILED(hr)) return false; hr = m_3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, &m_VertexShader); if (FAILED(hr)) return false; // // Create the input layout for the vertex shader. // D3D11_INPUT_ELEMENT_DESC vertexLayoutDesc[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(TerrainVertex, Position), D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(TerrainVertex, Normal),D3D11_INPUT_PER_VERTEX_DATA, 0 } }; hr = m_3dDevice->CreateInputLayout(vertexLayoutDesc, _countof(vertexLayoutDesc), vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &m_InputLayout); if (FAILED(hr)) return false; vertexShaderBlob->Release(); // // Load the compiled pixel shader. // ID3DBlob* pixelShaderBlob; #if _DEBUG LPCWSTR compiledPixelShaderObject = L"PixelShader_d.cso"; #else LPCWSTR compiledPixelShaderObject = L"PixelShader.cso"; #endif hr = D3DReadFileToBlob(compiledPixelShaderObject, &pixelShaderBlob); if (FAILED(hr)) return false; hr = m_3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), nullptr, &m_PixelShader); if (FAILED(hr)) return false; pixelShaderBlob->Release(); // // Setup the projection matrix. // RECT clientRect; GetClientRect(m_windowHandel, &clientRect); // Compute the exact client dimensions. // This is required for a correct projection matrix. float clientWidth = static_cast<float>(clientRect.right - clientRect.left); float clientHeight = static_cast<float>(clientRect.bottom - clientRect.top); m_ProjectionMatrix = XMMatrixPerspectiveFovLH(XMConvertToRadians(45.0f), clientWidth / clientHeight, 0.1f, 150.0f); m_3dDeviceContext->UpdateSubresource(g_d3dConstantBuffers[CB_Application], 0, nullptr, &m_ProjectionMatrix, 0, 0); return true; }