// Create point to quad geometry shader HRESULT CFW1GlyphRenderStates::createGlyphShaders() { if(m_featureLevel < D3D_FEATURE_LEVEL_10_0) return E_FAIL; // Geometry shader constructing glyphs from point input and texture buffer const char gsSimpleStr[] = "cbuffer ShaderConstants : register(b0) {\r\n" " float4x4 TransformMatrix : packoffset(c0);\r\n" "};\r\n" "\r\n" "Buffer<float4> tex0 : register(t0);\r\n" "\r\n" "struct GSIn {\r\n" " float3 PositionIndex : POSITIONINDEX;\r\n" " float4 GlyphColor : GLYPHCOLOR;\r\n" "};\r\n" "\r\n" "struct GSOut {\r\n" " float4 Position : SV_Position;\r\n" " float4 GlyphColor : COLOR;\r\n" " float2 TexCoord : TEXCOORD;\r\n" "};\r\n" "\r\n" "[maxvertexcount(4)]\r\n" "void GS(point GSIn Input[1], inout TriangleStream<GSOut> TriStream) {\r\n" " const float2 basePosition = Input[0].PositionIndex.xy;\r\n" " const uint glyphIndex = asuint(Input[0].PositionIndex.z);\r\n" " \r\n" " float4 texCoords = tex0.Load(uint2(glyphIndex*2, 0));\r\n" " float4 offsets = tex0.Load(uint2(glyphIndex*2+1, 0));\r\n" " \r\n" " GSOut Output;\r\n" " Output.GlyphColor = Input[0].GlyphColor;\r\n" " \r\n" " float4 positions = basePosition.xyxy + offsets;\r\n" " \r\n" " Output.Position = mul(TransformMatrix, float4(positions.xy, 0.0f, 1.0f));\r\n" " Output.TexCoord = texCoords.xy;\r\n" " TriStream.Append(Output);\r\n" " \r\n" " Output.Position = mul(TransformMatrix, float4(positions.zy, 0.0f, 1.0f));\r\n" " Output.TexCoord = texCoords.zy;\r\n" " TriStream.Append(Output);\r\n" " \r\n" " Output.Position = mul(TransformMatrix, float4(positions.xw, 0.0f, 1.0f));\r\n" " Output.TexCoord = texCoords.xw;\r\n" " TriStream.Append(Output);\r\n" " \r\n" " Output.Position = mul(TransformMatrix, float4(positions.zw, 0.0f, 1.0f));\r\n" " Output.TexCoord = texCoords.zw;\r\n" " TriStream.Append(Output);\r\n" " \r\n" " TriStream.RestartStrip();\r\n" "}\r\n" ""; // Geometry shader with rect clipping const char gsClipStr[] = "cbuffer ShaderConstants : register(b0) {\r\n" " float4x4 TransformMatrix : packoffset(c0);\r\n" " float4 ClipRect : packoffset(c4);\r\n" "};\r\n" "\r\n" "Buffer<float4> tex0 : register(t0);\r\n" "\r\n" "struct GSIn {\r\n" " float3 PositionIndex : POSITIONINDEX;\r\n" " float4 GlyphColor : GLYPHCOLOR;\r\n" "};\r\n" "\r\n" "struct GSOut {\r\n" " float4 Position : SV_Position;\r\n" " float4 GlyphColor : COLOR;\r\n" " float2 TexCoord : TEXCOORD;\r\n" " float4 ClipDistance : SV_ClipDistance;\r\n" "};\r\n" "\r\n" "[maxvertexcount(4)]\r\n" "void GS(point GSIn Input[1], inout TriangleStream<GSOut> TriStream) {\r\n" " const float2 basePosition = Input[0].PositionIndex.xy;\r\n" " const uint glyphIndex = asuint(Input[0].PositionIndex.z);\r\n" " \r\n" " float4 texCoords = tex0.Load(uint2(glyphIndex*2, 0));\r\n" " float4 offsets = tex0.Load(uint2(glyphIndex*2+1, 0));\r\n" " \r\n" " GSOut Output;\r\n" " Output.GlyphColor = Input[0].GlyphColor;\r\n" " \r\n" " float4 positions = basePosition.xyxy + offsets;\r\n" " \r\n" " Output.Position = mul(TransformMatrix, float4(positions.xy, 0.0f, 1.0f));\r\n" " Output.TexCoord = texCoords.xy;\r\n" " Output.ClipDistance = ClipRect + float4(positions.xy, -positions.xy);\r\n" " TriStream.Append(Output);\r\n" " \r\n" " Output.Position = mul(TransformMatrix, float4(positions.zy, 0.0f, 1.0f));\r\n" " Output.TexCoord = texCoords.zy;\r\n" " Output.ClipDistance = ClipRect + float4(positions.zy, -positions.zy);\r\n" " TriStream.Append(Output);\r\n" " \r\n" " Output.Position = mul(TransformMatrix, float4(positions.xw, 0.0f, 1.0f));\r\n" " Output.TexCoord = texCoords.xw;\r\n" " Output.ClipDistance = ClipRect + float4(positions.xw, -positions.xw);\r\n" " TriStream.Append(Output);\r\n" " \r\n" " Output.Position = mul(TransformMatrix, float4(positions.zw, 0.0f, 1.0f));\r\n" " Output.TexCoord = texCoords.zw;\r\n" " Output.ClipDistance = ClipRect + float4(positions.zw, -positions.zw);\r\n" " TriStream.Append(Output);\r\n" " \r\n" " TriStream.RestartStrip();\r\n" "}\r\n" ""; // Vertex shader const char vsEmptyStr[] = "struct GSIn {\r\n" " float3 PositionIndex : POSITIONINDEX;\r\n" " float4 GlyphColor : GLYPHCOLOR;\r\n" "};\r\n" "\r\n" "GSIn VS(GSIn Input) {\r\n" " return Input;\r\n" "}\r\n" ""; // Shader compile profiles const char *vs_profile = "vs_4_0"; const char *gs_profile = "gs_4_0"; if(m_featureLevel >= D3D_FEATURE_LEVEL_11_0) { vs_profile = "vs_5_0"; gs_profile = "gs_5_0"; } // Compile geometry shader ID3DBlob *pGSCode; HRESULT hResult = m_pfnD3DCompile( gsSimpleStr, sizeof(gsSimpleStr), NULL, NULL, NULL, "GS", gs_profile, D3DCOMPILE_OPTIMIZATION_LEVEL3, 0, &pGSCode, NULL ); if(FAILED(hResult)) { m_lastError = L"Failed to compile geometry shader"; } else { // Create geometry shader ID3D11GeometryShader *pGS; hResult = m_pDevice->CreateGeometryShader(pGSCode->GetBufferPointer(), pGSCode->GetBufferSize(), NULL, &pGS); if(FAILED(hResult)) { m_lastError = L"Failed to create geometry shader"; } else { // Compile clipping geometry shader ID3DBlob *pGSClipCode; hResult = m_pfnD3DCompile( gsClipStr, sizeof(gsClipStr), NULL, NULL, NULL, "GS", gs_profile, D3DCOMPILE_OPTIMIZATION_LEVEL3, 0, &pGSClipCode, NULL ); if(FAILED(hResult)) { m_lastError = L"Failed to compile clipping geometry shader"; } else { // Create clipping geometry shader ID3D11GeometryShader *pGSClip; hResult = m_pDevice->CreateGeometryShader( pGSClipCode->GetBufferPointer(), pGSClipCode->GetBufferSize(), NULL, &pGSClip ); if(FAILED(hResult)) { m_lastError = L"Failed to create clipping geometry shader"; } else { ID3DBlob *pVSEmptyCode; // Compile vertex shader hResult = m_pfnD3DCompile( vsEmptyStr, sizeof(vsEmptyStr), NULL, NULL, NULL, "VS", vs_profile, D3DCOMPILE_OPTIMIZATION_LEVEL3, 0, &pVSEmptyCode, NULL ); if(FAILED(hResult)) { m_lastError = L"Failed to compile empty vertex shader"; } else { // Create vertex shader ID3D11VertexShader *pVSEmpty; hResult = m_pDevice->CreateVertexShader( pVSEmptyCode->GetBufferPointer(), pVSEmptyCode->GetBufferSize(), NULL, &pVSEmpty ); if(FAILED(hResult)) { m_lastError = L"Failed to create empty vertex shader"; } else { ID3D11InputLayout *pInputLayout; // Input layout for geometry shader D3D11_INPUT_ELEMENT_DESC inputElements[] = { {"POSITIONINDEX", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"GLYPHCOLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0} }; hResult = m_pDevice->CreateInputLayout( inputElements, 2, pVSEmptyCode->GetBufferPointer(), pVSEmptyCode->GetBufferSize(), &pInputLayout ); if(FAILED(hResult)) { m_lastError = L"Failed to create input layout for geometry shader"; } else { // Success m_pVertexShaderPoint = pVSEmpty; m_pGeometryShaderPoint = pGS; m_pGeometryShaderClipPoint = pGSClip; m_pPointInputLayout = pInputLayout; m_hasGeometryShader = true; hResult = S_OK; } if(FAILED(hResult)) pVSEmpty->Release(); } pVSEmptyCode->Release(); } if(FAILED(hResult)) pGSClip->Release(); } pGSClipCode->Release(); } if(FAILED(hResult)) pGS->Release(); } pGSCode->Release(); } return hResult; }
//================================================================================================================= HRESULT ShaderCompiler::Compile(D3D* d3d, BetterString filename, BetterString shaderFuncName, int type, BetterString macroName, bool loadPrecompiledShader) { // Compiling Shaders with D3DCompileFromFile //Google: visual studio 2013 hlsl shader compiling //http://msdn.microsoft.com/en-us/library/windows/desktop/hh968107(v=vs.85).aspx //http://stackoverflow.com/questions/10759300/how-do-i-use-shader-model-5-0-compiled-shaders-in-visual-studio-11 /* Here "PixelShader.cso" is the precompiled hlsl shader generated by Visual Studio 11 from a .hlsl file in the project. The compiled .cso file is usually moved to the Projects/ProjectName/Debug folder by default. As a result it must be cut and paste into the same directory as your source code before using. Mind you this setting can be changed by right-clicking the HLSL file while inside Visual Studio 11 and editing the Output Settings. By default its: $(OutDir)%(Filename).cso, change it to: $(Directory)%(Filename).cso */ //Google: creating a cso file in DirectX11.1 //http://stackoverflow.com/questions/5020204/loading-a-precompiled-hlsl-shader-into-memory-for-use-with-createpixelshader BetterString base = "..\\Framework\\Shaders\\"; filename = base + filename; unique_ptr<wchar_t> name = filename.ToWideStr(); HRESULT hr; ID3DBlob* blob = nullptr; ID3DBlob* errorBlob = nullptr; UINT flags = D3DCOMPILE_ENABLE_STRICTNESS; #if defined( DEBUG ) || defined( _DEBUG ) flags |= D3DCOMPILE_DEBUG; #endif ShaderMacros* macros = 0; map<string, ShaderMacros*>::iterator it = m_ShaderMacros.find(macroName); if (it != m_ShaderMacros.end()) macros = (*it).second; switch (type) { case EShaderTypes::ST_VERTEX: { VertexShader* vs = new VertexShader(); LPCSTR profile = "vs_5_0"; blob = Compile(name.get(), shaderFuncName, profile, flags, errorBlob, macros, loadPrecompiledShader); if (blob == nullptr) { OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename); exit(0); } hr = d3d->GetDevice11()->CreateVertexShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, &vs->mShader); if( FAILED(hr) ) { OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename); exit(0); } vs->mBlobData = blob; vs->mName = shaderFuncName; #if defined(DEBUG) || defined(PROFILE) if ( SUCCEEDED(hr) ) { vs->mShader->SetPrivateData( WKPDID_D3DDebugObjectName, lstrlenA(shaderFuncName), shaderFuncName ); } #endif //Add the vertex shader to the list of shaders m_Shaders.push_back(vs); } break; case EShaderTypes::ST_HULL: { HullShader* hs = new HullShader(); LPCSTR profile = "hs_5_0"; blob = Compile(name.get(), shaderFuncName, profile, flags, errorBlob, macros, loadPrecompiledShader); if (blob == nullptr) { OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename); exit(0); } hr = d3d->GetDevice11()->CreateHullShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, &hs->mShader); if (FAILED(hr)) { OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename); exit(0); } hs->mBlobData = blob; hs->mName = shaderFuncName; #if defined(DEBUG) || defined(PROFILE) if (SUCCEEDED(hr)) { hs->mShader->SetPrivateData(WKPDID_D3DDebugObjectName, lstrlenA(shaderFuncName), shaderFuncName); } #endif //Add the hull shader to the list of shaders m_Shaders.push_back(hs); } break; case EShaderTypes::ST_DOMAIN: { DomainShader* ds = new DomainShader(); LPCSTR profile = "ds_5_0"; blob = Compile(name.get(), shaderFuncName, profile, flags, errorBlob, macros, loadPrecompiledShader); if (blob == nullptr) { OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename); exit(0); } hr = d3d->GetDevice11()->CreateDomainShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, &ds->mShader); if (FAILED(hr)) { OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename); exit(0); } ds->mBlobData = blob; ds->mName = shaderFuncName; #if defined(DEBUG) || defined(PROFILE) if (SUCCEEDED(hr)) { ds->mShader->SetPrivateData(WKPDID_D3DDebugObjectName, lstrlenA(shaderFuncName), shaderFuncName); } #endif //Add the domain shader to the list of shaders m_Shaders.push_back(ds); } break; case EShaderTypes::ST_PIXEL: { PixelShader* ps = new PixelShader(); LPCSTR profile = "ps_5_0"; blob = Compile(name.get(), shaderFuncName, profile, flags, errorBlob, macros, loadPrecompiledShader); if (blob == nullptr) { OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename); exit(0); } hr = d3d->GetDevice11()->CreatePixelShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, &ps->mShader); if (FAILED(hr)) { OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename); exit(0); } ps->mBlobData = blob; ps->mName = shaderFuncName; #if defined(DEBUG) || defined(PROFILE) if (SUCCEEDED(hr)) { ps->mShader->SetPrivateData(WKPDID_D3DDebugObjectName, lstrlenA(shaderFuncName), shaderFuncName); } #endif //Add the pixel shader to the list of shaders m_Shaders.push_back(ps); } break; case EShaderTypes::ST_GEOMETRY: { GeometryShader* gs = new GeometryShader(); LPCSTR profile = "gs_5_0"; blob = Compile(name.get(), shaderFuncName, profile, flags, errorBlob, macros, loadPrecompiledShader); if (blob == nullptr) { OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename); exit(0); } hr = d3d->GetDevice11()->CreateGeometryShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, &gs->mShader); if (FAILED(hr)) { OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename); exit(0); } gs->mBlobData = blob; gs->mName = shaderFuncName; #if defined(DEBUG) || defined(PROFILE) if (SUCCEEDED(hr)) { gs->mShader->SetPrivateData(WKPDID_D3DDebugObjectName, lstrlenA(shaderFuncName), shaderFuncName); } #endif //Add the geometry shader to the list of shaders m_Shaders.push_back(gs); } break; case EShaderTypes::ST_COMPUTE: { ComputeShader* cs = new ComputeShader(); LPCSTR profile = "cs_5_0"; blob = Compile(name.get(), shaderFuncName, profile, flags, errorBlob, macros, loadPrecompiledShader); if (blob == nullptr) { OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename); exit(0); } hr = d3d->GetDevice11()->CreateComputeShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, &cs->mShader); if (FAILED(hr)) { OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename); exit(0); } cs->mBlobData = blob; cs->mName = shaderFuncName; #if defined(DEBUG) || defined(PROFILE) if (SUCCEEDED(hr)) { cs->mShader->SetPrivateData(WKPDID_D3DDebugObjectName, lstrlenA(shaderFuncName), shaderFuncName); } #endif //Add the compute shader to the list of shaders m_Shaders.push_back(cs); } break; default: { ZShadeMessageCenter::MsgBoxError(NULL, "ShaderCompiler: ZShadeSandboxShader::Shader type not defined !!!"); exit(0); } break; } return S_OK; }
// // 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; }
// Load and register all the resources needed by the GUI system //----------------------------------------------------------------------------- CPUTResult CPUTGuiControllerDX11::RegisterGUIResources(ID3D11DeviceContext *pImmediateContext, cString VertexShaderFilename, cString PixelShaderFilename, cString RenderStateFile, cString DefaultFontFilename, cString ControlAtlasTexture) { if(NULL==pImmediateContext) { return CPUT_ERROR_INVALID_PARAMETER; } CPUTResult result; HRESULT hr; ID3D11Device *pD3dDevice = NULL; CPUTOSServices *pServices = NULL; CPUTAssetLibraryDX11 *pAssetLibrary = NULL; cString ErrorMessage; // Get the services/resource pointers we need pServices = CPUTOSServices::GetOSServices(); pImmediateContext->GetDevice(&pD3dDevice); pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibraryDX11::GetAssetLibrary(); // Get the resource directory cString ResourceDirectory; CPUTGuiControllerDX11::GetController()->GetResourceDirectory(ResourceDirectory); // 1. Load the renderstate configuration for the GUI system mpGUIRenderStateBlock = (CPUTRenderStateBlockDX11*) pAssetLibrary->GetRenderStateBlock(ResourceDirectory+RenderStateFile); ASSERT(mpGUIRenderStateBlock, _L("Error loading the render state file (.rs) needed for the CPUT GUI system")); // 2. Store the shader path from AssetLibrary, change it to OUR resource directory cString OriginalAssetLibraryDirectory = pAssetLibrary->GetShaderDirectory(); pAssetLibrary->SetShaderDirectoryName(ResourceDirectory); // 3. load the shaders for gui drawing // Load the GUI Vertex Shader cString FullPath, FinalPath; FullPath = mResourceDirectory + VertexShaderFilename; pServices->ResolveAbsolutePathAndFilename(FullPath, &FinalPath); result = pAssetLibrary->GetVertexShader(FinalPath, pD3dDevice, _L("VS"), _L("vs_4_0"), &mpGUIVertexShader, true); CPUTSetDebugName( mpGUIVertexShader->GetNativeVertexShader(), _L("GUIVertexShader")); if(CPUTFAILED(result)) { ASSERT(CPUTSUCCESS(result), _L("Error loading the vertex shader needed for the CPUT GUI system.")); } ID3DBlob *pVertexShaderBlob = mpGUIVertexShader->GetBlob(); // Load the GUI Pixel Shader FullPath = mResourceDirectory + PixelShaderFilename; pServices->ResolveAbsolutePathAndFilename(FullPath, &FinalPath); result = pAssetLibrary->GetPixelShader(FinalPath, pD3dDevice, _L("PS"), _L("ps_4_0"), &mpGUIPixelShader, true); CPUTSetDebugName( mpGUIPixelShader->GetNativePixelShader(), _L("GUIPixelShader")); if(CPUTFAILED(result)) { ASSERT(CPUTSUCCESS(result), _L("Error loading the pixel shader needed for the CPUT GUI system.")); } // Restore the previous shader directory pAssetLibrary->SetShaderDirectoryName(OriginalAssetLibraryDirectory); // 4. Create the vertex layout description for all the GUI controls we'll draw // set vertex shader as active so we can configure it ID3D11VertexShader *pVertexShader = mpGUIVertexShader->GetNativeVertexShader(); pImmediateContext->VSSetShader( pVertexShader, NULL, 0 ); D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; UINT numElements = ARRAYSIZE( layout ); // Create the input layout hr = pD3dDevice->CreateInputLayout( layout, numElements, pVertexShaderBlob->GetBufferPointer(), pVertexShaderBlob->GetBufferSize(), &mpVertexLayout ); ASSERT( SUCCEEDED(hr), _L("Error creating CPUT GUI system input layout" )); CPUTSetDebugName( mpVertexLayout, _L("CPUT GUI InputLayout object")); // 5. create the vertex shader constant buffer pointers D3D11_BUFFER_DESC bd; ZeroMemory( &bd, sizeof(bd) ); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof(GUIConstantBufferVS); bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bd.CPUAccessFlags = 0; hr = pD3dDevice->CreateBuffer( &bd, NULL, &mpConstantBufferVS ); ASSERT( SUCCEEDED(hr), _L("Error creating constant buffer VS" )); CPUTSetDebugName( mpConstantBufferVS, _L("GUI ConstantBuffer")); // Set the texture directory for loading the control texture atlas pAssetLibrary->SetTextureDirectoryName(ResourceDirectory); // load the control atlas mpControlTextureAtlas = (CPUTTextureDX11*) pAssetLibrary->GetTexture(ControlAtlasTexture); if(NULL==mpControlTextureAtlas) { return CPUT_TEXTURE_LOAD_ERROR; } mpControlTextureAtlasView = mpControlTextureAtlas->GetShaderResourceView(); mpControlTextureAtlasView->AddRef(); // restore the asset library's texture directory pAssetLibrary->SetTextureDirectoryName(OriginalAssetLibraryDirectory); // 6. Load the font atlas // store the existing asset library font directory OriginalAssetLibraryDirectory = pAssetLibrary->GetFontDirectory(); // set font directory to the resource directory pAssetLibrary->SetFontDirectoryName(ResourceDirectory); mpFont = (CPUTFontDX11*) pAssetLibrary->GetFont(DefaultFontFilename); if(NULL==mpFont) { return CPUT_TEXTURE_LOAD_ERROR; } mpTextTextureAtlas = mpFont->GetAtlasTexture(); mpTextTextureAtlas->AddRef(); mpTextTextureAtlasView = mpFont->GetAtlasTextureResourceView(); mpTextTextureAtlasView->AddRef(); // restore the asset library's font directory pAssetLibrary->SetTextureDirectoryName(OriginalAssetLibraryDirectory); // 7. Set up the DirectX uber-buffers that the controls draw into int maxSize = max(CPUT_GUI_BUFFER_STRING_SIZE, CPUT_GUI_BUFFER_SIZE); maxSize = max(maxSize, CPUT_GUI_VERTEX_BUFFER_SIZE); maxSize *= sizeof( CPUTGUIVertex ); char *pZeroedBuffer= new char[maxSize]; memset(pZeroedBuffer, 0, maxSize); // set up buffer description ZeroMemory( &bd, sizeof(bd) ); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_VERTEX_BUFFER_SIZE; //mUberBufferIndex; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = 0; // initialization data (all 0's for now) D3D11_SUBRESOURCE_DATA InitData; ZeroMemory( &InitData, sizeof(InitData) ); InitData.pSysMem = mpMirrorBuffer; // mpUberBuffer SAFE_RELEASE(mpUberBuffer); hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpUberBuffer ); ASSERT( !FAILED( hr ), _L("CPUT GUI FPS counter buffer creation failure")); CPUTSetDebugName(mpUberBuffer, _L("CPUT GUI: Control's main vertex buffer")); // mpTextUberBuffer bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_BUFFER_STRING_SIZE; hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpTextUberBuffer ); ASSERT( !FAILED( hr ), _L("CPUT GUI FPS counter buffer creation failure")); CPUTSetDebugName(mpTextUberBuffer, _L("CPUT GUI: control text vertex buffer")); // mpFocusedControlBuffer bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_VERTEX_BUFFER_SIZE; hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpFocusedControlBuffer ); ASSERT( !FAILED( hr ), _L("CPUT GUI FPS counter buffer creation failure")); CPUTSetDebugName(mpFocusedControlBuffer, _L("CPUT GUI: focused control images vertex buffer")); // mpFocusedControlTextBuffer bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_BUFFER_STRING_SIZE; //mFocusedControlTextBufferIndex; hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpFocusedControlTextBuffer ); ASSERT( !FAILED( hr ), _L("CPUT GUI FPS counter buffer creation failure")); CPUTSetDebugName(mpFocusedControlTextBuffer, _L("CPUT GUI: focused control text vertex buffer")); // mpFPSDirectXBuffer bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_BUFFER_STRING_SIZE; hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpFPSDirectXBuffer ); ASSERT( !FAILED( hr ), _L("CPUT GUI FPS counter buffer creation failure")); CPUTSetDebugName(mpFPSDirectXBuffer, _L("CPUT GUI: FPS display text")); // no longer need the device - release it. SAFE_RELEASE(pD3dDevice); SAFE_DELETE_ARRAY(pZeroedBuffer); // 8. Register all GUI sub-resources // Walk all the controls/fonts and have them register all their required static resources // Returning errors if you couldn't find your resources result = CPUTText::RegisterStaticResources(); if(CPUTFAILED(result)) { return result; } result = CPUTButton::RegisterStaticResources(); if(CPUTFAILED(result)) { return result; } result = CPUTCheckbox::RegisterStaticResources(); if(CPUTFAILED(result)) { return result; } result = CPUTSlider::RegisterStaticResources(); if(CPUTFAILED(result)) { return result; } result = CPUTDropdown::RegisterStaticResources(); if(CPUTFAILED(result)) { return result; } // create the FPS CPUTText object for drawing FPS mpFPSCounter = new CPUTText(_L("FPS:"), ID_CPUT_GUI_FPS_COUNTER, mpFont); mpFPSCounter->SetAutoArranged(false); mpFPSCounter->SetPosition(0,0); // start the timer mpFPSTimer->StartTimer(); // done return CPUT_SUCCESS; }
//-------------------------------------------------------------------------------------- // Create Direct3D device and swap chain //-------------------------------------------------------------------------------------- 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, D3D_DRIVER_TYPE_REFERENCE, }; UINT numDriverTypes = ARRAYSIZE( driverTypes ); D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT numFeatureLevels = ARRAYSIZE( featureLevels ); for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) { g_driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); if ( hr == E_INVALIDARG ) { // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); } if( SUCCEEDED( hr ) ) break; } if( FAILED( hr ) ) return hr; // Obtain DXGI factory from device (since we used nullptr for pAdapter above) IDXGIFactory1* dxgiFactory = nullptr; { IDXGIDevice* dxgiDevice = nullptr; hr = g_pd3dDevice->QueryInterface( __uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice) ); if (SUCCEEDED(hr)) { IDXGIAdapter* adapter = nullptr; hr = dxgiDevice->GetAdapter(&adapter); if (SUCCEEDED(hr)) { hr = adapter->GetParent( __uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory) ); adapter->Release(); } dxgiDevice->Release(); } } if (FAILED(hr)) return hr; // Create swap chain IDXGIFactory2* dxgiFactory2 = nullptr; hr = dxgiFactory->QueryInterface( __uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2) ); if ( dxgiFactory2 ) { // DirectX 11.1 or later hr = g_pd3dDevice->QueryInterface( __uuidof(ID3D11Device1), reinterpret_cast<void**>(&g_pd3dDevice1) ); if (SUCCEEDED(hr)) { (void) g_pImmediateContext->QueryInterface( __uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&g_pImmediateContext1) ); } DXGI_SWAP_CHAIN_DESC1 sd; ZeroMemory(&sd, sizeof(sd)); sd.Width = width; sd.Height = height; sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; hr = dxgiFactory2->CreateSwapChainForHwnd( g_pd3dDevice, g_hWnd, &sd, nullptr, nullptr, &g_pSwapChain1 ); if (SUCCEEDED(hr)) { hr = g_pSwapChain1->QueryInterface( __uuidof(IDXGISwapChain), reinterpret_cast<void**>(&g_pSwapChain) ); } dxgiFactory2->Release(); } else { // DirectX 11.0 systems 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; hr = dxgiFactory->CreateSwapChain( g_pd3dDevice, &sd, &g_pSwapChain ); } // Note this tutorial doesn't handle full-screen swapchains so we block the ALT+ENTER shortcut dxgiFactory->MakeWindowAssociation( g_hWnd, DXGI_MWA_NO_ALT_ENTER ); dxgiFactory->Release(); if (FAILED(hr)) return hr; // Create a render target view ID3D11Texture2D* pBackBuffer = nullptr; hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast<void**>( &pBackBuffer ) ); if( FAILED( hr ) ) return hr; hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, nullptr, &g_pRenderTargetView ); pBackBuffer->Release(); if( FAILED( hr ) ) return hr; g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, nullptr ); // 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 ); // Compile the vertex shader ID3DBlob* pVSBlob = nullptr; hr = CompileShaderFromFile( L"Tutorial03.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 ); if( FAILED( hr ) ) { 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 }, }; 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; hr = CompileShaderFromFile( L"Tutorial03.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 ); pPSBlob->Release(); if( FAILED( hr ) ) return hr; // Create vertex buffer SimpleVertex vertices[] = { XMFLOAT3( 0.0f, 0.5f, 0.5f ), XMFLOAT3( 0.5f, -0.5f, 0.5f ), XMFLOAT3( -0.5f, -0.5f, 0.5f ), }; D3D11_BUFFER_DESC bd; ZeroMemory( &bd, sizeof(bd) ); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( SimpleVertex ) * 3; 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 ); // Set primitive topology g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); return S_OK; }
_Use_decl_annotations_ HRESULT D3DX11CompileEffectFromFile( LPCWSTR pFileName, const D3D_SHADER_MACRO *pDefines, ID3DInclude *pInclude, UINT HLSLFlags, UINT FXFlags, ID3D11Device *pDevice, ID3DX11Effect **ppEffect, ID3DBlob **ppErrors ) { if ( !pFileName || !pDevice || !ppEffect ) return E_INVALIDARG; if ( FXFlags & D3DCOMPILE_EFFECT_CHILD_EFFECT ) { DPF(0, "Effect pools (i.e. D3DCOMPILE_EFFECT_CHILD_EFFECT) not supported" ); return E_NOTIMPL; } ID3DBlob *blob = nullptr; #if (D3D_COMPILER_VERSION >= 46) && ( !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_APP) ) HRESULT hr = D3DCompileFromFile( pFileName, pDefines, pInclude, "", "fx_5_0", HLSLFlags, FXFlags, &blob, ppErrors ); if ( FAILED(hr) ) { DPF(0, "D3DCompileFromFile of fx_5_0 profile failed %08X: %S", hr, pFileName ); return hr; } #else // D3D_COMPILER_VERSION < 46 std::unique_ptr<uint8_t[]> fileData; uint32_t size; HRESULT hr = LoadBinaryFromFile( pFileName, fileData, size ); if ( FAILED(hr) ) { DPF(0, "Failed to load effect file %08X: %S", hr, pFileName); return hr; } // Create debug object name from input filename CHAR strFileA[MAX_PATH]; int result = WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, pFileName, -1, strFileA, MAX_PATH, nullptr, FALSE ); if ( !result ) { DPF(0, "Failed to load effect file due to WC to MB conversion failure: %S", pFileName); return E_FAIL; } const CHAR* pstrName = strrchr( strFileA, '\\' ); if (!pstrName) { pstrName = strFileA; } else { pstrName++; } hr = D3DCompile( fileData.get(), size, pstrName, pDefines, pInclude, "", "fx_5_0", HLSLFlags, FXFlags, &blob, ppErrors ); if ( FAILED(hr) ) { DPF(0, "D3DCompile of fx_5_0 profile failed: %08X", hr ); return hr; } #endif // D3D_COMPILER_VERSION #ifdef _M_X64 if ( blob->GetBufferSize() > 0xFFFFFFFF ) { SAFE_RELEASE( blob ); return E_FAIL; } #endif // _M_X64 hr = S_OK; VN( *ppEffect = new CEffect( FXFlags & D3DX11_EFFECT_RUNTIME_VALID_FLAGS ) ); VH( ((CEffect*)(*ppEffect))->LoadEffect(blob->GetBufferPointer(), static_cast<uint32_t>( blob->GetBufferSize() ) ) ); SAFE_RELEASE( blob ); #if (D3D_COMPILER_VERSION >= 46) && ( !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_APP) ) // Create debug object name from input filename CHAR strFileA[MAX_PATH]; int result = WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, pFileName, -1, strFileA, MAX_PATH, nullptr, FALSE ); if ( !result ) { DPF(0, "Failed to load effect file due to WC to MB conversion failure: %S", pFileName); hr = E_FAIL; goto lExit; } const CHAR* pstrName = strrchr( strFileA, '\\' ); if (!pstrName) { pstrName = strFileA; } else { pstrName++; } #endif VH( ((CEffect*)(*ppEffect))->BindToDevice(pDevice, pstrName) ); lExit: if (FAILED(hr)) { SAFE_RELEASE(*ppEffect); } return hr; }
//-------------------------------------------------------------------------------------- // Load and compile Effect file (.fx file containing shaders) //-------------------------------------------------------------------------------------- // An effect file contains a set of "Techniques". A technique is a combination of vertex, geometry and pixel shaders (and some states) used for // rendering in a particular way. We load the effect file at runtime (it's written in HLSL and has the extension ".fx"). The effect code is compiled // *at runtime* into low-level GPU language. When rendering a particular model we specify which technique from the effect file that it will use bool CScene::LoadShaders() { ID3DBlob* pEffectBlob; ID3DBlob* pErrors; // This strangely typed variable collects any errors when compiling the effect file DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS; // These "flags" are used to set the compiler options //compile shaders individually HRESULT hr; hr = D3DX11CompileFromFile( L"VertexShader.hlsl", NULL, NULL, NULL, "fx_5_0", dwShaderFlags, 0, NULL, &pEffectBlob, &pErrors, &hr ); if( FAILED( hr ) ) { if( pErrors != 0 ) MessageBox( NULL, CA2CT( reinterpret_cast<char*>(pErrors->GetBufferPointer()) ), L"Error", MB_OK ); // Compiler error: display error message else MessageBox( NULL, L"Error loading Vertex Shader FX file. Ensure your FX file is in the same folder as this executable.", L"Error", MB_OK ); // No error message - probably file not found return false; } hr = mpd3dDevice->CreateVertexShader( pEffectBlob->GetBufferPointer(), pEffectBlob->GetBufferSize(), NULL, &mp_VertexShader[0] ); if( FAILED( hr ) ) { if( pErrors != 0 ) MessageBox( NULL, CA2CT( reinterpret_cast<char*>(pErrors->GetBufferPointer()) ), L"Error", MB_OK ); // Compiler error: display error message else MessageBox( NULL, L"Error creating Vertex Shader.", L"Error", MB_OK ); // No error message - probably file not found return false; } hr = D3DX11CompileFromFile( L"PixelShader.hlsl", NULL, NULL, "main", "fx_5_0", dwShaderFlags, 0, NULL, &pEffectBlob, &pErrors, &hr ); if( FAILED( hr ) ) { if( pErrors != 0 ) MessageBox( NULL, CA2CT( reinterpret_cast<char*>(pErrors->GetBufferPointer()) ), L"Error", MB_OK ); // Compiler error: display error message else MessageBox( NULL, L"Error loading Pixel Shader FX file. Ensure your FX file is in the same folder as this executable.", L"Error", MB_OK ); // No error message - probably file not found return false; } hr = mpd3dDevice->CreatePixelShader( pEffectBlob->GetBufferPointer(), pEffectBlob->GetBufferSize(), NULL, &mp_PixelShader[0] ); if( FAILED( hr ) ) { if( pErrors != 0 ) MessageBox( NULL, CA2CT( reinterpret_cast<char*>(pErrors->GetBufferPointer()) ), L"Error", MB_OK ); // Compiler error: display error message else MessageBox( NULL, L"Error Creating Pixel Shader", L"Error", MB_OK ); // No error message - probably file not found return false; } return true; }
// Requires the compiled shaders (.cso files) DXShader::DXShader( string vertexPath, string fragmentPath ) { HRESULT result; ID3DBlob* shaderCompileErrors; // Layout description, must match layout in vertex shader const int numLayoutElements = 3; const D3D11_INPUT_ELEMENT_DESC vLayout[] = { /*POS*/ { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, /*UV*/ { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, /*NORMAL*/ { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 } }; // ---- Load Vertex Shader ID3DBlob* vsb; wstring wVertexPath( vertexPath.begin(), vertexPath.end() ); ShaderInclude include( File( vertexPath ).GetDirectory() ); //D3DReadFileToBlob( wVertexPath.c_str(), &vsb ); result = D3DCompileFromFile( wVertexPath.c_str(), NULL, &include, "main", "vs_5_0", D3DCOMPILE_ENABLE_STRICTNESS, 0, &vsb, &shaderCompileErrors ); if( FAILED(result) ) { OutputController::PrintMessage( OutputType::Error, "Error compiling vertex shader\n" + vertexPath ); OutputController::PrintMessage( OutputType::Error, (char*)(shaderCompileErrors->GetBufferPointer()) ); } result = AdapterController::Get()->GetDevice().dx->CreateVertexShader( vsb->GetBufferPointer(), vsb->GetBufferSize(), NULL, &vertexShader ); if( FAILED(result) ) { OutputController::PrintMessage( OutputType::Error, "Failed to create vertex shader." ); } // Create Input Layout result = AdapterController::Get()->GetDevice().dx->CreateInputLayout( vLayout, numLayoutElements,//ARRAYSIZE(vertexLayout), vsb->GetBufferPointer(), vsb->GetBufferSize(), &vertexLayout ); if( FAILED(result) ) { OutputController::PrintMessage( OutputType::Error, "Failed to create input layout." ); } // ---- Load Pixel Shader ID3DBlob* psb; wstring wPixelPath( fragmentPath.begin(), fragmentPath.end() ); //D3DReadFileToBlob( wPixelPath.c_str(), &psb ); result = D3DCompileFromFile( wPixelPath.c_str(), NULL, &include, "main", "ps_5_0", D3DCOMPILE_ENABLE_STRICTNESS, 0, &psb, &shaderCompileErrors ); if( FAILED(result) ) { OutputController::PrintMessage( OutputType::Error, "Error compiling fragment shader\n" + fragmentPath ); OutputController::PrintMessage( OutputType::Error, (gChar*)(shaderCompileErrors->GetBufferPointer()) ); } result = AdapterController::Get()->GetDevice().dx->CreatePixelShader( psb->GetBufferPointer(), psb->GetBufferSize(), NULL, &pixelShader ); if( FAILED(result) ) { OutputController::PrintMessage( OutputType::Error, "Failed to create fragment shader." ); } // get constant buffer variables ID3D11ShaderReflection* vsReflection = nullptr; D3D11Reflect( vsb->GetBufferPointer(), vsb->GetBufferSize(), &vsReflection ); D3D11_SHADER_BUFFER_DESC vsShaderBufferDesc; vsReflection->GetConstantBufferByName( "uniforms" )->GetDesc( &vsShaderBufferDesc ); vsShaderBufferDesc.Name; UINT numVariables = vsShaderBufferDesc.Variables; ID3D11ShaderReflectionVariable* var2 = vsReflection->GetConstantBufferByName( "uniforms" )->GetVariableByIndex( 2 ); D3D11_SHADER_VARIABLE_DESC var2Desc; var2->GetDesc( &var2Desc ); var2Desc.Name; var2Desc.Size; ID3D11ShaderReflectionType* var2Type = var2->GetType(); var2Type->GetMemberTypeByIndex(0); // ---- Create Sampler State D3D11_SAMPLER_DESC samplerDesc; samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.MipLODBias = 0.0f; samplerDesc.MaxAnisotropy = 1; samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; samplerDesc.BorderColor[0] = 0; samplerDesc.BorderColor[1] = 0; samplerDesc.BorderColor[2] = 0; samplerDesc.BorderColor[3] = 0; samplerDesc.MinLOD = 0; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; result = AdapterController::Get()->GetDevice().dx->CreateSamplerState( &samplerDesc, &samplerState ); if( FAILED(result) ) { OutputController::PrintMessage( OutputType::Error, "Failed to create sampler state." ); } // release unneeded buffers ReleaseCOMobjMacro( psb ); ReleaseCOMobjMacro( vsb ); ReleaseCOMobjMacro( shaderCompileErrors ); // TEMPORARY BUFFER TO BE REMOVED FROM C++ SIDE auto buf = new ConstBuffer; buf->totalSize = 0; buf->AddProperty( "modelViewProj", sizeof(Matrix4) ); buf->AddProperty( "rotationMatrix", sizeof(Matrix4) ); buf->AddProperty( "ambientLight", AmbientLight::size ); buf->AddProperty( "dirLight", DirectionalLight::size ); RegisterConstBuffer( "uniforms", buf ); delete buf; }
static bool compile(bx::CommandLine& _cmdLine, uint32_t _version, const std::string& _code, bx::WriterI* _writer, bool _firstPass) { const char* profile = _cmdLine.findOption('p', "profile"); if (NULL == profile) { fprintf(stderr, "Error: Shader profile must be specified.\n"); return false; } s_compiler = load(); bool result = false; bool debug = _cmdLine.hasArg('\0', "debug"); uint32_t flags = D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY; flags |= debug ? D3DCOMPILE_DEBUG : 0; flags |= _cmdLine.hasArg('\0', "avoid-flow-control") ? D3DCOMPILE_AVOID_FLOW_CONTROL : 0; flags |= _cmdLine.hasArg('\0', "no-preshader") ? D3DCOMPILE_NO_PRESHADER : 0; flags |= _cmdLine.hasArg('\0', "partial-precision") ? D3DCOMPILE_PARTIAL_PRECISION : 0; flags |= _cmdLine.hasArg('\0', "prefer-flow-control") ? D3DCOMPILE_PREFER_FLOW_CONTROL : 0; flags |= _cmdLine.hasArg('\0', "backwards-compatibility") ? D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY : 0; bool werror = _cmdLine.hasArg('\0', "Werror"); if (werror) { flags |= D3DCOMPILE_WARNINGS_ARE_ERRORS; } uint32_t optimization = 3; if (_cmdLine.hasArg(optimization, 'O') ) { optimization = bx::uint32_min(optimization, BX_COUNTOF(s_optimizationLevelD3D11) - 1); flags |= s_optimizationLevelD3D11[optimization]; } else { flags |= D3DCOMPILE_SKIP_OPTIMIZATION; } BX_TRACE("Profile: %s", profile); BX_TRACE("Flags: 0x%08x", flags); ID3DBlob* code; ID3DBlob* errorMsg; // Output preprocessed shader so that HLSL can be debugged via GPA // or PIX. Compiling through memory won't embed preprocessed shader // file path. std::string hlslfp; if (debug) { hlslfp = _cmdLine.findOption('o'); hlslfp += ".hlsl"; writeFile(hlslfp.c_str(), _code.c_str(), (int32_t)_code.size() ); } HRESULT hr = D3DCompile(_code.c_str() , _code.size() , hlslfp.c_str() , NULL , NULL , "main" , profile , flags , 0 , &code , &errorMsg ); if (FAILED(hr) || (werror && NULL != errorMsg) ) { const char* log = (char*)errorMsg->GetBufferPointer(); int32_t line = 0; int32_t column = 0; int32_t start = 0; int32_t end = INT32_MAX; bool found = false || 2 == sscanf(log, "(%u,%u):", &line, &column) || 2 == sscanf(log, " :%u:%u: ", &line, &column) ; if (found && 0 != line) { start = bx::uint32_imax(1, line - 10); end = start + 20; } printCode(_code.c_str(), line, start, end, column); fprintf(stderr, "Error: D3DCompile failed 0x%08x %s\n", (uint32_t)hr, log); errorMsg->Release(); return false; } UniformArray uniforms; uint8_t numAttrs = 0; uint16_t attrs[bgfx::Attrib::Count]; uint16_t size = 0; if (_version == 9) { if (!getReflectionDataD3D9(code, uniforms) ) { fprintf(stderr, "Error: Unable to get D3D9 reflection data.\n"); goto error; } } else { UniformNameList unusedUniforms; if (!getReflectionDataD3D11(code, profile[0] == 'v', uniforms, numAttrs, attrs, size, unusedUniforms) ) { fprintf(stderr, "Error: Unable to get D3D11 reflection data.\n"); goto error; } if (_firstPass && unusedUniforms.size() > 0) { const size_t strLength = strlen("uniform"); // first time through, we just find unused uniforms and get rid of them std::string output; LineReader reader(_code.c_str() ); while (!reader.isEof() ) { std::string line = reader.getLine(); for (UniformNameList::iterator it = unusedUniforms.begin(), itEnd = unusedUniforms.end(); it != itEnd; ++it) { size_t index = line.find("uniform "); if (index == std::string::npos) { continue; } // matching lines like: uniform u_name; // we want to replace "uniform" with "static" so that it's no longer // included in the uniform blob that the application must upload // we can't just remove them, because unused functions might still reference // them and cause a compile error when they're gone if (!!bx::findIdentifierMatch(line.c_str(), it->c_str() ) ) { line = line.replace(index, strLength, "static"); unusedUniforms.erase(it); break; } } output += line; } // recompile with the unused uniforms converted to statics return compile(_cmdLine, _version, output.c_str(), _writer, false); } } { uint16_t count = (uint16_t)uniforms.size(); bx::write(_writer, count); uint32_t fragmentBit = profile[0] == 'p' ? BGFX_UNIFORM_FRAGMENTBIT : 0; for (UniformArray::const_iterator it = uniforms.begin(); it != uniforms.end(); ++it) { const Uniform& un = *it; uint8_t nameSize = (uint8_t)un.name.size(); bx::write(_writer, nameSize); bx::write(_writer, un.name.c_str(), nameSize); uint8_t type = uint8_t(un.type | fragmentBit); bx::write(_writer, type); bx::write(_writer, un.num); bx::write(_writer, un.regIndex); bx::write(_writer, un.regCount); BX_TRACE("%s, %s, %d, %d, %d" , un.name.c_str() , getUniformTypeName(un.type) , un.num , un.regIndex , un.regCount ); } } { ID3DBlob* stripped; hr = D3DStripShader(code->GetBufferPointer() , code->GetBufferSize() , D3DCOMPILER_STRIP_REFLECTION_DATA | D3DCOMPILER_STRIP_TEST_BLOBS , &stripped ); if (SUCCEEDED(hr) ) { code->Release(); code = stripped; } } { uint16_t shaderSize = (uint16_t)code->GetBufferSize(); bx::write(_writer, shaderSize); bx::write(_writer, code->GetBufferPointer(), shaderSize); uint8_t nul = 0; bx::write(_writer, nul); } if (_version > 9) { bx::write(_writer, numAttrs); bx::write(_writer, attrs, numAttrs*sizeof(uint16_t) ); bx::write(_writer, size); } if (_cmdLine.hasArg('\0', "disasm") ) { ID3DBlob* disasm; D3DDisassemble(code->GetBufferPointer() , code->GetBufferSize() , 0 , NULL , &disasm ); if (NULL != disasm) { std::string disasmfp = _cmdLine.findOption('o'); disasmfp += ".disasm"; writeFile(disasmfp.c_str(), disasm->GetBufferPointer(), (uint32_t)disasm->GetBufferSize() ); disasm->Release(); } } if (NULL != errorMsg) { errorMsg->Release(); } result = true; error: code->Release(); unload(); return result; }
HRESULT Shader::Init(ID3D11Device* device, ID3D11DeviceContext* deviceContext, char* filename, const D3D11_INPUT_ELEMENT_DESC* inputElementDesc, unsigned int numElements) { mImmediateContext = deviceContext; mDevice = device; HRESULT hr = S_OK; ID3DBlob* pBlobEffect = NULL; ID3DBlob* pBlobErrors = NULL; DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS; #if defined(DEBUG) || defined(_DEBUG) dwShaderFlags |= D3D10_SHADER_DEBUG; #endif hr = D3DX11CompileFromFile( filename, NULL, NULL, "", "fx_5_0", dwShaderFlags, NULL, NULL, &pBlobEffect, &pBlobErrors, NULL ); char* l_pError = NULL; if( FAILED(hr) ) { char msg[20000]; strcpy_s(msg, sizeof(msg), (char*)pBlobErrors->GetBufferPointer()); OutputDebugString(msg); MessageBox(GetDesktopWindow(), msg, "Effect compilation error", MB_OK | MB_ICONERROR); return hr; } if(FAILED(hr = D3DX11CreateEffectFromMemory( pBlobEffect->GetBufferPointer(), pBlobEffect->GetBufferSize(), dwShaderFlags, mDevice, &m_pEffect ))) { MessageBox(0, "Cannot create effect from memory.", "D3DX11CreateEffectFromMemory error", MB_OK | MB_ICONERROR); return hr; } m_pTechnique = m_pEffect->GetTechniqueByIndex(0); if(inputElementDesc) { D3DX11_PASS_DESC PassDesc; m_pTechnique->GetPassByIndex(0)->GetDesc(&PassDesc); if(FAILED(hr = mDevice->CreateInputLayout( inputElementDesc, numElements, PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize, &m_pInputLayout ))) { MessageBox(0, "Cannot create input layout.", "CreateInputLayout error", MB_OK | MB_ICONERROR); return hr; } } return hr; }
void VertexShader::InitFromFile(std::string inFileName) { assert(FileUtil::FileExists(inFileName.c_str())); CleanUp(); DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; std::wstring filename = std::wstring(inFileName.begin(), inFileName.end()); #ifdef _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. dwShaderFlags |= D3DCOMPILE_DEBUG; // Disable optimizations to further improve shader debugging dwShaderFlags |= D3DCOMPILE_SKIP_OPTIMIZATION; #endif ID3DBlob* pVSBlob = nullptr; ID3DBlob* pErrorBlob = nullptr; D3DCall(D3DCompileFromFile(filename.c_str(), nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE, "VS", "vs_5_0", dwShaderFlags, 0, &pVSBlob, &pErrorBlob)); if (pErrorBlob) { OutputDebugStringA(reinterpret_cast<const char*>(pErrorBlob->GetBufferPointer())); pErrorBlob->Release(); } D3DCall(theRenderContext.GetDevice()->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &mHandle)); // Reflect shader info ID3D11ShaderReflection* pVertexShaderReflection = NULL; D3DCall(D3DReflect(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&pVertexShaderReflection)); // Get shader info D3D11_SHADER_DESC shaderDesc; pVertexShaderReflection->GetDesc(&shaderDesc); // Read input layout description from shader info std::vector<D3D11_INPUT_ELEMENT_DESC> inputLayoutDesc; for (int i = 0; i < shaderDesc.InputParameters; i++) { D3D11_SIGNATURE_PARAMETER_DESC paramDesc; pVertexShaderReflection->GetInputParameterDesc(i, ¶mDesc); // fill out input element desc D3D11_INPUT_ELEMENT_DESC elementDesc; elementDesc.SemanticName = paramDesc.SemanticName; elementDesc.SemanticIndex = paramDesc.SemanticIndex; elementDesc.InputSlot = 0; if (i == 0) elementDesc.AlignedByteOffset = 0; else elementDesc.AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; elementDesc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; elementDesc.InstanceDataStepRate = 0; // determine DXGI format if (paramDesc.Mask == 1) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32_FLOAT; } else if (paramDesc.Mask <= 3) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32_FLOAT; } else if (paramDesc.Mask <= 7) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_FLOAT; } else if (paramDesc.Mask <= 15) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; } //save element desc inputLayoutDesc.push_back(elementDesc); } // Try to create Input Layout D3DCall(theRenderContext.GetDevice()->CreateInputLayout(&inputLayoutDesc[0], inputLayoutDesc.size(), pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &mVertexLayout)); //Free allocation shader reflection memory pVertexShaderReflection->Release(); pVSBlob->Release(); }
void hwRendererHelperDX::initializeDrawTextureEffect() { if( fDXContext == NULL ) return; // Create the effect if( fDrawTextureEffect == NULL ) { const char* simpleShaderCode = "Texture2D myTexture; \r\n" \ "SamplerState SamplerLinearWrap \r\n" \ "{ \r\n" \ " Filter = MIN_MAG_MIP_LINEAR; \r\n" \ " AddressU = Wrap; \r\n" \ " AddressV = Wrap; \r\n" \ "}; \r\n" \ "struct APP_TO_VS \r\n" \ "{ \r\n" \ " float3 Pos : POSITION; \r\n" \ " float2 TextCoord : TEXTCOORD; \r\n" \ "}; \r\n" \ "struct VS_TO_PS \r\n" \ "{ \r\n" \ " float4 Pos : SV_Position; \r\n" \ " float2 TextCoord : TEXTCOORD; \r\n" \ "}; \r\n" \ "VS_TO_PS BasicVS(APP_TO_VS IN) \r\n" \ "{ \r\n" \ " VS_TO_PS OUT; \r\n" \ " OUT.Pos = float4(IN.Pos, 1.0f); \r\n" \ " OUT.TextCoord = IN.TextCoord; \r\n" \ " return OUT; \r\n" \ "} \r\n" \ "float4 BasicPS(VS_TO_PS IN) : SV_Target \r\n" \ "{ \r\n" \ " float4 color = myTexture.Sample(SamplerLinearWrap, IN.TextCoord); \r\n" \ " return color; \r\n" \ "} \r\n" \ "technique10 simple \r\n" \ "{ \r\n" \ " pass p0 \r\n" \ " { \r\n" \ " SetVertexShader( CompileShader( vs_4_0, BasicVS() ) ); \r\n" \ " SetGeometryShader( NULL ); \r\n" \ " SetPixelShader( CompileShader( ps_4_0, BasicPS() ) ); \r\n" \ " } \r\n" \ "} \r\n"; const unsigned int simpleShaderLength = (unsigned int)strlen(simpleShaderCode); const D3D10_SHADER_MACRO macros[] = { { "DIRECT3D_VERSION", "0xb00" }, { NULL, NULL } }; #ifdef _DEBUG const unsigned int flags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else const unsigned int flags = 0; #endif ID3DBlob *shader = NULL; ID3DBlob *error = NULL; #if _MSC_VER >= 1700 HRESULT hr = D3DCompile((char*)simpleShaderCode, simpleShaderLength, NULL, macros, NULL, "", "fx_5_0", flags, 0, &shader, &error); #else HRESULT hr = D3DX11CompileFromMemory((char*)simpleShaderCode, simpleShaderLength, NULL, macros, NULL, "", "fx_5_0", flags, 0, NULL, &shader, &error, NULL); #endif if( SUCCEEDED( hr ) && shader != NULL ) { hr = D3DX11CreateEffectFromMemory(shader->GetBufferPointer(), shader->GetBufferSize(), 0, fDXDevice, &fDrawTextureEffect); if( SUCCEEDED( hr ) && fDrawTextureEffect != NULL ) { ID3DX11EffectVariable* textureVariable = fDrawTextureEffect->GetVariableByName( "myTexture" ); if( textureVariable != NULL ) { fDrawTextureShaderVariable = textureVariable->AsShaderResource(); } ID3DX11EffectTechnique* technique = fDrawTextureEffect->GetTechniqueByIndex(0); if( technique ) { fDrawTexturePass = technique->GetPassByIndex(0); } } } else { MString errorStr( (error && error->GetBufferSize() > 0) ? (char*) error->GetBufferPointer() : (char*) NULL ); MGlobal::displayWarning( hwApiTextureTestStrings::getString( hwApiTextureTestStrings::kDxErrorEffect, errorStr ) ); } if( shader != NULL ) { shader->Release(); } } // Create the vertex buffers and the input layout if( fDrawTextureInputLayout == NULL && fDrawTexturePass != NULL ) { fDrawTextureVertexBuffersCount = 0; D3D11_INPUT_ELEMENT_DESC inputDesc[MAX_VERTEX_BUFFERS]; HRESULT hr; // Create the position stream { const float position[] = { -1, -1, 0, // bottom-left -1, 1, 0, // top-left 1, 1, 0, // top-right 1, -1, 0 }; // bottom-right const D3D11_BUFFER_DESC bufDesc = { sizeof(position), D3D11_USAGE_IMMUTABLE, D3D11_BIND_VERTEX_BUFFER, 0, 0, 0 }; const D3D11_SUBRESOURCE_DATA bufData = { position, 0, 0 }; ID3D11Buffer *buffer = NULL; hr = fDXDevice->CreateBuffer(&bufDesc, &bufData, &buffer); if( SUCCEEDED( hr ) && buffer != NULL ) { inputDesc[fDrawTextureVertexBuffersCount].SemanticName = "POSITION"; inputDesc[fDrawTextureVertexBuffersCount].SemanticIndex = 0; inputDesc[fDrawTextureVertexBuffersCount].Format = DXGI_FORMAT_R32G32B32_FLOAT; inputDesc[fDrawTextureVertexBuffersCount].InputSlot = fDrawTextureVertexBuffersCount; inputDesc[fDrawTextureVertexBuffersCount].AlignedByteOffset = 0; inputDesc[fDrawTextureVertexBuffersCount].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; inputDesc[fDrawTextureVertexBuffersCount].InstanceDataStepRate = 0; fDrawTextureVertexBuffers[fDrawTextureVertexBuffersCount] = buffer; fDrawTextureVertexBuffersStrides[fDrawTextureVertexBuffersCount] = 3 * sizeof(float); fDrawTextureVertexBuffersOffsets[fDrawTextureVertexBuffersCount] = 0; ++fDrawTextureVertexBuffersCount; } } // Create the texture coord stream if( SUCCEEDED( hr ) ) { const float textCoord[] = { 0, 1, // bottom-left 0, 0, // top-left 1, 0, // top-right 1, 1 }; // bottom-right const D3D11_BUFFER_DESC bufDesc = { sizeof(textCoord), D3D11_USAGE_IMMUTABLE, D3D11_BIND_VERTEX_BUFFER, 0, 0, 0 }; const D3D11_SUBRESOURCE_DATA bufData = { textCoord, 0, 0 }; ID3D11Buffer *buffer = NULL; hr = fDXDevice->CreateBuffer(&bufDesc, &bufData, &buffer); if( SUCCEEDED( hr ) && buffer != NULL ) { inputDesc[fDrawTextureVertexBuffersCount].SemanticName = "TEXTCOORD"; inputDesc[fDrawTextureVertexBuffersCount].SemanticIndex = 0; inputDesc[fDrawTextureVertexBuffersCount].Format = DXGI_FORMAT_R32G32_FLOAT; inputDesc[fDrawTextureVertexBuffersCount].InputSlot = fDrawTextureVertexBuffersCount; inputDesc[fDrawTextureVertexBuffersCount].AlignedByteOffset = 0; inputDesc[fDrawTextureVertexBuffersCount].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; inputDesc[fDrawTextureVertexBuffersCount].InstanceDataStepRate = 0; fDrawTextureVertexBuffers[fDrawTextureVertexBuffersCount] = buffer; fDrawTextureVertexBuffersStrides[fDrawTextureVertexBuffersCount] = 2 * sizeof(float); fDrawTextureVertexBuffersOffsets[fDrawTextureVertexBuffersCount] = 0; ++fDrawTextureVertexBuffersCount; } } if( SUCCEEDED( hr ) ) { D3DX11_PASS_DESC descPass; fDrawTexturePass->GetDesc(&descPass); hr = fDXDevice->CreateInputLayout(inputDesc, fDrawTextureVertexBuffersCount, descPass.pIAInputSignature, descPass.IAInputSignatureSize, &fDrawTextureInputLayout); if( FAILED( hr ) ) { MGlobal::displayWarning( hwApiTextureTestStrings::getString( hwApiTextureTestStrings::kDxErrorInputLayout ) ); } } } // Create the index buffer if( fDrawTextureIndexBuffer == NULL && fDrawTextureVertexBuffersCount > 0 && fDrawTextureInputLayout != NULL ) { const unsigned int indices[] = { 0, 1, 3, 3, 2, 1 }; fDrawTextureIndexBufferCount = _countof(indices); const D3D11_BUFFER_DESC bufDesc = { sizeof(indices), D3D11_USAGE_IMMUTABLE, D3D11_BIND_INDEX_BUFFER, 0, 0, 0 }; const D3D11_SUBRESOURCE_DATA bufData = { indices, 0, 0 }; fDXDevice->CreateBuffer(&bufDesc, &bufData, &fDrawTextureIndexBuffer); } }
void KTRoboDemoRender::Init(Graphics* g) { HRESULT hr = S_OK; ID3DBlob* pblob = 0; font = 0; p_blendstate = 0; p_sampler = 0; p_rasterstate = 0; try { CompileShaderFromFile("resrc/shader/sample.fx", "VSFunc", "vs_4_0", &pblob); hr = g->getDevice()->CreateVertexShader(pblob->GetBufferPointer(), pblob->GetBufferSize(), NULL, &vs); if (FAILED(hr)) { pblob->Release(); pblob = 0; vs = 0; } // 入力レイアウトの定義 D3D11_INPUT_ELEMENT_DESC layout[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0}, }; unsigned int num = sizeof(layout)/ sizeof(layout[0]); hr = g->getDevice()->CreateInputLayout( layout,num,pblob->GetBufferPointer(), pblob->GetBufferSize(), &p_vertexlayout); if (FAILED(hr)) { throw new KTROBO::GameError(KTROBO::FATAL_ERROR, "layout make error");; } if (pblob) { pblob->Release(); pblob = 0; } // Set the input layout g->getDeviceContext()->IASetInputLayout( p_vertexlayout ); /* CompileShaderFromFile("resrc/shader/sample.fx", "GSFunc", "gs_4_0", &pblob); hr = g->getDevice()->CreateGeometryShader(pblob->GetBufferPointer(), pblob->GetBufferSize(), NULL, &gs); if (FAILED(hr)) { pblob->Release(); pblob = 0; gs = 0; } if (pblob) { pblob->Release(); pblob = 0; } */ CompileShaderFromFile("resrc/shader/sample.fx", "PSFunc", "ps_4_0", &pblob); hr = g->getDevice()->CreatePixelShader(pblob->GetBufferPointer(), pblob->GetBufferSize(), NULL,&ps); if (FAILED(hr)) { pblob->Release(); pblob = 0; ps = 0; } if (pblob) { pblob->Release(); pblob = 0; } D3D11_BLEND_DESC BlendDesc; memset(&BlendDesc, 0, sizeof(BlendDesc)); BlendDesc.AlphaToCoverageEnable = FALSE; BlendDesc.IndependentBlendEnable = FALSE; BlendDesc.RenderTarget[0].BlendEnable = FALSE; BlendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; BlendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_DEST_ALPHA; BlendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; BlendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; BlendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; BlendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; BlendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; HRESULT hr = g->getDevice()->CreateBlendState(&BlendDesc,&p_blendstate); if (FAILED(hr)) { throw new GameError(KTROBO::FATAL_ERROR, "failed in blend state create"); } } catch (KTROBO::GameError* e) { if (pblob) { pblob->Release(); pblob = 0; } Release(); // MessageBoxA(NULL,e->getMessage(), "shader compile error", MB_OK); throw e; } float de = 1/(float)4;//512.0/2049;//*512/4096.0f; float te = 1.0f/2 * 1 * 2; float of = 1.0f/4 * 1 * 2 ; float xof = 1.0f/4 * 1 * 2 ; // 頂点バッファの作成 SimpleVertex vertices[] = { {XMFLOAT3(0.0f-te-xof,0.0f,0.0f),XMFLOAT2(0.0f,1.0f*de)}, {XMFLOAT3(0.0f-te-xof,1.0f * te,0.0f),XMFLOAT2(0.0f,0.0f)}, {XMFLOAT3(1.0f* te-te-xof,0.0f,0.0f),XMFLOAT2(1.0f*de,1.0f*de)}, {XMFLOAT3(1.0f* te-te-xof,0.0f,0.0f),XMFLOAT2(1.0f*de,1.0f*de)}, {XMFLOAT3(0.0f-te-xof,1.0f* te,0.0f),XMFLOAT2(0.0f,0.0f)}, {XMFLOAT3(1.0f*te-te-xof,1.0f*te,0.0f),XMFLOAT2(1.0f*de,0.0f)}, {XMFLOAT3(0.0f-xof,0.0f,0.0f),XMFLOAT2(0.0f,1.0f*de/2+de/2)}, {XMFLOAT3(0.0f-xof,1.0f * te/2,0.0f),XMFLOAT2(0.0f,0.0f+de/2)}, {XMFLOAT3(1.0f* te/2-xof,0.0f,0.0f),XMFLOAT2(1.0f*de/2,1.0f*de/2+de/2)}, {XMFLOAT3(1.0f* te/2-xof,0.0f,0.0f),XMFLOAT2(1.0f*de/2,1.0f*de/2+de/2)}, {XMFLOAT3(0.0f-xof,1.0f* te/2,0.0f),XMFLOAT2(0.0f,0.0f+de/2)}, {XMFLOAT3(1.0f*te/2-xof,1.0f*te/2,0.0f),XMFLOAT2(1.0f*de/2,0.0f+de/2)}, {XMFLOAT3(0.0f + of-xof ,0.0f,0.0f),XMFLOAT2(0.0f+de/2,1.0f*de/2+de/2)}, {XMFLOAT3(0.0f+of-xof,1.0f * te/2,0.0f),XMFLOAT2(0.0f+de/2,0.0f+de/2)}, {XMFLOAT3(1.0f* te/2+of-xof,0.0f,0.0f),XMFLOAT2(1.0f*de/2+de/2,1.0f*de/2+de/2)}, {XMFLOAT3(1.0f* te/2+of-xof,0.0f,0.0f),XMFLOAT2(1.0f*de/2+de/2,1.0f*de/2+de/2)}, {XMFLOAT3(0.0f+of-xof,1.0f* te/2,0.0f),XMFLOAT2(0.0f+de/2,0.0f+de/2)}, {XMFLOAT3(1.0f*te/2+of-xof,1.0f*te/2,0.0f),XMFLOAT2(1.0f*de/2+de/2,0.0f+de/2)}, {XMFLOAT3(0.0f-xof,0.0f+of,0.0f),XMFLOAT2(0.0f,1.0f*de/2)}, {XMFLOAT3(0.0f-xof,1.0f * te/2+of,0.0f),XMFLOAT2(0.0f,0.0f)}, {XMFLOAT3(1.0f* te/2-xof,0.0f+of,0.0f),XMFLOAT2(1.0f*de/2,1.0f*de/2)}, {XMFLOAT3(1.0f* te/2-xof,0.0f+of,0.0f),XMFLOAT2(1.0f*de/2,1.0f*de/2)}, {XMFLOAT3(0.0f-xof,1.0f* te/2+of,0.0f),XMFLOAT2(0.0f,0.0f)}, {XMFLOAT3(1.0f*te/2-xof,1.0f*te/2+of,0.0f),XMFLOAT2(1.0f*de/2,0.0f)}, {XMFLOAT3(0.0f+of-xof,0.0f+of,0.0f),XMFLOAT2(0.0f+de/2,1.0f*de/2)}, {XMFLOAT3(0.0f+of-xof,1.0f * te/2+of,0.0f),XMFLOAT2(0.0f+de/2,0.0f)}, {XMFLOAT3(1.0f* te/2+of-xof,0.0f+of,0.0f),XMFLOAT2(1.0f*de/2+de/2,1.0f*de/2)}, {XMFLOAT3(1.0f* te/2+of-xof,0.0f+of,0.0f),XMFLOAT2(1.0f*de/2+de/2,1.0f*de/2)}, {XMFLOAT3(0.0f+of-xof,1.0f* te/2+of,0.0f),XMFLOAT2(0.0f+de/2,0.0f)}, {XMFLOAT3(1.0f*te/2+of-xof,1.0f*te/2+of,0.0f),XMFLOAT2(1.0f*de/2+de/2,0.0f)}, }; D3D11_BUFFER_DESC bd; memset(&bd,0,sizeof(bd)); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof(SimpleVertex)*30; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA initData; memset(&initData, 0, sizeof(initData)); initData.pSysMem = vertices; hr = g->getDevice()->CreateBuffer(&bd, &initData,&p_vertexbuffer); if (FAILED(hr)) { Release(); throw new KTROBO::GameError(KTROBO::FATAL_ERROR, "vertex buffer make error");; } unsigned int stride = sizeof(SimpleVertex); unsigned int offset = 0; g->getDeviceContext()->IASetInputLayout(p_vertexlayout); g->getDeviceContext()->IASetVertexBuffers( 0, 1, &p_vertexbuffer, &stride, &offset ); g->getDeviceContext()->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); font = new Font(); font->Init("resrc/azukiL.ttf","あずきフォントL",g); tex_loader = new MyTextureLoader(); tex_loader->init(g); render_target_tex = tex_loader->makeClass(1024,1024); msaa_tex = tex_loader->makeClass(1024,1024); D3D11_SAMPLER_DESC descS; memset(&descS, 0, sizeof(descS)); descS.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; descS.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; descS.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; descS.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; descS.BorderColor[0] = 0; descS.BorderColor[1] = 0; descS.BorderColor[2] = 0; descS.BorderColor[3] = 0; descS.ComparisonFunc = D3D11_COMPARISON_NEVER; descS.MaxAnisotropy = 1; descS.MinLOD = 1; descS.MaxLOD = D3D11_FLOAT32_MAX; hr = g->getDevice()->CreateSamplerState(&descS, &p_sampler); if (FAILED(hr)) { Release(); throw new KTROBO::GameError(KTROBO::FATAL_ERROR, "sampler make error");; } D3D11_RASTERIZER_DESC _rasterDesc; _rasterDesc.AntialiasedLineEnable = false;//true; // changed to true _rasterDesc.CullMode = D3D11_CULL_NONE; _rasterDesc.DepthBias = 0; _rasterDesc.DepthBiasClamp = 0.0f; _rasterDesc.DepthClipEnable = false; _rasterDesc.FillMode = D3D11_FILL_SOLID; _rasterDesc.FrontCounterClockwise = false; _rasterDesc.MultisampleEnable = false;//true; // changed to true _rasterDesc.ScissorEnable = false; _rasterDesc.SlopeScaledDepthBias = 0.0f; hr = g->getDevice()->CreateRasterizerState( &_rasterDesc, &p_rasterstate ); if( FAILED( hr ) ) { Release(); throw new KTROBO::GameError(KTROBO::FATAL_ERROR, "raster make error");; } }
// 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 main() { // Create Device const D3D_FEATURE_LEVEL lvl[] = { D3D_FEATURE_LEVEL_11_1 }; UINT createDeviceFlags = 0; #ifdef _DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif /* ================================== */ printf("Creating device..."); ID3D11Device* device = nullptr; HRESULT hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, lvl, _countof(lvl), D3D11_SDK_VERSION, &device, nullptr, nullptr); if (FAILED(hr)) { printf("Failed creating Direct3D 11 device %08X\n", hr); return returnDBG(-1); } /* ================================== */ printf("Compile Compute Shader..."); ID3DBlob *csBlob = nullptr; hr = CompileComputeShader(L"ComputeShader.hlsl", "main", device, &csBlob); if (FAILED(hr)) { device->Release(); printf("Failed compiling shader %08X\n", hr); return returnDBG(-1); } /* ================================== */ printf("Create Compute Shader..."); ID3D11ComputeShader* computeShader = nullptr; hr = device->CreateComputeShader(csBlob->GetBufferPointer(), csBlob->GetBufferSize(), nullptr, &computeShader); /* ================================== */ printf("Creating buffers and filling them with initial data..."); for (int i = 0; i < NUM_ELEMENTS; ++i) { g_vBuf0[i].i = i; g_vBuf0[i].f = (float)i; g_vBuf1[i].i = i; g_vBuf1[i].f = (float)i; } CreateRawBuffer(g_pDevice, NUM_ELEMENTS * sizeof(BufType), &g_vBuf0[0], &g_pBuf0); CreateRawBuffer(g_pDevice, NUM_ELEMENTS * sizeof(BufType), &g_vBuf1[0], &g_pBuf1); CreateRawBuffer(g_pDevice, NUM_ELEMENTS * sizeof(BufType), nullptr, &g_pBufResult); /* ================================== */ printf("Running Compute Shader..."); ID3D11ShaderResourceView* aRViews[2] = { g_pBuf0SRV, g_pBuf1SRV }; RunComputeShader(g_pContext, g_pCS, 2, aRViews, nullptr, nullptr, 0, g_pBufResultUAV, NUM_ELEMENTS, 1, 1); printf("done\n"); csBlob->Release(); if (FAILED(hr)) { device->Release(); } printf("Success\n"); // Clean up computeShader->Release(); device->Release(); return returnDBG(0); }
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, D3D_DRIVER_TYPE_REFERENCE, }; UINT numDriverTypes = ARRAYSIZE(driverTypes); D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_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; sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++) { g_driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDeviceAndSwapChain(NULL, g_driverType, NULL, 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 = NULL; hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); if (FAILED(hr)) return hr; hr = g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &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, NULL, &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); // Compile the vertex shader ID3DBlob* pVSBlob = NULL; hr = CompileShaderFromFile(L"Tutorial05.fx", "VS", "vs_4_0", &pVSBlob); if (FAILED(hr)) { MessageBox(NULL, 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(), NULL, &g_pVertexShader); if (FAILED(hr)) { 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 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 36, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 48, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "BINORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 60, 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 = NULL; hr = CompileShaderFromFile(L"Tutorial05.fx", "PS", "ps_4_0", &pPSBlob); if (FAILED(hr)) { MessageBox(NULL, 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(), NULL, &g_pPixelShader); pPSBlob->Release(); if (FAILED(hr)) return hr; // ------------------------------------------------------------- // JPE: Shaders para WireFrame // ------------------------------------------------------------- // Compile the vertex shader ID3DBlob* pVSBlobWF = NULL; hr = CompileShaderFromFile(L"Tutorial05.fx", "VS_WF", "vs_4_0", &pVSBlobWF); if (FAILED(hr)) { MessageBox(NULL, 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(pVSBlobWF->GetBufferPointer(), pVSBlobWF->GetBufferSize(), NULL, &g_pVertexShaderWF); pVSBlobWF->Release(); if (FAILED(hr)) return hr; // Compile the pixel shader ID3DBlob* pPSBlobWF = NULL; hr = CompileShaderFromFile(L"Tutorial05.fx", "PS_WF", "ps_4_0", &pPSBlobWF); if (FAILED(hr)) { MessageBox(NULL, 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(pPSBlobWF->GetBufferPointer(), pPSBlobWF->GetBufferSize(), NULL, &g_pPixelShaderWF); pPSBlobWF->Release(); if (FAILED(hr)) return hr; // ------------------------------------------------------------- // JPE: Create vertex buffer and index buffer SimpleVertex* vertices; WORD* indices; if (modelo == ModeloMono) { LoadFileOFF(&vertices, &indices, &cantVertices, &cantIndices); } else { LoadVertices(&vertices, &indices, &cantVertices, &cantIndices); } CalcularNormales(vertices, indices, cantVertices, cantIndices); // Crea Buffer para Vertices D3D11_BUFFER_DESC bd; ZeroMemory( &bd, sizeof(bd) ); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( SimpleVertex ) * cantVertices; 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 ); // Crea Buffer para Indexes bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( WORD ) * cantIndices; // 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, NULL, &g_pConstantBuffer ); if( FAILED( hr ) ) return hr; // JPE: Create the constant buffer for PixelShader bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof(ConstantBufferPS); bd.BindFlags = D3D11_BIND_SHADER_RESOURCE; bd.CPUAccessFlags = 0; hr = g_pd3dDevice->CreateBuffer(&bd, NULL, &g_pConstantBufferPS); if (FAILED(hr)) return hr; // Initialize the world matrix g_World1 = XMMatrixIdentity(); g_World2 = XMMatrixIdentity(); SetViewMatrix(); // Initialize the projection matrix g_Projection = XMMatrixPerspectiveFovLH( XM_PIDIV2, width / (FLOAT)height, 0.01f, 100.0f ); // JPE: Texturas loadTextures(g_pd3dDevice); // JPE: Raster state ///* D3D11_RASTERIZER_DESC rasterDesc; // Setup the raster description which will determine how and what polygons will be drawn. rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; // Create the rasterizer state from the description we just filled out. hr = g_pd3dDevice->CreateRasterizerState(&rasterDesc, &m_rasterState); if (FAILED(hr)) { return hr; } // Now set the rasterizer state. g_pImmediateContext->RSSetState(m_rasterState); //*/ // JPE: Raster state para WireFrame // Setup the raster description which will determine how and what polygons will be drawn. rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_FILL_WIREFRAME; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; // Create the rasterizer state from the description we just filled out. hr = g_pd3dDevice->CreateRasterizerState(&rasterDesc, &m_rasterStateWF); if (FAILED(hr)) { return hr; } // JPE: Parametros default if (modelo == ModeloMono) { bump = false; useTexture = false; rotate = false; } return S_OK; }
// Loads the specified shader and builds the variable table using // shader reflection // // 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; }
bool Graphics::CreateDefaultShader() { HRESULT r = 0; ID3DBlob* vsBuffer = 0; ID3DBlob* buffer = 0; ID3DBlob* Errors = 0; DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG; bool b = CompileD3DShader("..\\te010\\DefaultShader.fx", 0, "fx_5_0", &buffer); if (!b) { if (buffer) { buffer->Release(); } NAIA_FATAL("Unnable to compile default shader"); } r = D3DX11CreateEffectFromMemory(buffer->GetBufferPointer(), buffer->GetBufferSize(), 0 , m_Device, &m_Effect); if (FAILED(r)) { NAIA_FATAL("Unnable to create effect"); } m_Technique = m_Effect->GetTechniqueByName("DefaultTechnique"); if (!m_Technique) { NAIA_FATAL("Can not find DefaultTechnique in default shader"); } D3D11_INPUT_ELEMENT_DESC defaultLayout[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0} }; unsigned int totalLayoutElements = ARRAYSIZE(defaultLayout); D3DX11_PASS_DESC descPASS; m_Technique->GetPassByIndex(0)->GetDesc(&descPASS); r = m_Device->CreateInputLayout(defaultLayout, totalLayoutElements, descPASS.pIAInputSignature, descPASS.IAInputSignatureSize, &m_InputLayout); if (FAILED(r)) { NAIA_FATAL("Failed to create input layout"); } m_Context->IASetInputLayout(m_InputLayout); Mat4x4 world = Mat4x4::g_Identity; SetWorldMatrix(world); Mat4x4 view = Mat4x4::g_Identity; Vec3 eye(6.0f, 6.0f, 6.0f); Vec3 at(0.f,0.f,0.f); Vec3 up(0.f,1.0f,0.f); D3DXMatrixLookAtLH(&view, &eye, &at, &up); SetViewMatrix(view); Mat4x4 proj = Mat4x4::g_Identity; D3DXMatrixPerspectiveFovLH(&proj, NAIA_PI/2, Application::instance()->m_Width/(float)Application::instance()->m_Height, 0.01f, 100.0f); SetProjectionMatrix(proj); #pragma region Create constant buffers D3D11_BUFFER_DESC bd; ZeroMemory(&bd, sizeof(bd)); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof(CBNeverChanges); bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bd.CPUAccessFlags = 0; r = m_Device->CreateBuffer(&bd, NULL, &m_cbNeverChanges); if (FAILED(r)) { NAIA_FATAL("Can not create constant buffer (Never changes)"); } bd.ByteWidth = sizeof(CBChangeOnResize); r = m_Device->CreateBuffer(&bd, NULL, &m_cbChangesOnResize); if (FAILED(r)) { NAIA_FATAL("Can not create constant buffer (Changes on resize)"); } bd.ByteWidth = sizeof(CBChangesEveryFrame); r = m_Device->CreateBuffer(&bd, NULL, &m_cbChangesEveryFrame); if (FAILED(r)) { NAIA_FATAL("Can not create constant buffer (Changes every frame)"); } #pragma endregion CBNeverChanges cbNeverChanges; cbNeverChanges.View = view; m_Context->UpdateSubresource(m_cbNeverChanges, 0, NULL, &cbNeverChanges, 0, 0); CBChangeOnResize cbChangesOnResize; cbChangesOnResize.Projection = proj; m_Context->UpdateSubresource(m_cbChangesOnResize, 0, NULL, &cbChangesOnResize, 0, 0); CBChangesEveryFrame cbChangesEveryFrame; cbChangesEveryFrame.World = world; m_Context->UpdateSubresource(m_cbChangesEveryFrame, 0, NULL, &cbChangesEveryFrame, 0, 0); return true; }
static ID3DBlob* CompileShader(const wchar* path, const char* functionName, const char* profile, const D3D_SHADER_MACRO* defines, bool forceOptimization, vector<wstring>& filePaths) { // Make a hash off the expanded shader code string shaderCode = GetExpandedShaderCode(path, filePaths); wstring cacheName = MakeShaderCacheName(shaderCode, functionName, profile, defines); if (FileExists(cacheName.c_str())) { File cacheFile(cacheName.c_str(), File::OpenRead); const size_t shaderSize = cacheFile.Size(); vector<uint8> compressedShader; compressedShader.resize(shaderSize); cacheFile.Read(shaderSize, compressedShader.data()); ID3DBlob* decompressedShader[1] = { nullptr }; uint32 indices[1] = { 0 }; DXCall(D3DDecompressShaders(compressedShader.data(), shaderSize, 1, 0, indices, 0, decompressedShader, nullptr)); return decompressedShader[0]; } std::printf("Compiling shader %s %s %s\n", WStringToAnsi(GetFileName(path).c_str()).c_str(), profile, MakeDefinesString(defines).c_str()); // Loop until we succeed, or an exception is thrown while (true) { UINT flags = D3DCOMPILE_WARNINGS_ARE_ERRORS; #ifdef _DEBUG flags |= D3DCOMPILE_DEBUG; if(forceOptimization == false) flags |= D3DCOMPILE_SKIP_OPTIMIZATION; #endif ID3DBlob* compiledShader; ID3DBlobPtr errorMessages; HRESULT hr = D3DCompileFromFile(path, defines, D3D_COMPILE_STANDARD_FILE_INCLUDE, functionName, profile, flags, 0, &compiledShader, &errorMessages); if (FAILED(hr)) { if (errorMessages) { wchar message[1024] = { 0 }; char* blobdata = reinterpret_cast<char*>(errorMessages->GetBufferPointer()); MultiByteToWideChar(CP_ACP, 0, blobdata, static_cast<int>(errorMessages->GetBufferSize()), message, 1024); std::wstring fullMessage = L"Error compiling shader file \""; fullMessage += path; fullMessage += L"\" - "; fullMessage += message; // Pop up a message box allowing user to retry compilation int retVal = MessageBoxW(nullptr, fullMessage.c_str(), L"Shader Compilation Error", MB_RETRYCANCEL); if (retVal != IDRETRY) throw DXException(hr, fullMessage.c_str()); #if EnableShaderCaching_ shaderCode = GetExpandedShaderCode(path); cacheName = MakeShaderCacheName(shaderCode, functionName, profile, defines); #endif } else { _ASSERT(false); throw DXException(hr); } } else { // Compress the shader D3D_SHADER_DATA shaderData; shaderData.pBytecode = compiledShader->GetBufferPointer(); shaderData.BytecodeLength = compiledShader->GetBufferSize(); ID3DBlobPtr compressedShader; DXCall(D3DCompressShaders(1, &shaderData, D3D_COMPRESS_SHADER_KEEP_ALL_PARTS, &compressedShader)); // Create the cache directory if it doesn't exist if (DirectoryExists(baseCacheDir.c_str()) == false) Win32Call(CreateDirectory(baseCacheDir.c_str(), nullptr)); if (DirectoryExists(cacheDir.c_str()) == false) Win32Call(CreateDirectory(cacheDir.c_str(), nullptr)); File cacheFile(cacheName.c_str(), File::OpenWrite); // Write the compiled shader to disk size_t shaderSize = compressedShader->GetBufferSize(); cacheFile.Write(shaderSize, compressedShader->GetBufferPointer()); return compiledShader; } } }
bool ParticleManager::BuildShaders(ID3D11Device* pDevice) { #pragma region COMPILE_RENDER_SHADER if (!CompileShader(&m_vBlob, "Data/particles.fx", "VS_MAIN", "vs_5_0")) { return false; } ID3DBlob* pBlob = 0; if (!CompileShader(&pBlob, "Data/particles.fx", "PS_MAIN", "ps_5_0")) { if (pBlob) { pBlob->Release(); } return false; } #pragma endregion #pragma region COMPILE_UPDATE_SHADER ID3DBlob* vBlob = 0; if (!CompileShader(&vBlob, "Data/particles.fx", "VS_MAIN_SO", "vs_5_0")) { if (vBlob) { vBlob->Release(); } return false; } ID3DBlob* gBlob = 0; if (!CompileShader(&gBlob, "Data/particles.fx", "GS_MAIN_SO", "gs_5_0")) { if (gBlob) { gBlob->Release(); } return false; } #pragma endregion #pragma region CREATE_RENDER_SHADER HRESULT hr = 0; hr = pDevice->CreateVertexShader(m_vBlob->GetBufferPointer(), m_vBlob->GetBufferSize(), NULL, &m_vShader); if (FAILED(hr)) { return false; } hr = pDevice->CreatePixelShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), NULL, &m_pShader); if (FAILED(hr)) { pBlob->Release(); return false; } pBlob->Release(); #pragma endregion hr = pDevice->CreateVertexShader(vBlob->GetBufferPointer(), vBlob->GetBufferSize(), NULL, &m_vUpdate); if (FAILED(hr)) { vBlob->Release(); return false; } //Stream out decl D3D11_SO_DECLARATION_ENTRY dso[] = { { 0, "SV_POSITION", 0, 0, 3, 0 }, { 0, "VELOCITY", 0, 0, 3, 0 }, { 0, "COLOR", 0, 0, 4, 0 } }; UINT stride = sizeof(Particle); UINT elems = sizeof(dso) / sizeof(D3D11_SO_DECLARATION_ENTRY); hr = pDevice->CreateGeometryShaderWithStreamOutput( gBlob->GetBufferPointer(), gBlob->GetBufferSize(), dso, elems, &stride, 1, 0, NULL, &m_gUpdate); if (FAILED(hr)) { gBlob->Release(); return false; } vBlob->Release(); gBlob->Release(); return true; }
bool ColorShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR* vsFilename, WCHAR* psFilename) { HRESULT result = S_OK; ID3DBlob* vertexShaderBuffer; ID3DBlob* pixelShaderBuffer; D3D11_INPUT_ELEMENT_DESC polygonLayout[2]; unsigned int numElements; D3D11_BUFFER_DESC matrixBufferDesc; // Initialize the pointers this function will use to null. vertexShaderBuffer = 0; pixelShaderBuffer = 0; LPCSTR profile = ( device->GetFeatureLevel() >= D3D_FEATURE_LEVEL_11_0 ) ? "vs_5_0" : "vs_4_0"; // Compile the vertex shader code. result = CompileShaderFromFile(vsFilename,"ColorVertexShader",profile,&vertexShaderBuffer); if(FAILED(result)){ MessageBox(hwnd, L"Error compiling vertex shader.", vsFilename, MB_OK); return false; } profile = ( device->GetFeatureLevel() >= D3D_FEATURE_LEVEL_11_0 ) ? "ps_5_0" : "ps_4_0"; // Compile the pixel shader code. result = CompileShaderFromFile(psFilename, "ColorPixelShader", profile, &pixelShaderBuffer); if(FAILED(result)){ MessageBox(hwnd, L"Error compiling pixel shader.", psFilename, MB_OK); return false; } // Create the vertex shader from the buffer. result = device->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &m_vertexShader); if(FAILED(result)) { return false; } // Create the pixel shader from the buffer. result = device->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, &m_pixelShader); if(FAILED(result)) { return false; } // Create the vertex input layout description. // This setup needs to match the VertexType stucture in the ModelClass and in the shader. polygonLayout[0].SemanticName = "POSITION"; polygonLayout[0].SemanticIndex = 0; polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT; polygonLayout[0].InputSlot = 0; polygonLayout[0].AlignedByteOffset = 0; polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; polygonLayout[0].InstanceDataStepRate = 0; polygonLayout[1].SemanticName = "COLOR"; polygonLayout[1].SemanticIndex = 0; polygonLayout[1].Format = DXGI_FORMAT_R32G32B32A32_FLOAT; polygonLayout[1].InputSlot = 0; polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; polygonLayout[1].InstanceDataStepRate = 0; // Get a count of the elements in the layout. numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]); // Create the vertex input layout. result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), &m_layout); if(FAILED(result)) { return false; } // Release the vertex shader buffer and pixel shader buffer since they are no longer needed. vertexShaderBuffer->Release(); vertexShaderBuffer = 0; pixelShaderBuffer->Release(); pixelShaderBuffer = 0; // Setup the description of the dynamic matrix constant buffer that is in the vertex shader. matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC; matrixBufferDesc.ByteWidth = sizeof(ConstantBufferType); matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; matrixBufferDesc.MiscFlags = 0; matrixBufferDesc.StructureByteStride = 0; // Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class. result = device->CreateBuffer(&matrixBufferDesc, NULL, &m_matrixBuffer); if(FAILED(result)) { return false; } return true; }
//-------------------------------------------------------------------------------------- // Create Direct3D device and swap chain //-------------------------------------------------------------------------------------- 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, D3D_DRIVER_TYPE_REFERENCE, }; UINT numDriverTypes = ARRAYSIZE( driverTypes ); D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT numFeatureLevels = ARRAYSIZE( featureLevels ); for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) { g_driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); if ( hr == E_INVALIDARG ) { // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); } if( SUCCEEDED( hr ) ) break; } if( FAILED( hr ) ) return hr; // Obtain DXGI factory from device (since we used nullptr for pAdapter above) IDXGIFactory1* dxgiFactory = nullptr; { IDXGIDevice* dxgiDevice = nullptr; hr = g_pd3dDevice->QueryInterface( __uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice) ); if (SUCCEEDED(hr)) { IDXGIAdapter* adapter = nullptr; hr = dxgiDevice->GetAdapter(&adapter); if (SUCCEEDED(hr)) { hr = adapter->GetParent( __uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory) ); adapter->Release(); } dxgiDevice->Release(); } } if (FAILED(hr)) return hr; // Create swap chain IDXGIFactory2* dxgiFactory2 = nullptr; hr = dxgiFactory->QueryInterface( __uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2) ); if ( dxgiFactory2 ) { // DirectX 11.1 or later hr = g_pd3dDevice->QueryInterface( __uuidof(ID3D11Device1), reinterpret_cast<void**>(&g_pd3dDevice1) ); if (SUCCEEDED(hr)) { (void) g_pImmediateContext->QueryInterface( __uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&g_pImmediateContext1) ); } DXGI_SWAP_CHAIN_DESC1 sd; ZeroMemory(&sd, sizeof(sd)); sd.Width = width; sd.Height = height; sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; hr = dxgiFactory2->CreateSwapChainForHwnd( g_pd3dDevice, g_hWnd, &sd, nullptr, nullptr, &g_pSwapChain1 ); if (SUCCEEDED(hr)) { hr = g_pSwapChain1->QueryInterface( __uuidof(IDXGISwapChain), reinterpret_cast<void**>(&g_pSwapChain) ); } dxgiFactory2->Release(); } else { // DirectX 11.0 systems 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; hr = dxgiFactory->CreateSwapChain( g_pd3dDevice, &sd, &g_pSwapChain ); } // Note this tutorial doesn't handle full-screen swapchains so we block the ALT+ENTER shortcut dxgiFactory->MakeWindowAssociation( g_hWnd, DXGI_MWA_NO_ALT_ENTER ); dxgiFactory->Release(); if (FAILED(hr)) return hr; // Create a render target view ID3D11Texture2D* pBackBuffer = nullptr; hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast<void**>( &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 ); // Compile the vertex shader ID3DBlob* pVSBlob = nullptr; hr = CompileShaderFromFile( L"Tutorial07.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 ); if( FAILED( hr ) ) { 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 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_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; hr = CompileShaderFromFile( L"Tutorial07.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 ); pPSBlob->Release(); if( FAILED( hr ) ) return hr; // Create vertex buffer SimpleVertex vertices[] = { { XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, { XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, { XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, { XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, }; D3D11_BUFFER_DESC bd; ZeroMemory( &bd, sizeof(bd) ); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( SimpleVertex ) * 24; 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 // Create vertex buffer WORD indices[] = { 3,1,0, 2,1,3, 6,4,5, 7,4,6, 11,9,8, 10,9,11, 14,12,13, 15,12,14, 19,17,16, 18,17,19, 22,20,21, 23,20,22 }; bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( WORD ) * 36; 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 buffers bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof(CBNeverChanges); bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bd.CPUAccessFlags = 0; hr = g_pd3dDevice->CreateBuffer( &bd, nullptr, &g_pCBNeverChanges ); if( FAILED( hr ) ) return hr; bd.ByteWidth = sizeof(CBChangeOnResize); hr = g_pd3dDevice->CreateBuffer( &bd, nullptr, &g_pCBChangeOnResize ); if( FAILED( hr ) ) return hr; bd.ByteWidth = sizeof(CBChangesEveryFrame); hr = g_pd3dDevice->CreateBuffer( &bd, nullptr, &g_pCBChangesEveryFrame ); if( FAILED( hr ) ) return hr; // Load the Texture hr = CreateDDSTextureFromFile( g_pd3dDevice, L"seafloor.dds", nullptr, &g_pTextureRV ); if( FAILED( hr ) ) return hr; // Create the sample state D3D11_SAMPLER_DESC sampDesc; ZeroMemory( &sampDesc, sizeof(sampDesc) ); sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; sampDesc.MinLOD = 0; sampDesc.MaxLOD = D3D11_FLOAT32_MAX; hr = g_pd3dDevice->CreateSamplerState( &sampDesc, &g_pSamplerLinear ); if( FAILED( hr ) ) return hr; // Initialize the world matrices g_World = XMMatrixIdentity(); // Initialize the view matrix XMVECTOR Eye = XMVectorSet( 0.0f, 3.0f, -6.0f, 0.0f ); XMVECTOR At = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f ); XMVECTOR Up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f ); g_View = XMMatrixLookAtLH( Eye, At, Up ); CBNeverChanges cbNeverChanges; cbNeverChanges.mView = XMMatrixTranspose( g_View ); g_pImmediateContext->UpdateSubresource( g_pCBNeverChanges, 0, nullptr, &cbNeverChanges, 0, 0 ); // Initialize the projection matrix g_Projection = XMMatrixPerspectiveFovLH( XM_PIDIV4, width / (FLOAT)height, 0.01f, 100.0f ); CBChangeOnResize cbChangesOnResize; cbChangesOnResize.mProjection = XMMatrixTranspose( g_Projection ); g_pImmediateContext->UpdateSubresource( g_pCBChangeOnResize, 0, nullptr, &cbChangesOnResize, 0, 0 ); #ifdef USE_OPENVR // OpenVR. // Loading the SteamVR Runtime vr::EVRInitError eError = vr::VRInitError_None; openvr_system_ = vr::VR_Init(&eError, vr::VRApplication_Scene); if (eError != vr::VRInitError_None) { openvr_system_ = nullptr; ShowMessageBoxAndExit("Unable to init VR runtime: %s", vr::VR_GetVRInitErrorAsEnglishDescription(eError)); } if (!vr::VRCompositor()) { ShowMessageBoxAndExit("Failed to obtain compositor."); } #endif return S_OK; }
bool LoadContent() { assert(g_d3dDevice); D3D11_BUFFER_DESC vertexBufferDesc; ZeroMemory(&vertexBufferDesc, sizeof(D3D11_BUFFER_DESC)); vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; vertexBufferDesc.ByteWidth = sizeof(VertexPosColor) * _countof(g_Vertices); vertexBufferDesc.CPUAccessFlags = 0; vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT; D3D11_SUBRESOURCE_DATA resourceData; ZeroMemory(&resourceData, sizeof(D3D11_SUBRESOURCE_DATA)); resourceData.pSysMem = g_Vertices; HRESULT hResult = g_d3dDevice->CreateBuffer(&vertexBufferDesc, &resourceData, &g_d3dVertexBuffer); if (FAILED(hResult)) return false; D3D11_BUFFER_DESC indexBufferDesc; ZeroMemory(&indexBufferDesc, sizeof(D3D11_BUFFER_DESC)); indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; indexBufferDesc.ByteWidth = sizeof(WORD) * _countof(g_Indicies); indexBufferDesc.CPUAccessFlags = 0; indexBufferDesc.Usage = D3D11_USAGE_DEFAULT; resourceData.pSysMem = g_Indicies; hResult = g_d3dDevice->CreateBuffer(&indexBufferDesc, &resourceData, &g_d3dIndexBuffer); if (FAILED(hResult)) return false; 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; hResult = g_d3dDevice->CreateBuffer(&indexBufferDesc, nullptr, &g_d3dConstantBuffers[CB_Application]); if (FAILED(hResult)) return false; hResult = g_d3dDevice->CreateBuffer(&indexBufferDesc, nullptr, &g_d3dConstantBuffers[CB_Frame]); if (FAILED(hResult)) return false; hResult = g_d3dDevice->CreateBuffer(&indexBufferDesc, nullptr, &g_d3dConstantBuffers[CB_Object]); if (FAILED(hResult)) return false; #if _DEBUG LPCWSTR compiledVertexShaderObject = L"SimpleVertexShader_d.cso"; LPCWSTR compiledPixelShaderObject = L"SimplePixelShader_d.cso"; #else LPCWSTR compiledVertexShaderObject = L"SimpleVertexShader.cso"; LPCWSTR compiledPixelShaderObject = L"SimplePixelShader.cso"; #endif ID3DBlob *vertexShaderBlob; hResult = D3DReadFileToBlob(compiledVertexShaderObject, &vertexShaderBlob); if (FAILED(hResult)) return false; ID3DBlob *pixelShaderBlob; hResult = D3DReadFileToBlob(compiledPixelShaderObject, &pixelShaderBlob); if (FAILED(hResult)) return false; hResult = g_d3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, &g_d3dVertexShader); if (FAILED(hResult)) return false; hResult = g_d3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), nullptr, &g_d3dPixelShader); if (FAILED(hResult)) return false; }
bool DXShaderCompiler::CompileShader(const std::string& source_file, const std::string& entry_point, const char* target, ShaderOpt opt_level, bool debug, const ShaderDefine* defines, size_t num_defines, std::vector<uint8_t>& output, YFileUtils::FileEnv* file_env) { std::string work_dir = YFileUtils::FilePath::DirPath(source_file); const std::vector<uint8_t>* source_data = GetFileData(source_file, file_env); std::vector<D3D_SHADER_MACRO> macros; for (size_t i = 0; i < num_defines; ++i) { macros.push_back({defines[i].define, defines[i].value}); } macros.push_back({NULL, NULL}); DXIncludeData include_data(work_dir, file_env); UINT flags1 = D3DCOMPILE_WARNINGS_ARE_ERRORS; switch (opt_level) { case kShaderOpt_None: flags1 |= D3DCOMPILE_SKIP_OPTIMIZATION; break; case kShaderOpt_Level0: flags1 |= D3DCOMPILE_OPTIMIZATION_LEVEL0; break; case kShaderOpt_Level1: flags1 |= D3DCOMPILE_OPTIMIZATION_LEVEL1; break; case kShaderOpt_Level2: flags1 |= D3DCOMPILE_OPTIMIZATION_LEVEL2; break; case kShaderOpt_Level3: flags1 |= D3DCOMPILE_OPTIMIZATION_LEVEL3; break; default: std::cerr << "Invalid Shader Opt: " << opt_level << std::endl; return false; } if (debug) { flags1 |= D3DCOMPILE_DEBUG; } ID3DBlob* code; ID3DBlob* error_msgs; HRESULT ret = D3DCompile2( source_data->data(), // in LPCVOID pSrcData, source_data->size(), // in SIZE_T SrcDataSize, source_file.c_str(), // in LPCSTR pSourceName, macros.data(), // in const D3D_SHADER_MACRO *pDefines, &include_data, // in ID3DInclude *pInclude, entry_point.c_str(), // in LPCSTR pEntrypoint, target, // in LPCSTR pTarget, flags1, // in UINT Flags1, 0, // in UINT Flags2, 0, // in UINT SecondaryDataFlags, NULL, // in LPCVOID pSecondaryData, 0, // in SIZE_T SecondaryDataSize, &code, // out ID3DBlob **ppCode, &error_msgs // out ID3DBlob **ppErrorMsgs ); if (FAILED(ret)) { std::cerr << "[ERROR] " << static_cast<const char*>(error_msgs->GetBufferPointer()) << std::endl; return false; } size_t code_size = code->GetBufferSize(); output.resize(code_size); memcpy(output.data(), code->GetBufferPointer(), code_size); return true; }
HRESULT HorseObject::InitShader(ID3D11Device* device) { HRESULT hr = S_OK; // alpha blend state D3D11_BLEND_DESC blendDesc; ZeroMemory(&blendDesc, sizeof(D3D11_BLEND_DESC)); blendDesc.AlphaToCoverageEnable = FALSE; blendDesc.IndependentBlendEnable = FALSE; for (int i = 0; i < 8; ++i) { blendDesc.RenderTarget[i].BlendEnable = TRUE; blendDesc.RenderTarget[i].SrcBlend = D3D11_BLEND_SRC_ALPHA; blendDesc.RenderTarget[i].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; blendDesc.RenderTarget[i].BlendOp = D3D11_BLEND_OP_ADD; blendDesc.RenderTarget[i].SrcBlendAlpha = D3D11_BLEND_ONE; blendDesc.RenderTarget[i].DestBlendAlpha = D3D11_BLEND_ZERO; blendDesc.RenderTarget[i].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendDesc.RenderTarget[i].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; } hr = device->CreateBlendState(&blendDesc, &alphaBlendState); if (FAILED(hr)) { return hr; } // per-frame constant buffer D3D11_BUFFER_DESC bufferDesc; ZeroMemory(&bufferDesc, sizeof(D3D11_BUFFER_DESC)); bufferDesc.ByteWidth = sizeof(ConstantBufferPerFrame); bufferDesc.Usage = D3D11_USAGE_DEFAULT; bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bufferDesc.CPUAccessFlags = 0; hr = device->CreateBuffer(&bufferDesc, nullptr, &constantBufferPerFrame); if (FAILED(hr)) { assert(false && "ID3D11Device::CreateBuffer() Failed."); return false; } // matrix palette ZeroMemory(&bufferDesc, sizeof(D3D11_BUFFER_DESC)); bufferDesc.ByteWidth = sizeof(ConstantBufferSkinningMatrix); bufferDesc.Usage = D3D11_USAGE_DEFAULT; bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bufferDesc.CPUAccessFlags = 0; hr = device->CreateBuffer(&bufferDesc, nullptr, &constantBufferSkinningBone); if (FAILED(hr)) { assert(false && "ID3D11Device::CreateBuffer() Failed."); return hr; } // per-object constant buffer ZeroMemory(&bufferDesc, sizeof(D3D11_BUFFER_DESC)); bufferDesc.ByteWidth = sizeof(ConstantBufferPerObj); bufferDesc.Usage = D3D11_USAGE_DEFAULT; bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bufferDesc.CPUAccessFlags = 0; hr = device->CreateBuffer(&bufferDesc, nullptr, &constantBufferPerObj); if (FAILED(hr)) { assert(false && "ID3D11Device::CreateBuffer() Failed."); return hr; } // vertex shader ID3DBlob* blob = nullptr; hr = CompileShaderFromFile(L"./ssdr.fx", "LambertSkinVS", "vs_5_0", blob); if (FAILED(hr)) { if (blob != nullptr) { blob->Release(); } return hr; } hr = device->CreateVertexShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, &vertexShader); if (FAILED(hr)) { assert(false && "CompileShaderFromFile() Failed"); return false; } // vertex layout UINT numElements = ARRAYSIZE(customVertexLayout); hr = device->CreateInputLayout(customVertexLayout, numElements, blob->GetBufferPointer(), blob->GetBufferSize(), &inputLayout); if (blob != nullptr) { blob->Release(); } if (FAILED(hr)) { assert(false && "ID3D11Device::CreateInputLayout() Failed."); return false; } // pixel shader hr = CompileShaderFromFile(L"./ssdr.fx", "LambertPS", "ps_5_0", blob); if (FAILED(hr)) { if (blob != nullptr) { blob->Release(); } return hr; } hr = device->CreatePixelShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, &pixelShader); if (FAILED(hr)) { assert(false && "ID3D11Device::CreateVertexShader() Failed."); if (blob != nullptr) { blob->Release(); } return hr; } if (blob != nullptr) { blob->Release(); } return hr; }
VOID InitEffects() { ID3DBlob* pErrorBlob; // Create the effect DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS; #if defined( DEBUG ) || defined( _DEBUG ) // Set the D3D10_SHADER_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. dwShaderFlags |= D3D10_SHADER_DEBUG; #endif // Compile the effects file HRESULT hr = D3DX10CreateEffectFromFile( L"triangle_shader.fx", NULL, NULL, "fx_4_0", dwShaderFlags, 0, g_pd3dDevice, NULL, NULL, &g_pEffect, &pErrorBlob, NULL ); // Output the error message if compile failed if(FAILED(hr)) { if(pErrorBlob != NULL) { OutputDebugString((WCHAR*)pErrorBlob->GetBufferPointer()); pErrorBlob->Release(); } } // Release the Blob if(pErrorBlob) pErrorBlob->Release(); // Obtain the technique g_pTechnique = g_pEffect->GetTechniqueByName("Render"); // Define the input layout D3D10_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, }; UINT numElements = sizeof(layout) / sizeof(layout[0]); // Create the input layout D3D10_PASS_DESC PassDesc; g_pTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc ); hr = g_pd3dDevice->CreateInputLayout(layout, numElements, PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize, &g_pVertexLayout); if(FAILED(hr)) { MessageBox(NULL, L"Create input layout failed", L"Error", 0); } }
HRESULT Application::InitShadersAndInputLayout() { HRESULT hr; // Compile the vertex shader ID3DBlob* pVSBlob = nullptr; hr = CompileShaderFromFile(L"DX11 Framework.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 = _pd3dDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &_pVertexShader); if (FAILED(hr)) { pVSBlob->Release(); return hr; } // Compile the pixel shader ID3DBlob* pPSBlob = nullptr; hr = CompileShaderFromFile(L"DX11 Framework.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 = _pd3dDevice->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &_pPixelShader); pPSBlob->Release(); if (FAILED(hr)) 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 }, { "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 }, }; UINT numElements = ARRAYSIZE(layout); // Create the input layout hr = _pd3dDevice->CreateInputLayout(layout, numElements, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &_pVertexLayout); pVSBlob->Release(); if (FAILED(hr)) return hr; // Set the input layout _pImmediateContext->IASetInputLayout(_pVertexLayout); D3D11_SAMPLER_DESC sampDesc; ZeroMemory(&sampDesc, sizeof(sampDesc)); sampDesc.Filter = D3D11_FILTER_ANISOTROPIC; sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; sampDesc.MinLOD = 0; sampDesc.MaxLOD = D3D11_FLOAT32_MAX; hr = _pd3dDevice->CreateSamplerState(&sampDesc, &_pSamplerLinear); return hr; }
// プログラマブルシェーダ作成 HRESULT MakeShaders( void ) { HRESULT hr; ID3DBlob* pVertexShaderBuffer = NULL; ID3DBlob* pPixelShaderBuffer = NULL; ID3DBlob* pError = NULL; DWORD dwShaderFlags = 0; #ifdef _DEBUG dwShaderFlags |= D3DCOMPILE_DEBUG; #endif // コンパイル hr = D3DX11CompileFromFile( _T( "Basic_2D.fx" ), NULL, NULL, "VS", "vs_4_0_level_9_1", dwShaderFlags, 0, NULL, &pVertexShaderBuffer, &pError, NULL ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "Can't open Basic_2D.fx" ), _T( "Error" ), MB_OK ); SAFE_RELEASE( pError ); return hr; } hr = D3DX11CompileFromFile( _T( "Basic_2D.fx" ), NULL, NULL, "PS", "ps_4_0_level_9_1", dwShaderFlags, 0, NULL, &pPixelShaderBuffer, &pError, NULL ); if ( FAILED( hr ) ) { SAFE_RELEASE( pVertexShaderBuffer ); SAFE_RELEASE( pError ); return hr; } SAFE_RELEASE( pError ); // VertexShader作成 hr = g_pd3dDevice->CreateVertexShader( pVertexShaderBuffer->GetBufferPointer(), pVertexShaderBuffer->GetBufferSize(), NULL, &g_pVertexShader ); if ( FAILED( hr ) ) { SAFE_RELEASE( pVertexShaderBuffer ); SAFE_RELEASE( pPixelShaderBuffer ); return hr; } // PixelShader作成 hr = g_pd3dDevice->CreatePixelShader( pPixelShaderBuffer->GetBufferPointer(), pPixelShaderBuffer->GetBufferSize(), NULL, &g_pPixelShader ); if ( FAILED( hr ) ) { SAFE_RELEASE( pVertexShaderBuffer ); SAFE_RELEASE( pPixelShaderBuffer ); return hr; } // 入力バッファの入力形式 D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXTURE", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; UINT numElements = ARRAYSIZE( layout ); // 入力バッファの入力形式作成 hr = g_pd3dDevice->CreateInputLayout( layout, numElements, pVertexShaderBuffer->GetBufferPointer(), pVertexShaderBuffer->GetBufferSize(), &g_pInputLayout ); SAFE_RELEASE( pVertexShaderBuffer ); SAFE_RELEASE( pPixelShaderBuffer ); if ( FAILED( hr ) ) { return hr; } // シェーダ定数バッファ作成 D3D11_BUFFER_DESC bd; ZeroMemory( &bd, sizeof( bd ) ); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( CBNeverChanges ); bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bd.CPUAccessFlags = 0; hr = g_pd3dDevice->CreateBuffer( &bd, NULL, &g_pCBNeverChanges ); if( FAILED( hr ) ) return hr; // 変換行列 CBNeverChanges cbNeverChanges; XMMATRIX mScreen; mScreen = XMMatrixIdentity(); mScreen._11 = 2.0f / g_nClientWidth; mScreen._22 = -2.0f / g_nClientHeight; mScreen._41 = -1.0f; mScreen._42 = 1.0f; cbNeverChanges.mView = XMMatrixTranspose( mScreen ); g_pImmediateContext->UpdateSubresource( g_pCBNeverChanges, 0, NULL, &cbNeverChanges, 0, 0 ); return S_OK; }
// Compiles HLSL code into executable binaries ShaderBlob *Renderer::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, UINT optimizationFlags, bool alternateFlags) { if (!hlsl) { return NULL; } HRESULT result = S_OK; UINT flags = 0; std::string sourceText; if (gl::perfActive()) { flags |= D3DCOMPILE_DEBUG; #ifdef NDEBUG flags |= optimizationFlags; #else flags |= D3DCOMPILE_SKIP_OPTIMIZATION; #endif std::string sourcePath = getTempPath(); sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(hlsl); writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); } else { flags |= optimizationFlags; sourceText = hlsl; } // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options. // Try the default flags first and if compilation fails, try some alternatives. const static UINT extraFlags[] = { 0, D3DCOMPILE_AVOID_FLOW_CONTROL, D3DCOMPILE_PREFER_FLOW_CONTROL }; const static char * const extraFlagNames[] = { "default", "avoid flow control", "prefer flow control" }; int attempts = alternateFlags ? ArraySize(extraFlags) : 1; pD3DCompile compileFunc = reinterpret_cast<pD3DCompile>(mD3DCompileFunc); for (int i = 0; i < attempts; ++i) { ID3DBlob *errorMessage = NULL; ID3DBlob *binary = NULL; result = compileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL, "main", profile, flags | extraFlags[i], 0, &binary, &errorMessage); if (errorMessage) { const char *message = (const char*)errorMessage->GetBufferPointer(); infoLog.appendSanitized(message); TRACE("\n%s", hlsl); TRACE("\n%s", message); errorMessage->Release(); errorMessage = NULL; } if (SUCCEEDED(result)) { return (ShaderBlob*)binary; } else { if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) { return gl::error(GL_OUT_OF_MEMORY, (ShaderBlob*) NULL); } infoLog.append("Warning: D3D shader compilation failed with "); infoLog.append(extraFlagNames[i]); infoLog.append(" flags."); if (i + 1 < attempts) { infoLog.append(" Retrying with "); infoLog.append(extraFlagNames[i + 1]); infoLog.append(".\n"); } } } return NULL; }
// Create quad shaders HRESULT CFW1GlyphRenderStates::createQuadShaders() { // Vertex shaders const char vsSimpleStr[] = "cbuffer ShaderConstants : register(b0) {\r\n" " float4x4 TransformMatrix : packoffset(c0);\r\n" "};\r\n" "\r\n" "struct VSIn {\r\n" " float4 Position : POSITION;\r\n" " float4 GlyphColor : GLYPHCOLOR;\r\n" "};\r\n" "\r\n" "struct VSOut {\r\n" " float4 Position : SV_Position;\r\n" " float4 GlyphColor : COLOR;\r\n" " float2 TexCoord : TEXCOORD;\r\n" "};\r\n" "\r\n" "VSOut VS(VSIn Input) {\r\n" " VSOut Output;\r\n" " \r\n" " Output.Position = mul(TransformMatrix, float4(Input.Position.xy, 0.0f, 1.0f));\r\n" " Output.GlyphColor = Input.GlyphColor;\r\n" " Output.TexCoord = Input.Position.zw;\r\n" " \r\n" " return Output;\r\n" "}\r\n" ""; const char vsClipStr[] = "cbuffer ShaderConstants : register(b0) {\r\n" " float4x4 TransformMatrix : packoffset(c0);\r\n" " float4 ClipRect : packoffset(c4);\r\n" "};\r\n" "\r\n" "struct VSIn {\r\n" " float4 Position : POSITION;\r\n" " float4 GlyphColor : GLYPHCOLOR;\r\n" "};\r\n" "\r\n" "struct VSOut {\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" "VSOut VS(VSIn Input) {\r\n" " VSOut Output;\r\n" " \r\n" " Output.Position = mul(TransformMatrix, float4(Input.Position.xy, 0.0f, 1.0f));\r\n" " Output.GlyphColor = Input.GlyphColor;\r\n" " Output.TexCoord = Input.Position.zw;\r\n" " Output.ClipDistance = ClipRect + float4(Input.Position.xy, -Input.Position.xy);\r\n" " \r\n" " return Output;\r\n" "}\r\n" ""; // Shader compile profile const char *vs_profile = "vs_4_0_level_9_1"; if(m_featureLevel >= D3D_FEATURE_LEVEL_11_0) vs_profile = "vs_5_0"; else if(m_featureLevel >= D3D_FEATURE_LEVEL_10_0) vs_profile = "vs_4_0"; else if(m_featureLevel >= D3D_FEATURE_LEVEL_9_3) vs_profile = "vs_4_0_level_9_3"; // Compile vertex shader ID3DBlob *pVSCode; HRESULT hResult = m_pfnD3DCompile( vsSimpleStr, sizeof(vsSimpleStr), NULL, NULL, NULL, "VS", vs_profile, D3DCOMPILE_OPTIMIZATION_LEVEL3, 0, &pVSCode, NULL ); if(FAILED(hResult)) { m_lastError = L"Failed to compile vertex shader"; } else { // Create vertex shader ID3D11VertexShader *pVS; hResult = m_pDevice->CreateVertexShader(pVSCode->GetBufferPointer(), pVSCode->GetBufferSize(), NULL, &pVS); if(FAILED(hResult)) { m_lastError = L"Failed to create vertex shader"; } else { // Compile clipping vertex shader ID3DBlob *pVSClipCode; hResult = m_pfnD3DCompile( vsClipStr, sizeof(vsClipStr), NULL, NULL, NULL, "VS", vs_profile, D3DCOMPILE_OPTIMIZATION_LEVEL3, 0, &pVSClipCode, NULL ); if(FAILED(hResult)) { m_lastError = L"Failed to compile clipping vertex shader"; } else { // Create vertex shader ID3D11VertexShader *pVSClip; hResult = m_pDevice->CreateVertexShader( pVSClipCode->GetBufferPointer(), pVSClipCode->GetBufferSize(), NULL, &pVSClip ); if(FAILED(hResult)) { m_lastError = L"Failed to create clipping vertex shader"; } else { // Create input layout ID3D11InputLayout *pInputLayout; // Quad vertex input layout D3D11_INPUT_ELEMENT_DESC inputElements[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"GLYPHCOLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0} }; hResult = m_pDevice->CreateInputLayout( inputElements, 2, pVSCode->GetBufferPointer(), pVSCode->GetBufferSize(), &pInputLayout ); if(FAILED(hResult)) { m_lastError = L"Failed to create input layout"; } else { // Success m_pVertexShaderQuad = pVS; m_pVertexShaderClipQuad = pVSClip; m_pQuadInputLayout = pInputLayout; hResult = S_OK; } if(FAILED(hResult)) pVSClip->Release(); } pVSClipCode->Release(); } if(FAILED(hResult)) pVS->Release(); } pVSCode->Release(); } return hResult; }