WinRT: more code-moving from SDL_winrtrenderer* to SDL_render_d3d11*

This commit is contained in:
David Ludwig 2013-02-09 11:42:17 -05:00
parent 7eee7ec08f
commit 0bc7f7eac8
4 changed files with 247 additions and 200 deletions

View file

@ -27,14 +27,23 @@ extern "C" {
#include "../../core/windows/SDL_windows.h" #include "../../core/windows/SDL_windows.h"
//#include "SDL_hints.h" //#include "SDL_hints.h"
//#include "SDL_loadso.h" //#include "SDL_loadso.h"
#include "SDL_system.h"
#include "SDL_syswm.h" #include "SDL_syswm.h"
#include "../SDL_sysrender.h" #include "../SDL_sysrender.h"
//#include "stdio.h" //#include "stdio.h"
} }
#include <fstream>
#include <string>
#include <vector>
#include "SDL_render_d3d11_cpp.h" #include "SDL_render_d3d11_cpp.h"
/* Direct3D renderer implementation */ using namespace DirectX;
using namespace Microsoft::WRL;
using namespace std;
/* Direct3D 11.1 renderer implementation */
static SDL_Renderer *D3D11_CreateRenderer(SDL_Window * window, Uint32 flags); static SDL_Renderer *D3D11_CreateRenderer(SDL_Window * window, Uint32 flags);
//static void D3D11_WindowEvent(SDL_Renderer * renderer, //static void D3D11_WindowEvent(SDL_Renderer * renderer,
@ -67,6 +76,9 @@ static void D3D11_RenderPresent(SDL_Renderer * renderer);
// SDL_Texture * texture); // SDL_Texture * texture);
//static void D3D11_DestroyRenderer(SDL_Renderer * renderer); //static void D3D11_DestroyRenderer(SDL_Renderer * renderer);
/* Direct3D 11.1 Internal Functions */
HRESULT WINRT_CreateDeviceResources(SDL_Renderer * renderer);
extern "C" { extern "C" {
SDL_RenderDriver D3D11_RenderDriver = { SDL_RenderDriver D3D11_RenderDriver = {
@ -114,10 +126,12 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
data = new D3D11_RenderData; // Use the C++ 'new' operator to make sure the struct's members initialize using C++ rules data = new D3D11_RenderData; // Use the C++ 'new' operator to make sure the struct's members initialize using C++ rules
if (!data) { if (!data) {
delete data;
SDL_OutOfMemory(); SDL_OutOfMemory();
return NULL; return NULL;
} }
data->featureLevel = (D3D_FEATURE_LEVEL) 0;
data->vertexCount = 0;
data->loadingComplete = false;
// TODO: Create Direct3D Object(s) // TODO: Create Direct3D Object(s)
@ -280,6 +294,224 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
return renderer; return renderer;
} }
static bool
D3D11_ReadFileContents(const wstring & fileName, vector<char> & out)
{
ifstream in(fileName, ios::in | ios::binary);
if (!in) {
return false;
}
in.seekg(0, ios::end);
out.resize((size_t) in.tellg());
in.seekg(0, ios::beg);
in.read(&out[0], out.size());
return in.good();
}
static bool
D3D11_ReadShaderContents(const wstring & shaderName, vector<char> & out)
{
wstring fileName;
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
fileName = SDL_WinRTGetInstalledLocationPath();
fileName += L"\\SDL_VS2012_WinRT\\";
#elif WINAPI_FAMILY == WINAPI_PHONE_APP
fileName = SDL_WinRTGetInstalledLocationPath();
fileName += L"\\";
#endif
// WinRT, TODO: test Direct3D 11.1 shader loading on Win32
fileName += shaderName;
return D3D11_ReadFileContents(fileName, out);
}
HRESULT
WINRT_CreateDeviceResources(SDL_Renderer * renderer)
{
D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
// This flag adds support for surfaces with a different color channel ordering
// than the API default. It is required for compatibility with Direct2D.
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#if defined(_DEBUG)
// If the project is in a debug build, enable debugging via SDK Layers with this flag.
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
// This array defines the set of DirectX hardware feature levels this app will support.
// Note the ordering should be preserved.
// Don't forget to declare your application's minimum required feature level in its
// description. All applications are assumed to support 9.1 unless otherwise stated.
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1
};
// Create the Direct3D 11 API device object and a corresponding context.
ComPtr<ID3D11Device> device;
ComPtr<ID3D11DeviceContext> context;
HRESULT result = S_OK;
result = D3D11CreateDevice(
nullptr, // Specify nullptr to use the default adapter.
D3D_DRIVER_TYPE_HARDWARE,
nullptr,
creationFlags, // Set set debug and Direct2D compatibility flags.
featureLevels, // List of feature levels this app can support.
ARRAYSIZE(featureLevels),
D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps.
&device, // Returns the Direct3D device created.
&data->featureLevel, // Returns feature level of device created.
&context // Returns the device immediate context.
);
if (FAILED(result)) {
WIN_SetErrorFromHRESULT(__FUNCTION__, result);
return result;
}
// Get the Direct3D 11.1 API device and context interfaces.
Microsoft::WRL::ComPtr<ID3D11Device1> d3dDevice1;
result = device.As(&(data->d3dDevice));
if (FAILED(result)) {
WIN_SetErrorFromHRESULT(__FUNCTION__, result);
return result;
}
result = context.As(&data->d3dContext);
if (FAILED(result)) {
return result;
}
// Start loading GPU shaders:
vector<char> fileData;
//
// Load in SDL's one and only vertex shader:
//
if (!D3D11_ReadShaderContents(L"SimpleVertexShader.cso", fileData)) {
SDL_SetError("Unable to open SDL's vertex shader file.");
return E_FAIL;
}
result = data->d3dDevice->CreateVertexShader(
&fileData[0],
fileData.size(),
nullptr,
&data->vertexShader
);
if (FAILED(result)) {
WIN_SetErrorFromHRESULT(__FUNCTION__, result);
return result;
}
//
// Create an input layout for SDL's vertex shader:
//
const D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
{
{ "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 },
};
result = data->d3dDevice->CreateInputLayout(
vertexDesc,
ARRAYSIZE(vertexDesc),
&fileData[0],
fileData.size(),
&data->inputLayout
);
if (FAILED(result)) {
WIN_SetErrorFromHRESULT(__FUNCTION__, result);
return result;
}
//
// Load in SDL's one and only pixel shader (for now, more are likely to follow):
//
if (!D3D11_ReadShaderContents(L"SimplePixelShader.cso", fileData)) {
SDL_SetError("Unable to open SDL's pixel shader file.");
return E_FAIL;
}
result = data->d3dDevice->CreatePixelShader(
&fileData[0],
fileData.size(),
nullptr,
&data->pixelShader
);
if (FAILED(result)) {
WIN_SetErrorFromHRESULT(__FUNCTION__, result);
return result;
}
//
// Create a vertex buffer:
//
VertexPositionColor vertices[] =
{
{XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)},
{XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)},
{XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f)},
{XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)},
};
data->vertexCount = ARRAYSIZE(vertices);
D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
vertexBufferData.pSysMem = vertices;
vertexBufferData.SysMemPitch = 0;
vertexBufferData.SysMemSlicePitch = 0;
CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER);
result = data->d3dDevice->CreateBuffer(
&vertexBufferDesc,
&vertexBufferData,
&data->vertexBuffer
);
if (FAILED(result)) {
WIN_SetErrorFromHRESULT(__FUNCTION__, result);
return result;
}
//
// Create a sampler to use when drawing textures:
//
D3D11_SAMPLER_DESC samplerDesc;
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.MipLODBias = 0.0f;
samplerDesc.MaxAnisotropy = 1;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
samplerDesc.BorderColor[0] = 0.0f;
samplerDesc.BorderColor[1] = 0.0f;
samplerDesc.BorderColor[2] = 0.0f;
samplerDesc.BorderColor[3] = 0.0f;
samplerDesc.MinLOD = 0.0f;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = data->d3dDevice->CreateSamplerState(
&samplerDesc,
&data->mainSampler
);
if (FAILED(result)) {
WIN_SetErrorFromHRESULT(__FUNCTION__, result);
return result;
}
//
// All done!
//
data->loadingComplete = true; // This variable can probably be factored-out
return S_OK;
}
static int static int
D3D11_UpdateViewport(SDL_Renderer * renderer) D3D11_UpdateViewport(SDL_Renderer * renderer)
{ {

View file

@ -21,6 +21,7 @@
#include "SDL_config.h" #include "SDL_config.h"
#include <D3D11_1.h> #include <D3D11_1.h>
#include <DirectXMath.h>
#include <wrl/client.h> #include <wrl/client.h>
typedef struct typedef struct
@ -36,10 +37,19 @@ typedef struct
Microsoft::WRL::ComPtr<ID3D11Texture2D> mainTexture; Microsoft::WRL::ComPtr<ID3D11Texture2D> mainTexture;
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> mainTextureResourceView; Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> mainTextureResourceView;
Microsoft::WRL::ComPtr<ID3D11SamplerState> mainSampler; Microsoft::WRL::ComPtr<ID3D11SamplerState> mainSampler;
D3D_FEATURE_LEVEL featureLevel;
unsigned int vertexCount;
bool loadingComplete;
} D3D11_RenderData; } D3D11_RenderData;
typedef struct typedef struct
{ {
} D3D11_TextureData; } D3D11_TextureData;
struct VertexPositionColor
{
DirectX::XMFLOAT3 pos;
DirectX::XMFLOAT2 tex;
};
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View file

