src/video/windowsrt/SDL_winrtrenderer.cpp
author David Ludwig <dludwig@pobox.com>
Wed, 21 Nov 2012 17:07:48 -0500
changeset 8347 f0e61c2638ad
parent 8346 a15d524f1d2e
child 8348 7cdcd6d28c85
permissions -rw-r--r--
WinRT: made the fullscreen display be backed by a texture
     1 #include "SDLmain_WinRT_common.h"
     2 #include "SDL_winrtrenderer.h"
     3 
     4 using namespace DirectX;
     5 using namespace Microsoft::WRL;
     6 using namespace Windows::Foundation;
     7 using namespace Windows::UI::Core;
     8 
     9 SDL_winrtrenderer::SDL_winrtrenderer() :
    10 	m_loadingComplete(false),
    11 	m_vertexCount(0)
    12 {
    13 }
    14 
    15 void SDL_winrtrenderer::CreateDeviceResources()
    16 {
    17 	Direct3DBase::CreateDeviceResources();
    18 
    19 	auto loadVSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\SimpleVertexShader.cso");
    20 	auto loadPSTask = DX::ReadDataAsync("SDL_VS2012_WinRT\\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 			{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    37 		};
    38 
    39 		DX::ThrowIfFailed(
    40 			m_d3dDevice->CreateInputLayout(
    41 				vertexDesc,
    42 				ARRAYSIZE(vertexDesc),
    43 				fileData->Data,
    44 				fileData->Length,
    45 				&m_inputLayout
    46 				)
    47 			);
    48 	});
    49 
    50 	auto createPSTask = loadPSTask.then([this](Platform::Array<byte>^ fileData) {
    51 		DX::ThrowIfFailed(
    52 			m_d3dDevice->CreatePixelShader(
    53 				fileData->Data,
    54 				fileData->Length,
    55 				nullptr,
    56 				&m_pixelShader
    57 				)
    58 			);
    59 	});
    60 
    61 	auto createCubeTask = (createPSTask && createVSTask).then([this] () {
    62 		VertexPositionColor cubeVertices[] = 
    63 		{
    64 			{XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)},
    65 			{XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)},
    66 			{XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(1.0f, 0.0f)},
    67 			{XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT2(1.0f, 1.0f)},
    68 		};
    69 
    70 		m_vertexCount = ARRAYSIZE(cubeVertices);
    71 
    72 		D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
    73 		vertexBufferData.pSysMem = cubeVertices;
    74 		vertexBufferData.SysMemPitch = 0;
    75 		vertexBufferData.SysMemSlicePitch = 0;
    76 		CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(cubeVertices), D3D11_BIND_VERTEX_BUFFER);
    77 		DX::ThrowIfFailed(
    78 			m_d3dDevice->CreateBuffer(
    79 				&vertexBufferDesc,
    80 				&vertexBufferData,
    81 				&m_vertexBuffer
    82 				)
    83 			);
    84 	});
    85 
    86 	auto createMainTextureTask = createCubeTask.then([this] () {
    87 		D3D11_TEXTURE2D_DESC textureDesc = {0};
    88 		textureDesc.Width = (int)m_windowBounds.Width;
    89 		textureDesc.Height = (int)m_windowBounds.Height;
    90 		textureDesc.MipLevels = 1;
    91 		textureDesc.ArraySize = 1;
    92 		textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
    93 		textureDesc.SampleDesc.Count = 1;
    94 		textureDesc.SampleDesc.Quality = 0;
    95 		textureDesc.Usage = D3D11_USAGE_DYNAMIC;
    96 		textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    97 		textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    98 		textureDesc.MiscFlags = 0;
    99 
   100 		int numPixels = (int)m_windowBounds.Width * (int)m_windowBounds.Height;
   101 		std::vector<uint8> initialTexturePixels(numPixels * 4);
   102 		for (int i = 0; i < (numPixels * 4); i += 4) {
   103 			initialTexturePixels[i+0] = 0xFF;
   104 			initialTexturePixels[i+1] = 0x00;
   105 			initialTexturePixels[i+2] = 0x00;
   106 			initialTexturePixels[i+3] = 0xFF;
   107 		}
   108 		D3D11_SUBRESOURCE_DATA initialTextureData = {0};
   109 		initialTextureData.pSysMem = (void *)&(initialTexturePixels[0]);
   110 		initialTextureData.SysMemPitch = (int)m_windowBounds.Width * 4;
   111 		initialTextureData.SysMemSlicePitch = numPixels * 4;
   112 		DX::ThrowIfFailed(
   113 			m_d3dDevice->CreateTexture2D(
   114 				&textureDesc,
   115 				&initialTextureData,
   116 				&m_mainTexture
   117 				)
   118 			);
   119 
   120 		D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc;
   121 		resourceViewDesc.Format = textureDesc.Format;
   122 		resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
   123 		resourceViewDesc.Texture2D.MostDetailedMip = 0;
   124 		resourceViewDesc.Texture2D.MipLevels = textureDesc.MipLevels;
   125 		DX::ThrowIfFailed(
   126 			m_d3dDevice->CreateShaderResourceView(
   127 				m_mainTexture.Get(),
   128 				&resourceViewDesc,
   129 				&m_mainTextureResourceView)
   130 			);
   131 	});
   132 
   133 	auto createMainSamplerTask = createMainTextureTask.then([this] () {
   134 		D3D11_SAMPLER_DESC samplerDesc;
   135 		samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
   136 		samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
   137 		samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
   138 		samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
   139 		samplerDesc.MipLODBias = 0.0f;
   140 		samplerDesc.MaxAnisotropy = 1;
   141 		samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
   142 		samplerDesc.BorderColor[0] = 0.0f;
   143 		samplerDesc.BorderColor[1] = 0.0f;
   144 		samplerDesc.BorderColor[2] = 0.0f;
   145 		samplerDesc.BorderColor[3] = 0.0f;
   146 		samplerDesc.MinLOD = 0.0f;
   147 		samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
   148 		DX::ThrowIfFailed(
   149 			m_d3dDevice->CreateSamplerState(
   150 				&samplerDesc,
   151 				&m_mainSampler
   152 				)
   153 			);
   154 	});
   155 
   156 	createMainSamplerTask.then([this] () {
   157 		m_loadingComplete = true;
   158 	});
   159 }
   160 
   161 void SDL_winrtrenderer::Render()
   162 {
   163 	const float midnightBlue[] = { 0.098f, 0.098f, 0.439f, 1.000f };
   164 	m_d3dContext->ClearRenderTargetView(
   165 		m_renderTargetView.Get(),
   166 		midnightBlue
   167 		);
   168 
   169 	m_d3dContext->ClearDepthStencilView(
   170 		m_depthStencilView.Get(),
   171 		D3D11_CLEAR_DEPTH,
   172 		1.0f,
   173 		0
   174 		);
   175 
   176 	// Only draw the cube once it is loaded (loading is asynchronous).
   177 	if (!m_loadingComplete)
   178 	{
   179 		return;
   180 	}
   181 
   182 	m_d3dContext->OMSetRenderTargets(
   183 		1,
   184 		m_renderTargetView.GetAddressOf(),
   185 		m_depthStencilView.Get()
   186 		);
   187 
   188 	UINT stride = sizeof(VertexPositionColor);
   189 	UINT offset = 0;
   190 	m_d3dContext->IASetVertexBuffers(
   191 		0,
   192 		1,
   193 		m_vertexBuffer.GetAddressOf(),
   194 		&stride,
   195 		&offset
   196 		);
   197 
   198 	m_d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
   199 
   200 	m_d3dContext->IASetInputLayout(m_inputLayout.Get());
   201 
   202 	m_d3dContext->VSSetShader(
   203 		m_vertexShader.Get(),
   204 		nullptr,
   205 		0
   206 		);
   207 
   208 	m_d3dContext->PSSetShader(
   209 		m_pixelShader.Get(),
   210 		nullptr,
   211 		0
   212 		);
   213 
   214 	m_d3dContext->PSSetShaderResources(0, 1, m_mainTextureResourceView.GetAddressOf());
   215 
   216 	m_d3dContext->PSSetSamplers(0, 1, m_mainSampler.GetAddressOf());
   217 
   218 	m_d3dContext->Draw(4, 0);
   219 }