1 /*
2 * Nuklear - 1.32.0 - public domain
3 * no warrenty implied; use at your own risk.
4 * authored from 2015-2016 by Micha Mettke
5 */
6 /*
7 * ==============================================================
8 *
9 * API
10 *
11 * ===============================================================
12 */
13 #ifndef NK_D3D11_H_
14 #define NK_D3D11_H_
15
16 #define WIN32_LEAN_AND_MEAN
17 #include <windows.h>
18
19 typedef struct ID3D11Device ID3D11Device;
20 typedef struct ID3D11DeviceContext ID3D11DeviceContext;
21
22 NK_API struct nk_context *nk_d3d11_init(ID3D11Device *device, int width, int height, unsigned int max_vertex_buffer, unsigned int max_index_buffer);
23 NK_API void nk_d3d11_font_stash_begin(struct nk_font_atlas **atlas);
24 NK_API void nk_d3d11_font_stash_end(void);
25 NK_API int nk_d3d11_handle_event(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
26 NK_API void nk_d3d11_render(ID3D11DeviceContext *context, enum nk_anti_aliasing);
27 NK_API void nk_d3d11_resize(ID3D11DeviceContext *context, int width, int height);
28 NK_API void nk_d3d11_shutdown(void);
29
30 #endif
31 /*
32 * ==============================================================
33 *
34 * IMPLEMENTATION
35 *
36 * ===============================================================
37 */
38 #ifdef NK_D3D11_IMPLEMENTATION
39
40 #define WIN32_LEAN_AND_MEAN
41 #define COBJMACROS
42 #include <d3d11.h>
43
44 #include <stddef.h>
45 #include <string.h>
46 #include <float.h>
47 #include <assert.h>
48
49 #include "nuklear_d3d11_vertex_shader.h"
50 #include "nuklear_d3d11_pixel_shader.h"
51
52 struct nk_d3d11_vertex {
53 float position[2];
54 float uv[2];
55 nk_byte col[4];
56 };
57
58 static struct
59 {
60 struct nk_context ctx;
61 struct nk_font_atlas atlas;
62 struct nk_buffer cmds;
63
64 struct nk_draw_null_texture null;
65 unsigned int max_vertex_buffer;
66 unsigned int max_index_buffer;
67
68 D3D11_VIEWPORT viewport;
69 ID3D11Device *device;
70 ID3D11RasterizerState *rasterizer_state;
71 ID3D11VertexShader *vertex_shader;
72 ID3D11InputLayout *input_layout;
73 ID3D11Buffer *const_buffer;
74 ID3D11PixelShader *pixel_shader;
75 ID3D11BlendState *blend_state;
76 ID3D11Buffer *index_buffer;
77 ID3D11Buffer *vertex_buffer;
78 ID3D11ShaderResourceView *font_texture_view;
79 ID3D11SamplerState *sampler_state;
80 } d3d11;
81
82 NK_API void
nk_d3d11_render(ID3D11DeviceContext * context,enum nk_anti_aliasing AA)83 nk_d3d11_render(ID3D11DeviceContext *context, enum nk_anti_aliasing AA)
84 {
85 const float blend_factor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
86 const UINT stride = sizeof(struct nk_d3d11_vertex);
87 const UINT offset = 0;
88 #ifdef NK_UINT_DRAW_INDEX
89 DXGI_FORMAT index_buffer_format = DXGI_FORMAT_R32_UINT;
90 #else
91 DXGI_FORMAT index_buffer_format = DXGI_FORMAT_R16_UINT;
92 #endif
93
94 ID3D11DeviceContext_IASetInputLayout(context, d3d11.input_layout);
95 ID3D11DeviceContext_IASetVertexBuffers(context, 0, 1, &d3d11.vertex_buffer, &stride, &offset);
96 ID3D11DeviceContext_IASetIndexBuffer(context, d3d11.index_buffer, index_buffer_format, 0);
97 ID3D11DeviceContext_IASetPrimitiveTopology(context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
98
99 ID3D11DeviceContext_VSSetShader(context, d3d11.vertex_shader, NULL, 0);
100 ID3D11DeviceContext_VSSetConstantBuffers(context, 0, 1, &d3d11.const_buffer);
101
102 ID3D11DeviceContext_PSSetShader(context, d3d11.pixel_shader, NULL, 0);
103 ID3D11DeviceContext_PSSetSamplers(context, 0, 1, &d3d11.sampler_state);
104
105 ID3D11DeviceContext_OMSetBlendState(context, d3d11.blend_state, blend_factor, 0xffffffff);
106 ID3D11DeviceContext_RSSetState(context, d3d11.rasterizer_state);
107 ID3D11DeviceContext_RSSetViewports(context, 1, &d3d11.viewport);
108
109 /* Convert from command queue into draw list and draw to screen */
110 {/* load draw vertices & elements directly into vertex + element buffer */
111 D3D11_MAPPED_SUBRESOURCE vertices;
112 D3D11_MAPPED_SUBRESOURCE indices;
113 const struct nk_draw_command *cmd;
114 UINT offset = 0;
115 HRESULT hr;
116
117 hr = ID3D11DeviceContext_Map(context, (ID3D11Resource *)d3d11.vertex_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &vertices);
118 NK_ASSERT(SUCCEEDED(hr));
119 hr = ID3D11DeviceContext_Map(context, (ID3D11Resource *)d3d11.index_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &indices);
120 NK_ASSERT(SUCCEEDED(hr));
121
122 {/* fill converting configuration */
123 struct nk_convert_config config;
124 NK_STORAGE const struct nk_draw_vertex_layout_element vertex_layout[] = {
125 {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_d3d11_vertex, position)},
126 {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_d3d11_vertex, uv)},
127 {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_d3d11_vertex, col)},
128 {NK_VERTEX_LAYOUT_END}
129 };
130 memset(&config, 0, sizeof(config));
131 config.vertex_layout = vertex_layout;
132 config.vertex_size = sizeof(struct nk_d3d11_vertex);
133 config.vertex_alignment = NK_ALIGNOF(struct nk_d3d11_vertex);
134 config.global_alpha = 1.0f;
135 config.shape_AA = AA;
136 config.line_AA = AA;
137 config.circle_segment_count = 22;
138 config.curve_segment_count = 22;
139 config.arc_segment_count = 22;
140 config.null = d3d11.null;
141
142 {/* setup buffers to load vertices and elements */
143 struct nk_buffer vbuf, ibuf;
144 nk_buffer_init_fixed(&vbuf, vertices.pData, (size_t)d3d11.max_vertex_buffer);
145 nk_buffer_init_fixed(&ibuf, indices.pData, (size_t)d3d11.max_index_buffer);
146 nk_convert(&d3d11.ctx, &d3d11.cmds, &vbuf, &ibuf, &config);}
147 }
148
149 ID3D11DeviceContext_Unmap(context, (ID3D11Resource *)d3d11.vertex_buffer, 0);
150 ID3D11DeviceContext_Unmap(context, (ID3D11Resource *)d3d11.index_buffer, 0);
151
152 /* iterate over and execute each draw command */
153 nk_draw_foreach(cmd, &d3d11.ctx, &d3d11.cmds)
154 {
155 D3D11_RECT scissor;
156 ID3D11ShaderResourceView *texture_view = (ID3D11ShaderResourceView *)cmd->texture.ptr;
157 if (!cmd->elem_count) continue;
158
159 scissor.left = (LONG)cmd->clip_rect.x;
160 scissor.right = (LONG)(cmd->clip_rect.x + cmd->clip_rect.w);
161 scissor.top = (LONG)cmd->clip_rect.y;
162 scissor.bottom = (LONG)(cmd->clip_rect.y + cmd->clip_rect.h);
163
164 ID3D11DeviceContext_PSSetShaderResources(context, 0, 1, &texture_view);
165 ID3D11DeviceContext_RSSetScissorRects(context, 1, &scissor);
166 ID3D11DeviceContext_DrawIndexed(context, (UINT)cmd->elem_count, offset, 0);
167 offset += cmd->elem_count;
168 }
169 nk_clear(&d3d11.ctx);
170 nk_buffer_clear(&d3d11.cmds);}
171 }
172
173 static void
nk_d3d11_get_projection_matrix(int width,int height,float * result)174 nk_d3d11_get_projection_matrix(int width, int height, float *result)
175 {
176 const float L = 0.0f;
177 const float R = (float)width;
178 const float T = 0.0f;
179 const float B = (float)height;
180 float matrix[4][4] =
181 {
182 { 0.0f, 0.0f, 0.0f, 0.0f },
183 { 0.0f, 0.0f, 0.0f, 0.0f },
184 { 0.0f, 0.0f, 0.5f, 0.0f },
185 { 0.0f, 0.0f, 0.5f, 1.0f },
186 };
187 matrix[0][0] = 2.0f / (R - L);
188 matrix[1][1] = 2.0f / (T - B);
189 matrix[3][0] = (R + L) / (L - R);
190 matrix[3][1] = (T + B) / (B - T);
191 memcpy(result, matrix, sizeof(matrix));
192 }
193
194 NK_API void
nk_d3d11_resize(ID3D11DeviceContext * context,int width,int height)195 nk_d3d11_resize(ID3D11DeviceContext *context, int width, int height)
196 {
197 D3D11_MAPPED_SUBRESOURCE mapped;
198 if (SUCCEEDED(ID3D11DeviceContext_Map(context, (ID3D11Resource *)d3d11.const_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)))
199 {
200 nk_d3d11_get_projection_matrix(width, height, (float *)mapped.pData);
201 ID3D11DeviceContext_Unmap(context, (ID3D11Resource *)d3d11.const_buffer, 0);
202
203 d3d11.viewport.Width = (float)width;
204 d3d11.viewport.Height = (float)height;
205 }
206 }
207
208 NK_API int
nk_d3d11_handle_event(HWND wnd,UINT msg,WPARAM wparam,LPARAM lparam)209 nk_d3d11_handle_event(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
210 {
211 switch (msg)
212 {
213 case WM_KEYDOWN:
214 case WM_KEYUP:
215 case WM_SYSKEYDOWN:
216 case WM_SYSKEYUP:
217 {
218 int down = !((lparam >> 31) & 1);
219 int ctrl = GetKeyState(VK_CONTROL) & (1 << 15);
220
221 switch (wparam)
222 {
223 case VK_SHIFT:
224 case VK_LSHIFT:
225 case VK_RSHIFT:
226 nk_input_key(&d3d11.ctx, NK_KEY_SHIFT, down);
227 return 1;
228
229 case VK_DELETE:
230 nk_input_key(&d3d11.ctx, NK_KEY_DEL, down);
231 return 1;
232
233 case VK_RETURN:
234 nk_input_key(&d3d11.ctx, NK_KEY_ENTER, down);
235 return 1;
236
237 case VK_TAB:
238 nk_input_key(&d3d11.ctx, NK_KEY_TAB, down);
239 return 1;
240
241 case VK_LEFT:
242 if (ctrl)
243 nk_input_key(&d3d11.ctx, NK_KEY_TEXT_WORD_LEFT, down);
244 else
245 nk_input_key(&d3d11.ctx, NK_KEY_LEFT, down);
246 return 1;
247
248 case VK_RIGHT:
249 if (ctrl)
250 nk_input_key(&d3d11.ctx, NK_KEY_TEXT_WORD_RIGHT, down);
251 else
252 nk_input_key(&d3d11.ctx, NK_KEY_RIGHT, down);
253 return 1;
254
255 case VK_BACK:
256 nk_input_key(&d3d11.ctx, NK_KEY_BACKSPACE, down);
257 return 1;
258
259 case VK_HOME:
260 nk_input_key(&d3d11.ctx, NK_KEY_TEXT_START, down);
261 nk_input_key(&d3d11.ctx, NK_KEY_SCROLL_START, down);
262 return 1;
263
264 case VK_END:
265 nk_input_key(&d3d11.ctx, NK_KEY_TEXT_END, down);
266 nk_input_key(&d3d11.ctx, NK_KEY_SCROLL_END, down);
267 return 1;
268
269 case VK_NEXT:
270 nk_input_key(&d3d11.ctx, NK_KEY_SCROLL_DOWN, down);
271 return 1;
272
273 case VK_PRIOR:
274 nk_input_key(&d3d11.ctx, NK_KEY_SCROLL_UP, down);
275 return 1;
276
277 case 'C':
278 if (ctrl) {
279 nk_input_key(&d3d11.ctx, NK_KEY_COPY, down);
280 return 1;
281 }
282 break;
283
284 case 'V':
285 if (ctrl) {
286 nk_input_key(&d3d11.ctx, NK_KEY_PASTE, down);
287 return 1;
288 }
289 break;
290
291 case 'X':
292 if (ctrl) {
293 nk_input_key(&d3d11.ctx, NK_KEY_CUT, down);
294 return 1;
295 }
296 break;
297
298 case 'Z':
299 if (ctrl) {
300 nk_input_key(&d3d11.ctx, NK_KEY_TEXT_UNDO, down);
301 return 1;
302 }
303 break;
304
305 case 'R':
306 if (ctrl) {
307 nk_input_key(&d3d11.ctx, NK_KEY_TEXT_REDO, down);
308 return 1;
309 }
310 break;
311 }
312 return 0;
313 }
314
315 case WM_CHAR:
316 if (wparam >= 32)
317 {
318 nk_input_unicode(&d3d11.ctx, (nk_rune)wparam);
319 return 1;
320 }
321 break;
322
323 case WM_LBUTTONDOWN:
324 nk_input_button(&d3d11.ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
325 SetCapture(wnd);
326 return 1;
327
328 case WM_LBUTTONUP:
329 nk_input_button(&d3d11.ctx, NK_BUTTON_DOUBLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
330 nk_input_button(&d3d11.ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
331 ReleaseCapture();
332 return 1;
333
334 case WM_RBUTTONDOWN:
335 nk_input_button(&d3d11.ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
336 SetCapture(wnd);
337 return 1;
338
339 case WM_RBUTTONUP:
340 nk_input_button(&d3d11.ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
341 ReleaseCapture();
342 return 1;
343
344 case WM_MBUTTONDOWN:
345 nk_input_button(&d3d11.ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
346 SetCapture(wnd);
347 return 1;
348
349 case WM_MBUTTONUP:
350 nk_input_button(&d3d11.ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
351 ReleaseCapture();
352 return 1;
353
354 case WM_MOUSEWHEEL:
355 nk_input_scroll(&d3d11.ctx, nk_vec2(0,(float)(short)HIWORD(wparam) / WHEEL_DELTA));
356 return 1;
357
358 case WM_MOUSEMOVE:
359 nk_input_motion(&d3d11.ctx, (short)LOWORD(lparam), (short)HIWORD(lparam));
360 return 1;
361
362 case WM_LBUTTONDBLCLK:
363 nk_input_button(&d3d11.ctx, NK_BUTTON_DOUBLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
364 return 1;
365 }
366
367 return 0;
368 }
369
370 static void
nk_d3d11_clipboard_paste(nk_handle usr,struct nk_text_edit * edit)371 nk_d3d11_clipboard_paste(nk_handle usr, struct nk_text_edit *edit)
372 {
373 (void)usr;
374 if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL))
375 {
376 HGLOBAL mem = GetClipboardData(CF_UNICODETEXT);
377 if (mem)
378 {
379 SIZE_T size = GlobalSize(mem) - 1;
380 if (size)
381 {
382 LPCWSTR wstr = (LPCWSTR)GlobalLock(mem);
383 if (wstr)
384 {
385 int utf8size = WideCharToMultiByte(CP_UTF8, 0, wstr, size / sizeof(wchar_t), NULL, 0, NULL, NULL);
386 if (utf8size)
387 {
388 char* utf8 = (char*)malloc(utf8size);
389 if (utf8)
390 {
391 WideCharToMultiByte(CP_UTF8, 0, wstr, size / sizeof(wchar_t), utf8, utf8size, NULL, NULL);
392 nk_textedit_paste(edit, utf8, utf8size);
393 free(utf8);
394 }
395 }
396 GlobalUnlock(mem);
397 }
398 }
399 }
400 CloseClipboard();
401 }
402 }
403
404 static void
nk_d3d11_clipboard_copy(nk_handle usr,const char * text,int len)405 nk_d3d11_clipboard_copy(nk_handle usr, const char *text, int len)
406 {
407 (void)usr;
408 if (OpenClipboard(NULL))
409 {
410 int wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0);
411 if (wsize)
412 {
413 HGLOBAL mem = GlobalAlloc(GMEM_MOVEABLE, (wsize + 1) * sizeof(wchar_t));
414 if (mem)
415 {
416 wchar_t* wstr = (wchar_t*)GlobalLock(mem);
417 if (wstr)
418 {
419 MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize);
420 wstr[wsize] = 0;
421 GlobalUnlock(mem);
422 SetClipboardData(CF_UNICODETEXT, mem);
423 }
424 }
425 }
426 CloseClipboard();
427 }
428 }
429
430 NK_API struct nk_context*
nk_d3d11_init(ID3D11Device * device,int width,int height,unsigned int max_vertex_buffer,unsigned int max_index_buffer)431 nk_d3d11_init(ID3D11Device *device, int width, int height, unsigned int max_vertex_buffer, unsigned int max_index_buffer)
432 {
433 HRESULT hr;
434 d3d11.max_vertex_buffer = max_vertex_buffer;
435 d3d11.max_index_buffer = max_index_buffer;
436 d3d11.device = device;
437 ID3D11Device_AddRef(device);
438
439 nk_init_default(&d3d11.ctx, 0);
440 d3d11.ctx.clip.copy = nk_d3d11_clipboard_copy;
441 d3d11.ctx.clip.paste = nk_d3d11_clipboard_paste;
442 d3d11.ctx.clip.userdata = nk_handle_ptr(0);
443
444 nk_buffer_init_default(&d3d11.cmds);
445
446 {/* rasterizer state */
447 D3D11_RASTERIZER_DESC desc;
448 memset(&desc, 0, sizeof(desc));
449 desc.FillMode = D3D11_FILL_SOLID;
450 desc.CullMode = D3D11_CULL_NONE;
451 desc.FrontCounterClockwise = FALSE;
452 desc.DepthBias = 0;
453 desc.DepthBiasClamp = 0;
454 desc.SlopeScaledDepthBias = 0.0f;
455 desc.DepthClipEnable = TRUE;
456 desc.ScissorEnable = TRUE;
457 desc.MultisampleEnable = FALSE;
458 desc.AntialiasedLineEnable = FALSE;
459 hr = ID3D11Device_CreateRasterizerState(device,&desc, &d3d11.rasterizer_state);
460 NK_ASSERT(SUCCEEDED(hr));}
461
462 /* vertex shader */
463 {hr = ID3D11Device_CreateVertexShader(device,nk_d3d11_vertex_shader, sizeof(nk_d3d11_vertex_shader), NULL, &d3d11.vertex_shader);
464 NK_ASSERT(SUCCEEDED(hr));}
465
466 /* input layout */
467 {const D3D11_INPUT_ELEMENT_DESC layout[] = {
468 { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(struct nk_d3d11_vertex, position), D3D11_INPUT_PER_VERTEX_DATA, 0 },
469 { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(struct nk_d3d11_vertex, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
470 { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(struct nk_d3d11_vertex, col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
471 };
472 hr = ID3D11Device_CreateInputLayout(device,layout, ARRAYSIZE(layout), nk_d3d11_vertex_shader, sizeof(nk_d3d11_vertex_shader), &d3d11.input_layout);
473 NK_ASSERT(SUCCEEDED(hr));}
474
475 /* constant buffer */
476 {float matrix[4*4];
477 D3D11_BUFFER_DESC desc;
478 memset(&desc, 0, sizeof(desc));
479 desc.ByteWidth = sizeof(matrix);
480 desc.Usage = D3D11_USAGE_DYNAMIC;
481 desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
482 desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
483 desc.MiscFlags = 0;
484
485 {D3D11_SUBRESOURCE_DATA data;
486 data.pSysMem = matrix;
487 data.SysMemPitch = 0;
488 data.SysMemSlicePitch = 0;
489
490 nk_d3d11_get_projection_matrix(width, height, matrix);
491 hr = ID3D11Device_CreateBuffer(device, &desc, &data, &d3d11.const_buffer);
492 NK_ASSERT(SUCCEEDED(hr));}}
493
494 /* pixel shader */
495 {hr = ID3D11Device_CreatePixelShader(device, nk_d3d11_pixel_shader, sizeof(nk_d3d11_pixel_shader), NULL, &d3d11.pixel_shader);
496 NK_ASSERT(SUCCEEDED(hr));}
497
498 {/* blend state */
499 D3D11_BLEND_DESC desc;
500 memset(&desc, 0, sizeof(desc));
501 desc.AlphaToCoverageEnable = FALSE;
502 desc.RenderTarget[0].BlendEnable = TRUE;
503 desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
504 desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
505 desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
506 desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
507 desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
508 desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
509 desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
510 hr = ID3D11Device_CreateBlendState(device, &desc, &d3d11.blend_state);
511 NK_ASSERT(SUCCEEDED(hr));}
512
513 /* vertex buffer */
514 {D3D11_BUFFER_DESC desc;
515 memset(&desc, 0, sizeof(desc));
516 desc.Usage = D3D11_USAGE_DYNAMIC;
517 desc.ByteWidth = max_vertex_buffer;
518 desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
519 desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
520 desc.MiscFlags = 0;
521 hr = ID3D11Device_CreateBuffer(device, &desc, NULL, &d3d11.vertex_buffer);
522 NK_ASSERT(SUCCEEDED(hr));}
523
524 /* index buffer */
525 {D3D11_BUFFER_DESC desc;
526 memset(&desc, 0, sizeof(desc));
527 desc.Usage = D3D11_USAGE_DYNAMIC;
528 desc.ByteWidth = max_index_buffer;
529 desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
530 desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
531 hr = ID3D11Device_CreateBuffer(device, &desc, NULL, &d3d11.index_buffer);
532 NK_ASSERT(SUCCEEDED(hr));}
533
534 /* sampler state */
535 {D3D11_SAMPLER_DESC desc;
536 memset(&desc, 0, sizeof(desc));
537 desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
538 desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
539 desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
540 desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
541 desc.MipLODBias = 0.0f;
542 desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
543 desc.MinLOD = 0.0f;
544 desc.MaxLOD = FLT_MAX;
545 hr = ID3D11Device_CreateSamplerState(device, &desc, &d3d11.sampler_state);
546 NK_ASSERT(SUCCEEDED(hr));}
547
548 /* viewport */
549 {d3d11.viewport.TopLeftX = 0.0f;
550 d3d11.viewport.TopLeftY = 0.0f;
551 d3d11.viewport.Width = (float)width;
552 d3d11.viewport.Height = (float)height;
553 d3d11.viewport.MinDepth = 0.0f;
554 d3d11.viewport.MaxDepth = 1.0f;}
555 return &d3d11.ctx;
556 }
557
558 NK_API void
nk_d3d11_font_stash_begin(struct nk_font_atlas ** atlas)559 nk_d3d11_font_stash_begin(struct nk_font_atlas **atlas)
560 {
561 nk_font_atlas_init_default(&d3d11.atlas);
562 nk_font_atlas_begin(&d3d11.atlas);
563 *atlas = &d3d11.atlas;
564 }
565
566 NK_API void
nk_d3d11_font_stash_end(void)567 nk_d3d11_font_stash_end(void)
568 {
569 const void *image; int w, h;
570 image = nk_font_atlas_bake(&d3d11.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
571
572 /* upload font to texture and create texture view */
573 {ID3D11Texture2D *font_texture;
574 HRESULT hr;
575
576 D3D11_TEXTURE2D_DESC desc;
577 memset(&desc, 0, sizeof(desc));
578 desc.Width = (UINT)w;
579 desc.Height = (UINT)h;
580 desc.MipLevels = 1;
581 desc.ArraySize = 1;
582 desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
583 desc.SampleDesc.Count = 1;
584 desc.SampleDesc.Quality = 0;
585 desc.Usage = D3D11_USAGE_DEFAULT;
586 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
587 desc.CPUAccessFlags = 0;
588
589 {D3D11_SUBRESOURCE_DATA data;
590 data.pSysMem = image;
591 data.SysMemPitch = (UINT)(w * 4);
592 data.SysMemSlicePitch = 0;
593 hr = ID3D11Device_CreateTexture2D(d3d11.device, &desc, &data, &font_texture);
594 assert(SUCCEEDED(hr));}
595
596 {D3D11_SHADER_RESOURCE_VIEW_DESC srv;
597 memset(&srv, 0, sizeof(srv));
598 srv.Format = desc.Format;
599 srv.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
600 srv.Texture2D.MipLevels = 1;
601 srv.Texture2D.MostDetailedMip = 0;
602 hr = ID3D11Device_CreateShaderResourceView(d3d11.device, (ID3D11Resource *)font_texture, &srv, &d3d11.font_texture_view);
603 assert(SUCCEEDED(hr));}
604 ID3D11Texture2D_Release(font_texture);}
605
606 nk_font_atlas_end(&d3d11.atlas, nk_handle_ptr(d3d11.font_texture_view), &d3d11.null);
607 if (d3d11.atlas.default_font)
608 nk_style_set_font(&d3d11.ctx, &d3d11.atlas.default_font->handle);
609 }
610
611 NK_API
nk_d3d11_shutdown(void)612 void nk_d3d11_shutdown(void)
613 {
614 nk_font_atlas_clear(&d3d11.atlas);
615 nk_buffer_free(&d3d11.cmds);
616 nk_free(&d3d11.ctx);
617
618 ID3D11SamplerState_Release(d3d11.sampler_state);
619 ID3D11ShaderResourceView_Release(d3d11.font_texture_view);
620 ID3D11Buffer_Release(d3d11.vertex_buffer);
621 ID3D11Buffer_Release(d3d11.index_buffer);
622 ID3D11BlendState_Release(d3d11.blend_state);
623 ID3D11PixelShader_Release(d3d11.pixel_shader);
624 ID3D11Buffer_Release(d3d11.const_buffer);
625 ID3D11VertexShader_Release(d3d11.vertex_shader);
626 ID3D11InputLayout_Release(d3d11.input_layout);
627 ID3D11RasterizerState_Release(d3d11.rasterizer_state);
628 ID3D11Device_Release(d3d11.device);
629 }
630
631 #endif
632
633