@ -15,8 +15,6 @@ using namespace Windows::Graphics::Display;
// Constructor. // Constructor.
SDL_winrtrenderer::SDL_winrtrenderer() : SDL_winrtrenderer::SDL_winrtrenderer() :
m_mainTextureHelperSurface(NULL), m_mainTextureHelperSurface(NULL),
m_loadingComplete(false),
m_vertexCount(0),
m_sdlRenderer(NULL), m_sdlRenderer(NULL),
m_sdlRendererData(NULL) m_sdlRendererData(NULL)
{ {
@ -52,197 +50,12 @@ void SDL_winrtrenderer::HandleDeviceLost()
UpdateForWindowSizeChange(); UpdateForWindowSizeChange();
} }
static bool extern HRESULT WINRT_CreateDeviceResources(SDL_Renderer * renderer);
read_file_contents(const wstring & fileName, vector<char> & out)
{
ifstream in(fileName, ios::in | ios::binary);
if (!in) {
return false;
}
in.seekg(0, ios::end);
out.resize((size_t) in.tellg());
in.seekg(0, ios::beg);
in.read(&out[0], out.size());
return in.good();
}
static bool
read_shader_contents(const wstring & shaderName, vector<char> & out)
{
wstring fileName = SDL_WinRTGetInstalledLocationPath();
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
fileName += L"\\";
#else
fileName += L"\\SDL_VS2012_WinRT\\";
#endif
fileName += shaderName;
return read_file_contents(fileName, out);
}
// These are the resources that depend on the device. // These are the resources that depend on the device.
void SDL_winrtrenderer::CreateDeviceResources() void SDL_winrtrenderer::CreateDeviceResources()
{ {
// This flag adds support for surfaces with a different color channel ordering DX::ThrowIfFailed(WINRT_CreateDeviceResources(m_sdlRenderer));
// than the API default. It is required for compatibility with Direct2D.
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#if defined(_DEBUG)
// If the project is in a debug build, enable debugging via SDK Layers with this flag.
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
// This array defines the set of DirectX hardware feature levels this app will support.
// Note the ordering should be preserved.
// Don't forget to declare your application's minimum required feature level in its
// description. All applications are assumed to support 9.1 unless otherwise stated.
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1
};
// Create the Direct3D 11 API device object and a corresponding context.
ComPtr<ID3D11Device> device;
ComPtr<ID3D11DeviceContext> context;
DX::ThrowIfFailed(
D3D11CreateDevice(
nullptr, // Specify nullptr to use the default adapter.
D3D_DRIVER_TYPE_HARDWARE,
nullptr,
creationFlags, // Set set debug and Direct2D compatibility flags.
featureLevels, // List of feature levels this app can support.
ARRAYSIZE(featureLevels),
D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps.
&device, // Returns the Direct3D device created.
&m_featureLevel, // Returns feature level of device created.
&context // Returns the device immediate context.
)
);
// Get the Direct3D 11.1 API device and context interfaces.
Microsoft::WRL::ComPtr<ID3D11Device1> d3dDevice1;
DX::ThrowIfFailed(
device.As(&(m_sdlRendererData->d3dDevice))
);
DX::ThrowIfFailed(
context.As(&m_sdlRendererData->d3dContext)
);
// Start loading GPU shaders:
vector<char> fileData;
//
// Load in SDL's one and only vertex shader:
//
if (!read_shader_contents(L"SimpleVertexShader.cso", fileData)) {
throw ref new Platform::Exception(E_FAIL, L"Unable to open SDL's vertex shader file.");
}
DX::ThrowIfFailed(
(m_sdlRendererData->d3dDevice)->CreateVertexShader(
&fileData[0],
fileData.size(),
nullptr,
&m_sdlRendererData->vertexShader
)
);
//
// Create an input layout for SDL's vertex shader:
//
const D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
{
{ "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 },
};
DX::ThrowIfFailed(
m_sdlRendererData->d3dDevice->CreateInputLayout(
vertexDesc,
ARRAYSIZE(vertexDesc),
&fileData[0],
fileData.size(),
&m_sdlRendererData->inputLayout
)
);
//
// Load in SDL's one and only pixel shader (for now, more are likely to follow):
//
if (!read_shader_contents(L"SimplePixelShader.cso", fileData)) {
throw ref new Platform::Exception(E_FAIL, L"Unable to open SDL's pixel shader file.");
}
DX::ThrowIfFailed(
m_sdlRendererData->d3dDevice->CreatePixelShader(
&fileData[0],
fileData.size(),
nullptr,
&m_sdlRendererData->pixelShader
)
);
//
// Create a vertex buffer:
//
VertexPositionColor vertices[] =
{
{XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)},
{XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)},
{XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f)},
{XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)},
};
m_vertexCount = ARRAYSIZE(vertices);
D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
vertexBufferData.pSysMem = vertices;
vertexBufferData.SysMemPitch = 0;
vertexBufferData.SysMemSlicePitch = 0;
CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER);
DX::ThrowIfFailed(
m_sdlRendererData->d3dDevice->CreateBuffer(
&vertexBufferDesc,
&vertexBufferData,
&m_sdlRendererData->vertexBuffer
)
);
//
// Create a sampler to use when drawing textures:
//
D3D11_SAMPLER_DESC samplerDesc;
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.MipLODBias = 0.0f;
samplerDesc.MaxAnisotropy = 1;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
samplerDesc.BorderColor[0] = 0.0f;
samplerDesc.BorderColor[1] = 0.0f;
samplerDesc.BorderColor[2] = 0.0f;
samplerDesc.BorderColor[3] = 0.0f;
samplerDesc.MinLOD = 0.0f;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
DX::ThrowIfFailed(
m_sdlRendererData->d3dDevice->CreateSamplerState(
&samplerDesc,
&m_sdlRendererData->mainSampler
)
);
//
// All done!
//
m_loadingComplete = true; // This variable can probably be factored-out
} }
// Allocate all memory resources that change on a window SizeChanged event. // Allocate all memory resources that change on a window SizeChanged event.
@ -531,7 +344,7 @@ void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numr
); );
// Only draw the screen once it is loaded (some loading is asynchronous). // Only draw the screen once it is loaded (some loading is asynchronous).
if (!m_loadingComplete) if (!m_sdlRendererData->loadingComplete)
{ {
return; return;
} }

