~プログラミング~ DirectX 11で平行光源ライティングのソースコードです。
CD3DTest.h
#define SAFE_RELEASE(p) { if( NULL != p ) { p->Release(); p = NULL; } } class CD3DTest { public: ID3D11Device* m_pDevice; ID3D11DeviceContext* m_pImmediateContext; IDXGISwapChain* m_pSwapChain; ID3D11Texture2D* m_pDepthStencilTexture; ID3D11RenderTargetView* m_pRenderTargetView; ID3D11DepthStencilView* m_pDepthStencilView; ID3D11Buffer* m_pVertexBuffer; ID3D11Buffer* m_pIndexBuffer; ID3D11Buffer* m_pConstantBuffer; ID3D11InputLayout* m_pInputLayout; ID3D11VertexShader* m_pVertexShader; ID3D11PixelShader* m_pPixelShader; D3D11_VIEWPORT m_Viewport; public: CD3DTest(); virtual ~CD3DTest(); virtual HRESULT Create( HWND hwnd ); virtual void Release(); virtual void Render(); };
CD3DTest.cpp
#include "stdafx.h" struct Vertex { float pos[ 3 ]; float nor[ 3 ]; }; Vertex g_VertexList[] { { { -0.5f, 0.5f, -0.5f }, { 0.0f, 0.0f, -1.0f } }, { { 0.5f, 0.5f, -0.5f }, { 0.0f, 0.0f, -1.0f } }, { { -0.5f, -0.5f, -0.5f }, { 0.0f, 0.0f, -1.0f } }, { { 0.5f, -0.5f, -0.5f }, { 0.0f, 0.0f, -1.0f } }, { { -0.5f, 0.5f, 0.5f }, { 0.0f, 0.0f, 1.0f } }, { { -0.5f, -0.5f, 0.5f }, { 0.0f, 0.0f, 1.0f } }, { { 0.5f, 0.5f, 0.5f }, { 0.0f, 0.0f, 1.0f } }, { { 0.5f, -0.5f, 0.5f }, { 0.0f, 0.0f, 1.0f } }, { { -0.5f, 0.5f, 0.5f }, { -1.0f, 0.0f, 0.0f } }, { { -0.5f, 0.5f, -0.5f }, { -1.0f, 0.0f, 0.0f } }, { { -0.5f, -0.5f, 0.5f }, { -1.0f, 0.0f, 0.0f } }, { { -0.5f, -0.5f, -0.5f }, { -1.0f, 0.0f, 0.0f } }, { { 0.5f, 0.5f, 0.5f }, { 1.0f, 0.0f, 0.0f } }, { { 0.5f, -0.5f, 0.5f }, { 1.0f, 0.0f, 0.0f } }, { { 0.5f, 0.5f, -0.5f }, { 1.0f, 0.0f, 0.0f } }, { { 0.5f, -0.5f, -0.5f }, { 1.0f, 0.0f, 0.0f } }, { { -0.5f, 0.5f, 0.5f }, { 0.0f, 1.0f, 0.0f } }, { { 0.5f, 0.5f, 0.5f }, { 0.0f, 1.0f, 0.0f } }, { { -0.5f, 0.5f, -0.5f }, { 0.0f, 1.0f, 0.0f } }, { { 0.5f, 0.5f, -0.5f }, { 0.0f, 1.0f, 0.0f } }, { { -0.5f, -0.5f, 0.5f }, { 0.0f, -1.0f, 0.0f } }, { { -0.5f, -0.5f, -0.5f }, { 0.0f, -1.0f, 0.0f } }, { { 0.5f, -0.5f, 0.5f }, { 0.0f, -1.0f, 0.0f } }, { { 0.5f, -0.5f, -0.5f }, { 0.0f, -1.0f, 0.0f } }, }; WORD g_IndexList[] { 0, 1, 2, 3, 2, 1, 4, 5, 6, 7, 6, 5, 8, 9, 10, 11, 10, 9, 12, 13, 14, 15, 14, 13, 16, 17, 18, 19, 18, 17, 20, 21, 22, 23, 22, 21, }; D3D11_INPUT_ELEMENT_DESC g_VertexDesc[] { { "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 }, }; struct ConstantBuffer { XMFLOAT4X4 world; XMFLOAT4X4 view; XMFLOAT4X4 projection; XMFLOAT4 light; }; CD3DTest::CD3DTest() { m_pDevice = NULL; m_pImmediateContext = NULL; m_pSwapChain = NULL; m_pDepthStencilTexture = NULL; m_pRenderTargetView = NULL; m_pDepthStencilView = NULL; m_pVertexBuffer = NULL; m_pIndexBuffer = NULL; m_pConstantBuffer = NULL; m_pInputLayout = NULL; m_pVertexShader = NULL; m_pPixelShader = NULL; } CD3DTest::~CD3DTest() { Release(); } HRESULT CD3DTest::Create( HWND hwnd ) { Release(); HRESULT hr; CRect rect; DXGI_SWAP_CHAIN_DESC scDesc; ::GetClientRect( hwnd, &rect ); ::ZeroMemory( &scDesc, sizeof( scDesc ) ); scDesc.BufferCount = 1; scDesc.BufferDesc.Width = rect.Width(); scDesc.BufferDesc.Height = rect.Height(); scDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; scDesc.OutputWindow = hwnd; scDesc.SampleDesc.Count = 1; scDesc.SampleDesc.Quality = 0; scDesc.Windowed = TRUE; UINT flags = 0; #ifdef _DEBUG flags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL pLevels[] = { D3D_FEATURE_LEVEL_11_0 }; D3D_FEATURE_LEVEL level; hr = D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, pLevels, 1, D3D11_SDK_VERSION, &scDesc, &m_pSwapChain, &m_pDevice, &level, &m_pImmediateContext ); if ( FAILED( hr ) ) return hr; ID3D11Texture2D* pBackBuffer; hr = m_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (LPVOID*)&pBackBuffer ); if ( FAILED( hr ) ) return hr; hr = m_pDevice->CreateRenderTargetView( pBackBuffer, NULL, &m_pRenderTargetView ); pBackBuffer->Release(); if ( FAILED( hr ) ) return hr; //深度ステンシルバッファ作成 D3D11_TEXTURE2D_DESC txDesc; ZeroMemory( &txDesc, sizeof( txDesc ) ); txDesc.Width = rect.Width(); txDesc.Height = rect.Height(); txDesc.MipLevels = 1; txDesc.ArraySize = 1; txDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; txDesc.SampleDesc.Count = 1; txDesc.SampleDesc.Quality = 0; txDesc.Usage = D3D11_USAGE_DEFAULT; txDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; txDesc.CPUAccessFlags = 0; txDesc.MiscFlags = 0; hr = m_pDevice->CreateTexture2D( &txDesc, NULL, &m_pDepthStencilTexture ); if ( FAILED( hr ) ) return hr; D3D11_DEPTH_STENCIL_VIEW_DESC dsDesc; ZeroMemory( &dsDesc, sizeof( dsDesc ) ); dsDesc.Format = txDesc.Format; dsDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; dsDesc.Texture2D.MipSlice = 0; hr = m_pDevice->CreateDepthStencilView( m_pDepthStencilTexture, &dsDesc, &m_pDepthStencilView ); if ( FAILED( hr ) ) return hr; //頂点バッファ作成 D3D11_BUFFER_DESC vbDesc; vbDesc.ByteWidth = sizeof( Vertex ) * 24; vbDesc.Usage = D3D11_USAGE_DEFAULT; vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; vbDesc.CPUAccessFlags = 0; vbDesc.MiscFlags = 0; vbDesc.StructureByteStride = 0; D3D11_SUBRESOURCE_DATA vrData; vrData.pSysMem = g_VertexList; vrData.SysMemPitch = 0; vrData.SysMemSlicePitch = 0; hr = m_pDevice->CreateBuffer( &vbDesc, &vrData, &m_pVertexBuffer ); if ( FAILED( hr ) ) return hr; //インデックスバッファ作成 D3D11_BUFFER_DESC ibDesc; ibDesc.ByteWidth = sizeof( WORD ) * 6 * 6; ibDesc.Usage = D3D11_USAGE_DEFAULT; ibDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; ibDesc.CPUAccessFlags = 0; ibDesc.MiscFlags = 0; ibDesc.StructureByteStride = 0; D3D11_SUBRESOURCE_DATA irData; irData.pSysMem = g_IndexList; irData.SysMemPitch = 0; irData.SysMemSlicePitch = 0; hr = m_pDevice->CreateBuffer( &ibDesc, &irData, &m_pIndexBuffer ); if ( FAILED( hr ) ) return hr; //定数バッファ作成 D3D11_BUFFER_DESC cbDesc; cbDesc.ByteWidth = sizeof( ConstantBuffer ); cbDesc.Usage = D3D11_USAGE_DEFAULT; cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; cbDesc.CPUAccessFlags = 0; cbDesc.MiscFlags = 0; cbDesc.StructureByteStride = 0; hr = m_pDevice->CreateBuffer( &cbDesc, NULL, &m_pConstantBuffer ); if ( FAILED( hr ) ) return hr; //頂点レイアウト作成 hr = m_pDevice->CreateInputLayout( g_VertexDesc, ARRAYSIZE( g_VertexDesc ), g_vs_main, sizeof( g_vs_main ), &m_pInputLayout ); if ( FAILED( hr ) ) return hr; //頂点シェーダー生成 hr = m_pDevice->CreateVertexShader( &g_vs_main, sizeof( g_vs_main ), NULL, &m_pVertexShader ); if ( FAILED( hr ) ) return hr; //ピクセルシェーダー生成 hr = m_pDevice->CreatePixelShader( &g_ps_main, sizeof( g_ps_main ), NULL, &m_pPixelShader ); if ( FAILED( hr ) ) return hr; //ビューポート設定 m_Viewport.TopLeftX = 0; m_Viewport.TopLeftY = 0; m_Viewport.Width = (FLOAT)rect.Width(); m_Viewport.Height = (FLOAT)rect.Height(); m_Viewport.MinDepth = 0.0f; m_Viewport.MaxDepth = 1.0f; return hr; } void CD3DTest::Release() { if( m_pImmediateContext ) { m_pImmediateContext->ClearState(); } SAFE_RELEASE( m_pVertexBuffer ); SAFE_RELEASE( m_pIndexBuffer ); SAFE_RELEASE( m_pConstantBuffer ); SAFE_RELEASE( m_pInputLayout ); SAFE_RELEASE( m_pVertexShader ); SAFE_RELEASE( m_pPixelShader ); SAFE_RELEASE( m_pRenderTargetView ); SAFE_RELEASE( m_pDepthStencilView ); SAFE_RELEASE( m_pDepthStencilTexture ); SAFE_RELEASE( m_pSwapChain ); SAFE_RELEASE( m_pImmediateContext ); SAFE_RELEASE( m_pDevice ); } void CD3DTest::Render() { XMMATRIX worldMatrix = XMMatrixTranslation( 0.0f, 0.0f, 0.0f ); XMVECTOR eye = XMVectorSet( 2.0f, 2.0f, -2.0f, 0.0f ); XMVECTOR focus = XMVectorSet( 0.0f, 0.0f, 0.0f, 0.0f ); XMVECTOR up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f ); XMMATRIX viewMatrix = XMMatrixLookAtLH( eye, focus, up ); float fov = XMConvertToRadians( 45.0f ); float aspect = m_Viewport.Width / m_Viewport.Height; float nearZ = 0.1f; float farZ = 100.0f; XMMATRIX projMatrix = XMMatrixPerspectiveFovLH( fov, aspect, nearZ, farZ ); XMVECTOR light = XMVector3Normalize( XMVectorSet( 0.0f, 0.5f, -1.0f, 0.0f ) ); ConstantBuffer cb; XMStoreFloat4x4( &cb.world, XMMatrixTranspose( worldMatrix ) ); XMStoreFloat4x4( &cb.view, XMMatrixTranspose( viewMatrix ) ); XMStoreFloat4x4( &cb.projection, XMMatrixTranspose( projMatrix ) ); XMStoreFloat4( &cb.light, light ); m_pImmediateContext->UpdateSubresource( m_pConstantBuffer, 0, NULL, &cb, 0, 0 ); float clearColor[ 4 ] = { 0.0f, 0.0f, 0.0f, 1.0f }; //red,green,blue,alpha UINT strides = sizeof( Vertex ); UINT offsets = 0; m_pImmediateContext->IASetInputLayout( m_pInputLayout ); m_pImmediateContext->IASetVertexBuffers( 0, 1, &m_pVertexBuffer, &strides, &offsets ); m_pImmediateContext->IASetIndexBuffer( m_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0 ); m_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); m_pImmediateContext->VSSetConstantBuffers( 0, 1, &m_pConstantBuffer ); m_pImmediateContext->VSSetShader( m_pVertexShader, NULL, 0 ); m_pImmediateContext->RSSetViewports( 1, &m_Viewport ); m_pImmediateContext->PSSetShader( m_pPixelShader, NULL, 0 ); m_pImmediateContext->OMSetRenderTargets( 1, &m_pRenderTargetView, m_pDepthStencilView ); m_pImmediateContext->ClearRenderTargetView( m_pRenderTargetView, clearColor ); m_pImmediateContext->ClearDepthStencilView( m_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0 ); m_pImmediateContext->DrawIndexed( 36, 0, 0 ); m_pSwapChain->Present( 0, 0 ); }
vs_test.vsh
struct VS_IN { float4 pos : POSITION0; float4 nor : NORMAL0; }; struct VS_OUT { float4 pos : SV_POSITION; float4 col : COLOR0; }; cbuffer ConstantBuffer { float4x4 World; //ワールド変換行列 float4x4 View; //ビュー変換行列 float4x4 Projection; //透視射影変換行列 float4 Light; } VS_OUT vs_main( VS_IN input ) { VS_OUT output; float3 nor; float col; output.pos = mul(input.pos, World); output.pos = mul(output.pos, View); output.pos = mul(output.pos, Projection); nor = mul(input.nor, World).xyz; nor = normalize(nor); col = saturate(dot(nor, (float3)Light)); col = col * 0.5f + 0.5f; output.col = float4(col, col, col, 1.0f); return output; }
ps_test.psh
struct PS_IN { float4 pos : SV_POSITION; float4 col : COLOR0; }; float4 ps_main( PS_IN input ) : SV_Target { return input.col; }
コメントをお書きください