src/video/windowsrt/CubeRenderer.cpp
author David Ludwig <dludwig@pobox.com>
Sat, 27 Oct 2012 21:20:00 -0400
changeset 8322 839cd578a474
permissions -rw-r--r--
WinRT: moved contents of platform-specific SDLmain into SDL.dll, where it should probably have been in the first place
     1 #include "SDLmain_WinRT_common.h"
     2 #include "CubeRenderer.h"
     3 
     4 using namespace DirectX;
     5 using namespace Microsoft::WRL;
     6 using namespace Windows::Foundation;
     7 using namespace Windows::UI::Core;
     8 
     9 CubeRenderer::CubeRenderer() :
    10 	m_loadingComplete(false),
    11 	m_indexCount(0)
    12 {
    13 }
    14 
    15 void CubeRenderer::CreateDeviceResources()
    16 {
    17 	Direct3DBase::CreateDeviceResources();
    18 
    19 	auto loadVSTask = DX::ReadDataAsync("SimpleVertexShader.cso");
    20 	auto loadPSTask = DX::ReadDataAsync("SimplePixelShader.cso");
    21 
    22 	auto createVSTask = loadVSTask.then([this](Platform::Array<byte>^ fileData) {
    23 		DX::ThrowIfFailed(
    24 			m_d3dDevice->CreateVertexShader(
    25  				fileData->Data,
    26 				fileData->Length,
    27 				nullptr,
    28 				&m_vertexShader
    29 				)
    30 			);
    31 
    32 		const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = 
    33 		{
    34 			{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,  D3D11_INPUT_PER_VERTEX_DATA, 0 },
    35 			{ "COLOR",    0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    36 		};
    37 
    38 		DX::ThrowIfFailed(
    39 			m_d3dDevice->CreateInputLayout(
    40 				vertexDesc,
    41 				ARRAYSIZE(vertexDesc),
    42 				fileData->Data,
    43 				fileData->Length,
    44 				&m_inputLayout
    45 				)
    46 			);
    47 	});
    48 
    49 	auto createPSTask = loadPSTask.then([this](Platform::Array<byte>^ fileData) {
    50 		DX::ThrowIfFailed(
    51 			m_d3dDevice->CreatePixelShader(
    52 				fileData->Data,
    53 				fileData->Length,
    54 				nullptr,
    55 				&m_pixelShader
    56 				)
    57 			);
    58 
    59 		CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ModelViewProjectionConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
    60 		DX::ThrowIfFailed(
    61 			m_d3dDevice->CreateBuffer(
    62 				&constantBufferDesc,
    63 				nullptr,
    64 				&m_constantBuffer
    65 				)
    66 			);
    67 	});
    68 
    69 	auto createCubeTask = (createPSTask && createVSTask).then([this] () {
    70 		VertexPositionColor cubeVertices[] = 
    71 		{
    72 			{XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT3(0.0f, 0.0f, 0.0f)},
    73 			{XMFLOAT3(-0.5f, -0.5f,  0.5f), XMFLOAT3(0.0f, 0.0f, 1.0f)},
    74 			{XMFLOAT3(-0.5f,  0.5f, -0.5f), XMFLOAT3(0.0f, 1.0f, 0.0f)},
    75 			{XMFLOAT3(-0.5f,  0.5f,  0.5f), XMFLOAT3(0.0f, 1.0f, 1.0f)},
    76 			{XMFLOAT3( 0.5f, -0.5f, -0.5f), XMFLOAT3(1.0f, 0.0f, 0.0f)},
    77 			{XMFLOAT3( 0.5f, -0.5f,  0.5f), XMFLOAT3(1.0f, 0.0f, 1.0f)},
    78 			{XMFLOAT3( 0.5f,  0.5f, -0.5f), XMFLOAT3(1.0f, 1.0f, 0.0f)},
    79 			{XMFLOAT3( 0.5f,  0.5f,  0.5f), XMFLOAT3(1.0f, 1.0f, 1.0f)},
    80 		};
    81 
    82 		D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
    83 		vertexBufferData.pSysMem = cubeVertices;
    84 		vertexBufferData.SysMemPitch = 0;
    85 		vertexBufferData.SysMemSlicePitch = 0;
    86 		CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(cubeVertices), D3D11_BIND_VERTEX_BUFFER);
    87 		DX::ThrowIfFailed(
    88 			m_d3dDevice->CreateBuffer(
    89 				&vertexBufferDesc,
    90 				&vertexBufferData,
    91 				&m_vertexBuffer
    92 				)
    93 			);
    94 
    95 		unsigned short cubeIndices[] = 
    96 		{
    97 			0,2,1, // -x
    98 			1,2,3,
    99 
   100 			4,5,6, // +x
   101 			5,7,6,
   102 
   103 			0,1,5, // -y
   104 			0,5,4,
   105 
   106 			2,6,7, // +y
   107 			2,7,3,
   108 
   109 			0,4,6, // -z
   110 			0,6,2,
   111 
   112 			1,3,7, // +z
   113 			1,7,5,
   114 		};
   115 
   116 		m_indexCount = ARRAYSIZE(cubeIndices);
   117 
   118 		D3D11_SUBRESOURCE_DATA indexBufferData = {0};
   119 		indexBufferData.pSysMem = cubeIndices;
   120 		indexBufferData.SysMemPitch = 0;
   121 		indexBufferData.SysMemSlicePitch = 0;
   122 		CD3D11_BUFFER_DESC indexBufferDesc(sizeof(cubeIndices), D3D11_BIND_INDEX_BUFFER);
   123 		DX::ThrowIfFailed(
   124 			m_d3dDevice->CreateBuffer(
   125 				&indexBufferDesc,
   126 				&indexBufferData,
   127 				&m_indexBuffer
   128 				)
   129 			);
   130 	});
   131 
   132 	createCubeTask.then([this] () {
   133 		m_loadingComplete = true;
   134 	});
   135 }
   136 
   137 void CubeRenderer::CreateWindowSizeDependentResources()
   138 {
   139 	Direct3DBase::CreateWindowSizeDependentResources();
   140 
   141 	float aspectRatio = m_windowBounds.Width / m_windowBounds.Height;
   142 	float fovAngleY = 70.0f * XM_PI / 180.0f;
   143 
   144 	// Note that the m_orientationTransform3D matrix is post-multiplied here
   145 	// in order to correctly orient the scene to match the display orientation.
   146 	// This post-multiplication step is required for any draw calls that are
   147 	// made to the swap chain render target. For draw calls to other targets,
   148 	// this transform should not be applied.
   149 	XMStoreFloat4x4(
   150 		&m_constantBufferData.projection,
   151 		XMMatrixTranspose(
   152 			XMMatrixMultiply(
   153 				XMMatrixPerspectiveFovRH(
   154 					fovAngleY,
   155 					aspectRatio,
   156 					0.01f,
   157 					100.0f
   158 					),
   159 				XMLoadFloat4x4(&m_orientationTransform3D)
   160 				)
   161 			)
   162 		);
   163 }
   164 
   165 void CubeRenderer::Update(float timeTotal, float timeDelta)
   166 {
   167 	(void) timeDelta; // Unused parameter.
   168 
   169 	XMVECTOR eye = XMVectorSet(0.0f, 0.7f, 1.5f, 0.0f);
   170 	XMVECTOR at = XMVectorSet(0.0f, -0.1f, 0.0f, 0.0f);
   171 	XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
   172 
   173 	XMStoreFloat4x4(&m_constantBufferData.view, XMMatrixTranspose(XMMatrixLookAtRH(eye, at, up)));
   174 	XMStoreFloat4x4(&m_constantBufferData.model, XMMatrixTranspose(XMMatrixRotationY(timeTotal * XM_PIDIV4)));
   175 }
   176 
   177 void CubeRenderer::Render()
   178 {
   179 	const float midnightBlue[] = { 0.098f, 0.098f, 0.439f, 1.000f };
   180 	m_d3dContext->ClearRenderTargetView(
   181 		m_renderTargetView.Get(),
   182 		midnightBlue
   183 		);
   184 
   185 	m_d3dContext->ClearDepthStencilView(
   186 		m_depthStencilView.Get(),
   187 		D3D11_CLEAR_DEPTH,
   188 		1.0f,
   189 		0
   190 		);
   191 
   192 	// Only draw the cube once it is loaded (loading is asynchronous).
   193 	if (!m_loadingComplete)
   194 	{
   195 		return;
   196 	}
   197 
   198 	m_d3dContext->OMSetRenderTargets(
   199 		1,
   200 		m_renderTargetView.GetAddressOf(),
   201 		m_depthStencilView.Get()
   202 		);
   203 
   204 	m_d3dContext->UpdateSubresource(
   205 		m_constantBuffer.Get(),
   206 		0,
   207 		NULL,
   208 		&m_constantBufferData,
   209 		0,
   210 		0
   211 		);
   212 
   213 	UINT stride = sizeof(VertexPositionColor);
   214 	UINT offset = 0;
   215 	m_d3dContext->IASetVertexBuffers(
   216 		0,
   217 		1,
   218 		m_vertexBuffer.GetAddressOf(),
   219 		&stride,
   220 		&offset
   221 		);
   222 
   223 	m_d3dContext->IASetIndexBuffer(
   224 		m_indexBuffer.Get(),
   225 		DXGI_FORMAT_R16_UINT,
   226 		0
   227 		);
   228 
   229 	m_d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
   230 
   231 	m_d3dContext->IASetInputLayout(m_inputLayout.Get());
   232 
   233 	m_d3dContext->VSSetShader(
   234 		m_vertexShader.Get(),
   235 		nullptr,
   236 		0
   237 		);
   238 
   239 	m_d3dContext->VSSetConstantBuffers(
   240 		0,
   241 		1,
   242 		m_constantBuffer.GetAddressOf()
   243 		);
   244 
   245 	m_d3dContext->PSSetShader(
   246 		m_pixelShader.Get(),
   247 		nullptr,
   248 		0
   249 		);
   250 
   251 	m_d3dContext->DrawIndexed(
   252 		m_indexCount,
   253 		0,
   254 		0
   255 		);
   256 }