Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Latest commit

 

History

History
247 lines (213 loc) · 8.7 KB

SDL_winrtrenderer.cpp

File metadata and controls

247 lines (213 loc) · 8.7 KB
 
Feb 3, 2013
Feb 3, 2013
1
2
3
4
5

#include <fstream>
#include <string>
#include <vector>
#include "SDLmain_WinRT_common.h"
Nov 19, 2012
Nov 19, 2012
6
#include "SDL_winrtrenderer.h"
Feb 9, 2013
Feb 9, 2013
8
9
10
11
extern "C" {
#include "SDL_syswm.h"
}
12
13
using namespace DirectX;
using namespace Microsoft::WRL;
Feb 3, 2013
Feb 3, 2013
14
using namespace std;
15
using namespace Windows::UI::Core;
Nov 26, 2012
Nov 26, 2012
16
17
using namespace Windows::Foundation;
using namespace Windows::Graphics::Display;
Feb 9, 2013
Feb 9, 2013
19
20
21
22
extern HRESULT D3D11_CreateDeviceResources(SDL_Renderer * renderer);
extern CoreWindow ^ D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer);
extern HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer);
Nov 26, 2012
Nov 26, 2012
23
// Constructor.
Nov 19, 2012
Nov 19, 2012
24
SDL_winrtrenderer::SDL_winrtrenderer() :
Dec 10, 2012
Dec 10, 2012
25
m_mainTextureHelperSurface(NULL),
Feb 3, 2013
Feb 3, 2013
26
m_sdlRenderer(NULL),
Feb 3, 2013
Feb 3, 2013
27
m_sdlRendererData(NULL)
Dec 10, 2012
Dec 10, 2012
31
32
33
34
35
36
37
38
SDL_winrtrenderer::~SDL_winrtrenderer()
{
if (m_mainTextureHelperSurface) {
SDL_FreeSurface(m_mainTextureHelperSurface);
m_mainTextureHelperSurface = NULL;
}
}
Nov 26, 2012
Nov 26, 2012
39
// Initialize the Direct3D resources required to run.
Feb 9, 2013
Feb 9, 2013
40
41
void SDL_winrtrenderer::Initialize()
{
Jan 9, 2013
Jan 9, 2013
42
43
CreateDeviceResources();
CreateWindowSizeDependentResources();
Nov 26, 2012
Nov 26, 2012
44
45
46
47
48
}
// Recreate all device resources and set them back to the current state.
void SDL_winrtrenderer::HandleDeviceLost()
{
Jan 9, 2013
Jan 9, 2013
49
// Reset these member variables to ensure that UpdateForWindowSizeChange recreates all resources.
Feb 9, 2013
Feb 9, 2013
50
51
m_sdlRendererData->windowSizeInDIPs.x = 0;
m_sdlRendererData->windowSizeInDIPs.y = 0;
Feb 3, 2013
Feb 3, 2013
52
m_sdlRendererData->swapChain = nullptr;
Nov 26, 2012
Nov 26, 2012
53
Feb 3, 2013
Feb 3, 2013
54
// TODO, WinRT: reconnect HandleDeviceLost to SDL_Renderer
Jan 9, 2013
Jan 9, 2013
55
56
CreateDeviceResources();
UpdateForWindowSizeChange();
Nov 26, 2012
Nov 26, 2012
57
58
59
}
// These are the resources that depend on the device.
Nov 19, 2012
Nov 19, 2012
60
void SDL_winrtrenderer::CreateDeviceResources()
Feb 9, 2013
Feb 9, 2013
62
DX::ThrowIfFailed(D3D11_CreateDeviceResources(m_sdlRenderer));
Nov 26, 2012
Nov 26, 2012
65
66
// Allocate all memory resources that change on a window SizeChanged event.
void SDL_winrtrenderer::CreateWindowSizeDependentResources()
Jan 30, 2013
Jan 30, 2013
67
{
Feb 9, 2013
Feb 9, 2013
68
DX::ThrowIfFailed(D3D11_CreateWindowSizeDependentResources(m_sdlRenderer));
Nov 26, 2012
Nov 26, 2012
69
70
}
Nov 25, 2012
Nov 25, 2012
71
72
void SDL_winrtrenderer::ResizeMainTexture(int w, int h)
{
Dec 10, 2012
Dec 10, 2012
73
74
const int pixelSizeInBytes = 4;
Nov 25, 2012
Nov 25, 2012
75
D3D11_TEXTURE2D_DESC textureDesc = {0};
Jan 9, 2013
Jan 9, 2013
76
77
78
79
80
81
82
83
84
85
86
textureDesc.Width = w;
textureDesc.Height = h;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_B8G8R8X8_UNORM;
textureDesc.SampleDesc.Count = 1;
textureDesc.SampleDesc.Quality = 0;
textureDesc.Usage = D3D11_USAGE_DYNAMIC;
textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
textureDesc.MiscFlags = 0;
Nov 25, 2012
Nov 25, 2012
87
Dec 10, 2012
Dec 10, 2012
88
89
90
91
92
93
94
95
96
97
98
const int numPixels = textureDesc.Width * textureDesc.Height;
std::vector<uint8> initialTexturePixels(numPixels * pixelSizeInBytes, 0x00);
// Fill the texture with a non-black color, for debugging purposes:
//for (int i = 0; i < (numPixels * pixelSizeInBytes); i += pixelSizeInBytes) {
// initialTexturePixels[i+0] = 0xff;
// initialTexturePixels[i+1] = 0xff;
// initialTexturePixels[i+2] = 0x00;
// initialTexturePixels[i+3] = 0xff;
//}
Jan 9, 2013
Jan 9, 2013
99
100
101
102
103
D3D11_SUBRESOURCE_DATA initialTextureData = {0};
initialTextureData.pSysMem = (void *)&(initialTexturePixels[0]);
initialTextureData.SysMemPitch = textureDesc.Width * pixelSizeInBytes;
initialTextureData.SysMemSlicePitch = numPixels * pixelSizeInBytes;
DX::ThrowIfFailed(
Feb 3, 2013
Feb 3, 2013
104
m_sdlRendererData->d3dDevice->CreateTexture2D(
Jan 9, 2013
Jan 9, 2013
105
106
&textureDesc,
&initialTextureData,
Feb 3, 2013
Feb 3, 2013
107
&m_sdlRendererData->mainTexture
Jan 9, 2013
Jan 9, 2013
108
109
)
);
Nov 25, 2012
Nov 25, 2012
110
Dec 10, 2012
Dec 10, 2012
111
112
113
114
115
116
117
118
119
120
121
122
123
124
if (m_mainTextureHelperSurface) {
SDL_FreeSurface(m_mainTextureHelperSurface);
m_mainTextureHelperSurface = NULL;
}
m_mainTextureHelperSurface = SDL_CreateRGBSurfaceFrom(
NULL,
textureDesc.Width, textureDesc.Height,
(pixelSizeInBytes * 8),
0, // Use an nil pitch for now. This'll be filled in when updating the texture.
0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000); // TODO, WinRT: calculate masks given the Direct3D-defined pixel format of the texture
if (m_mainTextureHelperSurface == NULL) {
DX::ThrowIfFailed(E_FAIL); // TODO, WinRT: generate a better error here, taking into account who's calling this function.
}
Jan 9, 2013
Jan 9, 2013
125
126
127
128
129
130
D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc;
resourceViewDesc.Format = textureDesc.Format;
resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
resourceViewDesc.Texture2D.MostDetailedMip = 0;
resourceViewDesc.Texture2D.MipLevels = textureDesc.MipLevels;
DX::ThrowIfFailed(
Feb 3, 2013
Feb 3, 2013
131
132
m_sdlRendererData->d3dDevice->CreateShaderResourceView(
m_sdlRendererData->mainTexture.Get(),
Jan 9, 2013
Jan 9, 2013
133
&resourceViewDesc,
Feb 3, 2013
Feb 3, 2013
134
&m_sdlRendererData->mainTextureResourceView)
Jan 9, 2013
Jan 9, 2013
135
);
Nov 25, 2012
Nov 25, 2012
136
137
}
Nov 26, 2012
Nov 26, 2012
138
139
140
// This method is called in the event handler for the SizeChanged event.
void SDL_winrtrenderer::UpdateForWindowSizeChange()
{
Feb 9, 2013
Feb 9, 2013
141
142
143
144
CoreWindow ^ coreWindow = D3D11_GetCoreWindowFromSDLRenderer(m_sdlRenderer);
if (coreWindow->Bounds.Width != m_sdlRendererData->windowSizeInDIPs.x ||
coreWindow->Bounds.Height != m_sdlRendererData->windowSizeInDIPs.y ||
m_sdlRendererData->orientation != DisplayProperties::CurrentOrientation)
Jan 9, 2013
Jan 9, 2013
145
146
{
ID3D11RenderTargetView* nullViews[] = {nullptr};
Feb 3, 2013
Feb 3, 2013
147
148
149
m_sdlRendererData->d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr);
m_sdlRendererData->renderTargetView = nullptr;
m_sdlRendererData->d3dContext->Flush();
Jan 9, 2013
Jan 9, 2013
150
151
CreateWindowSizeDependentResources();
}
Nov 26, 2012
Nov 26, 2012
152
153
}
Nov 22, 2012
Nov 22, 2012
154
void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numrects)
Jan 9, 2013
Jan 9, 2013
156
const float blackColor[] = { 0.0f, 0.0f, 0.0f, 0.0f };
Feb 3, 2013
Feb 3, 2013
157
158
m_sdlRendererData->d3dContext->ClearRenderTargetView(
m_sdlRendererData->renderTargetView.Get(),
Jan 9, 2013
Jan 9, 2013
159
160
161
162
blackColor
);
// Only draw the screen once it is loaded (some loading is asynchronous).
Feb 9, 2013
Feb 9, 2013
163
if (!m_sdlRendererData->loadingComplete)
Jan 9, 2013
Jan 9, 2013
164
165
166
{
return;
}
Feb 3, 2013
Feb 3, 2013
167
if (!m_sdlRendererData->mainTextureResourceView)
Nov 25, 2012
Nov 25, 2012
168
169
170
{
return;
}
Jan 9, 2013
Jan 9, 2013
172
// Update the main texture (for SDL usage). Start by mapping the SDL
Dec 10, 2012
Dec 10, 2012
173
// window's main texture to CPU-accessible memory:
Jan 9, 2013
Jan 9, 2013
174
175
D3D11_MAPPED_SUBRESOURCE textureMemory = {0};
DX::ThrowIfFailed(
Feb 3, 2013
Feb 3, 2013
176
177
m_sdlRendererData->d3dContext->Map(
m_sdlRendererData->mainTexture.Get(),
Jan 9, 2013
Jan 9, 2013
178
179
180
181
182
0,
D3D11_MAP_WRITE_DISCARD,
0,
&textureMemory)
);
Nov 21, 2012
Nov 21, 2012
183
Dec 10, 2012
Dec 10, 2012
184
185
186
187
// Copy pixel data to the locked texture's memory:
m_mainTextureHelperSurface->pixels = textureMemory.pData;
m_mainTextureHelperSurface->pitch = textureMemory.RowPitch;
SDL_BlitSurface(surface, NULL, m_mainTextureHelperSurface, NULL);
Jan 9, 2013
Jan 9, 2013
188
// TODO, WinRT: only update the requested rects (passed to SDL_UpdateWindowSurface), rather than everything
Nov 21, 2012
Nov 21, 2012
189
Dec 10, 2012
Dec 10, 2012
190
191
192
// Clean up a bit, then commit the texture's memory back to Direct3D:
m_mainTextureHelperSurface->pixels = NULL;
m_mainTextureHelperSurface->pitch = 0;
Feb 3, 2013
Feb 3, 2013
193
194
m_sdlRendererData->d3dContext->Unmap(
m_sdlRendererData->mainTexture.Get(),
Jan 9, 2013
Jan 9, 2013
195
196
0);
Feb 3, 2013
Feb 3, 2013
197
m_sdlRendererData->d3dContext->OMSetRenderTargets(
Jan 9, 2013
Jan 9, 2013
198
1,
Feb 3, 2013
Feb 3, 2013
199
m_sdlRendererData->renderTargetView.GetAddressOf(),
Jan 9, 2013
Jan 9, 2013
200
201
202
203
204
nullptr
);
UINT stride = sizeof(VertexPositionColor);
UINT offset = 0;
Feb 3, 2013
Feb 3, 2013
205
m_sdlRendererData->d3dContext->IASetVertexBuffers(
Jan 9, 2013
Jan 9, 2013
206
207
0,
1,
Feb 3, 2013
Feb 3, 2013
208
m_sdlRendererData->vertexBuffer.GetAddressOf(),
Jan 9, 2013
Jan 9, 2013
209
210
211
212
&stride,
&offset
);
Feb 3, 2013
Feb 3, 2013
213
m_sdlRendererData->d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
Jan 9, 2013
Jan 9, 2013
214
Feb 3, 2013
Feb 3, 2013
215
m_sdlRendererData->d3dContext->IASetInputLayout(m_sdlRendererData->inputLayout.Get());
Jan 9, 2013
Jan 9, 2013
216
Feb 3, 2013
Feb 3, 2013
217
218
m_sdlRendererData->d3dContext->VSSetShader(
m_sdlRendererData->vertexShader.Get(),
Jan 9, 2013
Jan 9, 2013
219
220
221
222
nullptr,
0
);
Feb 3, 2013
Feb 3, 2013
223
224
m_sdlRendererData->d3dContext->PSSetShader(
m_sdlRendererData->pixelShader.Get(),
Jan 9, 2013
Jan 9, 2013
225
226
227
228
nullptr,
0
);
Feb 3, 2013
Feb 3, 2013
229
m_sdlRendererData->d3dContext->PSSetShaderResources(0, 1, m_sdlRendererData->mainTextureResourceView.GetAddressOf());
Jan 9, 2013
Jan 9, 2013
230
Feb 3, 2013
Feb 3, 2013
231
m_sdlRendererData->d3dContext->PSSetSamplers(0, 1, m_sdlRendererData->mainSampler.GetAddressOf());
Jan 9, 2013
Jan 9, 2013
232
Feb 3, 2013
Feb 3, 2013
233
m_sdlRendererData->d3dContext->Draw(4, 0);
Nov 26, 2012
Nov 26, 2012
235
236
237
238
// Method to deliver the final image to the display.
void SDL_winrtrenderer::Present()
{
Feb 3, 2013
Feb 3, 2013
239
SDL_RenderPresent(m_sdlRenderer);
Nov 26, 2012
Nov 26, 2012
240
241
242
243
244
}
// Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels.
float SDL_winrtrenderer::ConvertDipsToPixels(float dips)
{
Jan 9, 2013
Jan 9, 2013
245
246
static const float dipsPerInch = 96.0f;
return floor(dips * DisplayProperties::LogicalDpi / dipsPerInch + 0.5f); // Round to nearest integer.
Nov 26, 2012
Nov 26, 2012
247
}