void SaveTextureAsDDS(ID3D11Resource* texture, const wchar* filePath) { ID3D11DevicePtr device; texture->GetDevice(&device); ID3D11DeviceContextPtr context; device->GetImmediateContext(&context); ScratchImage scratchImage; DXCall(CaptureTexture(device, context, texture, scratchImage)); DXCall(SaveToDDSFile(scratchImage.GetImages(), scratchImage.GetImageCount(), scratchImage.GetMetadata(), DDS_FLAGS_FORCE_DX10_EXT, filePath)); }
void SaveTextureAsPNG(ID3D11Resource* texture, const wchar* filePath) { ID3D11DevicePtr device; texture->GetDevice(&device); ID3D11DeviceContextPtr context; device->GetImmediateContext(&context); ScratchImage scratchImage; DXCall(CaptureTexture(device, context, texture, scratchImage)); DXCall(SaveToWICFile(scratchImage.GetImages(), scratchImage.GetImageCount(), WIC_FLAGS_NONE, GetWICCodec(WIC_CODEC_PNG), filePath)); }
DX11LightAccumulationbuffer::DX11LightAccumulationbuffer(ID3D11DevicePtr device, ID3D11DeviceContextPtr context, D3D11_TEXTURE2D_DESC backbufferTextureDesc) : mContext(context), mAccumulationTexture(nullptr), mRTV(nullptr), mSRV(nullptr) { backbufferTextureDesc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; backbufferTextureDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT; // create acc texture/rtv/srv DXCALL(device->CreateTexture2D(&backbufferTextureDesc, NULL, &mAccumulationTexture)); DXCALL(device->CreateRenderTargetView(mAccumulationTexture, nullptr, &mRTV)); DXCALL(device->CreateShaderResourceView(mAccumulationTexture, nullptr, &mSRV)) }
bool Shader::createFromString(std::string vertex, std::string pixel, ID3D11DevicePtr device) { vsBlob = CompileShader(vertex.c_str(), vertex.length(), "vs_5_0"); if (vsBlob == nullptr) return false; auto psBlob = CompileShader(pixel.c_str(), pixel.length(), "ps_5_0"); if (psBlob == nullptr) { return false; } VERIFYDX(device->CreateVertexShader(vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), nullptr, &vertexShader)); VERIFYDX(device->CreatePixelShader(psBlob->GetBufferPointer(), psBlob->GetBufferSize(), nullptr, &pixelShader)); return true; }
DX11PostProcessor::DX11PostProcessor(ID3D11DevicePtr device, ID3D11DeviceContextPtr context, DX11FullscreenTrianglePass& fullscreenPass, D3D11_TEXTURE2D_DESC backbufferTextureDesc) : mContext(context), mFullscreenPass(fullscreenPass), mFXAACBuffer(device, context, mFXAACBuffer.CONSTANT_BUFFER_SLOT_PIXEL), mFXAABackbufferTexture(nullptr), mFXAARTV(nullptr), mFXAASRV(nullptr), mFXAAPixelShader(nullptr) { backbufferTextureDesc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; DXCALL(device->CreateTexture2D(&backbufferTextureDesc, nullptr, &mFXAABackbufferTexture)); DXCALL(device->CreateRenderTargetView(mFXAABackbufferTexture, nullptr, &mFXAARTV)); DXCALL(device->CreateShaderResourceView(mFXAABackbufferTexture, nullptr, &mFXAASRV)); DXCALL(device->CreatePixelShader(gFXAAPixelShader, sizeof(gFXAAPixelShader), nullptr, &mFXAAPixelShader)); }
DX11DirectionalLightPass::DX11DirectionalLightPass(ID3D11DevicePtr device, ID3D11DeviceContextPtr context, DX11FullscreenTrianglePass& fullscreenPass, DX11VertexTransformPass& transformPass, const RenderSettings::ShadowResolution shadowmapRes, const RenderSettings::ShadowReadbackLatency readbackLatency, const uint32_t windowWidth, const uint32_t windowHeight) : mWindowSize(windowWidth, windowHeight), mAspectRatio(mWindowSize.x / mWindowSize.y), mContext(context), mPCF2x2Shader(nullptr), mPCF3x3Shader(nullptr), mPCF5x5Shader(nullptr), mPCF7x7Shader(nullptr), mRSDepthClamp(nullptr), mFullscreenPass(fullscreenPass), mVertexTransformPass(transformPass), mShadowmap(device, context, shadowmapRes, NUM_SHADOWMAP_CASCADES, false), mDirLightCBuffer(device, context, mDirLightCBuffer.CONSTANT_BUFFER_SLOT_PIXEL) { DXCALL(device->CreatePixelShader(gDirectionalLightPCF2X2PixelShader, sizeof(gDirectionalLightPCF2X2PixelShader), nullptr, &mPCF2x2Shader)); DXCALL(device->CreatePixelShader(gDirectionalLightPCF3X3PixelShader, sizeof(gDirectionalLightPCF3X3PixelShader), nullptr, &mPCF3x3Shader)); DXCALL(device->CreatePixelShader(gDirectionalLightPCF5X5PixelShader, sizeof(gDirectionalLightPCF5X5PixelShader), nullptr, &mPCF5x5Shader)); DXCALL(device->CreatePixelShader(gDirectionalLightPCF7X7PixelShader, sizeof(gDirectionalLightPCF7X7PixelShader), nullptr, &mPCF7x7Shader)); // depth clamp to avoid meshes between frustrum split issues D3D11_RASTERIZER_DESC rasterizerDesc; ZeroMemory(&rasterizerDesc, sizeof(D3D11_RASTERIZER_DESC)); rasterizerDesc.FillMode = D3D11_FILL_SOLID; rasterizerDesc.CullMode = D3D11_CULL_BACK; rasterizerDesc.FrontCounterClockwise = true; rasterizerDesc.SlopeScaledDepthBias = 1.0f; rasterizerDesc.DepthBiasClamp = 1.0f; rasterizerDesc.DepthClipEnable = false; rasterizerDesc.ScissorEnable = false; rasterizerDesc.MultisampleEnable = false; rasterizerDesc.AntialiasedLineEnable = false; DXCALL(device->CreateRasterizerState(&rasterizerDesc, &mRSDepthClamp)); }
DX11Sampler::DX11Sampler(ID3D11DevicePtr device, ID3D11DeviceContextPtr context, const RenderSettings::Anisotropic maxAnisotropy, const D3D11_FILTER filter, const D3D11_TEXTURE_ADDRESS_MODE addressModeU, const D3D11_TEXTURE_ADDRESS_MODE addressModeV, const D3D11_TEXTURE_ADDRESS_MODE addressModeW, const D3D11_COMPARISON_FUNC comparison, const SHADER_SAMPLER_SLOT samplerSlot) : mContext(context), mTextureSampler(nullptr), mAnisotropicFiltering(maxAnisotropy), mSamplerSlot(samplerSlot) { D3D11_SAMPLER_DESC samplerDesc; ZeroMemory(&samplerDesc, sizeof(D3D11_SAMPLER_DESC)); samplerDesc.Filter = filter; samplerDesc.AddressU = addressModeU; samplerDesc.AddressV = addressModeV; samplerDesc.AddressW = addressModeW; samplerDesc.MaxAnisotropy = RenderSettingsToVal(mAnisotropicFiltering); samplerDesc.ComparisonFunc = comparison; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; DXCALL(device->CreateSamplerState(&samplerDesc, &mTextureSampler)); }
DX11TerrainPass::DX11TerrainPass(ID3D11DevicePtr device, ID3D11DeviceContextPtr context, DX11VertexTransformPass& vertexTransformer, const IDMap<DX11Texture>& textureMap, const RenderSettings::Tesselation& tessData) : mContext(context), mCBuffer(device, context, mCBuffer.CONSTANT_BUFFER_SLOT_DOMAIN), mPerTerrainCBuffer(device, context, mPerTerrainCBuffer.CONSTANT_BUFFER_SLOT_EXTRA), mTransformsBuffer(device, context), mQuadMesh(device, context, gQuadVertices, gQuadIndices, AABB::gUnitQuadAABB.Min(), AABB::gUnitQuadAABB.Max()), mVertexTransformer(vertexTransformer), mTextureMap(textureMap), mTessData(tessData) { // input layout // TODO: generalize into one class D3D11_INPUT_ELEMENT_DESC inputDescription[NUM_INPUT_LAYOUTS]; ZeroMemory(&inputDescription, sizeof(D3D11_INPUT_ELEMENT_DESC) * NUM_INPUT_LAYOUTS); inputDescription[VSInputLayout::POSITION].SemanticName = "POSITION"; inputDescription[VSInputLayout::POSITION].SemanticIndex = 0; inputDescription[VSInputLayout::POSITION].Format = DXGI_FORMAT_R32G32B32_FLOAT; inputDescription[VSInputLayout::POSITION].InputSlot = DX11Mesh::VERTEX_BUFFER_SLOT_POSITIONS; inputDescription[VSInputLayout::POSITION].AlignedByteOffset = 0; inputDescription[VSInputLayout::POSITION].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; inputDescription[VSInputLayout::POSITION].InstanceDataStepRate = 0; DXCALL(device->CreateInputLayout(inputDescription, VSInputLayout::NUM_INPUT_LAYOUTS, gTerrainVertexShader, sizeof(gTerrainVertexShader), &mLayout)); // shaders DXCALL(device->CreateVertexShader(gTerrainVertexShader, sizeof(gTerrainVertexShader), nullptr, &mVertexShader)); DXCALL(device->CreateHullShader(gTerrainHullShader, sizeof(gTerrainHullShader), nullptr, &mHullShader)); DXCALL(device->CreateDomainShader(gTerrainDomainShader, sizeof(gTerrainDomainShader), nullptr, &mDomainShader)); DXCALL(device->CreatePixelShader(gTerrainPixelShader, sizeof(gTerrainPixelShader), nullptr, &mPixelShader)); DXCALL( device->CreatePixelShader( gTerrainPixelDebugShader, sizeof( gTerrainPixelDebugShader ), nullptr, &mPixelDebugShader ) ); D3D11_RASTERIZER_DESC rasterizerDesc; ZeroMemory(&rasterizerDesc, sizeof(D3D11_RASTERIZER_DESC)); rasterizerDesc.FillMode = D3D11_FILL_WIREFRAME; rasterizerDesc.CullMode = D3D11_CULL_BACK; rasterizerDesc.FrontCounterClockwise = true; rasterizerDesc.DepthClipEnable = true; rasterizerDesc.ScissorEnable = false; rasterizerDesc.MultisampleEnable = false; rasterizerDesc.AntialiasedLineEnable = false; DXCALL(device->CreateRasterizerState(&rasterizerDesc, &mDebugRasterizer)); }
void D3D11RenderEngine::D3DDevice(ID3D11DevicePtr const & device, ID3D11DeviceContextPtr const & imm_ctx, D3D_FEATURE_LEVEL feature_level) { #if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) is_d3d_11_1_ = false; ID3D11Device1* d3d_device_1; device->QueryInterface(IID_ID3D11Device1, reinterpret_cast<void**>(&d3d_device_1)); if (d3d_device_1) { ID3D11DeviceContext1* d3d_imm_ctx_1; imm_ctx->QueryInterface(IID_ID3D11DeviceContext1, reinterpret_cast<void**>(&d3d_imm_ctx_1)); if (d3d_imm_ctx_1) { d3d_device_ = MakeCOMPtr(d3d_device_1); d3d_imm_ctx_ = MakeCOMPtr(d3d_imm_ctx_1); is_d3d_11_1_ = true; } else { d3d_device_1->Release(); } } if (!is_d3d_11_1_) { d3d_device_ = device; d3d_imm_ctx_ = imm_ctx; } #else d3d_device_ = device; d3d_imm_ctx_ = imm_ctx; #endif d3d_feature_level_ = feature_level; Verify(!!d3d_device_); this->FillRenderDeviceCaps(); }
SH9Color ProjectCubemapToSH9Color(ID3D11DeviceContext* context, ID3D11ShaderResourceView* cubeMap) { ID3D11Texture2DPtr srcTexture; cubeMap->GetResource(reinterpret_cast<ID3D11Resource**>(&srcTexture)); D3D11_TEXTURE2D_DESC srcDesc; srcTexture->GetDesc(&srcDesc); ID3D11DevicePtr device; context->GetDevice(&device); ID3D11Texture2DPtr tempTexture; D3D11_TEXTURE2D_DESC tempDesc = srcDesc; tempDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; tempDesc.MipLevels = 1; tempDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; tempDesc.Usage = D3D11_USAGE_DEFAULT; DXCall(device->CreateTexture2D(&tempDesc, NULL, &tempTexture)); ID3D11UnorderedAccessViewPtr tempUAV; DXCall(device->CreateUnorderedAccessView(tempTexture, NULL, &tempUAV)); ID3D11ShaderResourceViewPtr tempSRV; D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = srcDesc.Format; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; srvDesc.Texture2DArray.MostDetailedMip = 0; srvDesc.Texture2DArray.MipLevels = srcDesc.MipLevels; srvDesc.Texture2DArray.FirstArraySlice = 0; srvDesc.Texture2DArray.ArraySize = 6; DXCall(device->CreateShaderResourceView(srcTexture, &srvDesc, &tempSRV)); static const UINT32 TGSize = 1024; static ID3D11ComputeShaderPtr decodeShader; if(decodeShader.GetInterfacePtr() == NULL) { CompileOptions opts; opts.Add("TGSize_", TGSize); decodeShader.Attach(CompileCSFromFile(device, L"SampleFramework11\\Shaders\\DecodeTextureCS.hlsl", "DecodeTextureCS", "cs_5_0", opts.Defines())); } ID3D11ShaderResourceView* srvs[1] = { tempSRV }; context->CSSetShaderResources(0, 1, srvs); ID3D11UnorderedAccessView* uavs[1] = { tempUAV }; context->CSSetUnorderedAccessViews(0, 1, uavs, NULL); context->CSSetShader(decodeShader, NULL, 0); context->Dispatch(DispatchSize(TGSize, srcDesc.Width), srcDesc.Height, 6); float red[9]; float green[9]; float blue[9]; DXCall(D3DX11SHProjectCubeMap(context, 3, tempTexture, red, green, blue)); SH9Color sh; for(UINT_PTR i = 0; i < 9; ++i) sh.c[i] = XMVectorSet(red[i], green[i], blue[i], 0.0f); return sh; }
DX11Mesh::DX11Mesh(ID3D11DevicePtr device, ID3D11DeviceContextPtr context, const std::vector<float>& vertexData, const std::vector<float>& normalData, const std::vector<float>& texCoords, const std::vector<float>& tangentData, const std::vector<BoneWeight>& boneWeights, const std::vector<uint16_t>& indexData, const Vec3& minBounds, const Vec3& maxBounds) : mContext(context), mVertexBuffer(nullptr), mNormalBuffer(nullptr), mTangentBuffer(nullptr), mTexcoordBuffer(nullptr), mBoneWeightBuffer(nullptr), mIndexBuffer(nullptr), mMeshID(gNextMeshID++), mNumVertices(vertexData.size()), mNumIndices(indexData.size()), mHasBones(!boneWeights.empty()) { // vertex buffer // use a temporary vector to merge vertices and AABB points std::vector<float> tempVertexData(vertexData); AppendAABBVertices(tempVertexData, minBounds, maxBounds); D3D11_BUFFER_DESC bufferDescription; ZeroMemory(&bufferDescription, sizeof(D3D11_BUFFER_DESC)); bufferDescription.Usage = D3D11_USAGE_IMMUTABLE; bufferDescription.ByteWidth = tempVertexData.size() * sizeof(float); bufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER; D3D11_SUBRESOURCE_DATA initData; ZeroMemory(&initData, sizeof(D3D11_SUBRESOURCE_DATA)); initData.pSysMem = &tempVertexData.at(0); DXCALL(device->CreateBuffer(&bufferDescription, &initData, &mVertexBuffer)); // normal buffer if (normalData.size() > 0) { ZeroMemory(&bufferDescription, sizeof(D3D11_BUFFER_DESC)); bufferDescription.Usage = D3D11_USAGE_IMMUTABLE; bufferDescription.ByteWidth = normalData.size() * sizeof(float); bufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER; ZeroMemory(&initData, sizeof(D3D11_SUBRESOURCE_DATA)); initData.pSysMem = &normalData.at(0); DXCALL(device->CreateBuffer(&bufferDescription, &initData, &mNormalBuffer)); } // bitangent/tangent buffer const size_t tangentDataSize = tangentData.size(); if (tangentDataSize > 0) { ZeroMemory(&bufferDescription, sizeof(D3D11_BUFFER_DESC)); bufferDescription.Usage = D3D11_USAGE_IMMUTABLE; bufferDescription.ByteWidth = tangentDataSize * sizeof(float); bufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER; ZeroMemory(&initData, sizeof(D3D11_SUBRESOURCE_DATA)); initData.pSysMem = &tangentData.at(0); DXCALL(device->CreateBuffer(&bufferDescription, &initData, &mTangentBuffer)); } // texcoord buffer if (texCoords.size()) { ZeroMemory(&bufferDescription, sizeof(D3D11_BUFFER_DESC)); bufferDescription.Usage = D3D11_USAGE_IMMUTABLE; bufferDescription.ByteWidth = texCoords.size() * sizeof(float); bufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER; ZeroMemory(&initData, sizeof(D3D11_SUBRESOURCE_DATA)); initData.pSysMem = &texCoords.at(0); DXCALL(device->CreateBuffer(&bufferDescription, &initData, &mTexcoordBuffer)); } // bone indices/weights if (mHasBones) { ZeroMemory(&bufferDescription, sizeof(D3D11_BUFFER_DESC)); bufferDescription.Usage = D3D11_USAGE_IMMUTABLE; bufferDescription.ByteWidth = boneWeights.size() * sizeof(BoneWeight); bufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER; ZeroMemory(&initData, sizeof(D3D11_SUBRESOURCE_DATA)); initData.pSysMem = &boneWeights.at(0); DXCALL(device->CreateBuffer(&bufferDescription, &initData, &mBoneWeightBuffer)); } // index buffer // use a temporary vector to merge vertex indices and AABB indices std::vector<uint16_t> tempIndiceData(indexData); tempIndiceData.insert(tempIndiceData.end(), gAABBIndices.begin(), gAABBIndices.end()); ZeroMemory(&bufferDescription, sizeof(D3D11_BUFFER_DESC)); bufferDescription.Usage = D3D11_USAGE_IMMUTABLE; bufferDescription.ByteWidth = tempIndiceData.size() * sizeof(uint16_t); bufferDescription.BindFlags = D3D11_BIND_INDEX_BUFFER; ZeroMemory(&initData, sizeof(D3D11_SUBRESOURCE_DATA)); initData.pSysMem = &tempIndiceData.at(0); DXCALL(device->CreateBuffer(&bufferDescription, &initData, &mIndexBuffer)); }