View file

@ -4,12 +4,6 @@
#include "SDL.h" #include "SDL.h"
#include "../../render/direct3d11/SDL_render_d3d11_cpp.h" #include "../../render/direct3d11/SDL_render_d3d11_cpp.h"
struct VertexPositionColor
{
DirectX::XMFLOAT3 pos;
DirectX::XMFLOAT2 tex;
};
// Helper class that initializes DirectX APIs for 3D rendering. // Helper class that initializes DirectX APIs for 3D rendering.
ref class SDL_winrtrenderer ref class SDL_winrtrenderer
{ {
@ -40,12 +34,10 @@ protected private:
SDL_Surface * m_mainTextureHelperSurface; SDL_Surface * m_mainTextureHelperSurface;
// Cached renderer properties. // Cached renderer properties.
D3D_FEATURE_LEVEL m_featureLevel;
Windows::Foundation::Size m_renderTargetSize; Windows::Foundation::Size m_renderTargetSize;
Windows::Foundation::Rect m_windowBounds; Windows::Foundation::Rect m_windowBounds;
Platform::Agile<Windows::UI::Core::CoreWindow> m_window; Platform::Agile<Windows::UI::Core::CoreWindow> m_window;
Windows::Graphics::Display::DisplayOrientations m_orientation; Windows::Graphics::Display::DisplayOrientations m_orientation;
uint32 m_vertexCount;
// Transform used for display orientation. // Transform used for display orientation.
DirectX::XMFLOAT4X4 m_orientationTransform3D; DirectX::XMFLOAT4X4 m_orientationTransform3D;