std::shared_ptr<GraphicsPipelineState> Device::createGraphicsPipelineState(const GraphicsPipelineStateParams& params) { ID3D11VertexShader* vertexShader = nullptr; if (SUCCEEDED(m_device->CreateVertexShader(params.m_vsParams.m_shaderBytecode, params.m_vsParams.m_bytecodeLength, nullptr, &vertexShader))) { ID3D11ShaderReflection* vertexShaderReflector = nullptr; if (SUCCEEDED(D3DReflect(params.m_vsParams.m_shaderBytecode, params.m_vsParams.m_bytecodeLength, IID_ID3D11ShaderReflection, (void**)&vertexShaderReflector))) { ID3D11PixelShader* pixelShader = nullptr; if (SUCCEEDED(m_device->CreatePixelShader(params.m_psParams.m_shaderBytecode, params.m_psParams.m_bytecodeLength, nullptr, &pixelShader))) { ID3D11ShaderReflection* pixelShaderReflector = nullptr; if (SUCCEEDED(D3DReflect(params.m_psParams.m_shaderBytecode, params.m_psParams.m_bytecodeLength, IID_ID3D11ShaderReflection, (void**)&pixelShaderReflector))) { CD3D11_DEPTH_STENCIL_DESC depthStencilDesc(D3D11_DEFAULT); depthStencilDesc.DepthEnable = params.m_depthStencilParams.m_depthEnable; ID3D11DepthStencilState* depthStencilState = nullptr; if (SUCCEEDED(m_device->CreateDepthStencilState(&depthStencilDesc, &depthStencilState))) { D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; ID3D11InputLayout* inputLayout = nullptr; if (SUCCEEDED(m_device->CreateInputLayout(layout, ARRAYSIZE(layout), params.m_vsParams.m_shaderBytecode, params.m_vsParams.m_bytecodeLength, &inputLayout))) { return std::make_shared<GraphicsPipelineState>(vertexShader, vertexShaderReflector, pixelShader, pixelShaderReflector, depthStencilState, params.m_stencilRef, inputLayout, params.m_primitiveTopologyType); } depthStencilState->Release(); } pixelShaderReflector->Release(); } pixelShader->Release(); } vertexShaderReflector->Release(); } vertexShader->Release(); } return nullptr; }
int Release() { if (VS) VS->Release(); if (PS) PS->Release(); if (inputLayout) inputLayout->Release(); if (vertexBuffer) vertexBuffer->Release(); return 0; }
_Use_decl_annotations_ void DGSLEffectFactory::Impl::CreatePixelShader( const WCHAR* name, ID3D11PixelShader** pixelShader ) { if ( !name || !pixelShader ) throw std::exception("invalid arguments"); auto it = mShaderCache.find( name ); if ( mSharing && it != mShaderCache.end() ) { ID3D11PixelShader* ps = it->second.Get(); ps->AddRef(); *pixelShader = ps; } else { WCHAR fullName[MAX_PATH]={0}; wcscpy_s( fullName, mPath ); wcscat_s( fullName, name ); size_t dataSize = 0; std::unique_ptr<uint8_t[]> data; HRESULT hr = BinaryReader::ReadEntireFile( fullName, data, &dataSize ); if ( FAILED(hr) ) { DebugTrace( "CreatePixelShader failed (%08X) to load shader file '%ls'\n", hr, fullName ); throw std::exception( "CreatePixelShader" ); } ThrowIfFailed( device->CreatePixelShader( data.get(), dataSize, nullptr, pixelShader ) ); _Analysis_assume_(*pixelShader != 0); if ( mSharing && *name && it == mShaderCache.end() ) { std::lock_guard<std::mutex> lock(mutex); mShaderCache.insert( ShaderCache::value_type( name, *pixelShader ) ); } } }
// Create pixel shaders HRESULT CFW1GlyphRenderStates::createPixelShaders() { // Pixel shader const char psStr[] = "SamplerState sampler0 : register(s0);\r\n" "Texture2D<float> tex0 : register(t0);\r\n" "\r\n" "struct PSIn {\r\n" " float4 Position : SV_Position;\r\n" " float4 GlyphColor : COLOR;\r\n" " float2 TexCoord : TEXCOORD;\r\n" "};\r\n" "\r\n" "float4 PS(PSIn Input) : SV_Target {\r\n" " float a = tex0.Sample(sampler0, Input.TexCoord);\r\n" " \r\n" " if(a == 0.0f)\r\n" " discard;\r\n" " \r\n" " return (a * Input.GlyphColor.a) * float4(Input.GlyphColor.rgb, 1.0f);\r\n" "}\r\n" ""; // Clipping pixel shader const char psClipStr[] = "SamplerState sampler0 : register(s0);\r\n" "Texture2D<float> tex0 : register(t0);\r\n" "\r\n" "struct PSIn {\r\n" " float4 Position : SV_Position;\r\n" " float4 GlyphColor : COLOR;\r\n" " float2 TexCoord : TEXCOORD;\r\n" " float4 ClipDistance : CLIPDISTANCE;\r\n" "};\r\n" "\r\n" "float4 PS(PSIn Input) : SV_Target {\r\n" " clip(Input.ClipDistance);\r\n" " \r\n" " float a = tex0.Sample(sampler0, Input.TexCoord);\r\n" " \r\n" " if(a == 0.0f)\r\n" " discard;\r\n" " \r\n" " return (a * Input.GlyphColor.a) * float4(Input.GlyphColor.rgb, 1.0f);\r\n" "}\r\n" ""; // Shader compile profile const char *ps_profile = "ps_4_0_level_9_1"; if(m_featureLevel >= D3D_FEATURE_LEVEL_11_0) ps_profile = "ps_5_0"; else if(m_featureLevel >= D3D_FEATURE_LEVEL_10_0) ps_profile = "ps_4_0"; else if(m_featureLevel >= D3D_FEATURE_LEVEL_9_3) ps_profile = "ps_4_0_level_9_3"; // Compile pixel shader ID3DBlob *pPSCode; HRESULT hResult = m_pfnD3DCompile( psStr, sizeof(psStr), NULL, NULL, NULL, "PS", ps_profile, D3DCOMPILE_OPTIMIZATION_LEVEL3, 0, &pPSCode, NULL ); if(FAILED(hResult)) { m_lastError = L"Failed to compile pixel shader"; } else { // Create pixel shader ID3D11PixelShader *pPS; hResult = m_pDevice->CreatePixelShader(pPSCode->GetBufferPointer(), pPSCode->GetBufferSize(), NULL, &pPS); if(FAILED(hResult)) { m_lastError = L"Failed to create pixel shader"; } else { // Compile clipping pixel shader ID3DBlob *pPSClipCode; HRESULT hResult = m_pfnD3DCompile( psClipStr, sizeof(psClipStr), NULL, NULL, NULL, "PS", ps_profile, D3DCOMPILE_OPTIMIZATION_LEVEL3, 0, &pPSClipCode, NULL ); if(FAILED(hResult)) { m_lastError = L"Failed to compile clipping pixel shader"; } else { // Create pixel shader ID3D11PixelShader *pPSClip; hResult = m_pDevice->CreatePixelShader( pPSClipCode->GetBufferPointer(), pPSClipCode->GetBufferSize(), NULL, &pPSClip ); if(FAILED(hResult)) { m_lastError = L"Failed to create clipping pixel shader"; } else { // Success m_pPixelShader = pPS; m_pPixelShaderClip = pPSClip; hResult = S_OK; } pPSClipCode->Release(); } if(FAILED(hResult)) pPS->Release(); } pPSCode->Release(); } return hResult; }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int cmdShow) { DXTInputHandlerDefault inputHandler; DXTWindowEventHandlerDefault eventHandler; DXTWindow window(hInstance, &inputHandler, &eventHandler); DXTRenderParams params; params.Extent = { 800, 600 }; params.UseVSync = true; params.Windowed = true; HRESULT result; result = window.Initialize(params, "DXT Example (DirectX 11)"); if (SUCCEEDED(result)) { ID3D11Device* device; ID3D11DeviceContext* context; IDXGISwapChain* swapChain; result = DXTInitDevice(params, &window, &swapChain, &device, &context); if (SUCCEEDED(result)) { eventHandler.SetSwapChain(swapChain); FLOAT clearColor[] = { 0.5f, 0.5f, 1.0f, 1.0f }; D3D11_INPUT_ELEMENT_DESC inputDesc[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, sizeof(float) * 3, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, sizeof(float) * 5, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; UINT elementCount = 3; UINT stride = 8 * sizeof(FLOAT); UINT offset = 0; UINT indexCount = 0; FLOAT deltaTime = 0.016f; DXTSphericalCamera camera; DXTFirstPersonCameraController cameraController(&camera, &inputHandler); inputHandler.AddInputInterface(&cameraController); cameraController.Velocity = 40.0f; cameraController.RotationVelocity = 0.005f; camera.Position = DirectX::XMFLOAT3(20.0f, 20.0f, 20.0f); camera.LookAt(DirectX::XMFLOAT3(0.0f, 0.0f, 0.0f)); ID3D11RenderTargetView* renderTargetView; ID3D11Texture2D* depthBuffer; ID3D11DepthStencilView* depthBufferView; ID3D11VertexShader* vertexShader; ID3D11PixelShader* pixelShader; DXTBytecodeBlob vertexBytecode; ID3D11DepthStencilState* depthState; ID3D11RasterizerState* rasterizerState; ID3D11Buffer* vertexBuffer; ID3D11Buffer* indexBuffer; ID3D11InputLayout* inputLayout; ID3D11Buffer* transformBuffer; DXTCreateRenderTargetFromBackBuffer(swapChain, device, &renderTargetView); DXTCreateDepthStencilBuffer(device, params.Extent.Width, params.Extent.Height, DXGI_FORMAT_D24_UNORM_S8_UINT, &depthBuffer, &depthBufferView); DXTVertexShaderFromFile(device, "VertexShader.cso", &vertexShader, &vertexBytecode); DXTPixelShaderFromFile(device, "PixelShader.cso", &pixelShader); DXTCreateDepthStencilStateDepthTestEnabled(device, &depthState); DXTCreateRasterizerStateSolid(device, &rasterizerState); DXTLoadStaticMeshFromFile(device, "mesh.ase", DXTVertexAttributePosition | DXTVertexAttributeUV | DXTVertexAttributeNormal, DXTIndexTypeShort, &vertexBuffer, &indexBuffer, &indexCount); DXTCreateBuffer(device, sizeof(DirectX::XMFLOAT4X4) * 2, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE, D3D11_USAGE_DYNAMIC, &transformBuffer); device->CreateInputLayout(inputDesc, elementCount, vertexBytecode.Bytecode, vertexBytecode.BytecodeLength, &inputLayout); vertexBytecode.Destroy(); window.Present(false); while (!window.QuitMessageReceived()) { window.MessagePump(); if (inputHandler.IsKeyDown(VK_ESCAPE)) break; cameraController.Update(deltaTime); XMFLOAT4X4 ViewProj; XMFLOAT4X4 World; camera.GetViewProjectionMatrix(&ViewProj, params.Extent); XMStoreFloat4x4(&World, XMMatrixIdentity()); D3D11_MAPPED_SUBRESOURCE subres; context->Map(transformBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &subres); XMFLOAT4X4* ptr = (XMFLOAT4X4*)subres.pData; ptr[0] = World; ptr[1] = ViewProj; context->Unmap(transformBuffer, 0); D3D11_VIEWPORT viewport = { 0.0f, 0.0f, (FLOAT)params.Extent.Width, (FLOAT)params.Extent.Height, 0.0f, 1.0f }; context->ClearRenderTargetView(renderTargetView, clearColor); context->ClearDepthStencilView(depthBufferView, D3D11_CLEAR_DEPTH, 1.0f, 0); context->OMSetDepthStencilState(depthState, 0); context->OMSetRenderTargets(1, &renderTargetView, depthBufferView); context->RSSetState(rasterizerState); context->RSSetViewports(1, &viewport); context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); context->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset); context->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R16_UINT, 0); context->IASetInputLayout(inputLayout); context->VSSetShader(vertexShader, nullptr, 0); context->PSSetShader(pixelShader, nullptr, 0); context->VSSetConstantBuffers(0, 1, &transformBuffer); context->DrawIndexed(indexCount, 0, 0); swapChain->Present(1, 0); } swapChain->SetFullscreenState(false, nullptr); transformBuffer->Release(); depthBufferView->Release(); depthBuffer->Release(); inputLayout->Release(); vertexBuffer->Release(); indexBuffer->Release(); depthState->Release(); rasterizerState->Release(); vertexShader->Release(); pixelShader->Release(); renderTargetView->Release(); swapChain->Release(); context->Release(); device->Release(); } window.Destroy(); } }
ID3D11PixelShader* DXShaderManager::loadPixelShaderFromFile( const string& filename ) { DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; // Convert filename to wide string int filenameLen = (int)filename.length() + 1; int newLen = MultiByteToWideChar(CP_ACP, 0, filename.c_str(), filenameLen, 0, 0); wchar_t* buf = new wchar_t[filenameLen]; MultiByteToWideChar(CP_ACP, 0, filename.c_str(), filenameLen, buf, newLen); std::wstring wFilename(buf); delete[] buf; #if defined(_WOE_DEBUG) // Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders. // Setting this flag improves the shader debugging experience, but still allows // the shaders to be optimized and to run exactly the way they will run in // the release configuration of this program. shaderFlags |= D3DCOMPILE_DEBUG; #endif // _WOE_DEBUG ID3DBlob* pErrorBlob = nullptr; ID3DBlob* pOutputBlob = nullptr; HRESULT hr; hr = D3DCompileFromFile(wFilename.c_str(), nullptr, nullptr, (type == ShaderTypes::WOE_SHADER_TYPE_VERTEX ? "VS" : "PS"), (type == ShaderTypes::WOE_SHADER_TYPE_VERTEX ? "vs_4_0" : "ps_4_0"), shaderFlags, 0, &pOutputBlob, &pErrorBlob); if (FAILED(hr)) { if (pErrorBlob) { Log::ErrorFmt(getClassName(), "Failed to compile HLSL: %s", reinterpret_cast<const char*>(pErrorBlob->GetBufferPointer())); pErrorBlob->Release(); } else { if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { Log::Error(getClassName(), "Failed to compile HLSL, File not found"); } else { Log::Error(getClassName(), "Failed to compile HLSL, Unknown Error"); } } return nullptr; } if (pErrorBlob) pErrorBlob->Release(); ID3D11PixelShader* pPixelShader = nullptr; hr = Game::Instance()->getGraphicsSystem()->getDXDevice()->CreatePixelShader(pOutputBlob->GetBufferPointer(), pOutputBlob->GetBufferSize(), nullptr, &pPixelShader); if (FAILED(hr)) { Log::Error(getClassName(), "Failed to create vertex shader"); pOutputBlob->Release(); pPixelShader->Release(); return nullptr; } return pPixelShader; }