Directx11 ウィンドウの透過
ウィンドウの透過
docomoの羊を作るためにウィンドウの透過をしたかった。 DirectX12で行っていたが、ウィンドウの透過をするための情報が見つからず、DirectX11で行うことにした。
ヘッダ
App.h
#pragma once #include <Windows.h> #include <cstdint> #include <string> #include "DxManager.h" #include "Scene.h" class App { public: App(); void Run(); private: bool InitApp(); bool InitWindow(); void MainLoop(); static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); private: const std::wstring WindowClassName = L"WindowClass"; uint32_t _width; uint32_t _height; HWND _hwnd; HINSTANCE _hInstance; Scene scene; };
DxManager.h
#pragma once #include <iostream> #include <cstdint> #include <d3d11.h> #include <dxgi.h> #include <Windows.h> #include <wrl/client.h> #pragma comment(lib, "d3d11.lib") #pragma comment(lib, "dxgi.lib") using Microsoft::WRL::ComPtr; class DxManager { private: D3D_FEATURE_LEVEL _featurelevel; ComPtr<IDXGIFactory> _pFactory = nullptr; ComPtr<IDXGIAdapter> _pAdapter = nullptr; ComPtr<ID3D11Device> _pDevice = nullptr; ComPtr<ID3D11DeviceContext> _pDeviceContext = nullptr; ComPtr<IDXGISwapChain> _pSwapChain = nullptr; ComPtr<ID3D11Texture2D> _pRenderTarget = nullptr; ComPtr<ID3D11RenderTargetView> _pRenderTargetView = nullptr; ComPtr<ID3D11DepthStencilState> _pDepthStencilState = nullptr; ComPtr<ID3D11Texture2D> _pDepthStencilTex = nullptr; ComPtr<ID3D11DepthStencilView> _pDepthStencilView = nullptr; ComPtr<ID3D11BlendState> _pBlendState = nullptr; D3D11_VIEWPORT _viewport; uint32_t _width; uint32_t _height; HWND _hwnd; public: bool Init(uint32_t width, uint32_t height, HWND hwnd); void BeginRender(); void EndRender(); ID3D11Device* GetDevice(); ID3D11DeviceContext* GetDeviceContext(); uint32_t GetWindowWidth(); uint32_t GetWindowHeight(); private: bool CreateFactory(); bool CreateDeviceAndSwapChain(); bool CreateDepthStencilBuffer(); bool CreateBlendState(); }; extern DxManager* dx; //グローバル変数
VertexBuffer
#pragma once #include <iostream> #include <cstdint> #include <d3d11.h> #include <dxgi.h> #include <wrl/client.h> #include "DxManager.h" #include "DxStruct.h" #pragma comment(lib, "d3d11.lib") #pragma comment(lib, "dxgi.lib") using Microsoft::WRL::ComPtr; class VertexBuffer { public: bool CreateVertexBuffer(uint32_t size, uint32_t stride, const void* data); ID3D11Buffer** GetVertexBuffer(); uint32_t* GetStride(); uint32_t* GetOffset(); private: ComPtr<ID3D11Buffer> _pBuffer; uint32_t _size; uint32_t _stride; uint32_t _offset; };
IndexBuffer.h
#pragma once #include <iostream> #include <cstdint> #include <d3d11.h> #include <dxgi.h> #include <wrl/client.h> #include "DxManager.h" #include "DxStruct.h" #pragma comment(lib, "d3d11.lib") #pragma comment(lib, "dxgi.lib") using Microsoft::WRL::ComPtr; class IndexBuffer { public: bool CreateIndexBuffer(uint32_t size, uint32_t* data); ID3D11Buffer* GetIndexBuffer(); private: ComPtr<ID3D11Buffer> _pBuffer; };
PipelineState.h
#pragma once #include <iostream> #include <cstdint> #include <string> #include <d3d11.h> #include <d3dcompiler.h> #include <wrl/client.h> #include "DxManager.h" #pragma comment(lib, "d3d11.lib") #pragma comment(lib, "d3dcompiler.lib") using Microsoft::WRL::ComPtr; class PipelineState { public: PipelineState(); bool CreateVertexShader(std::wstring filePath, std::string mainFunc); bool CreatePixelShader(std::wstring filePath, std::string mainFunc); bool CreateInputLayout(D3D11_INPUT_ELEMENT_DESC* layout, uint32_t elementNum); ID3D11VertexShader* GetVertexShader(); ID3D11PixelShader* GetPixelShader(); ID3D11InputLayout* GetInputLayout(); private: ComPtr<ID3D11VertexShader> _pVertexShader; ComPtr<ID3D11PixelShader> _pPixelShader; ComPtr<ID3D11InputLayout> _pInputLayout; ComPtr<ID3DBlob> _pVSBlob; };
DxStruct.h
#pragma once #include <DirectXMath.h> struct Vertex { DirectX::XMFLOAT3 Position; DirectX::XMFLOAT4 Color; };
Scene.h
#pragma once #include <DirectXMath.h> #include <dxgi.h> #include "DxManager.h" #include "DxStruct.h" #include "IndexBuffer.h" #include "VertexBuffer.h" #include "PipelineState.h" #pragma comment(lib, "dxgi.lib") class Scene { public: bool Init(); void Draw(); private: PipelineState _pipelineState; VertexBuffer _vertexBuffer; IndexBuffer _indexBuffer; };
ソース
main. cpp
#include "App.h" int main() { App app; app.Run(); }
App.cpp
#include "App.h" App::App() { _width = 1080; _height = 720; _hwnd = nullptr; _hInstance = nullptr; } void App::Run() { if (!InitApp()) { return; } MainLoop(); } //初期化 bool App::InitApp() { if (!InitWindow()) { return false; } dx = new DxManager(); if (!dx->Init(_width, _height, _hwnd)) { return false; } if (!scene.Init()) { return false; } return true; } //ウィンドウの初期化 bool App::InitWindow() { _hInstance = GetModuleHandle(nullptr); if (_hInstance == nullptr) { return false; } //ウィンドウの設定 WNDCLASSEX wc = {}; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; //水平方向と垂直方向のサイズ変更で再描画 wc.lpfnWndProc = WndProc; //ウィンドウプロシージャの登録 wc.hIcon = LoadIcon(_hInstance, IDI_APPLICATION); //アイコン wc.hCursor = LoadCursor(_hInstance, IDC_ARROW); //マウスカーソル wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); //背景色は黒 wc.hInstance = _hInstance; //インスタンスハンドル wc.lpszMenuName = nullptr; //メニュー wc.lpszClassName = WindowClassName.c_str(); //ウィンドウクラスの名前 wc.hIconSm = LoadIcon(_hInstance, IDI_APPLICATION); //小さいアイコン RegisterClassEx(&wc); //ウィンドウクラスの登録 _hwnd = CreateWindowEx( WS_EX_LAYERED, //レイヤードウィンドウ WindowClassName.c_str(), L"Title", WS_POPUPWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, _width, _height, nullptr, nullptr, _hInstance, nullptr ); ShowWindow(_hwnd, SW_SHOWNORMAL); UpdateWindow(_hwnd); SetFocus(_hwnd); return true; } //メインループ void App::MainLoop() { MSG msg = {}; while (WM_QUIT != msg.message) { if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE == true)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { // ここに描画処理を書く dx->BeginRender(); scene.Draw(); dx->EndRender(); UpdateWindow(_hwnd); } } } //ウィンドウプロシージャ LRESULT CALLBACK App::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_DESTROY: PostQuitMessage(0); break; default: break; } return DefWindowProc(hwnd, msg, wParam, lParam); }
DxManager.cpp
#include "DxManager.h" DxManager* dx; bool DxManager::Init(uint32_t width, uint32_t height, HWND hwnd) { _width = width; _height = height; _hwnd = hwnd; if (!CreateFactory()) { return false; } if (!CreateDeviceAndSwapChain()) { return false; } if (!CreateDepthStencilBuffer()) { return false; } if (!CreateBlendState()) { return false; } return true; } bool DxManager::CreateFactory() { ComPtr<IDXGIOutput> pOutput; DXGI_ADAPTER_DESC adapterDesc; size_t stringLength; unsigned int numModes = 0; int GPUMaxMem = 0; int GPUNum = 0; HRESULT hResult = S_OK; hResult = CreateDXGIFactory(IID_PPV_ARGS(_pFactory.GetAddressOf())); if (FAILED(hResult)) { return false; } for (uint32_t i = 0; i < 100; i++) { IDXGIAdapter* adapter; hResult = _pFactory->EnumAdapters(i, &adapter); if (FAILED(hResult)) { break; } hResult = adapter->GetDesc(&adapterDesc); if (FAILED(hResult)) { return false; } char videoCardDesc[128]; int error = wcstombs_s(&stringLength, videoCardDesc, 128, adapterDesc.Description, 128); if (error != 0) { break; } //std::cout << "ビデオカード名 : " << videoCardDesc << std::endl; int videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1028 / 1024); //std::cout << "ビデオメモリー : " << videoCardMemory << std::endl; hResult = adapter->EnumOutputs(0, pOutput.GetAddressOf()); if (FAILED(hResult)) { continue; } hResult = pOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, nullptr); if (FAILED(hResult)) { continue; } //std::cout << "RGBA8_UNORM Count : " << numModes << std::endl; if (videoCardMemory > GPUMaxMem) { GPUMaxMem = videoCardMemory; GPUNum = i; } } hResult = _pFactory->EnumAdapters(GPUNum, _pAdapter.GetAddressOf()); if (FAILED(hResult)) { return false; } return true; } bool DxManager::CreateDeviceAndSwapChain() { HRESULT hResult = S_OK; UINT cdev_flags = 0; #ifdef _DEBUG cdev_flags |= D3D11_CREATE_DEVICE_DEBUG; #endif DXGI_MODE_DESC modeDesc = {}; modeDesc.Width = _width; modeDesc.Height = _height; modeDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; modeDesc.RefreshRate.Numerator = 60; modeDesc.RefreshRate.Denominator = 1; modeDesc.Scaling = DXGI_MODE_SCALING_CENTERED; modeDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); swapChainDesc.BufferCount = 2; swapChainDesc.BufferDesc = modeDesc; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = _hwnd; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.Windowed = true; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE; D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_12_0, D3D_FEATURE_LEVEL_12_1, }; hResult = D3D11CreateDeviceAndSwapChain( _pAdapter.Get(), D3D_DRIVER_TYPE_UNKNOWN, nullptr, cdev_flags, featureLevels, 6, D3D11_SDK_VERSION, &swapChainDesc, _pSwapChain.GetAddressOf(), _pDevice.GetAddressOf(), &_featurelevel, _pDeviceContext.GetAddressOf()); if (FAILED(hResult)) { return false; } _pAdapter->Release(); _pFactory->Release(); hResult = _pSwapChain->GetBuffer(0, IID_PPV_ARGS(_pRenderTarget.GetAddressOf())); if (FAILED(hResult)) { return false; } hResult = _pDevice->CreateRenderTargetView(_pRenderTarget.Get(), nullptr, _pRenderTargetView.GetAddressOf()); if (FAILED(hResult)) { return false; } _viewport.Width = static_cast<float>(_width); _viewport.Height = static_cast<float>(_height); _viewport.MinDepth = 0.0f; _viewport.MaxDepth = 1.0f; _viewport.TopLeftX = 0; _viewport.TopLeftY = 0; return true; } bool DxManager::CreateDepthStencilBuffer() { D3D11_DEPTH_STENCIL_DESC desc = {}; desc.DepthEnable = true; desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; desc.DepthFunc = D3D11_COMPARISON_LESS; desc.StencilEnable = false; desc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; desc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; desc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; desc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; HRESULT hResult = _pDevice->CreateDepthStencilState(&desc, _pDepthStencilState.GetAddressOf()); if (FAILED(hResult)) { return false; } D3D11_TEXTURE2D_DESC Tex2Desc = {}; Tex2Desc.Format = DXGI_FORMAT_R24G8_TYPELESS; Tex2Desc.Width = _width; Tex2Desc.Height = _height; Tex2Desc.ArraySize = 1; Tex2Desc.MipLevels = 1; Tex2Desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; Tex2Desc.Usage = D3D11_USAGE_DEFAULT; Tex2Desc.CPUAccessFlags = 0; Tex2Desc.SampleDesc.Count = 1; Tex2Desc.SampleDesc.Quality = 0; Tex2Desc.MiscFlags = 0; hResult = _pDevice->CreateTexture2D(&Tex2Desc, nullptr, _pDepthStencilTex.GetAddressOf()); if (FAILED(hResult)) { return false; } D3D11_DEPTH_STENCIL_VIEW_DESC DSVDesc = {}; DSVDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; DSVDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; DSVDesc.Texture2D.MipSlice = 0; DSVDesc.Flags = 0; hResult = _pDevice->CreateDepthStencilView(_pDepthStencilTex.Get(), &DSVDesc, _pDepthStencilView.GetAddressOf()); if (FAILED(hResult)) { return false; } return true; } bool DxManager::CreateBlendState() { D3D11_RENDER_TARGET_BLEND_DESC descRTBS = {}; descRTBS.BlendEnable = true; descRTBS.SrcBlend = D3D11_BLEND_SRC_ALPHA; descRTBS.DestBlend = D3D11_BLEND_INV_SRC_ALPHA; descRTBS.BlendOp = D3D11_BLEND_OP_ADD; descRTBS.SrcBlendAlpha = D3D11_BLEND_ONE; descRTBS.DestBlendAlpha = D3D11_BLEND_ZERO; descRTBS.BlendOpAlpha = D3D11_BLEND_OP_ADD; descRTBS.RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; D3D11_BLEND_DESC descBS = {}; descBS.AlphaToCoverageEnable = true; descBS.IndependentBlendEnable = true; for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) { descBS.RenderTarget[i] = descRTBS; } HRESULT hResult = _pDevice->CreateBlendState(&descBS, _pBlendState.GetAddressOf()); if (FAILED(hResult)) { return false; } return true; } void DxManager::BeginRender() { _pDeviceContext->OMSetRenderTargets(1, _pRenderTargetView.GetAddressOf(), _pDepthStencilView.Get()); _pDeviceContext->RSSetViewports(1, &_viewport); float clearColor[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; _pDeviceContext->ClearRenderTargetView(_pRenderTargetView.Get(), clearColor); _pDeviceContext->ClearDepthStencilView(_pDepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); } void DxManager::EndRender() { _pSwapChain->Present(1, 0); IDXGISurface1* pSurface; HRESULT hResult = _pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pSurface)); if (FAILED(hResult)) { return; } HDC surfaceDC; hResult = pSurface->GetDC(false, &surfaceDC); if (FAILED(hResult)) { return; } HDC ddc = GetDC(_hwnd); RECT rc; GetWindowRect(_hwnd, &rc); POINT wPos = { rc.left, rc.top }; SIZE wSize = { _width, _height }; BLENDFUNCTION blend; blend.BlendOp = AC_SRC_OVER; blend.BlendFlags = 0; blend.SourceConstantAlpha = 255; blend.AlphaFormat = AC_SRC_ALPHA; POINT layerPos; layerPos.x = 0; layerPos.y = 0; UpdateLayeredWindow(_hwnd, ddc, &wPos, &wSize, surfaceDC, &layerPos, RGB(255, 0, 0), &blend, ULW_ALPHA | ULW_COLORKEY); pSurface->ReleaseDC(nullptr); pSurface->Release(); _pDeviceContext->OMSetRenderTargets(1, _pRenderTargetView.GetAddressOf(), _pDepthStencilView.Get()); FLOAT blendFactor[4] = { D3D11_BLEND_ZERO, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO }; _pDeviceContext->OMSetBlendState(_pBlendState.Get(), blendFactor, 0xffffffff); } ID3D11Device* DxManager::GetDevice() { return _pDevice.Get(); } ID3D11DeviceContext* DxManager::GetDeviceContext() { return _pDeviceContext.Get(); } uint32_t DxManager::GetWindowWidth() { return _width; } uint32_t DxManager::GetWindowHeight() { return _height; }
VertexBuffer.cpp
#include "VertexBuffer.h" bool VertexBuffer::CreateVertexBuffer(uint32_t size, uint32_t stride, const void* data) { _size = size; _stride = stride; _offset = 0; _pBuffer = nullptr; D3D11_BUFFER_DESC desc = {}; desc.Usage = D3D11_USAGE_DEFAULT; desc.ByteWidth = size; desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; desc.CPUAccessFlags = 0; desc.MiscFlags = 0; desc.StructureByteStride = 0; D3D11_SUBRESOURCE_DATA subResourceData = {}; subResourceData.pSysMem = data; subResourceData.SysMemPitch = 0; subResourceData.SysMemSlicePitch = 0; HRESULT hResult = dx->GetDevice()->CreateBuffer(&desc, &subResourceData, _pBuffer.GetAddressOf()); if (FAILED(hResult)) { return false; } return true; } ID3D11Buffer** VertexBuffer::GetVertexBuffer() { return _pBuffer.GetAddressOf(); } uint32_t* VertexBuffer::GetStride() { return &_stride; } uint32_t* VertexBuffer::GetOffset() { return &_offset; }
IndexBuffer.cpp
#include "IndexBuffer.h" bool IndexBuffer::CreateIndexBuffer(uint32_t size, uint32_t* data) { D3D11_BUFFER_DESC desc = {}; ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC)); desc.ByteWidth = size; desc.StructureByteStride = sizeof(uint32_t); desc.Usage = D3D11_USAGE_DEFAULT; desc.BindFlags = D3D11_BIND_INDEX_BUFFER; desc.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA subResourceData; ZeroMemory(&subResourceData, sizeof(D3D11_SUBRESOURCE_DATA)); subResourceData.pSysMem = data; subResourceData.SysMemPitch = 0; subResourceData.SysMemSlicePitch = 0; HRESULT hResult = dx->GetDevice()->CreateBuffer(&desc, &subResourceData, _pBuffer.GetAddressOf()); if (FAILED(hResult)) { return false; } return true; } ID3D11Buffer* IndexBuffer::GetIndexBuffer() { return _pBuffer.Get(); }
PipelineState.cpp
#include "PipelineState.h" PipelineState::PipelineState() { } bool PipelineState::CreateVertexShader(std::wstring filePath, std::string mainFunc) { #if defined(_DEBUG) uint32_t compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else uint32_t compileFlags = 0; #endif ComPtr<ID3DBlob> pErrorBlob = nullptr; HRESULT hResult = D3DCompileFromFile( filePath.c_str(), nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE, mainFunc.c_str(), "vs_4_0", compileFlags, 0, _pVSBlob.GetAddressOf(), pErrorBlob.GetAddressOf() ); if (FAILED(hResult)) { std::cout << (char*)pErrorBlob->GetBufferPointer() << std::endl; return false; } hResult = dx->GetDevice()->CreateVertexShader(_pVSBlob->GetBufferPointer(), _pVSBlob->GetBufferSize(), nullptr, &_pVertexShader); if (FAILED(hResult)) { return false; } return true; } bool PipelineState::CreatePixelShader(std::wstring filePath, std::string mainFunc) { #if defined(_DEBUG) uint32_t compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else uint32_t compileFlags = 0; #endif ComPtr<ID3DBlob> blob; ComPtr<ID3DBlob> pErrorBlob = nullptr; HRESULT hResult = D3DCompileFromFile( filePath.c_str(), nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE, mainFunc.c_str(), "ps_4_0", compileFlags, 0, blob.GetAddressOf(), pErrorBlob.GetAddressOf() ); if (FAILED(hResult)) { std::cout << (char*)pErrorBlob->GetBufferPointer() << std::endl; return false; } hResult = dx->GetDevice()->CreatePixelShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, _pPixelShader.GetAddressOf()); if (FAILED(hResult)) { return false; } return true; } bool PipelineState::CreateInputLayout(D3D11_INPUT_ELEMENT_DESC* layout, uint32_t elementNum) { if (_pVSBlob == nullptr) { return false; } HRESULT hResult = dx->GetDevice()->CreateInputLayout(layout, elementNum, _pVSBlob->GetBufferPointer(), _pVSBlob->GetBufferSize(), _pInputLayout.GetAddressOf()); if (FAILED(hResult)) { return false; } return true; } ID3D11VertexShader* PipelineState::GetVertexShader() { return _pVertexShader.Get(); } ID3D11PixelShader* PipelineState::GetPixelShader() { return _pPixelShader.Get(); } ID3D11InputLayout* PipelineState::GetInputLayout() { return _pInputLayout.Get(); }
シェーダーと頂点レイアウトはPipelineStateというクラスを作成し一括で管理できるようにする。
シェーダーのバージョンは4.0にする。
Scene.cpp
#include "Scene.h" bool Scene::Init() { Vertex vertices[3] = {}; vertices[0].Position = DirectX::XMFLOAT3(-1.0f, -1.0f, 0.0f); vertices[0].Color = DirectX::XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f); vertices[1].Position = DirectX::XMFLOAT3(1.0f, -1.0f, 0.0f); vertices[1].Color = DirectX::XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f); vertices[2].Position = DirectX::XMFLOAT3(0.0f, 1.0f, 0.0f); vertices[2].Color = DirectX::XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f); uint32_t indices[3] = { 2, 1, 0}; const uint32_t elementCount = 2; D3D11_INPUT_ELEMENT_DESC elements[elementCount] = {}; elements[0].SemanticName = "POSITION"; elements[0].SemanticIndex = 0; elements[0].Format = DXGI_FORMAT_R32G32B32_FLOAT; //float型3つの配列 elements[0].InputSlot = 0; elements[0].AlignedByteOffset = 0; elements[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; elements[0].InstanceDataStepRate = 0; elements[1].SemanticName = "COLOR"; elements[1].SemanticIndex = 0; elements[1].Format = DXGI_FORMAT_R32G32B32A32_FLOAT; //float型4つの配列 elements[1].InputSlot = 0; elements[1].AlignedByteOffset = 12; elements[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; elements[1].InstanceDataStepRate = 0; if (!_vertexBuffer.CreateVertexBuffer(sizeof(vertices), sizeof(Vertex), vertices)) { std::cout << "Failed to create VertexBuffer" << std::endl; return false; } if (!_indexBuffer.CreateIndexBuffer(sizeof(indices), indices)) { std::cout << "Failed to create IndexBuffer" << std::endl; return false; } if (!_pipelineState.CreateVertexShader(L"VertexShader.hlsl", "main")) { std::cout << "Failed to create VertexShader" << std::endl; return false; } if (!_pipelineState.CreatePixelShader(L"PixelShader.hlsl", "main")) { std::cout << "Failed to create PixelShader" << std::endl; return false; } if (!_pipelineState.CreateInputLayout(elements, elementCount)) { std::cout << "Failed to create InputLayout" << std::endl; return false; } return true; } void Scene::Draw() { dx->GetDeviceContext()->IASetInputLayout(_pipelineState.GetInputLayout()); dx->GetDeviceContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); dx->GetDeviceContext()->IASetVertexBuffers(0, 1, _vertexBuffer.GetVertexBuffer(), _vertexBuffer.GetStride(), _vertexBuffer.GetOffset()); dx->GetDeviceContext()->IASetIndexBuffer(_indexBuffer.GetIndexBuffer(), DXGI_FORMAT_R32_UINT, 0); dx->GetDeviceContext()->VSSetShader(_pipelineState.GetVertexShader(), nullptr, 0); dx->GetDeviceContext()->PSSetShader(_pipelineState.GetPixelShader(), nullptr, 0); dx->GetDeviceContext()->DrawIndexed(3, 0, 0); }
シェーダー
VertexShader.hlsl
struct VSInput { float3 pos : POSITION; float4 color : COLOR; }; struct VSOutput { float4 svpos : SV_POSITION; float4 color : COLOR; }; VSOutput main(VSInput input) { VSOutput output; output.svpos = float4(input.pos, 1.0); output.color = input.color; return output; }
PixelShader.hlsl
struct PSInput { float4 svpos : SV_POSITION; // 頂点シェーダーから来た座標 float4 color : COLOR; }; float4 main(PSInput input) : SV_TARGET { return input.color; }
実行結果
参考資料
https://www.sfpgmr.net/blog/entry/立方体以外を透明化することができるようになっ.amp.html