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

Latest commit

 

History

History
240 lines (207 loc) · 8.53 KB

SDL_winrtrenderer.cpp

File metadata and controls

240 lines (207 loc) · 8.53 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
40
41
// Recreate all device resources and set them back to the current state.
void SDL_winrtrenderer::HandleDeviceLost()
{
Jan 9, 2013
Jan 9, 2013
42
// Reset these member variables to ensure that UpdateForWindowSizeChange recreates all resources.
Feb 9, 2013
Feb 9, 2013
43
44
m_sdlRendererData->windowSizeInDIPs.x = 0;
m_sdlRendererData->windowSizeInDIPs.y = 0;
Feb 3, 2013
Feb 3, 2013
45
m_sdlRendererData->swapChain = nullptr;
Nov 26, 2012
Nov 26, 2012
46
Feb 3, 2013
Feb 3, 2013
47
// TODO, WinRT: reconnect HandleDeviceLost to SDL_Renderer
Jan 9, 2013
Jan 9, 2013
48
49
CreateDeviceResources();
UpdateForWindowSizeChange();
Nov 26, 2012
Nov 26, 2012
50
51
52
}
// These are the resources that depend on the device.
Nov 19, 2012
Nov 19, 2012
53
void SDL_winrtrenderer::CreateDeviceResources()
Feb 9, 2013
Feb 9, 2013
55
DX::ThrowIfFailed(D3D11_CreateDeviceResources(m_sdlRenderer));
Nov 26, 2012
Nov 26, 2012
58
59
// Allocate all memory resources that change on a window SizeChanged event.
void SDL_winrtrenderer::CreateWindowSizeDependentResources()
Jan 30, 2013
Jan 30, 2013
60
{
Feb 9, 2013
Feb 9, 2013
61
DX::ThrowIfFailed(D3D11_CreateWindowSizeDependentResources(m_sdlRenderer));
Nov 26, 2012
Nov 26, 2012
62
63
}
Nov 25, 2012
Nov 25, 2012
64
65
void SDL_winrtrenderer::ResizeMainTexture(int w, int h)
{
Dec 10, 2012
Dec 10, 2012
66
67
const int pixelSizeInBytes = 4;
Nov 25, 2012
Nov 25, 2012
68
D3D11_TEXTURE2D_DESC textureDesc = {0};
Jan 9, 2013
Jan 9, 2013
69
70
71
72
73
74
75
76
77
78
79
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
80
Dec 10, 2012
Dec 10, 2012
81
82
83
84
85
86
87
88
89
90
91
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
92
93
94
95
96
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
97
m_sdlRendererData->d3dDevice->CreateTexture2D(
Jan 9, 2013
Jan 9, 2013
98
99
&textureDesc,
&initialTextureData,
Feb 3, 2013
Feb 3, 2013
100
&m_sdlRendererData->mainTexture
Jan 9, 2013
Jan 9, 2013
101
102
)
);
Nov 25, 2012
Nov 25, 2012
103
Dec 10, 2012
Dec 10, 2012
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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
118
119
120
121
122
123
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
124
125
m_sdlRendererData->d3dDevice->CreateShaderResourceView(
m_sdlRendererData->mainTexture.Get(),
Jan 9, 2013
Jan 9, 2013
126
&resourceViewDesc,
Feb 3, 2013
Feb 3, 2013
127
&m_sdlRendererData->mainTextureResourceView)
Jan 9, 2013
Jan 9, 2013
128
);
Nov 25, 2012
Nov 25, 2012
129
130
}
Nov 26, 2012
Nov 26, 2012
131
132
133
// This method is called in the event handler for the SizeChanged event.
void SDL_winrtrenderer::UpdateForWindowSizeChange()
{
Feb 9, 2013
Feb 9, 2013
134
135
136
137
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
138
139
{
ID3D11RenderTargetView* nullViews[] = {nullptr};
Feb 3, 2013
Feb 3, 2013
140
141
142
m_sdlRendererData->d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr);
m_sdlRendererData->renderTargetView = nullptr;
m_sdlRendererData->d3dContext->Flush();
Jan 9, 2013
Jan 9, 2013
143
144
CreateWindowSizeDependentResources();
}
Nov 26, 2012
Nov 26, 2012
145
146
}
Nov 22, 2012
Nov 22, 2012
147
void SDL_winrtrenderer::Render(SDL_Surface * surface, SDL_Rect * rects, int numrects)
Jan 9, 2013
Jan 9, 2013
149
const float blackColor[] = { 0.0f, 0.0f, 0.0f, 0.0f };
Feb 3, 2013
Feb 3, 2013
150
151
m_sdlRendererData->d3dContext->ClearRenderTargetView(
m_sdlRendererData->renderTargetView.Get(),
Jan 9, 2013
Jan 9, 2013
152
153
154
155
blackColor
);
// Only draw the screen once it is loaded (some loading is asynchronous).
Feb 9, 2013
Feb 9, 2013
156
if (!m_sdlRendererData->loadingComplete)
Jan 9, 2013
Jan 9, 2013
157
158
159
{
return;
}
Feb 3, 2013
Feb 3, 2013
160
if (!m_sdlRendererData->mainTextureResourceView)
Nov 25, 2012
Nov 25, 2012
161
162
163
{
return;
}
Jan 9, 2013
Jan 9, 2013
165
// Update the main texture (for SDL usage). Start by mapping the SDL
Dec 10, 2012
Dec 10, 2012
166
// window's main texture to CPU-accessible memory:
Jan 9, 2013
Jan 9, 2013
167
168
D3D11_MAPPED_SUBRESOURCE textureMemory = {0};
DX::ThrowIfFailed(
Feb 3, 2013
Feb 3, 2013
169
170
m_sdlRendererData->d3dContext->Map(
m_sdlRendererData->mainTexture.Get(),
Jan 9, 2013
Jan 9, 2013
171
172
173
174
175
0,
D3D11_MAP_WRITE_DISCARD,
0,
&textureMemory)
);
Nov 21, 2012
Nov 21, 2012
176
Dec 10, 2012
Dec 10, 2012
177
178
179
180
// 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
181
// TODO, WinRT: only update the requested rects (passed to SDL_UpdateWindowSurface), rather than everything
Nov 21, 2012
Nov 21, 2012
182
Dec 10, 2012
Dec 10, 2012
183
184
185
// 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
186
187
m_sdlRendererData->d3dContext->Unmap(
m_sdlRendererData->mainTexture.Get(),
Jan 9, 2013
Jan 9, 2013
188
189
0);
Feb 3, 2013
Feb 3, 2013
190
m_sdlRendererData->d3dContext->OMSetRenderTargets(
Jan 9, 2013
Jan 9, 2013
191
1,
Feb 3, 2013
Feb 3, 2013
192
m_sdlRendererData->renderTargetView.GetAddressOf(),
Jan 9, 2013
Jan 9, 2013
193
194
195
196
197
nullptr
);
UINT stride = sizeof(VertexPositionColor);
UINT offset = 0;
Feb 3, 2013
Feb 3, 2013
198
m_sdlRendererData->d3dContext->IASetVertexBuffers(
Jan 9, 2013
Jan 9, 2013
199
200
0,
1,
Feb 3, 2013
Feb 3, 2013
201
m_sdlRendererData->vertexBuffer.GetAddressOf(),
Jan 9, 2013
Jan 9, 2013
202
203
204
205
&stride,
&offset
);
Feb 3, 2013
Feb 3, 2013
206
m_sdlRendererData->d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
Jan 9, 2013
Jan 9, 2013
207
Feb 3, 2013
Feb 3, 2013
208
m_sdlRendererData->d3dContext->IASetInputLayout(m_sdlRendererData->inputLayout.Get());
Jan 9, 2013
Jan 9, 2013
209
Feb 3, 2013
Feb 3, 2013
210
211
m_sdlRendererData->d3dContext->VSSetShader(
m_sdlRendererData->vertexShader.Get(),
Jan 9, 2013
Jan 9, 2013
212
213
214
215
nullptr,
0
);
Feb 3, 2013
Feb 3, 2013
216
217
m_sdlRendererData->d3dContext->PSSetShader(
m_sdlRendererData->pixelShader.Get(),
Jan 9, 2013
Jan 9, 2013
218
219
220
221
nullptr,
0
);
Feb 3, 2013
Feb 3, 2013
222
m_sdlRendererData->d3dContext->PSSetShaderResources(0, 1, m_sdlRendererData->mainTextureResourceView.GetAddressOf());
Jan 9, 2013
Jan 9, 2013
223
Feb 3, 2013
Feb 3, 2013
224
m_sdlRendererData->d3dContext->PSSetSamplers(0, 1, m_sdlRendererData->mainSampler.GetAddressOf());
Jan 9, 2013
Jan 9, 2013
225
Feb 3, 2013
Feb 3, 2013
226
m_sdlRendererData->d3dContext->Draw(4, 0);
Nov 26, 2012
Nov 26, 2012
228
229
230
231
// Method to deliver the final image to the display.
void SDL_winrtrenderer::Present()
{
Feb 3, 2013
Feb 3, 2013
232
SDL_RenderPresent(m_sdlRenderer);
Nov 26, 2012
Nov 26, 2012
233
234
235
236
237
}
// 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
238
239
static const float dipsPerInch = 96.0f;
return floor(dips * DisplayProperties::LogicalDpi / dipsPerInch + 0.5f); // Round to nearest integer.
Nov 26, 2012
Nov 26, 2012
240
}