Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Extras / CDTestFramework / AntTweakBar / src / TwDirect3D11.cpp
1 //  ---------------------------------------------------------------------------\r
2 //\r
3 //  @file       TwDirect3D11.cpp\r
4 //  @author     Philippe Decaudin - http://www.antisphere.com\r
5 //  @license    This file is part of the AntTweakBar library.\r
6 //              For conditions of distribution and use, see License.txt\r
7 //\r
8 //  ---------------------------------------------------------------------------\r
9 \r
10 \r
11 #include "TwPrecomp.h"\r
12 #include "TwDirect3D11.h"\r
13 #include "TwMgr.h"\r
14 #include "TwColors.h"\r
15 \r
16 #include "d3d10vs2003.h" // Workaround to include D3D10.h and D3D11.h with VS2003\r
17 #define D3D11_IGNORE_SDK_LAYERS // d3d11sdklayers.h may not exist\r
18 #include <d3d11.h>\r
19 \r
20 \r
21 using namespace std;\r
22 \r
23 const char *g_ErrCantLoadD3D11   = "Cannot load Direct3D11 library dynamically";\r
24 const char *g_ErrCreateVS11      = "Direct3D11 vertex shader creation failed";\r
25 const char *g_ErrCreatePS11      = "Direct3D11 pixel shader creation failed";\r
26 const char *g_ErrCreateLayout11  = "Direct3D11 vertex layout creation failed";\r
27 const char *g_ErrCreateBuffer11  = "Direct3D11 vertex buffer creation failed";\r
28 const char *g_ErrCreateSampler11 = "Direct3D11 sampler state creation failed";\r
29 \r
30 //  ---------------------------------------------------------------------------\r
31 //  Shaders : In order to avoid linkage with D3DX11 or D3DCompile libraries,\r
32 //  vertex and pixel shaders are compiled offline in a pre-build step using\r
33 //  the fxc.exe compiler (from the DirectX SDK Aug'09 or later)\r
34 \r
35 #ifdef _WIN64\r
36 #   ifdef _DEBUG\r
37 #       include "debug64\TwDirect3D11_LineRectVS.h"\r
38 #       include "debug64\TwDirect3D11_LineRectCstColorVS.h"\r
39 #       include "debug64\TwDirect3D11_LineRectPS.h"\r
40 #       include "debug64\TwDirect3D11_TextVS.h"\r
41 #       include "debug64\TwDirect3D11_TextCstColorVS.h"\r
42 #       include "debug64\TwDirect3D11_TextPS.h"\r
43 #   else\r
44 #       include "release64\TwDirect3D11_LineRectVS.h"\r
45 #       include "release64\TwDirect3D11_LineRectCstColorVS.h"\r
46 #       include "release64\TwDirect3D11_LineRectPS.h"\r
47 #       include "release64\TwDirect3D11_TextVS.h"\r
48 #       include "release64\TwDirect3D11_TextCstColorVS.h"\r
49 #       include "release64\TwDirect3D11_TextPS.h"\r
50 #   endif\r
51 #else\r
52 #   ifdef _DEBUG\r
53 #       include "debug32\TwDirect3D11_LineRectVS.h"\r
54 #       include "debug32\TwDirect3D11_LineRectCstColorVS.h"\r
55 #       include "debug32\TwDirect3D11_LineRectPS.h"\r
56 #       include "debug32\TwDirect3D11_TextVS.h"\r
57 #       include "debug32\TwDirect3D11_TextCstColorVS.h"\r
58 #       include "debug32\TwDirect3D11_TextPS.h"\r
59 #   else\r
60 #       include "release32\TwDirect3D11_LineRectVS.h"\r
61 #       include "release32\TwDirect3D11_LineRectCstColorVS.h"\r
62 #       include "release32\TwDirect3D11_LineRectPS.h"\r
63 #       include "release32\TwDirect3D11_TextVS.h"\r
64 #       include "release32\TwDirect3D11_TextCstColorVS.h"\r
65 #       include "release32\TwDirect3D11_TextPS.h"\r
66 #   endif\r
67 #endif\r
68 \r
69 //  ---------------------------------------------------------------------------\r
70 \r
71 const RECT FullRect = {0, 0, 16000, 16000};\r
72 static bool RectIsFull(const RECT& r) { return r.left==FullRect.left && r.right==FullRect.right && r.top==FullRect.top && r.bottom==FullRect.bottom; }\r
73 \r
74 //  ---------------------------------------------------------------------------\r
75 \r
76 static void BindFont(ID3D11Device *_Dev, const CTexFont *_Font, ID3D11Texture2D **_Tex, ID3D11ShaderResourceView **_TexRV)\r
77 {\r
78     assert(_Font!=NULL);\r
79     *_Tex = NULL;\r
80     *_TexRV = NULL;\r
81 \r
82     int w = _Font->m_TexWidth;\r
83     int h = _Font->m_TexHeight;\r
84     color32 *font32 = new color32[w*h];\r
85     color32 *p = font32;\r
86     for( int i=0; i<w*h; ++i, ++p )\r
87         *p = 0x00ffffff | (((color32)(_Font->m_TexBytes[i]))<<24);\r
88 \r
89     D3D11_TEXTURE2D_DESC desc;\r
90     desc.Width = w;\r
91     desc.Height = h;\r
92     desc.MipLevels = 1;\r
93     desc.ArraySize = 1;\r
94     desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;\r
95     desc.SampleDesc.Count = 1;\r
96     desc.SampleDesc.Quality = 0;\r
97     desc.Usage = D3D11_USAGE_IMMUTABLE;\r
98     desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;\r
99     desc.CPUAccessFlags = 0;\r
100     desc.MiscFlags = 0;\r
101     D3D11_SUBRESOURCE_DATA data;\r
102     data.pSysMem = font32;\r
103     data.SysMemPitch = w*sizeof(color32);\r
104     data.SysMemSlicePitch = 0;\r
105 \r
106     if( SUCCEEDED(_Dev->CreateTexture2D(&desc, &data, _Tex)) )\r
107         _Dev->CreateShaderResourceView(*_Tex, NULL, _TexRV);\r
108 \r
109     delete[] font32;\r
110 }\r
111 \r
112 //  ---------------------------------------------------------------------------\r
113 \r
114 static void UnbindFont(ID3D11Device *_Dev, ID3D11Texture2D *_Tex, ID3D11ShaderResourceView *_TexRV)\r
115 {\r
116     (void)_Dev;\r
117 \r
118     if( _TexRV )\r
119     {\r
120         ULONG rc = _TexRV->Release();\r
121         assert( rc==0 ); (void)rc;\r
122     }\r
123     if( _Tex )\r
124     {\r
125         ULONG rc = _Tex->Release();\r
126         assert( rc==0 ); (void)rc;\r
127     }\r
128 }\r
129 \r
130 //  ---------------------------------------------------------------------------\r
131 \r
132 struct CState11\r
133 {\r
134     ID3D11ComputeShader *   m_CSShader;\r
135     ID3D11ClassInstance **  m_CSClassInstances;\r
136     UINT                    m_CSNumClassInstances;\r
137     ID3D11DomainShader *    m_DSShader;\r
138     ID3D11ClassInstance **  m_DSClassInstances;\r
139     UINT                    m_DSNumClassInstances;\r
140     ID3D11GeometryShader *  m_GSShader;\r
141     ID3D11ClassInstance **  m_GSClassInstances;\r
142     UINT                    m_GSNumClassInstances;\r
143     ID3D11HullShader *      m_HSShader;\r
144     ID3D11ClassInstance **  m_HSClassInstances;\r
145     UINT                    m_HSNumClassInstances;\r
146     ID3D11PixelShader *     m_PSShader;\r
147     ID3D11ClassInstance **  m_PSClassInstances;\r
148     UINT                    m_PSNumClassInstances;\r
149     ID3D11Buffer *          m_PSConstantBuffer; // backup the first constant buffer only\r
150     ID3D11SamplerState *    m_PSSampler; // backup the first sampler only\r
151     ID3D11ShaderResourceView*m_PSShaderResourceView; // backup the first shader resource only\r
152     ID3D11VertexShader *    m_VSShader;\r
153     ID3D11ClassInstance **  m_VSClassInstances;\r
154     UINT                    m_VSNumClassInstances;\r
155     ID3D11Buffer *          m_VSConstantBuffer; // backup the first constant buffer only\r
156 \r
157     ID3D11Buffer *          m_IAIndexBuffer;\r
158     DXGI_FORMAT             m_IAIndexBufferFormat;\r
159     UINT                    m_IAIndexBufferOffset;\r
160     ID3D11InputLayout *     m_IAInputLayout;\r
161     D3D11_PRIMITIVE_TOPOLOGY m_IATopology;\r
162     ID3D11Buffer *          m_IAVertexBuffer; // backup the first buffer only\r
163     UINT                    m_IAVertexBufferStride;\r
164     UINT                    m_IAVertexBufferOffset;\r
165 \r
166     ID3D11BlendState *      m_OMBlendState;\r
167     FLOAT                   m_OMBlendFactor[4];\r
168     UINT                    m_OMSampleMask;\r
169     ID3D11DepthStencilState*m_OMDepthStencilState;\r
170     UINT                    m_OMStencilRef;\r
171 \r
172     UINT                    m_RSScissorNumRects;\r
173     D3D11_RECT              m_RSScissorRects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];\r
174     ID3D11RasterizerState * m_RSRasterizerState;\r
175     UINT                    m_RSNumViewports;\r
176     D3D11_VIEWPORT          m_RSViewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];\r
177 \r
178     void                    Save();\r
179     void                    Restore();\r
180     void                    Release();\r
181                             CState11(ID3D11Device *_Dev, ID3D11DeviceContext *_ImmCtx);\r
182                             ~CState11();\r
183 private:\r
184     ID3D11Device *          m_D3DDev;\r
185     ID3D11DeviceContext *   m_D3DDevImmContext;\r
186 };\r
187 \r
188 CState11::CState11(ID3D11Device *_Dev, ID3D11DeviceContext *_ImmCtx)\r
189 {\r
190     ZeroMemory(this, sizeof(CState11));\r
191     m_D3DDev = _Dev;\r
192     m_D3DDevImmContext = _ImmCtx;\r
193 }\r
194 \r
195 CState11::~CState11()\r
196 {\r
197     Release();\r
198     m_D3DDev = NULL;\r
199     m_D3DDevImmContext = NULL;\r
200 }\r
201 \r
202 void CState11::Save()\r
203 {\r
204     // Release previous state if needed\r
205     Release();\r
206 \r
207     // Save shaders.\r
208     // Not sure how xxGetShader works, D3D11 doc is evasive... Attempt:\r
209     // First call GetShader with NULL ClassInstances to get the number of class instances.\r
210     // Second, if not zero allocate an array of class instances and call GetShader again\r
211     // with this array ptr to get the class instances and release the shader since its\r
212     // ref count has been incremented a second time.\r
213 \r
214     m_CSShader = NULL;\r
215     m_CSClassInstances = NULL;\r
216     m_CSNumClassInstances = 0;\r
217     m_D3DDevImmContext->CSGetShader(&m_CSShader, NULL, &m_CSNumClassInstances);\r
218     if (m_CSNumClassInstances > 0) \r
219     {\r
220         m_CSClassInstances = new ID3D11ClassInstance*[m_CSNumClassInstances];\r
221         for (UINT i = 0; i < m_CSNumClassInstances; i++)\r
222             m_CSClassInstances[i] = NULL;\r
223         m_D3DDevImmContext->CSGetShader(&m_CSShader, m_CSClassInstances, &m_CSNumClassInstances);\r
224         if (m_CSShader != NULL) \r
225             m_CSShader->Release();\r
226     }\r
227 \r
228     m_DSShader = NULL;\r
229     m_DSClassInstances = NULL;\r
230     m_DSNumClassInstances = 0;\r
231     m_D3DDevImmContext->DSGetShader(&m_DSShader, NULL, &m_DSNumClassInstances);\r
232     if (m_DSNumClassInstances > 0) \r
233     {\r
234         m_DSClassInstances = new ID3D11ClassInstance*[m_DSNumClassInstances];\r
235         for (UINT i = 0; i < m_DSNumClassInstances; i++)\r
236             m_DSClassInstances[i] = NULL;\r
237         m_D3DDevImmContext->DSGetShader(&m_DSShader, m_DSClassInstances, &m_DSNumClassInstances);\r
238         if (m_DSShader != NULL) \r
239             m_DSShader->Release();\r
240     }\r
241 \r
242     m_GSShader = NULL;\r
243     m_GSClassInstances = NULL;\r
244     m_GSNumClassInstances = 0;\r
245     m_D3DDevImmContext->GSGetShader(&m_GSShader, NULL, &m_GSNumClassInstances);\r
246     if (m_GSNumClassInstances > 0) \r
247     {\r
248         m_GSClassInstances = new ID3D11ClassInstance*[m_GSNumClassInstances];\r
249         for (UINT i = 0; i < m_GSNumClassInstances; i++)\r
250             m_GSClassInstances[i] = NULL;\r
251         m_D3DDevImmContext->GSGetShader(&m_GSShader, m_GSClassInstances, &m_GSNumClassInstances);\r
252         if (m_GSShader != NULL) \r
253             m_GSShader->Release();\r
254     }\r
255 \r
256     m_HSShader = NULL;\r
257     m_HSClassInstances = NULL;\r
258     m_HSNumClassInstances = 0;\r
259     m_D3DDevImmContext->HSGetShader(&m_HSShader, NULL, &m_HSNumClassInstances);\r
260     if (m_HSNumClassInstances > 0) \r
261     {\r
262         m_HSClassInstances = new ID3D11ClassInstance*[m_HSNumClassInstances];\r
263         for (UINT i = 0; i < m_HSNumClassInstances; i++)\r
264             m_HSClassInstances[i] = NULL;\r
265         m_D3DDevImmContext->HSGetShader(&m_HSShader, m_HSClassInstances, &m_HSNumClassInstances);\r
266         if (m_HSShader != NULL) \r
267             m_HSShader->Release();\r
268     }\r
269 \r
270     m_PSShader = NULL;\r
271     m_PSClassInstances = NULL;\r
272     m_PSNumClassInstances = 0;\r
273     m_D3DDevImmContext->PSGetShader(&m_PSShader, NULL, &m_PSNumClassInstances);\r
274     if (m_PSNumClassInstances > 0) \r
275     {\r
276         m_PSClassInstances = new ID3D11ClassInstance*[m_PSNumClassInstances];\r
277         for (UINT i = 0; i < m_PSNumClassInstances; i++)\r
278             m_PSClassInstances[i] = NULL;\r
279         m_D3DDevImmContext->PSGetShader(&m_PSShader, m_PSClassInstances, &m_PSNumClassInstances);\r
280         if (m_PSShader != NULL) \r
281             m_PSShader->Release();\r
282     }\r
283     m_D3DDevImmContext->PSGetConstantBuffers(0, 1, &m_PSConstantBuffer);\r
284     m_D3DDevImmContext->PSGetSamplers(0, 1, &m_PSSampler);\r
285     m_D3DDevImmContext->PSGetShaderResources(0, 1, &m_PSShaderResourceView);\r
286 \r
287     m_VSShader = NULL;\r
288     m_VSClassInstances = NULL;\r
289     m_VSNumClassInstances = 0;\r
290     m_D3DDevImmContext->VSGetShader(&m_VSShader, NULL, &m_VSNumClassInstances);\r
291     if (m_VSNumClassInstances > 0) \r
292     {\r
293         m_VSClassInstances = new ID3D11ClassInstance*[m_VSNumClassInstances];\r
294         for (UINT i = 0; i < m_VSNumClassInstances; i++)\r
295             m_VSClassInstances[i] = NULL;\r
296         m_D3DDevImmContext->VSGetShader(&m_VSShader, m_VSClassInstances, &m_VSNumClassInstances);\r
297         if (m_VSShader != NULL) \r
298             m_VSShader->Release();\r
299     }\r
300     m_D3DDevImmContext->VSGetConstantBuffers(0, 1, &m_VSConstantBuffer);\r
301 \r
302     // Save Input-Assembler states\r
303     m_D3DDevImmContext->IAGetIndexBuffer(&m_IAIndexBuffer, &m_IAIndexBufferFormat, &m_IAIndexBufferOffset);\r
304     m_D3DDevImmContext->IAGetInputLayout(&m_IAInputLayout);\r
305     m_D3DDevImmContext->IAGetPrimitiveTopology(&m_IATopology);\r
306     m_D3DDevImmContext->IAGetVertexBuffers(0, 1, &m_IAVertexBuffer, &m_IAVertexBufferStride, &m_IAVertexBufferOffset);\r
307 \r
308     // Save Ouput-Merger states\r
309     m_D3DDevImmContext->OMGetBlendState(&m_OMBlendState, m_OMBlendFactor, &m_OMSampleMask);\r
310     m_D3DDevImmContext->OMGetDepthStencilState(&m_OMDepthStencilState, &m_OMStencilRef);\r
311 \r
312     // Save Rasterizer states\r
313     m_D3DDevImmContext->RSGetScissorRects(&m_RSScissorNumRects, NULL);\r
314     if (m_RSScissorNumRects > 0)\r
315         m_D3DDevImmContext->RSGetScissorRects(&m_RSScissorNumRects, m_RSScissorRects);\r
316     m_D3DDevImmContext->RSGetViewports(&m_RSNumViewports, NULL);\r
317     if (m_RSNumViewports > 0)\r
318         m_D3DDevImmContext->RSGetViewports(&m_RSNumViewports, m_RSViewports);\r
319     m_D3DDevImmContext->RSGetState(&m_RSRasterizerState);\r
320 }\r
321 \r
322 void CState11::Restore()\r
323 {\r
324     // Restore shaders\r
325     m_D3DDevImmContext->CSSetShader(m_CSShader, m_CSClassInstances, m_CSNumClassInstances);\r
326     m_D3DDevImmContext->DSSetShader(m_DSShader, m_DSClassInstances, m_DSNumClassInstances);\r
327     m_D3DDevImmContext->GSSetShader(m_GSShader, m_GSClassInstances, m_GSNumClassInstances);\r
328     m_D3DDevImmContext->HSSetShader(m_HSShader, m_HSClassInstances, m_HSNumClassInstances);\r
329     m_D3DDevImmContext->PSSetShader(m_PSShader, m_PSClassInstances, m_PSNumClassInstances);\r
330     m_D3DDevImmContext->PSSetConstantBuffers(0, 1, &m_PSConstantBuffer);\r
331     m_D3DDevImmContext->PSSetSamplers(0, 1, &m_PSSampler);\r
332     m_D3DDevImmContext->PSSetShaderResources(0, 1, &m_PSShaderResourceView);\r
333     m_D3DDevImmContext->VSSetShader(m_VSShader, m_VSClassInstances, m_VSNumClassInstances);\r
334     m_D3DDevImmContext->VSSetConstantBuffers(0, 1, &m_VSConstantBuffer);\r
335 \r
336     // Restore Input-Assembler\r
337     m_D3DDevImmContext->IASetIndexBuffer(m_IAIndexBuffer, m_IAIndexBufferFormat, m_IAIndexBufferOffset);\r
338     m_D3DDevImmContext->IASetInputLayout(m_IAInputLayout);\r
339     m_D3DDevImmContext->IASetPrimitiveTopology(m_IATopology);\r
340     m_D3DDevImmContext->IASetVertexBuffers(0, 1, &m_IAVertexBuffer, &m_IAVertexBufferStride, &m_IAVertexBufferOffset);\r
341 \r
342     // Restore Ouput-Merger\r
343     m_D3DDevImmContext->OMSetBlendState(m_OMBlendState, m_OMBlendFactor, m_OMSampleMask);\r
344     m_D3DDevImmContext->OMSetDepthStencilState(m_OMDepthStencilState, m_OMStencilRef);\r
345 \r
346     // Restore Rasterizer states\r
347     m_D3DDevImmContext->RSSetScissorRects(m_RSScissorNumRects, m_RSScissorRects);\r
348     m_D3DDevImmContext->RSSetViewports(m_RSNumViewports, m_RSViewports);\r
349     m_D3DDevImmContext->RSSetState(m_RSRasterizerState);\r
350 }\r
351 \r
352 void CState11::Release()\r
353 {\r
354     // Release stored shaders\r
355 \r
356     if (m_CSClassInstances != NULL) \r
357     {\r
358         for (UINT i = 0; i < m_CSNumClassInstances; i++)\r
359             if (m_CSClassInstances[i] != NULL) \r
360                 m_CSClassInstances[i]->Release();\r
361         delete[] m_CSClassInstances;\r
362         m_CSClassInstances = NULL;\r
363         m_CSNumClassInstances = 0;\r
364     }\r
365     if (m_CSShader != NULL)\r
366     {\r
367         m_CSShader->Release();\r
368         m_CSShader = NULL;\r
369     }\r
370 \r
371     if (m_DSClassInstances != NULL) \r
372     {\r
373         for (UINT i = 0; i < m_DSNumClassInstances; i++)\r
374             if (m_DSClassInstances[i] != NULL) \r
375                 m_DSClassInstances[i]->Release();\r
376         delete[] m_DSClassInstances;\r
377         m_DSClassInstances = NULL;\r
378         m_DSNumClassInstances = 0;\r
379     }\r
380     if (m_DSShader != NULL)\r
381     {\r
382         m_DSShader->Release();\r
383         m_DSShader = NULL;\r
384     }\r
385 \r
386     if (m_GSClassInstances != NULL) \r
387     {\r
388         for (UINT i = 0; i < m_GSNumClassInstances; i++)\r
389             if (m_GSClassInstances[i] != NULL) \r
390                 m_GSClassInstances[i]->Release();\r
391         delete[] m_GSClassInstances;\r
392         m_GSClassInstances = NULL;\r
393         m_GSNumClassInstances = 0;\r
394     }\r
395     if (m_GSShader != NULL)\r
396     {\r
397         m_GSShader->Release();\r
398         m_GSShader = NULL;\r
399     }\r
400 \r
401     if (m_HSClassInstances != NULL) \r
402     {\r
403         for (UINT i = 0; i < m_HSNumClassInstances; i++)\r
404             if (m_HSClassInstances[i] != NULL) \r
405                 m_HSClassInstances[i]->Release();\r
406         delete[] m_HSClassInstances;\r
407         m_HSClassInstances = NULL;\r
408         m_HSNumClassInstances = 0;\r
409     }\r
410     if (m_HSShader != NULL)\r
411     {\r
412         m_HSShader->Release();\r
413         m_HSShader = NULL;\r
414     }\r
415 \r
416     if (m_PSClassInstances != NULL) \r
417     {\r
418         for (UINT i = 0; i < m_PSNumClassInstances; i++)\r
419             if (m_PSClassInstances[i] != NULL) \r
420                 m_PSClassInstances[i]->Release();\r
421         delete[] m_PSClassInstances;\r
422         m_PSClassInstances = NULL;\r
423         m_PSNumClassInstances = 0;\r
424     }\r
425     if (m_PSShader != NULL)\r
426     {\r
427         m_PSShader->Release();\r
428         m_PSShader = NULL;\r
429     }\r
430     if (m_PSConstantBuffer != NULL)\r
431     {\r
432         m_PSConstantBuffer->Release();\r
433         m_PSConstantBuffer = NULL;\r
434     }\r
435     if (m_PSSampler != NULL)\r
436     {\r
437         m_PSSampler->Release();\r
438         m_PSSampler = NULL;\r
439     }\r
440     if (m_PSShaderResourceView != NULL)\r
441     {\r
442         m_PSShaderResourceView->Release();\r
443         m_PSShaderResourceView = NULL;\r
444     }\r
445 \r
446     if (m_VSClassInstances != NULL) \r
447     {\r
448         for (UINT i = 0; i < m_VSNumClassInstances; i++)\r
449             if (m_VSClassInstances[i] != NULL) \r
450                 m_VSClassInstances[i]->Release();\r
451         delete[] m_VSClassInstances;\r
452         m_VSClassInstances = NULL;\r
453         m_VSNumClassInstances = 0;\r
454     }\r
455     if (m_VSShader != NULL)\r
456     {\r
457         m_VSShader->Release();\r
458         m_VSShader = NULL;\r
459     }\r
460     if (m_VSConstantBuffer != NULL)\r
461     {\r
462         m_VSConstantBuffer->Release();\r
463         m_VSConstantBuffer = NULL;\r
464     }\r
465 \r
466     // Release Input-Assembler states\r
467     if (m_IAIndexBuffer != NULL) \r
468     {\r
469         m_IAIndexBuffer->Release();\r
470         m_IAIndexBuffer = NULL;\r
471     }\r
472     if (m_IAInputLayout != NULL)\r
473     {\r
474         m_IAInputLayout->Release();\r
475         m_IAInputLayout = 0;\r
476     }\r
477     if (m_IAVertexBuffer != NULL)\r
478     {\r
479         m_IAVertexBuffer->Release();\r
480         m_IAVertexBuffer = NULL;\r
481     }\r
482 \r
483     // Release Output-Merger states\r
484     if (m_OMBlendState != NULL) \r
485     {\r
486         m_OMBlendState->Release();\r
487         m_OMBlendState = NULL;\r
488     }\r
489     if (m_OMDepthStencilState != NULL) \r
490     {\r
491         m_OMDepthStencilState->Release();\r
492         m_OMDepthStencilState = NULL;\r
493     }\r
494 \r
495     // Release Rasterizer state\r
496     if (m_RSRasterizerState != 0) \r
497     {\r
498         m_RSRasterizerState->Release();\r
499         m_RSRasterizerState = NULL;\r
500     }\r
501     m_RSNumViewports = 0;\r
502     m_RSScissorNumRects = 0;\r
503 }\r
504 \r
505 //  ---------------------------------------------------------------------------\r
506 \r
507 int CTwGraphDirect3D11::Init()\r
508 {\r
509     assert(g_TwMgr!=NULL);\r
510     assert(g_TwMgr->m_Device!=NULL);\r
511 \r
512     m_D3DDev = static_cast<ID3D11Device *>(g_TwMgr->m_Device);\r
513     m_D3DDevInitialRefCount = m_D3DDev->AddRef() - 1;\r
514     m_D3DDev->GetImmediateContext(&m_D3DDevImmContext);\r
515 \r
516     m_Drawing = false;\r
517     m_OffsetX = m_OffsetY = 0;\r
518     m_ViewportInit = new D3D11_VIEWPORT;\r
519     m_FontTex = NULL;\r
520     m_FontD3DTex = NULL;\r
521     m_FontD3DTexRV = NULL;\r
522     m_WndWidth = 0;\r
523     m_WndHeight = 0;\r
524     m_State = NULL;\r
525     m_DepthStencilState = NULL;\r
526     m_BlendState = NULL;\r
527     m_RasterState = NULL;\r
528     m_RasterStateAntialiased = NULL;\r
529     m_RasterStateMultisample = NULL;\r
530     m_RasterStateCullCW = NULL;\r
531     m_RasterStateCullCCW = NULL;\r
532     m_LineRectVS = NULL;\r
533     m_LineRectCstColorVS = NULL;\r
534     m_LineRectPS = NULL;\r
535     m_LineRectVertexLayout = NULL;\r
536     m_TextVS = NULL;\r
537     m_TextCstColorVS = NULL;\r
538     m_TextPS = NULL;\r
539     m_TextVertexLayout = NULL;\r
540     m_LineVertexBuffer = NULL;\r
541     m_RectVertexBuffer = NULL;\r
542     m_TrianglesVertexBuffer = NULL;\r
543     m_TrianglesVertexBufferCount = 0;\r
544     m_ConstantBuffer = NULL;\r
545     m_SamplerState = NULL;\r
546 \r
547     // Allocate state object\r
548     m_State = new CState11(m_D3DDev, m_D3DDevImmContext);\r
549 \r
550     // Disable client shaders\r
551     m_D3DDevImmContext->CSSetShader(NULL, NULL, 0);\r
552     m_D3DDevImmContext->DSSetShader(NULL, NULL, 0);\r
553     m_D3DDevImmContext->GSSetShader(NULL, NULL, 0);\r
554     m_D3DDevImmContext->HSSetShader(NULL, NULL, 0);\r
555     m_D3DDevImmContext->PSSetShader(NULL, NULL, 0);\r
556     m_D3DDevImmContext->VSSetShader(NULL, NULL, 0);\r
557 \r
558     // Create shaders\r
559     HRESULT hr = m_D3DDev->CreateVertexShader(g_LineRectVS, sizeof(g_LineRectVS), NULL, &m_LineRectVS);\r
560     if( FAILED(hr) )\r
561     {\r
562         g_TwMgr->SetLastError(g_ErrCreateVS11);\r
563         Shut();\r
564         return 0;\r
565     }\r
566     hr = m_D3DDev->CreateVertexShader(g_LineRectCstColorVS, sizeof(g_LineRectCstColorVS), NULL, &m_LineRectCstColorVS);\r
567     if( FAILED(hr) )\r
568     {\r
569         g_TwMgr->SetLastError(g_ErrCreateVS11);\r
570         Shut();\r
571         return 0;\r
572     }\r
573     hr = m_D3DDev->CreatePixelShader(g_LineRectPS, sizeof(g_LineRectPS), NULL, &m_LineRectPS);\r
574     if( FAILED(hr) )\r
575     {\r
576         g_TwMgr->SetLastError(g_ErrCreatePS11);\r
577         Shut();\r
578         return 0;\r
579     }\r
580     hr = m_D3DDev->CreateVertexShader(g_TextVS, sizeof(g_TextVS), NULL, &m_TextVS);\r
581     if( FAILED(hr) )\r
582     {\r
583         g_TwMgr->SetLastError(g_ErrCreateVS11);\r
584         Shut();\r
585         return 0;\r
586     }\r
587     hr = m_D3DDev->CreateVertexShader(g_TextCstColorVS, sizeof(g_TextCstColorVS), NULL, &m_TextCstColorVS);\r
588     if( FAILED(hr) )\r
589     {\r
590         g_TwMgr->SetLastError(g_ErrCreateVS11);\r
591         Shut();\r
592         return 0;\r
593     }\r
594     hr = m_D3DDev->CreatePixelShader(g_TextPS, sizeof(g_TextPS), NULL, &m_TextPS);\r
595     if( FAILED(hr) )\r
596     {\r
597         g_TwMgr->SetLastError(g_ErrCreatePS11);\r
598         Shut();\r
599         return 0;\r
600     }\r
601  \r
602     // Create input layout for lines & rect\r
603     D3D11_INPUT_ELEMENT_DESC lineRectLayout[] =\r
604     {\r
605         { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },  \r
606         { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(CLineRectVtx, m_Color), D3D11_INPUT_PER_VERTEX_DATA, 0 }\r
607     };\r
608     hr = m_D3DDev->CreateInputLayout(lineRectLayout, sizeof(lineRectLayout)/sizeof(lineRectLayout[0]), g_LineRectVS, sizeof(g_LineRectVS), &m_LineRectVertexLayout);\r
609     if( FAILED(hr) )\r
610     {\r
611         g_TwMgr->SetLastError(g_ErrCreateLayout11);\r
612         Shut();\r
613         return 0;\r
614     }\r
615 \r
616     // Create line vertex buffer\r
617     D3D11_BUFFER_DESC bd;\r
618     bd.Usage = D3D11_USAGE_DYNAMIC;\r
619     bd.ByteWidth = 2 * sizeof(CLineRectVtx);\r
620     bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;\r
621     bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\r
622     bd.MiscFlags = 0;\r
623     bd.StructureByteStride = 0;\r
624     hr = m_D3DDev->CreateBuffer(&bd, NULL, &m_LineVertexBuffer);\r
625     if( FAILED(hr) )\r
626     {\r
627         g_TwMgr->SetLastError(g_ErrCreateBuffer11);\r
628         Shut();\r
629         return 0;\r
630     }\r
631 \r
632     // Create rect vertex buffer\r
633     bd.ByteWidth = 4 * sizeof(CLineRectVtx);\r
634     hr = m_D3DDev->CreateBuffer(&bd, NULL, &m_RectVertexBuffer);\r
635     if( FAILED(hr) )\r
636     {\r
637         g_TwMgr->SetLastError(g_ErrCreateBuffer11);\r
638         Shut();\r
639         return 0;\r
640     }\r
641 \r
642     // Create constant buffer\r
643     bd.ByteWidth = sizeof(CConstants);\r
644     bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;\r
645     hr = m_D3DDev->CreateBuffer(&bd, NULL, &m_ConstantBuffer);\r
646     if( FAILED(hr) )\r
647     {\r
648         g_TwMgr->SetLastError(g_ErrCreateBuffer11);\r
649         Shut();\r
650         return 0;\r
651     }\r
652 \r
653     // Create sampler\r
654     D3D11_SAMPLER_DESC sd;\r
655     sd.AddressU = sd.AddressV = sd.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;\r
656     sd.BorderColor[0] = sd.BorderColor[1] = sd.BorderColor[2] = sd.BorderColor[3] = 0;\r
657     sd.ComparisonFunc = D3D11_COMPARISON_NEVER;\r
658     sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;\r
659     sd.MaxAnisotropy = 1;\r
660     sd.MaxLOD = sd.MinLOD = 0;\r
661     sd.MipLODBias = 0;\r
662     hr = m_D3DDev->CreateSamplerState(&sd, &m_SamplerState);\r
663     if( FAILED(hr) )\r
664     {\r
665         g_TwMgr->SetLastError(g_ErrCreateSampler11);\r
666         Shut();\r
667         return 0;\r
668     }\r
669 \r
670     // Create input layout for text\r
671     D3D11_INPUT_ELEMENT_DESC textLayout[] =\r
672     {\r
673         { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },  \r
674         { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(CTextVtx, m_Color), D3D11_INPUT_PER_VERTEX_DATA, 0 }, \r
675         { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(CTextVtx, m_UV), D3D11_INPUT_PER_VERTEX_DATA, 0 }\r
676     };\r
677     hr = m_D3DDev->CreateInputLayout(textLayout, sizeof(textLayout)/sizeof(textLayout[0]), g_TextVS, sizeof(g_TextVS), &m_TextVertexLayout);\r
678     if( FAILED(hr) )\r
679     {\r
680         g_TwMgr->SetLastError(g_ErrCreateLayout11);\r
681         Shut();\r
682         return 0;\r
683     }\r
684 \r
685     // Create depth stencil state object\r
686     D3D11_DEPTH_STENCILOP_DESC od;\r
687     od.StencilFunc = D3D11_COMPARISON_ALWAYS;\r
688     od.StencilFailOp = D3D11_STENCIL_OP_KEEP;\r
689     od.StencilPassOp = D3D11_STENCIL_OP_KEEP;\r
690     od.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;\r
691     D3D11_DEPTH_STENCIL_DESC dsd;\r
692     dsd.DepthEnable = FALSE;\r
693     dsd.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;\r
694     dsd.DepthFunc = D3D11_COMPARISON_ALWAYS;\r
695     dsd.StencilEnable = FALSE;\r
696     dsd.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;\r
697     dsd.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;\r
698     dsd.FrontFace = od;\r
699     dsd.BackFace = od;\r
700     m_D3DDev->CreateDepthStencilState(&dsd, &m_DepthStencilState);\r
701 \r
702     // Create blend state object\r
703     D3D11_BLEND_DESC bsd;\r
704     bsd.AlphaToCoverageEnable = FALSE;\r
705     bsd.IndependentBlendEnable = FALSE;\r
706     for(int i=0; i<8; ++i)\r
707     {\r
708         bsd.RenderTarget[i].BlendEnable = TRUE;\r
709         bsd.RenderTarget[i].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;\r
710         bsd.RenderTarget[i].SrcBlend = D3D11_BLEND_SRC_ALPHA;\r
711         bsd.RenderTarget[i].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;\r
712         bsd.RenderTarget[i].BlendOp =  D3D11_BLEND_OP_ADD;\r
713         bsd.RenderTarget[i].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;\r
714         bsd.RenderTarget[i].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;\r
715         bsd.RenderTarget[i].BlendOpAlpha = D3D11_BLEND_OP_ADD;\r
716     }\r
717     m_D3DDev->CreateBlendState(&bsd, &m_BlendState);\r
718 \r
719     // Create rasterizer state object\r
720     D3D11_RASTERIZER_DESC rd;\r
721     rd.FillMode = D3D11_FILL_SOLID;\r
722     rd.CullMode = D3D11_CULL_NONE;\r
723     rd.FrontCounterClockwise = true;\r
724     rd.DepthBias = false;\r
725     rd.DepthBiasClamp = 0;\r
726     rd.SlopeScaledDepthBias = 0;\r
727     rd.DepthClipEnable = false;\r
728     rd.ScissorEnable = true;\r
729     rd.MultisampleEnable = false; // do not allow msaa (fonts would be degraded)\r
730     rd.AntialiasedLineEnable = false;\r
731     m_D3DDev->CreateRasterizerState(&rd, &m_RasterState);\r
732 \r
733     rd.AntialiasedLineEnable = true;\r
734     m_D3DDev->CreateRasterizerState(&rd, &m_RasterStateAntialiased);\r
735     rd.AntialiasedLineEnable = false;\r
736 \r
737     // the three following raster states allow msaa\r
738     rd.MultisampleEnable = true;\r
739     m_D3DDev->CreateRasterizerState(&rd, &m_RasterStateMultisample);\r
740 \r
741     rd.CullMode = D3D11_CULL_BACK;\r
742     m_D3DDev->CreateRasterizerState(&rd, &m_RasterStateCullCW);\r
743 \r
744     rd.CullMode = D3D11_CULL_FRONT;\r
745     m_D3DDev->CreateRasterizerState(&rd, &m_RasterStateCullCCW);\r
746 \r
747     return 1;\r
748 }\r
749 \r
750 //  ---------------------------------------------------------------------------\r
751 \r
752 int CTwGraphDirect3D11::Shut()\r
753 {\r
754     assert(m_Drawing==false);\r
755 \r
756     UnbindFont(m_D3DDev, m_FontD3DTex, m_FontD3DTexRV);\r
757     m_FontD3DTex = NULL;\r
758     m_FontD3DTexRV = NULL;\r
759     if( m_State )\r
760     {\r
761         delete m_State;\r
762         m_State = NULL;\r
763     }\r
764     if( m_ViewportInit )\r
765     {\r
766         delete m_ViewportInit;\r
767         m_ViewportInit = NULL;\r
768     }\r
769 \r
770     if( m_DepthStencilState )\r
771     {\r
772         ULONG rc = m_DepthStencilState->Release();\r
773         //assert( rc==0 ); // no assert: the client can use a similar (then shared) state\r
774         (void)rc;\r
775         m_DepthStencilState = NULL;\r
776     }\r
777     if( m_BlendState )\r
778     {\r
779         ULONG rc = m_BlendState->Release();\r
780         //assert( rc==0 ); // no assert: the client can use a similar (then shared) state\r
781         (void)rc;\r
782         m_BlendState = NULL;\r
783     }\r
784     if( m_RasterState )\r
785     {\r
786         ULONG rc = m_RasterState->Release();\r
787         //assert( rc==0 ); // no assert: the client can use a similar (then shared) state\r
788         (void)rc;\r
789         m_RasterState = NULL;\r
790     }\r
791     if( m_RasterStateAntialiased )\r
792     {\r
793         ULONG rc = m_RasterStateAntialiased->Release();\r
794         //assert( rc==0 ); // no assert: the client can use a similar (then shared) state\r
795         (void)rc;\r
796         m_RasterStateAntialiased = NULL;\r
797     }\r
798     if( m_RasterStateMultisample )\r
799     {\r
800         ULONG rc = m_RasterStateMultisample->Release();\r
801         //assert( rc==0 ); // no assert: the client can use a similar (then shared) state\r
802         (void)rc;\r
803         m_RasterStateMultisample = NULL;\r
804     }\r
805     if( m_RasterStateCullCW )\r
806     {\r
807         ULONG rc = m_RasterStateCullCW->Release();\r
808         //assert( rc==0 ); // no assert: the client can use a similar (then shared) state\r
809         (void)rc;\r
810         m_RasterStateCullCW = NULL;\r
811     }\r
812     if( m_RasterStateCullCCW )\r
813     {\r
814         ULONG rc = m_RasterStateCullCCW->Release();\r
815         //assert( rc==0 ); // no assert: the client can use a similar (then shared) state\r
816         (void)rc;\r
817         m_RasterStateCullCCW = NULL;\r
818     }\r
819     if( m_SamplerState )\r
820     {\r
821         ULONG rc = m_SamplerState->Release();\r
822         //assert( rc==0 ); // no assert: the client can use a similar (then shared) state\r
823         (void)rc;\r
824         m_SamplerState = NULL;\r
825     }\r
826 \r
827     if( m_LineRectVS )\r
828     {\r
829         ULONG rc = m_LineRectVS->Release();\r
830         assert( rc==0 ); (void)rc;\r
831         m_LineRectVS = NULL;\r
832     }\r
833     if( m_LineRectCstColorVS )\r
834     {\r
835         ULONG rc = m_LineRectCstColorVS->Release();\r
836         assert( rc==0 ); (void)rc;\r
837         m_LineRectCstColorVS = NULL;\r
838     }\r
839     if( m_LineRectPS )\r
840     {\r
841         ULONG rc = m_LineRectPS->Release();\r
842         assert( rc==0 ); (void)rc;\r
843         m_LineRectPS = NULL;\r
844     }\r
845     if( m_TextVS )\r
846     {\r
847         ULONG rc = m_TextVS->Release();\r
848         assert( rc==0 ); (void)rc;\r
849         m_TextVS = NULL;\r
850     }\r
851     if( m_TextCstColorVS )\r
852     {\r
853         ULONG rc = m_TextCstColorVS->Release();\r
854         assert( rc==0 ); (void)rc;\r
855         m_TextCstColorVS = NULL;\r
856     }\r
857     if( m_TextPS )\r
858     {\r
859         ULONG rc = m_TextPS->Release();\r
860         assert( rc==0 ); (void)rc;\r
861         m_TextPS = NULL;\r
862     }\r
863     if( m_LineVertexBuffer )\r
864     {\r
865         ULONG rc = m_LineVertexBuffer->Release();\r
866         assert( rc==0 ); (void)rc;\r
867         m_LineVertexBuffer = NULL;\r
868     }\r
869     if( m_RectVertexBuffer )\r
870     {\r
871         ULONG rc = m_RectVertexBuffer->Release();\r
872         assert( rc==0 ); (void)rc;\r
873         m_RectVertexBuffer = NULL;\r
874     }\r
875     if( m_TrianglesVertexBuffer )\r
876     {\r
877         ULONG rc = m_TrianglesVertexBuffer->Release();\r
878         assert( rc==0 ); (void)rc;\r
879         m_TrianglesVertexBuffer = NULL;\r
880         m_TrianglesVertexBufferCount = 0;\r
881     }\r
882     if( m_ConstantBuffer )\r
883     {\r
884         ULONG rc = m_ConstantBuffer->Release();\r
885         assert( rc==0 ); (void)rc;\r
886         m_ConstantBuffer = NULL;\r
887     }\r
888     if( m_LineRectVertexLayout ) \r
889     {\r
890         ULONG rc = m_LineRectVertexLayout->Release();\r
891         assert( rc==0 ); (void)rc;\r
892         m_LineRectVertexLayout = NULL;\r
893     }\r
894     if( m_TextVertexLayout ) \r
895     {\r
896         ULONG rc = m_TextVertexLayout->Release();\r
897         assert( rc==0 ); (void)rc;\r
898         m_TextVertexLayout = NULL;\r
899     }\r
900 \r
901     if( m_D3DDevImmContext )\r
902     {\r
903         m_D3DDevImmContext->Release();\r
904         m_D3DDevImmContext = NULL;\r
905     }\r
906 \r
907     if( m_D3DDev )\r
908     {\r
909         //unsigned int rc = m_D3DDev->Release();\r
910         //assert( m_D3DDevInitialRefCount==rc ); (void)rc;\r
911         m_D3DDev->Release();\r
912         m_D3DDev = NULL;\r
913     }\r
914 \r
915     return 1;\r
916 }\r
917 \r
918 //  ---------------------------------------------------------------------------\r
919 \r
920 void CTwGraphDirect3D11::BeginDraw(int _WndWidth, int _WndHeight)\r
921 {\r
922     assert(m_Drawing==false && _WndWidth>0 && _WndHeight>0);\r
923     m_Drawing = true;\r
924 \r
925     m_WndWidth  = _WndWidth;\r
926     m_WndHeight = _WndHeight;\r
927     m_OffsetX = m_OffsetY = 0;\r
928 \r
929     // save client context state\r
930     m_State->Save();\r
931 \r
932     // Setup the viewport\r
933     D3D11_VIEWPORT vp;\r
934     vp.Width = (FLOAT)_WndWidth;\r
935     vp.Height = (FLOAT)_WndHeight;\r
936     vp.MinDepth = 0.0f;\r
937     vp.MaxDepth = 1.0f;\r
938     vp.TopLeftX = 0;\r
939     vp.TopLeftY = 0;\r
940     m_D3DDevImmContext->RSSetViewports(1, &vp);\r
941     *static_cast<D3D11_VIEWPORT *>(m_ViewportInit) = vp;\r
942 \r
943     m_ViewportAndScissorRects[0] = FullRect;\r
944     m_ViewportAndScissorRects[1] = FullRect;\r
945     m_D3DDevImmContext->RSSetScissorRects(1, m_ViewportAndScissorRects);\r
946 \r
947     m_D3DDevImmContext->RSSetState(m_RasterState);\r
948 \r
949     m_D3DDevImmContext->OMSetDepthStencilState(m_DepthStencilState, 0);\r
950     float blendFactors[4] = { 1, 1, 1, 1 };\r
951     m_D3DDevImmContext->OMSetBlendState(m_BlendState, blendFactors, 0xffffffff);\r
952 \r
953     m_D3DDevImmContext->CSSetShader(NULL, NULL, 0);\r
954     m_D3DDevImmContext->DSSetShader(NULL, NULL, 0);\r
955     m_D3DDevImmContext->GSSetShader(NULL, NULL, 0);\r
956     m_D3DDevImmContext->HSSetShader(NULL, NULL, 0);\r
957 }\r
958 \r
959 //  ---------------------------------------------------------------------------\r
960 \r
961 void CTwGraphDirect3D11::EndDraw()\r
962 {\r
963     m_D3DDevImmContext->RSSetState(NULL);\r
964     m_D3DDevImmContext->OMSetDepthStencilState(NULL, 0);\r
965     m_D3DDevImmContext->OMSetBlendState(NULL, NULL, 0xffffffff);\r
966 \r
967     assert(m_Drawing==true);\r
968     m_Drawing = false;\r
969 \r
970     // restore and release client context state\r
971     m_State->Restore();\r
972     m_State->Release();\r
973 }\r
974 \r
975 //  ---------------------------------------------------------------------------\r
976 \r
977 bool CTwGraphDirect3D11::IsDrawing()\r
978 {\r
979     return m_Drawing;\r
980 }\r
981 \r
982 //  ---------------------------------------------------------------------------\r
983 \r
984 void CTwGraphDirect3D11::Restore()\r
985 {\r
986     if( m_State )\r
987         m_State->Release();\r
988 \r
989     UnbindFont(m_D3DDev, m_FontD3DTex, m_FontD3DTexRV);\r
990     m_FontD3DTexRV = NULL;\r
991     m_FontD3DTex = NULL;\r
992     \r
993     m_FontTex = NULL;\r
994 }\r
995 \r
996 //  ---------------------------------------------------------------------------\r
997 \r
998 static inline float ToNormScreenX(int x, int wndWidth)\r
999 {\r
1000     return 2.0f*((float)x-0.5f)/wndWidth - 1.0f;\r
1001 }\r
1002 \r
1003 static inline float ToNormScreenY(int y, int wndHeight)\r
1004 {\r
1005     return 1.0f - 2.0f*((float)y-0.5f)/wndHeight;\r
1006 }\r
1007 \r
1008 static inline color32 ToR8G8B8A8(color32 col)\r
1009 {\r
1010     return (col & 0xff00ff00) | ((col>>16) & 0xff) | ((col<<16) & 0xff0000);\r
1011 }\r
1012 \r
1013 //  ---------------------------------------------------------------------------\r
1014 \r
1015 void CTwGraphDirect3D11::DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color0, color32 _Color1, bool _AntiAliased)\r
1016 {\r
1017     assert(m_Drawing==true);\r
1018 \r
1019     float x0 = ToNormScreenX(_X0 + m_OffsetX, m_WndWidth);\r
1020     float y0 = ToNormScreenY(_Y0 + m_OffsetY, m_WndHeight);\r
1021     float x1 = ToNormScreenX(_X1 + m_OffsetX, m_WndWidth);\r
1022     float y1 = ToNormScreenY(_Y1 + m_OffsetY, m_WndHeight);\r
1023  \r
1024     D3D11_MAPPED_SUBRESOURCE mappedResource;\r
1025     HRESULT hr = m_D3DDevImmContext->Map(m_LineVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);\r
1026     if( SUCCEEDED(hr) )\r
1027     {\r
1028         CLineRectVtx *vertices = (CLineRectVtx *)mappedResource.pData;\r
1029         // Fill vertex buffer\r
1030         vertices[0].m_Pos[0] = x0;\r
1031         vertices[0].m_Pos[1] = y0;\r
1032         vertices[0].m_Pos[2] = 0;\r
1033         vertices[0].m_Color = ToR8G8B8A8(_Color0);\r
1034         vertices[1].m_Pos[0] = x1;\r
1035         vertices[1].m_Pos[1] = y1;\r
1036         vertices[1].m_Pos[2] = 0;\r
1037         vertices[1].m_Color = ToR8G8B8A8(_Color1);\r
1038 \r
1039         m_D3DDevImmContext->Unmap(m_LineVertexBuffer, 0);\r
1040 \r
1041         if( _AntiAliased )\r
1042             m_D3DDevImmContext->RSSetState(m_RasterStateAntialiased);\r
1043 \r
1044         // Reset shader constants\r
1045         hr = m_D3DDevImmContext->Map(m_ConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);\r
1046         if( SUCCEEDED(hr) )\r
1047         {\r
1048             CConstants *constants = (CConstants *)mappedResource.pData;\r
1049             constants->m_Offset[0] = 0;\r
1050             constants->m_Offset[1] = 0;\r
1051             constants->m_Offset[2] = 0;\r
1052             constants->m_Offset[3] = 0;\r
1053             constants->m_CstColor[0] = 1;\r
1054             constants->m_CstColor[1] = 1;\r
1055             constants->m_CstColor[2] = 1;\r
1056             constants->m_CstColor[3] = 1;\r
1057 \r
1058             m_D3DDevImmContext->Unmap(m_ConstantBuffer, 0);\r
1059         }\r
1060 \r
1061         // Set the input layout\r
1062         m_D3DDevImmContext->IASetInputLayout(m_LineRectVertexLayout);\r
1063 \r
1064         // Set vertex buffer\r
1065         UINT stride = sizeof(CLineRectVtx);\r
1066         UINT offset = 0;\r
1067         m_D3DDevImmContext->IASetVertexBuffers(0, 1, &m_LineVertexBuffer, &stride, &offset);\r
1068 \r
1069         // Set primitive topology\r
1070         m_D3DDevImmContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);\r
1071 \r
1072         // Render the line\r
1073         m_D3DDevImmContext->VSSetConstantBuffers(0, 1, &m_ConstantBuffer);\r
1074         m_D3DDevImmContext->VSSetShader(m_LineRectVS, NULL, 0);\r
1075         m_D3DDevImmContext->PSSetShader(m_LineRectPS, NULL, 0);\r
1076         m_D3DDevImmContext->Draw(2, 0);\r
1077 \r
1078         if( _AntiAliased )\r
1079             m_D3DDevImmContext->RSSetState(m_RasterState); // restore default raster state\r
1080     }\r
1081 }\r
1082 \r
1083 //  ---------------------------------------------------------------------------\r
1084 \r
1085 void CTwGraphDirect3D11::DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color00, color32 _Color10, color32 _Color01, color32 _Color11)\r
1086 {\r
1087     assert(m_Drawing==true);\r
1088 \r
1089     // border adjustment\r
1090     if(_X0<_X1)\r
1091         ++_X1;\r
1092     else if(_X0>_X1)\r
1093         ++_X0;\r
1094     if(_Y0<_Y1)\r
1095         ++_Y1;\r
1096     else if(_Y0>_Y1)\r
1097         ++_Y0;\r
1098 \r
1099     float x0 = ToNormScreenX(_X0 + m_OffsetX, m_WndWidth);\r
1100     float y0 = ToNormScreenY(_Y0 + m_OffsetY, m_WndHeight);\r
1101     float x1 = ToNormScreenX(_X1 + m_OffsetX, m_WndWidth);\r
1102     float y1 = ToNormScreenY(_Y1 + m_OffsetY, m_WndHeight);\r
1103  \r
1104     D3D11_MAPPED_SUBRESOURCE mappedResource;\r
1105     HRESULT hr = m_D3DDevImmContext->Map(m_RectVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);\r
1106     if( SUCCEEDED(hr) )\r
1107     {\r
1108         CLineRectVtx *vertices = (CLineRectVtx *)mappedResource.pData;\r
1109         // Fill vertex buffer\r
1110         vertices[0].m_Pos[0] = x0;\r
1111         vertices[0].m_Pos[1] = y0;\r
1112         vertices[0].m_Pos[2] = 0;\r
1113         vertices[0].m_Color = ToR8G8B8A8(_Color00);\r
1114         vertices[1].m_Pos[0] = x1;\r
1115         vertices[1].m_Pos[1] = y0;\r
1116         vertices[1].m_Pos[2] = 0;\r
1117         vertices[1].m_Color = ToR8G8B8A8(_Color10);\r
1118         vertices[2].m_Pos[0] = x0;\r
1119         vertices[2].m_Pos[1] = y1;\r
1120         vertices[2].m_Pos[2] = 0;\r
1121         vertices[2].m_Color = ToR8G8B8A8(_Color01);\r
1122         vertices[3].m_Pos[0] = x1;\r
1123         vertices[3].m_Pos[1] = y1;\r
1124         vertices[3].m_Pos[2] = 0;\r
1125         vertices[3].m_Color = ToR8G8B8A8(_Color11);\r
1126 \r
1127         m_D3DDevImmContext->Unmap(m_RectVertexBuffer, 0);\r
1128 \r
1129         // Reset shader constants\r
1130         hr = m_D3DDevImmContext->Map(m_ConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);\r
1131         if( SUCCEEDED(hr) )\r
1132         {\r
1133             CConstants *constants = (CConstants *)mappedResource.pData;\r
1134             constants->m_Offset[0] = 0;\r
1135             constants->m_Offset[1] = 0;\r
1136             constants->m_Offset[2] = 0;\r
1137             constants->m_Offset[3] = 0;\r
1138             constants->m_CstColor[0] = 1;\r
1139             constants->m_CstColor[1] = 1;\r
1140             constants->m_CstColor[2] = 1;\r
1141             constants->m_CstColor[3] = 1;\r
1142 \r
1143             m_D3DDevImmContext->Unmap(m_ConstantBuffer, 0);\r
1144         }\r
1145 \r
1146         // Set the input layout\r
1147         m_D3DDevImmContext->IASetInputLayout(m_LineRectVertexLayout);\r
1148 \r
1149         // Set vertex buffer\r
1150         UINT stride = sizeof(CLineRectVtx);\r
1151         UINT offset = 0;\r
1152         m_D3DDevImmContext->IASetVertexBuffers(0, 1, &m_RectVertexBuffer, &stride, &offset);\r
1153 \r
1154         // Set primitive topology\r
1155         m_D3DDevImmContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);\r
1156 \r
1157         // Render the rect\r
1158         m_D3DDevImmContext->VSSetConstantBuffers(0, 1, &m_ConstantBuffer);\r
1159         m_D3DDevImmContext->VSSetShader(m_LineRectVS, NULL, 0);\r
1160         m_D3DDevImmContext->PSSetShader(m_LineRectPS, NULL, 0);\r
1161         m_D3DDevImmContext->Draw(4, 0);\r
1162     }\r
1163 }\r
1164 \r
1165 //  ---------------------------------------------------------------------------\r
1166 \r
1167 void *CTwGraphDirect3D11::NewTextObj()\r
1168 {\r
1169     CTextObj *textObj = new CTextObj;\r
1170     memset(textObj, 0, sizeof(CTextObj));\r
1171     return textObj;\r
1172 }\r
1173 \r
1174 //  ---------------------------------------------------------------------------\r
1175 \r
1176 void CTwGraphDirect3D11::DeleteTextObj(void *_TextObj)\r
1177 {\r
1178     assert(_TextObj!=NULL);\r
1179     CTextObj *textObj = static_cast<CTextObj *>(_TextObj);\r
1180     if( textObj->m_TextVertexBuffer )\r
1181         textObj->m_TextVertexBuffer->Release();\r
1182     if( textObj->m_BgVertexBuffer )\r
1183         textObj->m_BgVertexBuffer->Release();\r
1184     memset(textObj, 0, sizeof(CTextObj));\r
1185     delete textObj;\r
1186 }\r
1187 \r
1188 //  ---------------------------------------------------------------------------\r
1189 \r
1190 void CTwGraphDirect3D11::BuildText(void *_TextObj, const std::string *_TextLines, color32 *_LineColors, color32 *_LineBgColors, int _NbLines, const CTexFont *_Font, int _Sep, int _BgWidth)\r
1191 {\r
1192     assert(m_Drawing==true);\r
1193     assert(_TextObj!=NULL);\r
1194     assert(_Font!=NULL);\r
1195 \r
1196     if( _Font != m_FontTex )\r
1197     {\r
1198         UnbindFont(m_D3DDev, m_FontD3DTex, m_FontD3DTexRV);\r
1199         BindFont(m_D3DDev, _Font, &m_FontD3DTex, &m_FontD3DTexRV);\r
1200         m_FontTex = _Font;\r
1201     }\r
1202 \r
1203     int nbTextVerts = 0;\r
1204     int line;\r
1205     for( line=0; line<_NbLines; ++line )\r
1206         nbTextVerts += 6 * (int)_TextLines[line].length();\r
1207     int nbBgVerts = 0;\r
1208     if( _BgWidth>0 )\r
1209         nbBgVerts = _NbLines*6;\r
1210 \r
1211     CTextObj *textObj = static_cast<CTextObj *>(_TextObj);\r
1212     textObj->m_LineColors = (_LineColors!=NULL);\r
1213     textObj->m_LineBgColors = (_LineBgColors!=NULL);\r
1214 \r
1215     // (re)create text vertex buffer if needed, and map it\r
1216     CTextVtx *textVerts = NULL;\r
1217     if( nbTextVerts>0 )\r
1218     {\r
1219         if( textObj->m_TextVertexBuffer==NULL || textObj->m_TextVertexBufferSize<nbTextVerts )\r
1220         {\r
1221             if( textObj->m_TextVertexBuffer!=NULL )\r
1222             {\r
1223                 ULONG rc = textObj->m_TextVertexBuffer->Release();\r
1224                 assert( rc==0 ); (void)rc;\r
1225                 textObj->m_TextVertexBuffer = NULL;\r
1226             }\r
1227             textObj->m_TextVertexBufferSize = nbTextVerts + 6*256; // add a reserve of 256 characters\r
1228             D3D11_BUFFER_DESC bd;\r
1229             bd.Usage = D3D11_USAGE_DYNAMIC;\r
1230             bd.ByteWidth = textObj->m_TextVertexBufferSize * sizeof(CTextVtx);\r
1231             bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;\r
1232             bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\r
1233             bd.MiscFlags = 0;\r
1234             bd.StructureByteStride = 0;\r
1235             m_D3DDev->CreateBuffer(&bd, NULL, &textObj->m_TextVertexBuffer);\r
1236         }\r
1237 \r
1238         if( textObj->m_TextVertexBuffer!=NULL )\r
1239         {\r
1240             D3D11_MAPPED_SUBRESOURCE mappedResource;\r
1241             m_D3DDevImmContext->Map(textObj->m_TextVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);\r
1242             textVerts = (CTextVtx *)mappedResource.pData;\r
1243         }\r
1244     }\r
1245 \r
1246     // (re)create bg vertex buffer if needed, and map it\r
1247     CLineRectVtx *bgVerts = NULL;\r
1248     if( nbBgVerts>0 )\r
1249     {\r
1250         if( textObj->m_BgVertexBuffer==NULL || textObj->m_BgVertexBufferSize<nbBgVerts )\r
1251         {\r
1252             if( textObj->m_BgVertexBuffer!=NULL )\r
1253             {\r
1254                 ULONG rc = textObj->m_BgVertexBuffer->Release();\r
1255                 assert( rc==0 ); (void)rc;\r
1256                 textObj->m_BgVertexBuffer = NULL;\r
1257             }\r
1258             textObj->m_BgVertexBufferSize = nbBgVerts + 6*32; // add a reserve of 32 rects\r
1259             D3D11_BUFFER_DESC bd;\r
1260             bd.Usage = D3D11_USAGE_DYNAMIC;\r
1261             bd.ByteWidth = textObj->m_BgVertexBufferSize * sizeof(CLineRectVtx);\r
1262             bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;\r
1263             bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\r
1264             bd.MiscFlags = 0;\r
1265             bd.StructureByteStride = 0;\r
1266             m_D3DDev->CreateBuffer(&bd, NULL, &textObj->m_BgVertexBuffer);\r
1267         }\r
1268 \r
1269         if( textObj->m_BgVertexBuffer!=NULL )\r
1270         {\r
1271             D3D11_MAPPED_SUBRESOURCE mappedResource;\r
1272             m_D3DDevImmContext->Map(textObj->m_BgVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);\r
1273             bgVerts = (CLineRectVtx *)mappedResource.pData;\r
1274         }\r
1275     }\r
1276 \r
1277     int x, x1, y, y1, i, len;\r
1278     float px, px1, py, py1;\r
1279     unsigned char ch;\r
1280     const unsigned char *text;\r
1281     color32 lineColor = COLOR32_RED;\r
1282     CTextVtx vtx;\r
1283     vtx.m_Pos[2] = 0;\r
1284     CLineRectVtx bgVtx;\r
1285     bgVtx.m_Pos[2] = 0;\r
1286     int textVtxIndex = 0;\r
1287     int bgVtxIndex = 0;\r
1288     for( line=0; line<_NbLines; ++line )\r
1289     {\r
1290         x = 0;\r
1291         y = line * (_Font->m_CharHeight+_Sep);\r
1292         y1 = y+_Font->m_CharHeight;\r
1293         len = (int)_TextLines[line].length();\r
1294         text = (const unsigned char *)(_TextLines[line].c_str());\r
1295         if( _LineColors!=NULL )\r
1296             lineColor = ToR8G8B8A8(_LineColors[line]);\r
1297 \r
1298         if( textVerts!=NULL )\r
1299             for( i=0; i<len; ++i )\r
1300             {\r
1301                 ch = text[i];\r
1302                 x1 = x + _Font->m_CharWidth[ch];\r
1303 \r
1304                 px  = ToNormScreenX(x,  m_WndWidth);\r
1305                 py  = ToNormScreenY(y,  m_WndHeight);\r
1306                 px1 = ToNormScreenX(x1, m_WndWidth);\r
1307                 py1 = ToNormScreenY(y1, m_WndHeight);\r
1308 \r
1309                 vtx.m_Color  = lineColor;\r
1310 \r
1311                 vtx.m_Pos[0] = px;\r
1312                 vtx.m_Pos[1] = py;\r
1313                 vtx.m_UV [0] = _Font->m_CharU0[ch];\r
1314                 vtx.m_UV [1] = _Font->m_CharV0[ch];\r
1315                 textVerts[textVtxIndex++] = vtx;\r
1316 \r
1317                 vtx.m_Pos[0] = px1;\r
1318                 vtx.m_Pos[1] = py;\r
1319                 vtx.m_UV [0] = _Font->m_CharU1[ch];\r
1320                 vtx.m_UV [1] = _Font->m_CharV0[ch];\r
1321                 textVerts[textVtxIndex++] = vtx;\r
1322 \r
1323                 vtx.m_Pos[0] = px;\r
1324                 vtx.m_Pos[1] = py1;\r
1325                 vtx.m_UV [0] = _Font->m_CharU0[ch];\r
1326                 vtx.m_UV [1] = _Font->m_CharV1[ch];\r
1327                 textVerts[textVtxIndex++] = vtx;\r
1328 \r
1329                 vtx.m_Pos[0] = px1;\r
1330                 vtx.m_Pos[1] = py;\r
1331                 vtx.m_UV [0] = _Font->m_CharU1[ch];\r
1332                 vtx.m_UV [1] = _Font->m_CharV0[ch];\r
1333                 textVerts[textVtxIndex++] = vtx;\r
1334 \r
1335                 vtx.m_Pos[0] = px1;\r
1336                 vtx.m_Pos[1] = py1;\r
1337                 vtx.m_UV [0] = _Font->m_CharU1[ch];\r
1338                 vtx.m_UV [1] = _Font->m_CharV1[ch];\r
1339                 textVerts[textVtxIndex++] = vtx;\r
1340 \r
1341                 vtx.m_Pos[0] = px;\r
1342                 vtx.m_Pos[1] = py1;\r
1343                 vtx.m_UV [0] = _Font->m_CharU0[ch];\r
1344                 vtx.m_UV [1] = _Font->m_CharV1[ch];\r
1345                 textVerts[textVtxIndex++] = vtx;\r
1346 \r
1347                 x = x1;\r
1348             }\r
1349 \r
1350         if( _BgWidth>0 && bgVerts!=NULL )\r
1351         {\r
1352             if( _LineBgColors!=NULL )\r
1353                 bgVtx.m_Color = ToR8G8B8A8(_LineBgColors[line]);\r
1354             else\r
1355                 bgVtx.m_Color = ToR8G8B8A8(COLOR32_BLACK);\r
1356 \r
1357             px  = ToNormScreenX(-1, m_WndWidth);\r
1358             py  = ToNormScreenY(y,  m_WndHeight);\r
1359             px1 = ToNormScreenX(_BgWidth+1, m_WndWidth);\r
1360             py1 = ToNormScreenY(y1, m_WndHeight);\r
1361 \r
1362             bgVtx.m_Pos[0] = px;\r
1363             bgVtx.m_Pos[1] = py;\r
1364             bgVerts[bgVtxIndex++] = bgVtx;\r
1365 \r
1366             bgVtx.m_Pos[0] = px1;\r
1367             bgVtx.m_Pos[1] = py;\r
1368             bgVerts[bgVtxIndex++] = bgVtx;\r
1369 \r
1370             bgVtx.m_Pos[0] = px;\r
1371             bgVtx.m_Pos[1] = py1;\r
1372             bgVerts[bgVtxIndex++] = bgVtx;\r
1373 \r
1374             bgVtx.m_Pos[0] = px1;\r
1375             bgVtx.m_Pos[1] = py;\r
1376             bgVerts[bgVtxIndex++] = bgVtx;\r
1377 \r
1378             bgVtx.m_Pos[0] = px1;\r
1379             bgVtx.m_Pos[1] = py1;\r
1380             bgVerts[bgVtxIndex++] = bgVtx;\r
1381 \r
1382             bgVtx.m_Pos[0] = px;\r
1383             bgVtx.m_Pos[1] = py1;\r
1384             bgVerts[bgVtxIndex++] = bgVtx;\r
1385         }\r
1386     }\r
1387     assert( textVtxIndex==nbTextVerts );\r
1388     assert( bgVtxIndex==nbBgVerts );\r
1389     textObj->m_NbTextVerts = nbTextVerts;\r
1390     textObj->m_NbBgVerts = nbBgVerts;\r
1391 \r
1392     if( textVerts!=NULL )\r
1393         m_D3DDevImmContext->Unmap(textObj->m_TextVertexBuffer, 0);\r
1394     if( bgVerts!=NULL )\r
1395         m_D3DDevImmContext->Unmap(textObj->m_BgVertexBuffer, 0);\r
1396 }\r
1397 \r
1398 //  ---------------------------------------------------------------------------\r
1399 \r
1400 void CTwGraphDirect3D11::DrawText(void *_TextObj, int _X, int _Y, color32 _Color, color32 _BgColor)\r
1401 {\r
1402     assert(m_Drawing==true);\r
1403     assert(_TextObj!=NULL);\r
1404     CTextObj *textObj = static_cast<CTextObj *>(_TextObj);\r
1405     float dx = 2.0f*(float)(_X + m_OffsetX)/m_WndWidth;\r
1406     float dy = -2.0f*(float)(_Y + m_OffsetY)/m_WndHeight;\r
1407 \r
1408     // Draw background\r
1409     if( textObj->m_NbBgVerts>=4 && textObj->m_BgVertexBuffer!=NULL )\r
1410     {\r
1411         // Set offset and constant color\r
1412         D3D11_MAPPED_SUBRESOURCE mappedResource;\r
1413         HRESULT hr = m_D3DDevImmContext->Map(m_ConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);\r
1414         if( SUCCEEDED(hr) )\r
1415         {\r
1416             CConstants *constants = (CConstants *)mappedResource.pData;\r
1417             constants->m_Offset[0] = dx;\r
1418             constants->m_Offset[1] = dy;\r
1419             constants->m_Offset[2] = 0;\r
1420             constants->m_Offset[3] = 0;\r
1421             Color32ToARGBf(_BgColor, constants->m_CstColor+3, constants->m_CstColor+0, constants->m_CstColor+1, constants->m_CstColor+2);\r
1422             m_D3DDevImmContext->Unmap(m_ConstantBuffer, 0);\r
1423         }\r
1424 \r
1425         // Set the input layout\r
1426         m_D3DDevImmContext->IASetInputLayout(m_LineRectVertexLayout);\r
1427 \r
1428         // Set vertex buffer\r
1429         UINT stride = sizeof(CLineRectVtx);\r
1430         UINT offset = 0;\r
1431         m_D3DDevImmContext->IASetVertexBuffers(0, 1, &textObj->m_BgVertexBuffer, &stride, &offset);\r
1432 \r
1433         // Set primitive topology\r
1434         m_D3DDevImmContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);\r
1435 \r
1436         // Render the bg rectangles\r
1437         m_D3DDevImmContext->VSSetConstantBuffers(0, 1, &m_ConstantBuffer);\r
1438         if( _BgColor!=0 || !textObj->m_LineBgColors ) // use a constant bg color\r
1439             m_D3DDevImmContext->VSSetShader(m_LineRectCstColorVS, NULL, 0);\r
1440         else\r
1441             m_D3DDevImmContext->VSSetShader(m_LineRectVS, NULL, 0);\r
1442         m_D3DDevImmContext->PSSetSamplers(0, 1, &m_SamplerState);\r
1443         m_D3DDevImmContext->PSSetShader(m_LineRectPS, NULL, 0);\r
1444         m_D3DDevImmContext->Draw(textObj->m_NbBgVerts, 0);\r
1445     }\r
1446 \r
1447     // Draw text\r
1448     if( textObj->m_NbTextVerts>=4 && textObj->m_TextVertexBuffer!=NULL )\r
1449     {\r
1450         // Set offset and constant color\r
1451         D3D11_MAPPED_SUBRESOURCE mappedResource;\r
1452         HRESULT hr = m_D3DDevImmContext->Map(m_ConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);\r
1453         if( SUCCEEDED(hr) )\r
1454         {\r
1455             CConstants *constants = (CConstants *)mappedResource.pData;\r
1456             constants->m_Offset[0] = dx;\r
1457             constants->m_Offset[1] = dy;\r
1458             constants->m_Offset[2] = 0;\r
1459             constants->m_Offset[3] = 0;\r
1460             Color32ToARGBf(_Color, constants->m_CstColor+3, constants->m_CstColor+0, constants->m_CstColor+1, constants->m_CstColor+2);\r
1461             m_D3DDevImmContext->Unmap(m_ConstantBuffer, 0);\r
1462         }\r
1463 \r
1464         // Set the input layout\r
1465         m_D3DDevImmContext->IASetInputLayout(m_TextVertexLayout);\r
1466 \r
1467         // Set vertex buffer\r
1468         UINT stride = sizeof(CTextVtx);\r
1469         UINT offset = 0;\r
1470         m_D3DDevImmContext->IASetVertexBuffers(0, 1, &textObj->m_TextVertexBuffer, &stride, &offset);\r
1471 \r
1472         // Set primitive topology\r
1473         m_D3DDevImmContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);\r
1474 \r
1475         // Render the text\r
1476         m_D3DDevImmContext->VSSetConstantBuffers(0, 1, &m_ConstantBuffer);\r
1477         if( _Color!=0 || !textObj->m_LineColors ) // use a constant color\r
1478             m_D3DDevImmContext->VSSetShader(m_TextCstColorVS, NULL, 0);\r
1479         else\r
1480             m_D3DDevImmContext->VSSetShader(m_TextVS, NULL, 0);\r
1481         m_D3DDevImmContext->PSSetShaderResources(0, 1, &m_FontD3DTexRV);\r
1482         m_D3DDevImmContext->PSSetSamplers(0, 1, &m_SamplerState);\r
1483         m_D3DDevImmContext->PSSetShader(m_TextPS, NULL, 0);\r
1484         m_D3DDevImmContext->Draw(textObj->m_NbTextVerts, 0);\r
1485     }\r
1486 }\r
1487 \r
1488 //  ---------------------------------------------------------------------------\r
1489 \r
1490 void CTwGraphDirect3D11::ChangeViewport(int _X0, int _Y0, int _Width, int _Height, int _OffsetX, int _OffsetY)\r
1491 {\r
1492     if( _Width>0 && _Height>0 )\r
1493     {\r
1494             /* viewport changes screen coordinates, use scissor instead\r
1495         D3D11_VIEWPORT vp;\r
1496         vp.TopLeftX = _X0;\r
1497         vp.TopLeftY = _Y0;\r
1498         vp.Width = _Width;\r
1499         vp.Height = _Height;\r
1500         vp.MinDepth = 0;\r
1501         vp.MaxDepth = 1;\r
1502         m_D3DDev->RSSetViewports(1, &vp);\r
1503         */\r
1504             \r
1505         m_ViewportAndScissorRects[0].left = _X0;\r
1506         m_ViewportAndScissorRects[0].right = _X0 + _Width - 1;\r
1507         m_ViewportAndScissorRects[0].top = _Y0;\r
1508         m_ViewportAndScissorRects[0].bottom = _Y0 + _Height - 1;\r
1509         if( RectIsFull(m_ViewportAndScissorRects[1]) )\r
1510             m_D3DDevImmContext->RSSetScissorRects(1, m_ViewportAndScissorRects); // viewport clipping only\r
1511         else\r
1512             m_D3DDevImmContext->RSSetScissorRects(2, m_ViewportAndScissorRects);\r
1513 \r
1514         m_OffsetX = _X0 + _OffsetX;\r
1515         m_OffsetY = _Y0 + _OffsetY;\r
1516     }\r
1517 }\r
1518 \r
1519 //  ---------------------------------------------------------------------------\r
1520 \r
1521 void CTwGraphDirect3D11::RestoreViewport()\r
1522 {\r
1523     //m_D3DDevImmContext->RSSetViewports(1, static_cast<D3D11_VIEWPORT *>(m_ViewportInit));\r
1524     m_ViewportAndScissorRects[0] = FullRect;\r
1525     m_D3DDevImmContext->RSSetScissorRects(1, m_ViewportAndScissorRects+1); // scissor only\r
1526         \r
1527     m_OffsetX = m_OffsetY = 0;\r
1528 }\r
1529 \r
1530 //  ---------------------------------------------------------------------------\r
1531 \r
1532 void CTwGraphDirect3D11::SetScissor(int _X0, int _Y0, int _Width, int _Height)\r
1533 {\r
1534     if( _Width>0 && _Height>0 )\r
1535     {\r
1536         m_ViewportAndScissorRects[1].left = _X0 - 2;\r
1537         m_ViewportAndScissorRects[1].right = _X0 + _Width - 3;\r
1538         m_ViewportAndScissorRects[1].top = _Y0 - 1;\r
1539         m_ViewportAndScissorRects[1].bottom = _Y0 + _Height - 1;\r
1540         if( RectIsFull(m_ViewportAndScissorRects[0]) )\r
1541             m_D3DDevImmContext->RSSetScissorRects(1, m_ViewportAndScissorRects+1); // no viewport clipping\r
1542         else\r
1543             m_D3DDevImmContext->RSSetScissorRects(2, m_ViewportAndScissorRects);\r
1544     }\r
1545     else\r
1546     {\r
1547         m_ViewportAndScissorRects[1] = FullRect;\r
1548         m_D3DDevImmContext->RSSetScissorRects(1, m_ViewportAndScissorRects); // apply viewport clipping only\r
1549     }\r
1550 }\r
1551 \r
1552 //  ---------------------------------------------------------------------------\r
1553 \r
1554 void CTwGraphDirect3D11::DrawTriangles(int _NumTriangles, int *_Vertices, color32 *_Colors, Cull _CullMode)\r
1555 {\r
1556     assert(m_Drawing==true);\r
1557 \r
1558     if( _NumTriangles<=0 )\r
1559         return;\r
1560 \r
1561     if( m_TrianglesVertexBufferCount<3*_NumTriangles ) // force re-creation\r
1562     {\r
1563             if( m_TrianglesVertexBuffer!=NULL )\r
1564                 m_TrianglesVertexBuffer->Release();\r
1565         m_TrianglesVertexBuffer = NULL;\r
1566         m_TrianglesVertexBufferCount = 0;\r
1567     }\r
1568 \r
1569     // DrawTriangles uses LineRect layout and shaders\r
1570 \r
1571     if( m_TrianglesVertexBuffer==NULL )\r
1572     {\r
1573         // Create triangles vertex buffer\r
1574         D3D11_BUFFER_DESC bd;\r
1575         bd.Usage = D3D11_USAGE_DYNAMIC;\r
1576         bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;\r
1577         bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\r
1578         bd.MiscFlags = 0;\r
1579         bd.ByteWidth = 3*_NumTriangles * sizeof(CLineRectVtx);\r
1580         bd.StructureByteStride = 0;\r
1581         HRESULT hr = m_D3DDev->CreateBuffer(&bd, NULL, &m_TrianglesVertexBuffer);\r
1582         if( SUCCEEDED(hr) )\r
1583             m_TrianglesVertexBufferCount = 3*_NumTriangles;\r
1584         else\r
1585         {\r
1586             m_TrianglesVertexBuffer = NULL;\r
1587             m_TrianglesVertexBufferCount = 0;\r
1588             return; // Problem: cannot create triangles VB\r
1589         }\r
1590     }\r
1591     assert( m_TrianglesVertexBufferCount>=3*_NumTriangles );\r
1592     assert( m_TrianglesVertexBuffer!=NULL );\r
1593 \r
1594     D3D11_MAPPED_SUBRESOURCE mappedResource;\r
1595     HRESULT hr = m_D3DDevImmContext->Map(m_TrianglesVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);\r
1596     if( SUCCEEDED(hr) )\r
1597     {\r
1598         CLineRectVtx *vertices = (CLineRectVtx *)mappedResource.pData;\r
1599         // Fill vertex buffer\r
1600         for( int i=0; i<3*_NumTriangles; ++ i )\r
1601         {\r
1602             vertices[i].m_Pos[0] = ToNormScreenX(_Vertices[2*i+0] + m_OffsetX, m_WndWidth);\r
1603             vertices[i].m_Pos[1] = ToNormScreenY(_Vertices[2*i+1] + m_OffsetY, m_WndHeight);\r
1604             vertices[i].m_Pos[2] = 0;\r
1605             vertices[i].m_Color = ToR8G8B8A8(_Colors[i]);\r
1606         }\r
1607         m_D3DDevImmContext->Unmap(m_TrianglesVertexBuffer, 0);\r
1608 \r
1609         // Reset shader constants\r
1610         hr = m_D3DDevImmContext->Map(m_ConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);\r
1611         if( SUCCEEDED(hr) )\r
1612         {\r
1613             CConstants *constants = (CConstants *)mappedResource.pData;\r
1614             constants->m_Offset[0] = 0;\r
1615             constants->m_Offset[1] = 0;\r
1616             constants->m_Offset[2] = 0;\r
1617             constants->m_Offset[3] = 0;\r
1618             constants->m_CstColor[0] = 1;\r
1619             constants->m_CstColor[1] = 1;\r
1620             constants->m_CstColor[2] = 1;\r
1621             constants->m_CstColor[3] = 1;\r
1622             m_D3DDevImmContext->Unmap(m_ConstantBuffer, 0);\r
1623         }\r
1624 \r
1625         // Set the input layout\r
1626         m_D3DDevImmContext->IASetInputLayout(m_LineRectVertexLayout);\r
1627 \r
1628         // Set vertex buffer\r
1629         UINT stride = sizeof(CLineRectVtx);\r
1630         UINT offset = 0;\r
1631         m_D3DDevImmContext->IASetVertexBuffers(0, 1, &m_TrianglesVertexBuffer, &stride, &offset);\r
1632 \r
1633         // Set primitive topology\r
1634         m_D3DDevImmContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);\r
1635 \r
1636         if( _CullMode==CULL_CW )\r
1637             m_D3DDevImmContext->RSSetState(m_RasterStateCullCW);\r
1638         else if( _CullMode==CULL_CCW )\r
1639             m_D3DDevImmContext->RSSetState(m_RasterStateCullCCW);\r
1640         else \r
1641             m_D3DDevImmContext->RSSetState(m_RasterStateMultisample);\r
1642 \r
1643         // Render the triangles\r
1644         m_D3DDevImmContext->VSSetConstantBuffers(0, 1, &m_ConstantBuffer);\r
1645         m_D3DDevImmContext->VSSetShader(m_LineRectVS, NULL, 0);\r
1646         m_D3DDevImmContext->PSSetShader(m_LineRectPS, NULL, 0);\r
1647         m_D3DDevImmContext->Draw(3*_NumTriangles, 0);\r
1648 \r
1649         m_D3DDevImmContext->RSSetState(m_RasterState); // restore default raster state\r
1650     }\r
1651 }\r
1652 \r
1653 //  ---------------------------------------------------------------------------\r