Explorar el Código

Removed bgfx::setPlatformData usage from entry example harness.

Бранимир Караџић hace 3 años
padre
commit
72cbe83275
Se han modificado 65 ficheros con 2339 adiciones y 2425 borrados
  1. 2 0
      examples/00-helloworld/helloworld.cpp
  2. 2 0
      examples/01-cubes/cubes.cpp
  3. 2 0
      examples/02-metaballs/metaballs.cpp
  4. 2 0
      examples/03-raymarch/raymarch.cpp
  5. 2 0
      examples/04-mesh/mesh.cpp
  6. 2 0
      examples/05-instancing/instancing.cpp
  7. 2 0
      examples/06-bump/bump.cpp
  8. 2 0
      examples/07-callback/callback.cpp
  9. 2 0
      examples/08-update/update.cpp
  10. 2 0
      examples/09-hdr/hdr.cpp
  11. 2 0
      examples/10-font/font.cpp
  12. 2 0
      examples/11-fontsdf/fontsdf.cpp
  13. 2 0
      examples/12-lod/lod.cpp
  14. 2 0
      examples/13-stencil/stencil.cpp
  15. 2 0
      examples/14-shadowvolumes/shadowvolumes.cpp
  16. 2 0
      examples/15-shadowmaps-simple/shadowmaps_simple.cpp
  17. 2 0
      examples/16-shadowmaps/shadowmaps.cpp
  18. 2 0
      examples/17-drawstress/drawstress.cpp
  19. 2 0
      examples/18-ibl/ibl.cpp
  20. 2 0
      examples/19-oit/oit.cpp
  21. 2 0
      examples/20-nanovg/nanovg.cpp
  22. 2 0
      examples/21-deferred/deferred.cpp
  23. 2 0
      examples/22-windows/windows.cpp
  24. 2 0
      examples/23-vectordisplay/main.cpp
  25. 2 0
      examples/24-nbody/nbody.cpp
  26. 5 0
      examples/25-c99/helloworld.c
  27. 2 0
      examples/26-occlusion/occlusion.cpp
  28. 2 0
      examples/27-terrain/terrain.cpp
  29. 2 0
      examples/28-wireframe/wireframe.cpp
  30. 2 0
      examples/29-debugdraw/debugdraw.cpp
  31. 2 0
      examples/30-picking/picking.cpp
  32. 2 0
      examples/31-rsm/reflectiveshadowmap.cpp
  33. 2 0
      examples/32-particles/particles.cpp
  34. 2 0
      examples/33-pom/pom.cpp
  35. 2 0
      examples/34-mvs/mvs.cpp
  36. 2 0
      examples/35-dynamic/dynamic.cpp
  37. 485 483
      examples/36-sky/sky.cpp
  38. 2 0
      examples/37-gpudrivenrendering/gpudrivenrendering.cpp
  39. 2 1
      examples/38-bloom/bloom.cpp
  40. 5 4
      examples/39-assao/assao.cpp
  41. 5 4
      examples/40-svt/svt.cpp
  42. 758 757
      examples/41-tess/tess.cpp
  43. 2 0
      examples/42-bunnylod/bunnylod.cpp
  44. 4 3
      examples/43-denoise/denoise.cpp
  45. 11 9
      examples/44-sss/screen_space_shadows.cpp
  46. 5 4
      examples/45-bokeh/bokeh.cpp
  47. 640 639
      examples/46-fsr/app.cpp
  48. 13 8
      examples/47-pixelformats/pixelformats.cpp
  49. 50 17
      examples/common/entry/entry.cpp
  50. 50 9
      examples/common/entry/entry.h
  51. 15 15
      examples/common/entry/entry_android.cpp
  52. 40 44
      examples/common/entry/entry_glfw.cpp
  53. 25 17
      examples/common/entry/entry_html5.cpp
  54. 22 17
      examples/common/entry/entry_ios.mm
  55. 11 0
      examples/common/entry/entry_noop.cpp
  56. 10 14
      examples/common/entry/entry_osx.mm
  57. 25 30
      examples/common/entry/entry_sdl.cpp
  58. 10 11
      examples/common/entry/entry_windows.cpp
  59. 0 237
      examples/common/entry/entry_winrt.cx
  60. 54 59
      examples/common/entry/entry_x11.cpp
  61. 2 2
      examples/common/entry/input.cpp
  62. 2 14
      src/bgfx.cpp
  63. 6 19
      src/renderer_gl.cpp
  64. 5 4
      tools/geometryv/geometryv.cpp
  65. 5 4
      tools/texturev/texturev.cpp

+ 2 - 0
examples/00-helloworld/helloworld.cpp

@@ -32,6 +32,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/01-cubes/cubes.cpp

@@ -147,6 +147,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/02-metaballs/metaballs.cpp

@@ -506,6 +506,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/03-raymarch/raymarch.cpp

@@ -119,6 +119,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/04-mesh/mesh.cpp

@@ -30,6 +30,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/05-instancing/instancing.cpp

@@ -82,6 +82,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/06-bump/bump.cpp

@@ -102,6 +102,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/07-callback/callback.cpp

@@ -329,6 +329,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/08-update/update.cpp

@@ -245,6 +245,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/09-hdr/hdr.cpp

@@ -157,6 +157,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/10-font/font.cpp

@@ -71,6 +71,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/11-fontsdf/fontsdf.cpp

@@ -54,6 +54,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/12-lod/lod.cpp

@@ -46,6 +46,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/13-stencil/stencil.cpp

@@ -812,6 +812,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_viewState.m_width;
 		init.resolution.height = m_viewState.m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/14-shadowvolumes/shadowvolumes.cpp

@@ -1784,6 +1784,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_viewState.m_width;
 		init.resolution.height = m_viewState.m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/15-shadowmaps-simple/shadowmaps_simple.cpp

@@ -78,6 +78,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/16-shadowmaps/shadowmaps.cpp

@@ -1157,6 +1157,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_viewState.m_width;
 		init.resolution.height = m_viewState.m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/17-drawstress/drawstress.cpp

@@ -129,6 +129,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/18-ibl/ibl.cpp

@@ -418,6 +418,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/19-oit/oit.cpp

@@ -169,6 +169,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/20-nanovg/nanovg.cpp

@@ -1402,6 +1402,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/21-deferred/deferred.cpp

@@ -211,6 +211,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/22-windows/windows.cpp

@@ -86,6 +86,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/23-vectordisplay/main.cpp

@@ -53,6 +53,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/24-nbody/nbody.cpp

@@ -130,6 +130,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 5 - 0
examples/25-c99/helloworld.c

@@ -7,6 +7,8 @@
 #include "../00-helloworld/logo.h"
 
 extern bool entry_process_events(uint32_t* _width, uint32_t* _height, uint32_t* _debug, uint32_t* _reset);
+extern void* entry_get_default_native_window_handle();
+extern void* entry_get_native_display_handle();
 
 uint16_t uint16_max(uint16_t _a, uint16_t _b)
 {
@@ -25,6 +27,9 @@ int32_t _main_(int32_t _argc, char** _argv)
 	bgfx_init_t init;
 	bgfx_init_ctor(&init);
 
+	init.platformData.nwh = entry_get_default_native_window_handle();
+	init.platformData.ndt = entry_get_native_display_handle();
+
 	bgfx_init(&init);
 	bgfx_reset(width, height, reset, init.resolution.format);
 

+ 2 - 0
examples/26-occlusion/occlusion.cpp

@@ -82,6 +82,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/27-terrain/terrain.cpp

@@ -78,6 +78,8 @@ ExampleTerrain(const char* _name, const char* _description, const char* _url)
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/28-wireframe/wireframe.cpp

@@ -291,6 +291,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/29-debugdraw/debugdraw.cpp

@@ -778,6 +778,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/30-picking/picking.cpp

@@ -38,6 +38,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/31-rsm/reflectiveshadowmap.cpp

@@ -211,6 +211,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/32-particles/particles.cpp

@@ -246,6 +246,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/33-pom/pom.cpp

@@ -128,6 +128,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/34-mvs/mvs.cpp

@@ -124,6 +124,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 0
examples/35-dynamic/dynamic.cpp

@@ -102,6 +102,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 485 - 483
examples/36-sky/sky.cpp

@@ -57,605 +57,607 @@
 
 namespace
 {
-	// Represents color. Color-space depends on context.
-	// In the code below, used to represent color in XYZ, and RGB color-space
-	typedef bx::Vec3 Color;
+// Represents color. Color-space depends on context.
+// In the code below, used to represent color in XYZ, and RGB color-space
+typedef bx::Vec3 Color;
 
-	// HDTV rec. 709 matrix.
-	static constexpr float M_XYZ2RGB[] =
-	{
-		 3.240479f, -0.969256f,  0.055648f,
-		-1.53715f,   1.875991f, -0.204043f,
-		-0.49853f,   0.041556f,  1.057311f,
-	};
+// HDTV rec. 709 matrix.
+static constexpr float M_XYZ2RGB[] =
+{
+	3.240479f, -0.969256f,  0.055648f,
+	-1.53715f,   1.875991f, -0.204043f,
+	-0.49853f,   0.041556f,  1.057311f,
+};
 
-	// Converts color representation from CIE XYZ to RGB color-space.
-	Color xyzToRgb(const Color& xyz)
-	{
-		Color rgb(bx::init::None);
-		rgb.x = M_XYZ2RGB[0] * xyz.x + M_XYZ2RGB[3] * xyz.y + M_XYZ2RGB[6] * xyz.z;
-		rgb.y = M_XYZ2RGB[1] * xyz.x + M_XYZ2RGB[4] * xyz.y + M_XYZ2RGB[7] * xyz.z;
-		rgb.z = M_XYZ2RGB[2] * xyz.x + M_XYZ2RGB[5] * xyz.y + M_XYZ2RGB[8] * xyz.z;
-		return rgb;
-	};
+// Converts color representation from CIE XYZ to RGB color-space.
+Color xyzToRgb(const Color& xyz)
+{
+	Color rgb(bx::init::None);
+	rgb.x = M_XYZ2RGB[0] * xyz.x + M_XYZ2RGB[3] * xyz.y + M_XYZ2RGB[6] * xyz.z;
+	rgb.y = M_XYZ2RGB[1] * xyz.x + M_XYZ2RGB[4] * xyz.y + M_XYZ2RGB[7] * xyz.z;
+	rgb.z = M_XYZ2RGB[2] * xyz.x + M_XYZ2RGB[5] * xyz.y + M_XYZ2RGB[8] * xyz.z;
+	return rgb;
+};
+
+// Precomputed luminance of sunlight in XYZ colorspace.
+// Computed using code from Game Engine Gems, Volume One, chapter 15. Implementation based on Dr. Richard Bird model.
+// This table is used for piecewise linear interpolation. Transitions from and to 0.0 at sunset and sunrise are highly inaccurate
+static std::map<float, Color> sunLuminanceXYZTable =
+{
+	{  5.0f, {  0.000000f,  0.000000f,  0.000000f } },
+	{  7.0f, { 12.703322f, 12.989393f,  9.100411f } },
+	{  8.0f, { 13.202644f, 13.597814f, 11.524929f } },
+	{  9.0f, { 13.192974f, 13.597458f, 12.264488f } },
+	{ 10.0f, { 13.132943f, 13.535914f, 12.560032f } },
+	{ 11.0f, { 13.088722f, 13.489535f, 12.692996f } },
+	{ 12.0f, { 13.067827f, 13.467483f, 12.745179f } },
+	{ 13.0f, { 13.069653f, 13.469413f, 12.740822f } },
+	{ 14.0f, { 13.094319f, 13.495428f, 12.678066f } },
+	{ 15.0f, { 13.142133f, 13.545483f, 12.526785f } },
+	{ 16.0f, { 13.201734f, 13.606017f, 12.188001f } },
+	{ 17.0f, { 13.182774f, 13.572725f, 11.311157f } },
+	{ 18.0f, { 12.448635f, 12.672520f,  8.267771f } },
+	{ 20.0f, {  0.000000f,  0.000000f,  0.000000f } },
+};
+
+
+// Precomputed luminance of sky in the zenith point in XYZ colorspace.
+// Computed using code from Game Engine Gems, Volume One, chapter 15. Implementation based on Dr. Richard Bird model.
+// This table is used for piecewise linear interpolation. Day/night transitions are highly inaccurate.
+// The scale of luminance change in Day/night transitions is not preserved.
+// Luminance at night was increased to eliminate need the of HDR render.
+static std::map<float, Color> skyLuminanceXYZTable =
+{
+	{  0.0f, { 0.308f,    0.308f,    0.411f    } },
+	{  1.0f, { 0.308f,    0.308f,    0.410f    } },
+	{  2.0f, { 0.301f,    0.301f,    0.402f    } },
+	{  3.0f, { 0.287f,    0.287f,    0.382f    } },
+	{  4.0f, { 0.258f,    0.258f,    0.344f    } },
+	{  5.0f, { 0.258f,    0.258f,    0.344f    } },
+	{  7.0f, { 0.962851f, 1.000000f, 1.747835f } },
+	{  8.0f, { 0.967787f, 1.000000f, 1.776762f } },
+	{  9.0f, { 0.970173f, 1.000000f, 1.788413f } },
+	{ 10.0f, { 0.971431f, 1.000000f, 1.794102f } },
+	{ 11.0f, { 0.972099f, 1.000000f, 1.797096f } },
+	{ 12.0f, { 0.972385f, 1.000000f, 1.798389f } },
+	{ 13.0f, { 0.972361f, 1.000000f, 1.798278f } },
+	{ 14.0f, { 0.972020f, 1.000000f, 1.796740f } },
+	{ 15.0f, { 0.971275f, 1.000000f, 1.793407f } },
+	{ 16.0f, { 0.969885f, 1.000000f, 1.787078f } },
+	{ 17.0f, { 0.967216f, 1.000000f, 1.773758f } },
+	{ 18.0f, { 0.961668f, 1.000000f, 1.739891f } },
+	{ 20.0f, { 0.264f,    0.264f,    0.352f    } },
+	{ 21.0f, { 0.264f,    0.264f,    0.352f    } },
+	{ 22.0f, { 0.290f,    0.290f,    0.386f    } },
+	{ 23.0f, { 0.303f,    0.303f,    0.404f    } },
+};
+
+
+// Turbidity tables. Taken from:
+// A. J. Preetham, P. Shirley, and B. Smits. A Practical Analytic Model for Daylight. SIGGRAPH '99
+// Coefficients correspond to xyY colorspace.
+static constexpr Color ABCDE[] =
+{
+	{ -0.2592f, -0.2608f, -1.4630f },
+	{  0.0008f,  0.0092f,  0.4275f },
+	{  0.2125f,  0.2102f,  5.3251f },
+	{ -0.8989f, -1.6537f, -2.5771f },
+	{  0.0452f,  0.0529f,  0.3703f },
+};
+
+static constexpr Color ABCDE_t[] =
+{
+	{ -0.0193f, -0.0167f,  0.1787f },
+	{ -0.0665f, -0.0950f, -0.3554f },
+	{ -0.0004f, -0.0079f, -0.0227f },
+	{ -0.0641f, -0.0441f,  0.1206f },
+	{ -0.0033f, -0.0109f, -0.0670f },
+};
 
-	// Precomputed luminance of sunlight in XYZ colorspace.
-	// Computed using code from Game Engine Gems, Volume One, chapter 15. Implementation based on Dr. Richard Bird model.
-	// This table is used for piecewise linear interpolation. Transitions from and to 0.0 at sunset and sunrise are highly inaccurate
-	static std::map<float, Color> sunLuminanceXYZTable =
-	{
-		{  5.0f, {  0.000000f,  0.000000f,  0.000000f } },
-		{  7.0f, { 12.703322f, 12.989393f,  9.100411f } },
-		{  8.0f, { 13.202644f, 13.597814f, 11.524929f } },
-		{  9.0f, { 13.192974f, 13.597458f, 12.264488f } },
-		{ 10.0f, { 13.132943f, 13.535914f, 12.560032f } },
-		{ 11.0f, { 13.088722f, 13.489535f, 12.692996f } },
-		{ 12.0f, { 13.067827f, 13.467483f, 12.745179f } },
-		{ 13.0f, { 13.069653f, 13.469413f, 12.740822f } },
-		{ 14.0f, { 13.094319f, 13.495428f, 12.678066f } },
-		{ 15.0f, { 13.142133f, 13.545483f, 12.526785f } },
-		{ 16.0f, { 13.201734f, 13.606017f, 12.188001f } },
-		{ 17.0f, { 13.182774f, 13.572725f, 11.311157f } },
-		{ 18.0f, { 12.448635f, 12.672520f,  8.267771f } },
-		{ 20.0f, {  0.000000f,  0.000000f,  0.000000f } },
-	};
 
+// Performs piecewise linear interpolation of a Color parameter.
+class DynamicValueController
+{
+	typedef Color ValueType;
+	typedef std::map<float, ValueType> KeyMap;
 
-	// Precomputed luminance of sky in the zenith point in XYZ colorspace.
-	// Computed using code from Game Engine Gems, Volume One, chapter 15. Implementation based on Dr. Richard Bird model.
-	// This table is used for piecewise linear interpolation. Day/night transitions are highly inaccurate.
-	// The scale of luminance change in Day/night transitions is not preserved.
-	// Luminance at night was increased to eliminate need the of HDR render.
-	static std::map<float, Color> skyLuminanceXYZTable =
+public:
+	DynamicValueController()
 	{
-		{  0.0f, { 0.308f,    0.308f,    0.411f    } },
-		{  1.0f, { 0.308f,    0.308f,    0.410f    } },
-		{  2.0f, { 0.301f,    0.301f,    0.402f    } },
-		{  3.0f, { 0.287f,    0.287f,    0.382f    } },
-		{  4.0f, { 0.258f,    0.258f,    0.344f    } },
-		{  5.0f, { 0.258f,    0.258f,    0.344f    } },
-		{  7.0f, { 0.962851f, 1.000000f, 1.747835f } },
-		{  8.0f, { 0.967787f, 1.000000f, 1.776762f } },
-		{  9.0f, { 0.970173f, 1.000000f, 1.788413f } },
-		{ 10.0f, { 0.971431f, 1.000000f, 1.794102f } },
-		{ 11.0f, { 0.972099f, 1.000000f, 1.797096f } },
-		{ 12.0f, { 0.972385f, 1.000000f, 1.798389f } },
-		{ 13.0f, { 0.972361f, 1.000000f, 1.798278f } },
-		{ 14.0f, { 0.972020f, 1.000000f, 1.796740f } },
-		{ 15.0f, { 0.971275f, 1.000000f, 1.793407f } },
-		{ 16.0f, { 0.969885f, 1.000000f, 1.787078f } },
-		{ 17.0f, { 0.967216f, 1.000000f, 1.773758f } },
-		{ 18.0f, { 0.961668f, 1.000000f, 1.739891f } },
-		{ 20.0f, { 0.264f,    0.264f,    0.352f    } },
-		{ 21.0f, { 0.264f,    0.264f,    0.352f    } },
-		{ 22.0f, { 0.290f,    0.290f,    0.386f    } },
-		{ 23.0f, { 0.303f,    0.303f,    0.404f    } },
-	};
-
+	}
 
-	// Turbidity tables. Taken from:
-	// A. J. Preetham, P. Shirley, and B. Smits. A Practical Analytic Model for Daylight. SIGGRAPH '99
-	// Coefficients correspond to xyY colorspace.
-	static constexpr Color ABCDE[] =
+	~DynamicValueController()
 	{
-		{ -0.2592f, -0.2608f, -1.4630f },
-		{  0.0008f,  0.0092f,  0.4275f },
-		{  0.2125f,  0.2102f,  5.3251f },
-		{ -0.8989f, -1.6537f, -2.5771f },
-		{  0.0452f,  0.0529f,  0.3703f },
-	};
+	}
 
-	static constexpr Color ABCDE_t[] =
+	void SetMap(const KeyMap& keymap)
 	{
-		{ -0.0193f, -0.0167f,  0.1787f },
-		{ -0.0665f, -0.0950f, -0.3554f },
-		{ -0.0004f, -0.0079f, -0.0227f },
-		{ -0.0641f, -0.0441f,  0.1206f },
-		{ -0.0033f, -0.0109f, -0.0670f },
-	};
+		m_keyMap = keymap;
+	}
 
-
-	// Performs piecewise linear interpolation of a Color parameter.
-	class DynamicValueController
+	ValueType GetValue(float time) const
 	{
-		typedef Color ValueType;
-		typedef std::map<float, ValueType> KeyMap;
+		typename KeyMap::const_iterator itUpper = m_keyMap.upper_bound(time + 1e-6f);
+		typename KeyMap::const_iterator itLower = itUpper;
+		--itLower;
 
-	public:
-		DynamicValueController()
+		if (itLower == m_keyMap.end())
 		{
+			return itUpper->second;
 		}
 
-		~DynamicValueController()
+		if (itUpper == m_keyMap.end())
 		{
+			return itLower->second;
 		}
 
-		void SetMap(const KeyMap& keymap)
-		{
-			m_keyMap = keymap;
-		}
+		float lowerTime = itLower->first;
+		const ValueType& lowerVal = itLower->second;
+		float upperTime = itUpper->first;
+		const ValueType& upperVal = itUpper->second;
 
-		ValueType GetValue(float time) const
+		if (lowerTime == upperTime)
 		{
-			typename KeyMap::const_iterator itUpper = m_keyMap.upper_bound(time + 1e-6f);
-			typename KeyMap::const_iterator itLower = itUpper;
-			--itLower;
-
-			if (itLower == m_keyMap.end())
-			{
-				return itUpper->second;
-			}
-
-			if (itUpper == m_keyMap.end())
-			{
-				return itLower->second;
-			}
-
-			float lowerTime = itLower->first;
-			const ValueType& lowerVal = itLower->second;
-			float upperTime = itUpper->first;
-			const ValueType& upperVal = itUpper->second;
+			return lowerVal;
+		}
 
-			if (lowerTime == upperTime)
-			{
-				return lowerVal;
-			}
+		return interpolate(lowerTime, lowerVal, upperTime, upperVal, time);
+	};
 
-			return interpolate(lowerTime, lowerVal, upperTime, upperVal, time);
-		};
+	void Clear()
+	{
+		m_keyMap.clear();
+	};
 
-		void Clear()
-		{
-			m_keyMap.clear();
-		};
+private:
+	ValueType interpolate(float lowerTime, const ValueType& lowerVal, float upperTime, const ValueType& upperVal, float time) const
+	{
+		const float tt = (time - lowerTime) / (upperTime - lowerTime);
+		const ValueType result = bx::lerp(lowerVal, upperVal, tt);
+		return result;
+	};
 
-	private:
-		ValueType interpolate(float lowerTime, const ValueType& lowerVal, float upperTime, const ValueType& upperVal, float time) const
-		{
-			const float tt = (time - lowerTime) / (upperTime - lowerTime);
-			const ValueType result = bx::lerp(lowerVal, upperVal, tt);
-			return result;
-		};
+	KeyMap	m_keyMap;
+};
 
-		KeyMap	m_keyMap;
+// Controls sun position according to time, month, and observer's latitude.
+// Sun position computation based on Earth's orbital elements: https://nssdc.gsfc.nasa.gov/planetary/factsheet/earthfact.html
+class SunController
+{
+public:
+	enum Month : int
+	{
+		January = 0,
+		February,
+		March,
+		April,
+		May,
+		June,
+		July,
+		August,
+		September,
+		October,
+		November,
+		December
 	};
 
-	// Controls sun position according to time, month, and observer's latitude.
-	// Sun position computation based on Earth's orbital elements: https://nssdc.gsfc.nasa.gov/planetary/factsheet/earthfact.html
-	class SunController
+	SunController()
+		: m_northDir(1.0f,  0.0f, 0.0f)
+		, m_sunDir(0.0f, -1.0f, 0.0f)
+		, m_upDir(0.0f,  1.0f, 0.0f)
+		, m_latitude(50.0f)
+		, m_month(June)
+		, m_eclipticObliquity(bx::toRad(23.4f) )
+		, m_delta(0.0f)
 	{
-	public:
-		enum Month : int
-		{
-			January = 0,
-			February,
-			March,
-			April,
-			May,
-			June,
-			July,
-			August,
-			September,
-			October,
-			November,
-			December
-		};
+	}
 
-		SunController()
-			: m_northDir(1.0f,  0.0f, 0.0f)
-			, m_sunDir(0.0f, -1.0f, 0.0f)
-			, m_upDir(0.0f,  1.0f, 0.0f)
-			, m_latitude(50.0f)
-			, m_month(June)
-			, m_eclipticObliquity(bx::toRad(23.4f) )
-			, m_delta(0.0f)
-		{
-		}
+	void Update(float _time)
+	{
+		CalculateSunOrbit();
+		UpdateSunPosition(_time - 12.0f);
+	}
+
+	bx::Vec3 m_northDir;
+	bx::Vec3 m_sunDir;
+	bx::Vec3 m_upDir;
+	float m_latitude;
+	Month m_month;
+
+private:
+	void CalculateSunOrbit()
+	{
+		const float day = 30.0f * float(m_month) + 15.0f;
+		float lambda = 280.46f + 0.9856474f * day;
+		lambda  = bx::toRad(lambda);
+		m_delta = bx::asin(bx::sin(m_eclipticObliquity) * bx::sin(lambda) );
+	}
 
-		void Update(float _time)
-		{
-			CalculateSunOrbit();
-			UpdateSunPosition(_time - 12.0f);
-		}
+	void UpdateSunPosition(float _hour)
+	{
+		const float latitude = bx::toRad(m_latitude);
+		const float hh = _hour * bx::kPi / 12.0f;
+		const float azimuth = bx::atan2(
+				bx::sin(hh)
+			, bx::cos(hh) * bx::sin(latitude) - bx::tan(m_delta) * bx::cos(latitude)
+			);
+
+		const float altitude = bx::asin(
+			bx::sin(latitude) * bx::sin(m_delta) + bx::cos(latitude) * bx::cos(m_delta) * bx::cos(hh)
+			);
+
+		const bx::Quaternion rot0 = bx::fromAxisAngle(m_upDir, -azimuth);
+		const bx::Vec3 dir = bx::mul(m_northDir, rot0);
+		const bx::Vec3 uxd = bx::cross(m_upDir, dir);
+
+		const bx::Quaternion rot1 = bx::fromAxisAngle(uxd, altitude);
+		m_sunDir = bx::mul(dir, rot1);
+	}
+
+	float m_eclipticObliquity;
+	float m_delta;
+};
+
+struct ScreenPosVertex
+{
+	float m_x;
+	float m_y;
 
-		bx::Vec3 m_northDir;
-		bx::Vec3 m_sunDir;
-		bx::Vec3 m_upDir;
-		float m_latitude;
-		Month m_month;
+	static void init()
+	{
+		ms_layout
+			.begin()
+			.add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float)
+			.end();
+	}
 
-	private:
-		void CalculateSunOrbit()
-		{
-			const float day = 30.0f * float(m_month) + 15.0f;
-			float lambda = 280.46f + 0.9856474f * day;
-			lambda  = bx::toRad(lambda);
-			m_delta = bx::asin(bx::sin(m_eclipticObliquity) * bx::sin(lambda) );
-		}
+	static bgfx::VertexLayout ms_layout;
+};
 
-		void UpdateSunPosition(float _hour)
-		{
-			const float latitude = bx::toRad(m_latitude);
-			const float hh = _hour * bx::kPi / 12.0f;
-			const float azimuth = bx::atan2(
-				  bx::sin(hh)
-				, bx::cos(hh) * bx::sin(latitude) - bx::tan(m_delta) * bx::cos(latitude)
-				);
+bgfx::VertexLayout ScreenPosVertex::ms_layout;
 
-			const float altitude = bx::asin(
-				bx::sin(latitude) * bx::sin(m_delta) + bx::cos(latitude) * bx::cos(m_delta) * bx::cos(hh)
-				);
+// Renders a screen-space grid of triangles.
+// Because of performance reasons, and because sky color is smooth, sky color is computed in vertex shader.
+// 32x32 is a reasonable size for the grid to have smooth enough colors.
+struct ProceduralSky
+{
+	void init(int verticalCount, int horizontalCount)
+	{
+		// Create vertex stream declaration.
+		ScreenPosVertex::init();
 
-			const bx::Quaternion rot0 = bx::fromAxisAngle(m_upDir, -azimuth);
-			const bx::Vec3 dir = bx::mul(m_northDir, rot0);
-			const bx::Vec3 uxd = bx::cross(m_upDir, dir);
+		m_skyProgram = loadProgram("vs_sky", "fs_sky");
+		m_skyProgram_colorBandingFix = loadProgram("vs_sky", "fs_sky_color_banding_fix");
 
-			const bx::Quaternion rot1 = bx::fromAxisAngle(uxd, altitude);
-			m_sunDir = bx::mul(dir, rot1);
-		}
+		m_preventBanding = true;
 
-		float m_eclipticObliquity;
-		float m_delta;
-	};
+		bx::AllocatorI* allocator = entry::getAllocator();
 
-	struct ScreenPosVertex
-	{
-		float m_x;
-		float m_y;
+		ScreenPosVertex* vertices = (ScreenPosVertex*)BX_ALLOC(allocator
+			, verticalCount * horizontalCount * sizeof(ScreenPosVertex)
+			);
 
-		static void init()
+		for (int i = 0; i < verticalCount; i++)
 		{
-			ms_layout
-				.begin()
-				.add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float)
-				.end();
+			for (int j = 0; j < horizontalCount; j++)
+			{
+				ScreenPosVertex& v = vertices[i * verticalCount + j];
+				v.m_x = float(j) / (horizontalCount - 1) * 2.0f - 1.0f;
+				v.m_y = float(i) / (verticalCount - 1) * 2.0f - 1.0f;
+			}
 		}
 
-		static bgfx::VertexLayout ms_layout;
-	};
-
-	bgfx::VertexLayout ScreenPosVertex::ms_layout;
+		uint16_t* indices = (uint16_t*)BX_ALLOC(allocator
+			, (verticalCount - 1) * (horizontalCount - 1) * 6 * sizeof(uint16_t)
+			);
 
-	// Renders a screen-space grid of triangles.
-	// Because of performance reasons, and because sky color is smooth, sky color is computed in vertex shader.
-	// 32x32 is a reasonable size for the grid to have smooth enough colors.
-	struct ProceduralSky
-	{
-		void init(int verticalCount, int horizontalCount)
+		int k = 0;
+		for (int i = 0; i < verticalCount - 1; i++)
 		{
-			// Create vertex stream declaration.
-			ScreenPosVertex::init();
-
-			m_skyProgram = loadProgram("vs_sky", "fs_sky");
-			m_skyProgram_colorBandingFix = loadProgram("vs_sky", "fs_sky_color_banding_fix");
+			for (int j = 0; j < horizontalCount - 1; j++)
+			{
+				indices[k++] = (uint16_t)(j + 0 + horizontalCount * (i + 0));
+				indices[k++] = (uint16_t)(j + 1 + horizontalCount * (i + 0));
+				indices[k++] = (uint16_t)(j + 0 + horizontalCount * (i + 1));
 
-			m_preventBanding = true;
+				indices[k++] = (uint16_t)(j + 1 + horizontalCount * (i + 0));
+				indices[k++] = (uint16_t)(j + 1 + horizontalCount * (i + 1));
+				indices[k++] = (uint16_t)(j + 0 + horizontalCount * (i + 1));
+			}
+		}
 
-			bx::AllocatorI* allocator = entry::getAllocator();
+		m_vbh = bgfx::createVertexBuffer(bgfx::copy(vertices, sizeof(ScreenPosVertex) * verticalCount * horizontalCount), ScreenPosVertex::ms_layout);
+		m_ibh = bgfx::createIndexBuffer(bgfx::copy(indices, sizeof(uint16_t) * k));
 
-			ScreenPosVertex* vertices = (ScreenPosVertex*)BX_ALLOC(allocator
-				, verticalCount * horizontalCount * sizeof(ScreenPosVertex)
-				);
+		BX_FREE(allocator, indices);
+		BX_FREE(allocator, vertices);
+	}
 
-			for (int i = 0; i < verticalCount; i++)
-			{
-				for (int j = 0; j < horizontalCount; j++)
-				{
-					ScreenPosVertex& v = vertices[i * verticalCount + j];
-					v.m_x = float(j) / (horizontalCount - 1) * 2.0f - 1.0f;
-					v.m_y = float(i) / (verticalCount - 1) * 2.0f - 1.0f;
-				}
-			}
-
-			uint16_t* indices = (uint16_t*)BX_ALLOC(allocator
-				, (verticalCount - 1) * (horizontalCount - 1) * 6 * sizeof(uint16_t)
-				);
+	void shutdown()
+	{
+		bgfx::destroy(m_ibh);
+		bgfx::destroy(m_vbh);
+		bgfx::destroy(m_skyProgram);
+		bgfx::destroy(m_skyProgram_colorBandingFix);
+	}
 
-			int k = 0;
-			for (int i = 0; i < verticalCount - 1; i++)
-			{
-				for (int j = 0; j < horizontalCount - 1; j++)
-				{
-					indices[k++] = (uint16_t)(j + 0 + horizontalCount * (i + 0));
-					indices[k++] = (uint16_t)(j + 1 + horizontalCount * (i + 0));
-					indices[k++] = (uint16_t)(j + 0 + horizontalCount * (i + 1));
-
-					indices[k++] = (uint16_t)(j + 1 + horizontalCount * (i + 0));
-					indices[k++] = (uint16_t)(j + 1 + horizontalCount * (i + 1));
-					indices[k++] = (uint16_t)(j + 0 + horizontalCount * (i + 1));
-				}
-			}
+	void draw()
+	{
+		bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_DEPTH_TEST_EQUAL);
+		bgfx::setIndexBuffer(m_ibh);
+		bgfx::setVertexBuffer(0, m_vbh);
+		bgfx::submit(0, m_preventBanding ? m_skyProgram_colorBandingFix : m_skyProgram);
+	}
 
-			m_vbh = bgfx::createVertexBuffer(bgfx::copy(vertices, sizeof(ScreenPosVertex) * verticalCount * horizontalCount), ScreenPosVertex::ms_layout);
-			m_ibh = bgfx::createIndexBuffer(bgfx::copy(indices, sizeof(uint16_t) * k));
+	bgfx::VertexBufferHandle m_vbh;
+	bgfx::IndexBufferHandle m_ibh;
 
-			BX_FREE(allocator, indices);
-			BX_FREE(allocator, vertices);
-		}
+	bgfx::ProgramHandle m_skyProgram;
+	bgfx::ProgramHandle m_skyProgram_colorBandingFix;
 
-		void shutdown()
-		{
-			bgfx::destroy(m_ibh);
-			bgfx::destroy(m_vbh);
-			bgfx::destroy(m_skyProgram);
-			bgfx::destroy(m_skyProgram_colorBandingFix);
-		}
+	bool m_preventBanding;
+};
 
-		void draw()
-		{
-			bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_DEPTH_TEST_EQUAL);
-			bgfx::setIndexBuffer(m_ibh);
-			bgfx::setVertexBuffer(0, m_vbh);
-			bgfx::submit(0, m_preventBanding ? m_skyProgram_colorBandingFix : m_skyProgram);
-		}
+class ExampleProceduralSky : public entry::AppI
+{
+public:
+	ExampleProceduralSky(const char* _name, const char* _description, const char* _url)
+		: entry::AppI(_name, _description, _url)
+	{
+	}
 
-		bgfx::VertexBufferHandle m_vbh;
-		bgfx::IndexBufferHandle m_ibh;
+	void init(int32_t _argc, const char* const* _argv, uint32_t _width, uint32_t _height) override
+	{
+		Args args(_argc, _argv);
 
-		bgfx::ProgramHandle m_skyProgram;
-		bgfx::ProgramHandle m_skyProgram_colorBandingFix;
+		m_width = _width;
+		m_height = _height;
+		m_debug = BGFX_DEBUG_NONE;
+		m_reset = BGFX_RESET_VSYNC;
 
-		bool m_preventBanding;
-	};
+		bgfx::Init init;
+		init.type     = args.m_type;
+		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
+		init.resolution.width  = m_width;
+		init.resolution.height = m_height;
+		init.resolution.reset  = m_reset;
+		bgfx::init(init);
 
-	class ExampleProceduralSky : public entry::AppI
-	{
-	public:
-		ExampleProceduralSky(const char* _name, const char* _description, const char* _url)
-			: entry::AppI(_name, _description, _url)
-		{
-		}
+		// Enable m_debug text.
+		bgfx::setDebug(m_debug);
 
-		void init(int32_t _argc, const char* const* _argv, uint32_t _width, uint32_t _height) override
-		{
-			Args args(_argc, _argv);
-
-			m_width = _width;
-			m_height = _height;
-			m_debug = BGFX_DEBUG_NONE;
-			m_reset = BGFX_RESET_VSYNC;
-
-			bgfx::Init init;
-			init.type     = args.m_type;
-			init.vendorId = args.m_pciId;
-			init.resolution.width  = m_width;
-			init.resolution.height = m_height;
-			init.resolution.reset  = m_reset;
-			bgfx::init(init);
-
-			// Enable m_debug text.
-			bgfx::setDebug(m_debug);
-
-			// Set view 0 clear state.
-			bgfx::setViewClear(0
-				, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
-				, 0x000000ff
-				, 1.0f
-				, 0
-				);
+		// Set view 0 clear state.
+		bgfx::setViewClear(0
+			, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
+			, 0x000000ff
+			, 1.0f
+			, 0
+			);
 
-			m_sunLuminanceXYZ.SetMap(sunLuminanceXYZTable);
-			m_skyLuminanceXYZ.SetMap(skyLuminanceXYZTable);
+		m_sunLuminanceXYZ.SetMap(sunLuminanceXYZTable);
+		m_skyLuminanceXYZ.SetMap(skyLuminanceXYZTable);
 
-			m_mesh = meshLoad("meshes/test_scene.bin");
+		m_mesh = meshLoad("meshes/test_scene.bin");
 
-			m_lightmapTexture = loadTexture("textures/lightmap.ktx");
+		m_lightmapTexture = loadTexture("textures/lightmap.ktx");
 
-			// Imgui.
-			imguiCreate();
+		// Imgui.
+		imguiCreate();
 
-			m_timeOffset = bx::getHPCounter();
-			m_time = 0.0f;
-			m_timeScale = 1.0f;
+		m_timeOffset = bx::getHPCounter();
+		m_time = 0.0f;
+		m_timeScale = 1.0f;
 
-			s_texLightmap     = bgfx::createUniform("s_texLightmap",     bgfx::UniformType::Sampler);
-			u_sunLuminance    = bgfx::createUniform("u_sunLuminance",    bgfx::UniformType::Vec4);
-			u_skyLuminanceXYZ = bgfx::createUniform("u_skyLuminanceXYZ", bgfx::UniformType::Vec4);
-			u_skyLuminance    = bgfx::createUniform("u_skyLuminance",    bgfx::UniformType::Vec4);
-			u_sunDirection    = bgfx::createUniform("u_sunDirection",    bgfx::UniformType::Vec4);
-			u_parameters      = bgfx::createUniform("u_parameters",      bgfx::UniformType::Vec4);
-			u_perezCoeff      = bgfx::createUniform("u_perezCoeff",      bgfx::UniformType::Vec4, 5);
+		s_texLightmap     = bgfx::createUniform("s_texLightmap",     bgfx::UniformType::Sampler);
+		u_sunLuminance    = bgfx::createUniform("u_sunLuminance",    bgfx::UniformType::Vec4);
+		u_skyLuminanceXYZ = bgfx::createUniform("u_skyLuminanceXYZ", bgfx::UniformType::Vec4);
+		u_skyLuminance    = bgfx::createUniform("u_skyLuminance",    bgfx::UniformType::Vec4);
+		u_sunDirection    = bgfx::createUniform("u_sunDirection",    bgfx::UniformType::Vec4);
+		u_parameters      = bgfx::createUniform("u_parameters",      bgfx::UniformType::Vec4);
+		u_perezCoeff      = bgfx::createUniform("u_perezCoeff",      bgfx::UniformType::Vec4, 5);
 
-			m_landscapeProgram = loadProgram("vs_sky_landscape", "fs_sky_landscape");
+		m_landscapeProgram = loadProgram("vs_sky_landscape", "fs_sky_landscape");
 
-			m_sky.init(32, 32);
+		m_sky.init(32, 32);
 
-			m_sun.Update(0);
+		m_sun.Update(0);
 
-			cameraCreate();
+		cameraCreate();
 
-			cameraSetPosition({ 5.0f, 3.0, 0.0f });
-			cameraSetVerticalAngle(bx::kPi / 8.0f);
-			cameraSetHorizontalAngle(-bx::kPi / 3.0f);
+		cameraSetPosition({ 5.0f, 3.0, 0.0f });
+		cameraSetVerticalAngle(bx::kPi / 8.0f);
+		cameraSetHorizontalAngle(-bx::kPi / 3.0f);
 
-			m_turbidity = 2.15f;
-		}
+		m_turbidity = 2.15f;
+	}
 
-		virtual int shutdown() override
-		{
-			// Cleanup.
-			cameraDestroy();
-			imguiDestroy();
+	virtual int shutdown() override
+	{
+		// Cleanup.
+		cameraDestroy();
+		imguiDestroy();
 
-			meshUnload(m_mesh);
+		meshUnload(m_mesh);
 
-			m_sky.shutdown();
+		m_sky.shutdown();
 
-			bgfx::destroy(s_texLightmap);
-			bgfx::destroy(u_sunLuminance);
-			bgfx::destroy(u_skyLuminanceXYZ);
-			bgfx::destroy(u_skyLuminance);
-			bgfx::destroy(u_sunDirection);
-			bgfx::destroy(u_parameters);
-			bgfx::destroy(u_perezCoeff);
+		bgfx::destroy(s_texLightmap);
+		bgfx::destroy(u_sunLuminance);
+		bgfx::destroy(u_skyLuminanceXYZ);
+		bgfx::destroy(u_skyLuminance);
+		bgfx::destroy(u_sunDirection);
+		bgfx::destroy(u_parameters);
+		bgfx::destroy(u_perezCoeff);
 
-			bgfx::destroy(m_lightmapTexture);
-			bgfx::destroy(m_landscapeProgram);
+		bgfx::destroy(m_lightmapTexture);
+		bgfx::destroy(m_landscapeProgram);
 
-			bgfx::frame();
+		bgfx::frame();
 
-			// Shutdown bgfx.
-			bgfx::shutdown();
+		// Shutdown bgfx.
+		bgfx::shutdown();
 
-			return 0;
-		}
+		return 0;
+	}
 
-		void imgui(float _width)
+	void imgui(float _width)
+	{
+		ImGui::Begin("ProceduralSky");
+		ImGui::SetWindowSize(ImVec2(_width, 200.0f) );
+		ImGui::SliderFloat("Time scale", &m_timeScale, 0.0f, 1.0f);
+		ImGui::SliderFloat("Time", &m_time, 0.0f, 24.0f);
+		ImGui::SliderFloat("Latitude", &m_sun.m_latitude, -90.0f, 90.0f);
+		ImGui::SliderFloat("Turbidity", &m_turbidity, 1.9f, 10.0f);
+		ImGui::Checkbox("Prevent color banding", &m_sky.m_preventBanding);
+
+		const char* items[] =
 		{
-			ImGui::Begin("ProceduralSky");
-			ImGui::SetWindowSize(ImVec2(_width, 200.0f) );
-			ImGui::SliderFloat("Time scale", &m_timeScale, 0.0f, 1.0f);
-			ImGui::SliderFloat("Time", &m_time, 0.0f, 24.0f);
-			ImGui::SliderFloat("Latitude", &m_sun.m_latitude, -90.0f, 90.0f);
-			ImGui::SliderFloat("Turbidity", &m_turbidity, 1.9f, 10.0f);
-			ImGui::Checkbox("Prevent color banding", &m_sky.m_preventBanding);
-
-			const char* items[] =
-			{
-				"January",
-				"February",
-				"March",
-				"April",
-				"May",
-				"June",
-				"July",
-				"August",
-				"September",
-				"October",
-				"November",
-				"December"
-			};
-
-			ImGui::Combo("Month", (int*)&m_sun.m_month, items, 12);
-
-			ImGui::End();
-		}
+			"January",
+			"February",
+			"March",
+			"April",
+			"May",
+			"June",
+			"July",
+			"August",
+			"September",
+			"October",
+			"November",
+			"December"
+		};
 
-		bool update() override
-		{
-			if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState))
-			{
-				int64_t now = bx::getHPCounter();
-				static int64_t last = now;
-				const int64_t frameTime = now - last;
-				last = now;
-				const double freq = double(bx::getHPFrequency());
-				const float deltaTime = float(frameTime / freq);
-				m_time += m_timeScale * deltaTime;
-				m_time = bx::mod(m_time, 24.0f);
-				m_sun.Update(m_time);
+		ImGui::Combo("Month", (int*)&m_sun.m_month, items, 12);
 
-				imguiBeginFrame(m_mouseState.m_mx
-					, m_mouseState.m_my
-					, (m_mouseState.m_buttons[entry::MouseButton::Left]   ? IMGUI_MBUT_LEFT   : 0)
-					| (m_mouseState.m_buttons[entry::MouseButton::Right]  ? IMGUI_MBUT_RIGHT  : 0)
-					| (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0)
-					, m_mouseState.m_mz
-					, uint16_t(m_width)
-					, uint16_t(m_height)
-					);
+		ImGui::End();
+	}
 
-				showExampleDialog(this);
+	bool update() override
+	{
+		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState))
+		{
+			int64_t now = bx::getHPCounter();
+			static int64_t last = now;
+			const int64_t frameTime = now - last;
+			last = now;
+			const double freq = double(bx::getHPFrequency());
+			const float deltaTime = float(frameTime / freq);
+			m_time += m_timeScale * deltaTime;
+			m_time = bx::mod(m_time, 24.0f);
+			m_sun.Update(m_time);
+
+			imguiBeginFrame(m_mouseState.m_mx
+				, m_mouseState.m_my
+				, (m_mouseState.m_buttons[entry::MouseButton::Left]   ? IMGUI_MBUT_LEFT   : 0)
+				| (m_mouseState.m_buttons[entry::MouseButton::Right]  ? IMGUI_MBUT_RIGHT  : 0)
+				| (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0)
+				, m_mouseState.m_mz
+				, uint16_t(m_width)
+				, uint16_t(m_height)
+				);
 
-				ImGui::SetNextWindowPos(
-					  ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f)
-					, ImGuiCond_FirstUseEver
-					);
+			showExampleDialog(this);
 
-				imgui(m_width / 5.0f - 10.0f);
+			ImGui::SetNextWindowPos(
+					ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f)
+				, ImGuiCond_FirstUseEver
+				);
 
-				imguiEndFrame();
+			imgui(m_width / 5.0f - 10.0f);
 
-				// Update camera.
-				cameraUpdate(deltaTime, m_mouseState, ImGui::MouseOverArea() );
+			imguiEndFrame();
 
-				// Set view 0 default viewport.
-				bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height));
+			// Update camera.
+			cameraUpdate(deltaTime, m_mouseState, ImGui::MouseOverArea() );
 
-				float view[16];
-				cameraGetViewMtx(view);
+			// Set view 0 default viewport.
+			bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height));
 
-				float proj[16];
-				bx::mtxProj(proj, 60.0f, float(m_width) / float(m_height), 0.1f, 2000.0f, bgfx::getCaps()->homogeneousDepth);
+			float view[16];
+			cameraGetViewMtx(view);
 
-				bgfx::setViewTransform(0, view, proj);
+			float proj[16];
+			bx::mtxProj(proj, 60.0f, float(m_width) / float(m_height), 0.1f, 2000.0f, bgfx::getCaps()->homogeneousDepth);
 
-				Color sunLuminanceXYZ = m_sunLuminanceXYZ.GetValue(m_time);
-				Color sunLuminanceRGB = xyzToRgb(sunLuminanceXYZ);
+			bgfx::setViewTransform(0, view, proj);
 
-				Color skyLuminanceXYZ = m_skyLuminanceXYZ.GetValue(m_time);
-				Color skyLuminanceRGB = xyzToRgb(skyLuminanceXYZ);
+			Color sunLuminanceXYZ = m_sunLuminanceXYZ.GetValue(m_time);
+			Color sunLuminanceRGB = xyzToRgb(sunLuminanceXYZ);
 
-				bgfx::setUniform(u_sunLuminance,    &sunLuminanceRGB.x);
-				bgfx::setUniform(u_skyLuminanceXYZ, &skyLuminanceXYZ.x);
-				bgfx::setUniform(u_skyLuminance,    &skyLuminanceRGB.x);
+			Color skyLuminanceXYZ = m_skyLuminanceXYZ.GetValue(m_time);
+			Color skyLuminanceRGB = xyzToRgb(skyLuminanceXYZ);
 
-				bgfx::setUniform(u_sunDirection, &m_sun.m_sunDir.x);
+			bgfx::setUniform(u_sunLuminance,    &sunLuminanceRGB.x);
+			bgfx::setUniform(u_skyLuminanceXYZ, &skyLuminanceXYZ.x);
+			bgfx::setUniform(u_skyLuminance,    &skyLuminanceRGB.x);
 
-				float exposition[4] = { 0.02f, 3.0f, 0.1f, m_time };
-				bgfx::setUniform(u_parameters, exposition);
+			bgfx::setUniform(u_sunDirection, &m_sun.m_sunDir.x);
 
-				float perezCoeff[4 * 5];
-				computePerezCoeff(m_turbidity, perezCoeff);
-				bgfx::setUniform(u_perezCoeff, perezCoeff, 5);
+			float exposition[4] = { 0.02f, 3.0f, 0.1f, m_time };
+			bgfx::setUniform(u_parameters, exposition);
 
-				bgfx::setTexture(0, s_texLightmap, m_lightmapTexture);
-				meshSubmit(m_mesh, 0, m_landscapeProgram, NULL);
+			float perezCoeff[4 * 5];
+			computePerezCoeff(m_turbidity, perezCoeff);
+			bgfx::setUniform(u_perezCoeff, perezCoeff, 5);
 
-				m_sky.draw();
+			bgfx::setTexture(0, s_texLightmap, m_lightmapTexture);
+			meshSubmit(m_mesh, 0, m_landscapeProgram, NULL);
 
-				bgfx::frame();
+			m_sky.draw();
 
-				return true;
-			}
+			bgfx::frame();
 
-			return false;
+			return true;
 		}
 
-		void computePerezCoeff(float _turbidity, float* _outPerezCoeff)
+		return false;
+	}
+
+	void computePerezCoeff(float _turbidity, float* _outPerezCoeff)
+	{
+		const bx::Vec3 turbidity = { _turbidity, _turbidity, _turbidity };
+		for (uint32_t ii = 0; ii < 5; ++ii)
 		{
-			const bx::Vec3 turbidity = { _turbidity, _turbidity, _turbidity };
-			for (uint32_t ii = 0; ii < 5; ++ii)
-			{
-				const bx::Vec3 tmp = bx::mad(ABCDE_t[ii], turbidity, ABCDE[ii]);
-				float* out = _outPerezCoeff + 4 * ii;
-				bx::store(out, tmp);
-				out[3] = 0.0f;
-			}
+			const bx::Vec3 tmp = bx::mad(ABCDE_t[ii], turbidity, ABCDE[ii]);
+			float* out = _outPerezCoeff + 4 * ii;
+			bx::store(out, tmp);
+			out[3] = 0.0f;
 		}
+	}
 
-		bgfx::ProgramHandle m_landscapeProgram;
-		bgfx::UniformHandle s_texLightmap;
-		bgfx::TextureHandle m_lightmapTexture;
+	bgfx::ProgramHandle m_landscapeProgram;
+	bgfx::UniformHandle s_texLightmap;
+	bgfx::TextureHandle m_lightmapTexture;
 
-		bgfx::UniformHandle u_sunLuminance;
-		bgfx::UniformHandle u_skyLuminanceXYZ;
-		bgfx::UniformHandle u_skyLuminance;
-		bgfx::UniformHandle u_sunDirection;
-		bgfx::UniformHandle u_parameters;
-		bgfx::UniformHandle u_perezCoeff;
+	bgfx::UniformHandle u_sunLuminance;
+	bgfx::UniformHandle u_skyLuminanceXYZ;
+	bgfx::UniformHandle u_skyLuminance;
+	bgfx::UniformHandle u_sunDirection;
+	bgfx::UniformHandle u_parameters;
+	bgfx::UniformHandle u_perezCoeff;
 
-		ProceduralSky m_sky;
-		SunController m_sun;
+	ProceduralSky m_sky;
+	SunController m_sun;
 
-		DynamicValueController m_sunLuminanceXYZ;
-		DynamicValueController m_skyLuminanceXYZ;
+	DynamicValueController m_sunLuminanceXYZ;
+	DynamicValueController m_skyLuminanceXYZ;
 
-		uint32_t m_width;
-		uint32_t m_height;
-		uint32_t m_debug;
-		uint32_t m_reset;
+	uint32_t m_width;
+	uint32_t m_height;
+	uint32_t m_debug;
+	uint32_t m_reset;
 
-		Mesh* m_mesh;
+	Mesh* m_mesh;
 
-		entry::MouseState m_mouseState;
+	entry::MouseState m_mouseState;
 
-		float m_time;
-		float m_timeScale;
-		int64_t m_timeOffset;
+	float m_time;
+	float m_timeScale;
+	int64_t m_timeOffset;
 
-		float m_turbidity;
-	};
+	float m_turbidity;
+};
 
 } // namespace
 

+ 2 - 0
examples/37-gpudrivenrendering/gpudrivenrendering.cpp

@@ -328,6 +328,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 2 - 1
examples/38-bloom/bloom.cpp

@@ -196,9 +196,10 @@ public:
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::Init init;
-
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 5 - 4
examples/39-assao/assao.cpp

@@ -267,12 +267,13 @@ namespace
 			m_reset = BGFX_RESET_VSYNC;
 
 			bgfx::Init init;
-			init.type = args.m_type;
-
+			init.type     = args.m_type;
 			init.vendorId = args.m_pciId;
-			init.resolution.width = m_width;
+			init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+			init.platformData.ndt  = entry::getNativeDisplayHandle();
+			init.resolution.width  = m_width;
 			init.resolution.height = m_height;
-			init.resolution.reset = m_reset;
+			init.resolution.reset  = m_reset;
 			bgfx::init(init);
 
 			// Enable debug text.

+ 5 - 4
examples/40-svt/svt.cpp

@@ -78,12 +78,13 @@ public:
 		m_reset = BGFX_RESET_VSYNC;
 
 		bgfx::Init init;
-
-		init.type = args.m_type;
+		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
-		init.resolution.width = m_width;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
+		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
-		init.resolution.reset = m_reset;
+		init.resolution.reset  = m_reset;
 		bgfx::init(init);
 
 		// Enable m_debug text.

+ 758 - 757
examples/41-tess/tess.cpp

@@ -23,901 +23,902 @@
 
 namespace
 {
-	static const char* s_shaderOptions[] =
-	{
-		"Normal",
-		"Diffuse"
-	};
+static const char* s_shaderOptions[] =
+{
+	"Normal",
+	"Diffuse"
+};
 
-	static const float s_verticesL0[] =
-	{
-		0.0f, 0.0f,
-		1.0f, 0.0f,
-		0.0f, 1.0f,
-	};
+static const float s_verticesL0[] =
+{
+	0.0f, 0.0f,
+	1.0f, 0.0f,
+	0.0f, 1.0f,
+};
 
-	static const uint32_t s_indexesL0[] = { 0u, 1u, 2u };
+static const uint32_t s_indexesL0[] = { 0u, 1u, 2u };
 
-	static const float s_verticesL1[] =
-	{
-		0.0f, 1.0f,
-		0.5f, 0.5f,
-		0.0f, 0.5f,
-		0.0f, 0.0f,
-		0.5f, 0.0f,
-		1.0f, 0.0f,
-	};
+static const float s_verticesL1[] =
+{
+	0.0f, 1.0f,
+	0.5f, 0.5f,
+	0.0f, 0.5f,
+	0.0f, 0.0f,
+	0.5f, 0.0f,
+	1.0f, 0.0f,
+};
+
+static const uint32_t s_indexesL1[] =
+{
+	1u, 0u, 2u,
+	1u, 2u, 3u,
+	1u, 3u, 4u,
+	1u, 4u, 5u,
+};
 
-	static const uint32_t s_indexesL1[] =
-	{
-		1u, 0u, 2u,
-		1u, 2u, 3u,
-		1u, 3u, 4u,
-		1u, 4u, 5u,
-	};
+static const float s_verticesL2[] =
+{
+	0.25f, 0.75f,
+	0.0f,  1.0f,
+	0.0f,  0.75f,
+	0.0f,  0.5f,
+	0.25f, 0.5f,
+	0.5f,  0.5f,
+
+	0.25f, 0.25f,
+	0.0f,  0.25f,
+	0.0f,  0.0f,
+	0.25f, 0.0f,
+	0.5f,  0.0f,
+	0.5f,  0.25f,
+	0.75f, 0.25f,
+	0.75f, 0.0f,
+	1.0f,  0.0f,
+};
+
+static const uint32_t s_indexesL2[] =
+{
+	0u, 1u, 2u,
+	0u, 2u, 3u,
+	0u, 3u, 4u,
+	0u, 4u, 5u,
+
+	6u, 5u, 4u,
+	6u, 4u, 3u,
+	6u, 3u, 7u,
+	6u, 7u, 8u,
+
+	6u, 8u, 9u,
+	6u, 9u, 10u,
+	6u, 10u, 11u,
+	6u, 11u, 5u,
+
+	12u, 5u, 11u,
+	12u, 11u, 10u,
+	12u, 10u, 13u,
+	12u, 13u, 14u,
+};
+
+static const float s_verticesL3[] =
+{
+	0.25f*0.5f, 0.75f*0.5f + 0.5f,
+	0.0f*0.5f, 1.0f*0.5f + 0.5f,
+	0.0f*0.5f, 0.75f*0.5f + 0.5f,
+	0.0f*0.5f , 0.5f*0.5f + 0.5f,
+	0.25f*0.5f, 0.5f*0.5f + 0.5f,
+	0.5f*0.5f, 0.5f*0.5f + 0.5f,
+	0.25f*0.5f, 0.25f*0.5f + 0.5f,
+	0.0f*0.5f, 0.25f*0.5f + 0.5f,
+	0.0f*0.5f, 0.0f*0.5f + 0.5f,
+	0.25f*0.5f, 0.0f*0.5f + 0.5f,
+	0.5f*0.5f, 0.0f*0.5f + 0.5f,
+	0.5f*0.5f, 0.25f*0.5f + 0.5f,
+	0.75f*0.5f, 0.25f*0.5f + 0.5f,
+	0.75f*0.5f, 0.0f*0.5f + 0.5f,
+	1.0f*0.5f, 0.0f*0.5f + 0.5f,        //14
+
+	0.375f, 0.375f,
+	0.25f, 0.375f,
+	0.25f, 0.25f,
+	0.375f, 0.25f,
+	0.5f, 0.25f,
+	0.5f, 0.375f,    //20
+
+	0.125f, 0.375f,
+	0.0f, 0.375f,
+	0.0f, 0.25f,
+	0.125f, 0.25f,    //24
+
+	0.125f, 0.125f,
+	0.0f, 0.125f,
+	0.0f, 0.0f,
+	0.125f, 0.0f,
+	0.25f, 0.0f,
+	0.25f, 0.125f,    //30
+
+	0.375f, 0.125f,
+	0.375f, 0.0f,
+	0.5f, 0.0f,
+	0.5f, 0.125f,    //34
+
+	0.625f, 0.375f,
+	0.625f, 0.25f,
+	0.75f, 0.25f,    //37
+
+	0.625f, 0.125f,
+	0.625f, 0.0f,
+	0.75f, 0.0f,
+	0.75f, 0.125f,    //41
+
+	0.875f, 0.125f,
+	0.875f, 0.0f,
+	1.0f, 0.0f,    //44
+};
+
+static const uint32_t s_indexesL3[] =
+{
+	0u, 1u, 2u,
+	0u, 2u, 3u,
+	0u, 3u, 4u,
+	0u, 4u, 5u,
+
+	6u, 5u, 4u,
+	6u, 4u, 3u,
+	6u, 3u, 7u,
+	6u, 7u, 8u,
+
+	6u, 8u, 9u,
+	6u, 9u, 10u,
+	6u, 10u, 11u,
+	6u, 11u, 5u,
+
+	12u, 5u, 11u,
+	12u, 11u, 10u,
+	12u, 10u, 13u,
+	12u, 13u, 14u,        //End fo first big triangle
+
+	15u, 14u, 13u,
+	15u, 13u, 10u,
+	15u, 10u, 16u,
+	15u, 16u, 17u,
+	15u, 17u, 18u,
+	15u, 18u, 19u,
+	15u, 19u, 20u,
+	15u, 20u, 14u,
+
+	21u, 10u, 9u,
+	21u, 9u, 8u,
+	21u, 8u, 22u,
+	21u, 22u, 23u,
+	21u, 23u, 24u,
+	21u, 24u, 17u,
+	21u, 17u, 16u,
+	21u, 16u, 10u,
+
+	25u, 17u, 24u,
+	25u, 24u, 23u,
+	25u, 23u, 26u,
+	25u, 26u, 27u,
+	25u, 27u, 28u,
+	25u, 28u, 29u,
+	25u, 29u, 30u,
+	25u, 30u, 17u,
+
+	31u, 19u, 18u,
+	31u, 18u, 17u,
+	31u, 17u, 30u,
+	31u, 30u, 29u,
+	31u, 29u, 32u,
+	31u, 32u, 33u,
+	31u, 33u, 34u,
+	31u, 34u, 19u,
+
+	35u, 14u, 20u,
+	35u, 20u, 19u,
+	35u, 19u, 36u,
+	35u, 36u, 37u,
+
+	38u, 37u, 36u,
+	38u, 36u, 19u,
+	38u, 19u, 34u,
+	38u, 34u, 33u,
+	38u, 33u, 39u,
+	38u, 39u, 40u,
+	38u, 40u, 41u,
+	38u, 41u, 37u,
+
+	42u, 37u, 41u,
+	42u, 41u, 40u,
+	42u, 40u, 43u,
+	42u, 43u, 44u,
+};
+
+enum
+{
+	PROGRAM_TERRAIN_NORMAL,
+	PROGRAM_TERRAIN,
 
-	static const float s_verticesL2[] =
-	{
-		0.25f, 0.75f,
-		0.0f,  1.0f,
-		0.0f,  0.75f,
-		0.0f,  0.5f,
-		0.25f, 0.5f,
-		0.5f,  0.5f,
-
-		0.25f, 0.25f,
-		0.0f,  0.25f,
-		0.0f,  0.0f,
-		0.25f, 0.0f,
-		0.5f,  0.0f,
-		0.5f,  0.25f,
-		0.75f, 0.25f,
-		0.75f, 0.0f,
-		1.0f,  0.0f,
-	};
+	SHADING_COUNT
+};
 
-	static const uint32_t s_indexesL2[] =
-	{
-		0u, 1u, 2u,
-		0u, 2u, 3u,
-		0u, 3u, 4u,
-		0u, 4u, 5u,
-
-		6u, 5u, 4u,
-		6u, 4u, 3u,
-		6u, 3u, 7u,
-		6u, 7u, 8u,
-
-		6u, 8u, 9u,
-		6u, 9u, 10u,
-		6u, 10u, 11u,
-		6u, 11u, 5u,
-
-		12u, 5u, 11u,
-		12u, 11u, 10u,
-		12u, 10u, 13u,
-		12u, 13u, 14u,
-	};
+enum
+{
+	BUFFER_SUBD
+};
 
-	static const float s_verticesL3[] =
-	{
-		0.25f*0.5f, 0.75f*0.5f + 0.5f,
-		0.0f*0.5f, 1.0f*0.5f + 0.5f,
-		0.0f*0.5f, 0.75f*0.5f + 0.5f,
-		0.0f*0.5f , 0.5f*0.5f + 0.5f,
-		0.25f*0.5f, 0.5f*0.5f + 0.5f,
-		0.5f*0.5f, 0.5f*0.5f + 0.5f,
-		0.25f*0.5f, 0.25f*0.5f + 0.5f,
-		0.0f*0.5f, 0.25f*0.5f + 0.5f,
-		0.0f*0.5f, 0.0f*0.5f + 0.5f,
-		0.25f*0.5f, 0.0f*0.5f + 0.5f,
-		0.5f*0.5f, 0.0f*0.5f + 0.5f,
-		0.5f*0.5f, 0.25f*0.5f + 0.5f,
-		0.75f*0.5f, 0.25f*0.5f + 0.5f,
-		0.75f*0.5f, 0.0f*0.5f + 0.5f,
-		1.0f*0.5f, 0.0f*0.5f + 0.5f,        //14
-
-		0.375f, 0.375f,
-		0.25f, 0.375f,
-		0.25f, 0.25f,
-		0.375f, 0.25f,
-		0.5f, 0.25f,
-		0.5f, 0.375f,    //20
-
-		0.125f, 0.375f,
-		0.0f, 0.375f,
-		0.0f, 0.25f,
-		0.125f, 0.25f,    //24
-
-		0.125f, 0.125f,
-		0.0f, 0.125f,
-		0.0f, 0.0f,
-		0.125f, 0.0f,
-		0.25f, 0.0f,
-		0.25f, 0.125f,    //30
-
-		0.375f, 0.125f,
-		0.375f, 0.0f,
-		0.5f, 0.0f,
-		0.5f, 0.125f,    //34
-
-		0.625f, 0.375f,
-		0.625f, 0.25f,
-		0.75f, 0.25f,    //37
-
-		0.625f, 0.125f,
-		0.625f, 0.0f,
-		0.75f, 0.0f,
-		0.75f, 0.125f,    //41
-
-		0.875f, 0.125f,
-		0.875f, 0.0f,
-		1.0f, 0.0f,    //44
-	};
+enum
+{
+	PROGRAM_SUBD_CS_LOD,
+	PROGRAM_UPDATE_INDIRECT,
+	PROGRAM_INIT_INDIRECT,
+	PROGRAM_UPDATE_DRAW,
 
-	static const uint32_t s_indexesL3[] =
-	{
-		0u, 1u, 2u,
-		0u, 2u, 3u,
-		0u, 3u, 4u,
-		0u, 4u, 5u,
-
-		6u, 5u, 4u,
-		6u, 4u, 3u,
-		6u, 3u, 7u,
-		6u, 7u, 8u,
-
-		6u, 8u, 9u,
-		6u, 9u, 10u,
-		6u, 10u, 11u,
-		6u, 11u, 5u,
-
-		12u, 5u, 11u,
-		12u, 11u, 10u,
-		12u, 10u, 13u,
-		12u, 13u, 14u,        //End fo first big triangle
-
-		15u, 14u, 13u,
-		15u, 13u, 10u,
-		15u, 10u, 16u,
-		15u, 16u, 17u,
-		15u, 17u, 18u,
-		15u, 18u, 19u,
-		15u, 19u, 20u,
-		15u, 20u, 14u,
-
-		21u, 10u, 9u,
-		21u, 9u, 8u,
-		21u, 8u, 22u,
-		21u, 22u, 23u,
-		21u, 23u, 24u,
-		21u, 24u, 17u,
-		21u, 17u, 16u,
-		21u, 16u, 10u,
-
-		25u, 17u, 24u,
-		25u, 24u, 23u,
-		25u, 23u, 26u,
-		25u, 26u, 27u,
-		25u, 27u, 28u,
-		25u, 28u, 29u,
-		25u, 29u, 30u,
-		25u, 30u, 17u,
-
-		31u, 19u, 18u,
-		31u, 18u, 17u,
-		31u, 17u, 30u,
-		31u, 30u, 29u,
-		31u, 29u, 32u,
-		31u, 32u, 33u,
-		31u, 33u, 34u,
-		31u, 34u, 19u,
-
-		35u, 14u, 20u,
-		35u, 20u, 19u,
-		35u, 19u, 36u,
-		35u, 36u, 37u,
-
-		38u, 37u, 36u,
-		38u, 36u, 19u,
-		38u, 19u, 34u,
-		38u, 34u, 33u,
-		38u, 33u, 39u,
-		38u, 39u, 40u,
-		38u, 40u, 41u,
-		38u, 41u, 37u,
-
-		42u, 37u, 41u,
-		42u, 41u, 40u,
-		42u, 40u, 43u,
-		42u, 43u, 44u,
-	};
+	PROGRAM_COUNT
+};
 
-	enum
-	{
-		PROGRAM_TERRAIN_NORMAL,
-		PROGRAM_TERRAIN,
+enum
+{
+	TERRAIN_DMAP_SAMPLER,
+	TERRAIN_SMAP_SAMPLER,
 
-		SHADING_COUNT
-	};
+	SAMPLER_COUNT
+};
 
-	enum
-	{
-		BUFFER_SUBD
-	};
+enum
+{
+	TEXTURE_DMAP,
+	TEXTURE_SMAP,
 
-	enum
-	{
-		PROGRAM_SUBD_CS_LOD,
-		PROGRAM_UPDATE_INDIRECT,
-		PROGRAM_INIT_INDIRECT,
-		PROGRAM_UPDATE_DRAW,
+	TEXTURE_COUNT
+};
 
-		PROGRAM_COUNT
-	};
+constexpr int32_t kNumVec4 = 2;
 
-	enum
+struct Uniforms
+{
+	void init()
 	{
-		TERRAIN_DMAP_SAMPLER,
-		TERRAIN_SMAP_SAMPLER,
+		u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4, kNumVec4);
 
-		SAMPLER_COUNT
-	};
+		cull = 1;
+		freeze = 0;
+		gpuSubd = 3;
 
-	enum
-	{
-		TEXTURE_DMAP,
-		TEXTURE_SMAP,
+	}
 
-		TEXTURE_COUNT
-	};
+	void submit()
+	{
+		bgfx::setUniform(u_params, params, kNumVec4);
+	}
 
-	constexpr int32_t kNumVec4 = 2;
+	void destroy()
+	{
+		bgfx::destroy(u_params);
+	}
 
-	struct Uniforms
+	union
 	{
-		void init()
+		struct
 		{
-			u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4, kNumVec4);
+			float dmapFactor;
+			float lodFactor;
+			float cull;
+			float freeze;
+
+			float gpuSubd;
+			float padding0;
+			float padding1;
+			float padding2;
+		};
 
-			cull = 1;
-			freeze = 0;
-			gpuSubd = 3;
+		float params[kNumVec4 * 4];
+	};
 
-		}
+	bgfx::UniformHandle u_params;
+};
 
-		void submit()
-		{
-			bgfx::setUniform(u_params, params, kNumVec4);
-		}
+class ExampleTessellation : public entry::AppI
+{
+public:
+	ExampleTessellation(const char* _name, const char* _description, const char* _url)
+		: entry::AppI(_name, _description, _url)
+	{
+	}
 
-		void destroy()
+	void init(int32_t _argc, const char* const* _argv, uint32_t _width, uint32_t _height) override
+	{
+		Args args(_argc, _argv);
+
+		m_width = _width;
+		m_height = _height;
+		m_debug = BGFX_DEBUG_NONE;
+		m_reset = BGFX_RESET_NONE;
+
+		bgfx::Init init;
+		init.type = args.m_type;
+		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
+		init.resolution.width = m_width;
+		init.resolution.height = m_height;
+		init.resolution.reset = m_reset;
+		bgfx::init(init);
+
+		m_dmap = { "textures/dmap.png", 0.45f };
+		m_computeThreadCount = 5;
+		m_shading = PROGRAM_TERRAIN;
+		m_primitivePixelLengthTarget = 7.0f;
+		m_fovy = 60.0f;
+		m_pingPong = 0;
+		m_restart = true;
+
+		// Enable m_debug text.
+		bgfx::setDebug(m_debug);
+
+		// Set view 0 clear state.
+		bgfx::setViewClear(0
+			, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
+			, 0x303030ff
+			, 1.0f
+			, 0
+			);
+
+		bgfx::setViewClear(1
+			, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
+			, 0x303030ff
+			, 1.0f
+			, 0
+			);
+
+		// Imgui.
+		imguiCreate();
+
+		m_timeOffset = bx::getHPCounter();
+
+		m_oldWidth = 0;
+		m_oldHeight = 0;
+		m_oldReset = m_reset;
+
+		cameraCreate();
+		cameraSetPosition({ 0.0f, 0.5f, 0.0f });
+		cameraSetVerticalAngle(0);
+
+		m_wireframe = false;
+		m_freeze = false;
+		m_cull = true;
+
+		loadPrograms();
+		loadBuffers();
+		loadTextures();
+
+		createAtomicCounters();
+
+		m_dispatchIndirect = bgfx::createIndirectBuffer(2);
+	}
+
+	virtual int shutdown() override
+	{
+		// Cleanup.
+		cameraDestroy();
+		imguiDestroy();
+
+		m_uniforms.destroy();
+
+		bgfx::destroy(m_bufferCounter);
+		bgfx::destroy(m_bufferCulledSubd);
+		bgfx::destroy(m_bufferSubd[0]);
+		bgfx::destroy(m_bufferSubd[1]);
+		bgfx::destroy(m_dispatchIndirect);
+		bgfx::destroy(m_geometryIndices);
+		bgfx::destroy(m_geometryVertices);
+		bgfx::destroy(m_instancedGeometryIndices);
+		bgfx::destroy(m_instancedGeometryVertices);
+
+		for (uint32_t i = 0; i < PROGRAM_COUNT; ++i)
 		{
-			bgfx::destroy(u_params);
+			bgfx::destroy(m_programsCompute[i]);
 		}
 
-		union
+		for (uint32_t i = 0; i < SHADING_COUNT; ++i)
 		{
-			struct
-			{
-				float dmapFactor;
-				float lodFactor;
-				float cull;
-				float freeze;
-
-				float gpuSubd;
-				float padding0;
-				float padding1;
-				float padding2;
-			};
-
-			float params[kNumVec4 * 4];
-		};
+			bgfx::destroy(m_programsDraw[i]);
+		}
 
-		bgfx::UniformHandle u_params;
-	};
-	class ExampleTessellation : public entry::AppI
-	{
-	public:
-		ExampleTessellation(const char* _name, const char* _description, const char* _url)
-			: entry::AppI(_name, _description, _url)
+		for (uint32_t i = 0; i < SAMPLER_COUNT; ++i)
 		{
+			bgfx::destroy(m_samplers[i]);
 		}
 
-		void init(int32_t _argc, const char* const* _argv, uint32_t _width, uint32_t _height) override
+		for (uint32_t i = 0; i < TEXTURE_COUNT; ++i)
 		{
-			Args args(_argc, _argv);
-
-			m_width = _width;
-			m_height = _height;
-			m_debug = BGFX_DEBUG_NONE;
-			m_reset = BGFX_RESET_NONE;
-
-			bgfx::Init init;
-			init.type = args.m_type;
-			init.vendorId = args.m_pciId;
-			init.resolution.width = m_width;
-			init.resolution.height = m_height;
-			init.resolution.reset = m_reset;
-			bgfx::init(init);
-
-			m_dmap = { "textures/dmap.png", 0.45f };
-			m_computeThreadCount = 5;
-			m_shading = PROGRAM_TERRAIN;
-			m_primitivePixelLengthTarget = 7.0f;
-			m_fovy = 60.0f;
-			m_pingPong = 0;
-			m_restart = true;
-
-			// Enable m_debug text.
-			bgfx::setDebug(m_debug);
-
-			// Set view 0 clear state.
-			bgfx::setViewClear(0
-				, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
-				, 0x303030ff
-				, 1.0f
-				, 0
-				);
-
-			bgfx::setViewClear(1
-				, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
-				, 0x303030ff
-				, 1.0f
-				, 0
-				);
-
-			// Imgui.
-			imguiCreate();
-
-			m_timeOffset = bx::getHPCounter();
-
-			m_oldWidth = 0;
-			m_oldHeight = 0;
-			m_oldReset = m_reset;
-
-			cameraCreate();
-			cameraSetPosition({ 0.0f, 0.5f, 0.0f });
-			cameraSetVerticalAngle(0);
+			bgfx::destroy(m_textures[i]);
+		}
 
-			m_wireframe = false;
-			m_freeze = false;
-			m_cull = true;
+		// Shutdown bgfx.
+		bgfx::shutdown();
 
-			loadPrograms();
-			loadBuffers();
-			loadTextures();
+		return 0;
+	}
 
-			createAtomicCounters();
+	bool update() override
+	{
+		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
+		{
+			int64_t now = bx::getHPCounter();
+			static int64_t last = now;
+			const int64_t frameTime = now - last;
+			last = now;
+			const double freq = double(bx::getHPFrequency() );
+			const float deltaTime = float(frameTime / freq);
+
+			imguiBeginFrame(
+					m_mouseState.m_mx
+				, m_mouseState.m_my
+				, (m_mouseState.m_buttons[entry::MouseButton::Left]   ? IMGUI_MBUT_LEFT   : 0)
+				| (m_mouseState.m_buttons[entry::MouseButton::Right]  ? IMGUI_MBUT_RIGHT  : 0)
+				| (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0)
+				, m_mouseState.m_mz
+				, uint16_t(m_width)
+				, uint16_t(m_height)
+				);
 
-			m_dispatchIndirect = bgfx::createIndirectBuffer(2);
-		}
+			showExampleDialog(this);
 
-		virtual int shutdown() override
-		{
-			// Cleanup.
-			cameraDestroy();
-			imguiDestroy();
-
-			m_uniforms.destroy();
-
-			bgfx::destroy(m_bufferCounter);
-			bgfx::destroy(m_bufferCulledSubd);
-			bgfx::destroy(m_bufferSubd[0]);
-			bgfx::destroy(m_bufferSubd[1]);
-			bgfx::destroy(m_dispatchIndirect);
-			bgfx::destroy(m_geometryIndices);
-			bgfx::destroy(m_geometryVertices);
-			bgfx::destroy(m_instancedGeometryIndices);
-			bgfx::destroy(m_instancedGeometryVertices);
-
-			for (uint32_t i = 0; i < PROGRAM_COUNT; ++i)
-			{
-				bgfx::destroy(m_programsCompute[i]);
-			}
+			ImGui::SetNextWindowPos(
+					ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f)
+				, ImGuiCond_FirstUseEver
+				);
+			ImGui::SetNextWindowSize(
+					ImVec2(m_width / 5.0f, m_height / 3.0f)
+				, ImGuiCond_FirstUseEver
+				);
+			ImGui::Begin("Settings", NULL, 0);
 
-			for (uint32_t i = 0; i < SHADING_COUNT; ++i)
+			if (ImGui::Checkbox("Debug wireframe", &m_wireframe) )
 			{
-				bgfx::destroy(m_programsDraw[i]);
+				bgfx::setDebug(m_wireframe
+					? BGFX_DEBUG_WIREFRAME
+					: BGFX_DEBUG_NONE
+					);
 			}
 
-			for (uint32_t i = 0; i < SAMPLER_COUNT; ++i)
-			{
-				bgfx::destroy(m_samplers[i]);
-			}
+			ImGui::SameLine();
 
-			for (uint32_t i = 0; i < TEXTURE_COUNT; ++i)
+			if (ImGui::Checkbox("Cull", &m_cull) )
 			{
-				bgfx::destroy(m_textures[i]);
+				m_uniforms.cull = m_cull ? 1.0f : 0.0f;
 			}
 
-			// Shutdown bgfx.
-			bgfx::shutdown();
+			ImGui::SameLine();
 
-			return 0;
-		}
-
-		bool update() override
-		{
-			if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
+			if (ImGui::Checkbox("Freeze subdividing", &m_freeze) )
 			{
-				int64_t now = bx::getHPCounter();
-				static int64_t last = now;
-				const int64_t frameTime = now - last;
-				last = now;
-				const double freq = double(bx::getHPFrequency() );
-				const float deltaTime = float(frameTime / freq);
-
-				imguiBeginFrame(
-					  m_mouseState.m_mx
-					, m_mouseState.m_my
-					, (m_mouseState.m_buttons[entry::MouseButton::Left]   ? IMGUI_MBUT_LEFT   : 0)
-					| (m_mouseState.m_buttons[entry::MouseButton::Right]  ? IMGUI_MBUT_RIGHT  : 0)
-					| (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0)
-					, m_mouseState.m_mz
-					, uint16_t(m_width)
-					, uint16_t(m_height)
-					);
-
-				showExampleDialog(this);
-
-				ImGui::SetNextWindowPos(
-					  ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f)
-					, ImGuiCond_FirstUseEver
-					);
-				ImGui::SetNextWindowSize(
-					  ImVec2(m_width / 5.0f, m_height / 3.0f)
-					, ImGuiCond_FirstUseEver
-					);
-				ImGui::Begin("Settings", NULL, 0);
-
-				if (ImGui::Checkbox("Debug wireframe", &m_wireframe) )
-				{
-					bgfx::setDebug(m_wireframe
-						? BGFX_DEBUG_WIREFRAME
-						: BGFX_DEBUG_NONE
-						);
-				}
-
-				ImGui::SameLine();
-
-				if (ImGui::Checkbox("Cull", &m_cull) )
-				{
-					m_uniforms.cull = m_cull ? 1.0f : 0.0f;
-				}
-
-				ImGui::SameLine();
-
-				if (ImGui::Checkbox("Freeze subdividing", &m_freeze) )
-				{
-					m_uniforms.freeze = m_freeze ? 1.0f : 0.0f;
-				}
-
-
-				ImGui::SliderFloat("Pixels per edge", &m_primitivePixelLengthTarget, 1, 20);
-
-				int gpuSlider = (int)m_uniforms.gpuSubd;
+				m_uniforms.freeze = m_freeze ? 1.0f : 0.0f;
+			}
 
-				if (ImGui::SliderInt("Triangle Patch level", &gpuSlider, 0, 3) )
-				{
-					m_restart = true;
-					m_uniforms.gpuSubd = float(gpuSlider);
-				}
 
-				ImGui::Combo("Shading", &m_shading, s_shaderOptions, 2);
+			ImGui::SliderFloat("Pixels per edge", &m_primitivePixelLengthTarget, 1, 20);
 
-				ImGui::Text("Some variables require rebuilding the subdivide buffers and causes a stutter.");
+			int gpuSlider = (int)m_uniforms.gpuSubd;
 
-				ImGui::End();
+			if (ImGui::SliderInt("Triangle Patch level", &gpuSlider, 0, 3) )
+			{
+				m_restart = true;
+				m_uniforms.gpuSubd = float(gpuSlider);
+			}
 
-				// Update camera.
-				cameraUpdate(deltaTime*0.01f, m_mouseState, ImGui::MouseOverArea() );
+			ImGui::Combo("Shading", &m_shading, s_shaderOptions, 2);
 
-				bgfx::touch(0);
-				bgfx::touch(1);
+			ImGui::Text("Some variables require rebuilding the subdivide buffers and causes a stutter.");
 
-				configureUniforms();
+			ImGui::End();
 
-				cameraGetViewMtx(m_viewMtx);
+			// Update camera.
+			cameraUpdate(deltaTime*0.01f, m_mouseState, ImGui::MouseOverArea() );
 
-				float model[16];
+			bgfx::touch(0);
+			bgfx::touch(1);
 
-				bx::mtxRotateX(model, bx::toRad(90) );
+			configureUniforms();
 
-				bx::mtxProj(m_projMtx, m_fovy, float(m_width) / float(m_height), 0.0001f, 2000.0f, bgfx::getCaps()->homogeneousDepth);
+			cameraGetViewMtx(m_viewMtx);
 
-				// Set view 0
-				bgfx::setViewTransform(0, m_viewMtx, m_projMtx);
+			float model[16];
 
-				// Set view 1
-				bgfx::setViewRect(1, 0, 0, uint16_t(m_width), uint16_t(m_height) );
-				bgfx::setViewTransform(1, m_viewMtx, m_projMtx);
+			bx::mtxRotateX(model, bx::toRad(90) );
 
-				m_uniforms.submit();
+			bx::mtxProj(m_projMtx, m_fovy, float(m_width) / float(m_height), 0.0001f, 2000.0f, bgfx::getCaps()->homogeneousDepth);
 
-				// update the subd buffers
-				if (m_restart)
-				{
-					m_pingPong = 1;
+			// Set view 0
+			bgfx::setViewTransform(0, m_viewMtx, m_projMtx);
 
-					bgfx::destroy(m_instancedGeometryVertices);
-					bgfx::destroy(m_instancedGeometryIndices);
+			// Set view 1
+			bgfx::setViewRect(1, 0, 0, uint16_t(m_width), uint16_t(m_height) );
+			bgfx::setViewTransform(1, m_viewMtx, m_projMtx);
 
-					bgfx::destroy(m_bufferSubd[BUFFER_SUBD]);
-					bgfx::destroy(m_bufferSubd[BUFFER_SUBD + 1]);
-					bgfx::destroy(m_bufferCulledSubd);
+			m_uniforms.submit();
 
-					loadInstancedGeometryBuffers();
-					loadSubdivisionBuffers();
+			// update the subd buffers
+			if (m_restart)
+			{
+				m_pingPong = 1;
 
-					//init indirect
-					bgfx::setBuffer(1, m_bufferSubd[m_pingPong], bgfx::Access::ReadWrite);
-					bgfx::setBuffer(2, m_bufferCulledSubd, bgfx::Access::ReadWrite);
-					bgfx::setBuffer(3, m_dispatchIndirect, bgfx::Access::ReadWrite);
-					bgfx::setBuffer(4, m_bufferCounter, bgfx::Access::ReadWrite);
-					bgfx::setBuffer(8, m_bufferSubd[1 - m_pingPong], bgfx::Access::ReadWrite);
-					bgfx::dispatch(0, m_programsCompute[PROGRAM_INIT_INDIRECT], 1, 1, 1);
+				bgfx::destroy(m_instancedGeometryVertices);
+				bgfx::destroy(m_instancedGeometryIndices);
 
+				bgfx::destroy(m_bufferSubd[BUFFER_SUBD]);
+				bgfx::destroy(m_bufferSubd[BUFFER_SUBD + 1]);
+				bgfx::destroy(m_bufferCulledSubd);
 
-					m_restart = false;
-				}
-				else
-				{
-					// update batch
-					bgfx::setBuffer(3, m_dispatchIndirect, bgfx::Access::ReadWrite);
-					bgfx::setBuffer(4, m_bufferCounter, bgfx::Access::ReadWrite);
-					bgfx::dispatch(0, m_programsCompute[PROGRAM_UPDATE_INDIRECT], 1, 1, 1);
-				}
+				loadInstancedGeometryBuffers();
+				loadSubdivisionBuffers();
 
+				//init indirect
 				bgfx::setBuffer(1, m_bufferSubd[m_pingPong], bgfx::Access::ReadWrite);
 				bgfx::setBuffer(2, m_bufferCulledSubd, bgfx::Access::ReadWrite);
+				bgfx::setBuffer(3, m_dispatchIndirect, bgfx::Access::ReadWrite);
 				bgfx::setBuffer(4, m_bufferCounter, bgfx::Access::ReadWrite);
-				bgfx::setBuffer(6, m_geometryVertices, bgfx::Access::Read);
-				bgfx::setBuffer(7, m_geometryIndices, bgfx::Access::Read);
-				bgfx::setBuffer(8, m_bufferSubd[1 - m_pingPong], bgfx::Access::Read);
-				bgfx::setTransform(model);
-
-				bgfx::setTexture(0, m_samplers[TERRAIN_DMAP_SAMPLER], m_textures[TEXTURE_DMAP], BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP);
-
-				m_uniforms.submit();
+				bgfx::setBuffer(8, m_bufferSubd[1 - m_pingPong], bgfx::Access::ReadWrite);
+				bgfx::dispatch(0, m_programsCompute[PROGRAM_INIT_INDIRECT], 1, 1, 1);
 
-				// update the subd buffer
-				bgfx::dispatch(0, m_programsCompute[PROGRAM_SUBD_CS_LOD], m_dispatchIndirect, 1);
 
-				// update draw
+				m_restart = false;
+			}
+			else
+			{
+				// update batch
 				bgfx::setBuffer(3, m_dispatchIndirect, bgfx::Access::ReadWrite);
 				bgfx::setBuffer(4, m_bufferCounter, bgfx::Access::ReadWrite);
+				bgfx::dispatch(0, m_programsCompute[PROGRAM_UPDATE_INDIRECT], 1, 1, 1);
+			}
 
-				m_uniforms.submit();
+			bgfx::setBuffer(1, m_bufferSubd[m_pingPong], bgfx::Access::ReadWrite);
+			bgfx::setBuffer(2, m_bufferCulledSubd, bgfx::Access::ReadWrite);
+			bgfx::setBuffer(4, m_bufferCounter, bgfx::Access::ReadWrite);
+			bgfx::setBuffer(6, m_geometryVertices, bgfx::Access::Read);
+			bgfx::setBuffer(7, m_geometryIndices, bgfx::Access::Read);
+			bgfx::setBuffer(8, m_bufferSubd[1 - m_pingPong], bgfx::Access::Read);
+			bgfx::setTransform(model);
 
-				bgfx::dispatch(1, m_programsCompute[PROGRAM_UPDATE_DRAW], 1, 1, 1);
+			bgfx::setTexture(0, m_samplers[TERRAIN_DMAP_SAMPLER], m_textures[TEXTURE_DMAP], BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP);
 
-				// render the terrain
-				bgfx::setTexture(0, m_samplers[TERRAIN_DMAP_SAMPLER], m_textures[TEXTURE_DMAP], BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP);
-				bgfx::setTexture(1, m_samplers[TERRAIN_SMAP_SAMPLER], m_textures[TEXTURE_SMAP], BGFX_SAMPLER_MIN_ANISOTROPIC | BGFX_SAMPLER_MAG_ANISOTROPIC);
+			m_uniforms.submit();
 
-				bgfx::setTransform(model);
-				bgfx::setVertexBuffer(0, m_instancedGeometryVertices);
-				bgfx::setIndexBuffer(m_instancedGeometryIndices);
-				bgfx::setBuffer(2, m_bufferCulledSubd, bgfx::Access::Read);
-				bgfx::setBuffer(3, m_geometryVertices, bgfx::Access::Read);
-				bgfx::setBuffer(4, m_geometryIndices, bgfx::Access::Read);
-				bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_Z | BGFX_STATE_DEPTH_TEST_LESS);
+			// update the subd buffer
+			bgfx::dispatch(0, m_programsCompute[PROGRAM_SUBD_CS_LOD], m_dispatchIndirect, 1);
 
-				m_uniforms.submit();
+			// update draw
+			bgfx::setBuffer(3, m_dispatchIndirect, bgfx::Access::ReadWrite);
+			bgfx::setBuffer(4, m_bufferCounter, bgfx::Access::ReadWrite);
 
-				bgfx::submit(1, m_programsDraw[m_shading], m_dispatchIndirect);
+			m_uniforms.submit();
 
-				m_pingPong = 1 - m_pingPong;
+			bgfx::dispatch(1, m_programsCompute[PROGRAM_UPDATE_DRAW], 1, 1, 1);
 
-				imguiEndFrame();
+			// render the terrain
+			bgfx::setTexture(0, m_samplers[TERRAIN_DMAP_SAMPLER], m_textures[TEXTURE_DMAP], BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP);
+			bgfx::setTexture(1, m_samplers[TERRAIN_SMAP_SAMPLER], m_textures[TEXTURE_SMAP], BGFX_SAMPLER_MIN_ANISOTROPIC | BGFX_SAMPLER_MAG_ANISOTROPIC);
 
-				// Advance to next frame. Rendering thread will be kicked to
-				// process submitted rendering primitives.
-				bgfx::frame(false);
+			bgfx::setTransform(model);
+			bgfx::setVertexBuffer(0, m_instancedGeometryVertices);
+			bgfx::setIndexBuffer(m_instancedGeometryIndices);
+			bgfx::setBuffer(2, m_bufferCulledSubd, bgfx::Access::Read);
+			bgfx::setBuffer(3, m_geometryVertices, bgfx::Access::Read);
+			bgfx::setBuffer(4, m_geometryIndices, bgfx::Access::Read);
+			bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_Z | BGFX_STATE_DEPTH_TEST_LESS);
 
-				return true;
-			}
+			m_uniforms.submit();
 
-			return false;
-		}
-
-		void createAtomicCounters()
-		{
-			m_bufferCounter = bgfx::createDynamicIndexBuffer(3, BGFX_BUFFER_INDEX32 | BGFX_BUFFER_COMPUTE_READ_WRITE);
-		}
+			bgfx::submit(1, m_programsDraw[m_shading], m_dispatchIndirect);
 
-		void configureUniforms()
-		{
-			float lodFactor = 2.0f * bx::tan(bx::toRad(m_fovy) / 2.0f)
-				/ m_width * (1 << (int)m_uniforms.gpuSubd)
-				* m_primitivePixelLengthTarget;
+			m_pingPong = 1 - m_pingPong;
 
-			m_uniforms.lodFactor = lodFactor;
-			m_uniforms.dmapFactor = m_dmap.scale;
-		}
+			imguiEndFrame();
 
-		/**
-		* Load the Terrain Program
-		*
-		* This program renders an adaptive terrain using the implicit subdivision
-		* technique described in GPU Zen 2.
-		**/
-		void loadPrograms()
-		{
-			m_samplers[TERRAIN_DMAP_SAMPLER] = bgfx::createUniform("u_DmapSampler", bgfx::UniformType::Sampler);
-			m_samplers[TERRAIN_SMAP_SAMPLER] = bgfx::createUniform("u_SmapSampler", bgfx::UniformType::Sampler);
+			// Advance to next frame. Rendering thread will be kicked to
+			// process submitted rendering primitives.
+			bgfx::frame(false);
 
-			m_uniforms.init();
+			return true;
+		}
 
-			m_programsDraw[PROGRAM_TERRAIN] = loadProgram("vs_terrain_render", "fs_terrain_render");
-			m_programsDraw[PROGRAM_TERRAIN_NORMAL] = loadProgram("vs_terrain_render", "fs_terrain_render_normal");
+		return false;
+	}
 
-			m_programsCompute[PROGRAM_SUBD_CS_LOD] = bgfx::createProgram(loadShader("cs_terrain_lod"), true);
-			m_programsCompute[PROGRAM_UPDATE_INDIRECT] = bgfx::createProgram(loadShader("cs_terrain_update_indirect"), true);
-			m_programsCompute[PROGRAM_UPDATE_DRAW] = bgfx::createProgram(loadShader("cs_terrain_update_draw"), true);
-			m_programsCompute[PROGRAM_INIT_INDIRECT] = bgfx::createProgram(loadShader("cs_terrain_init"), true);
-		}
+	void createAtomicCounters()
+	{
+		m_bufferCounter = bgfx::createDynamicIndexBuffer(3, BGFX_BUFFER_INDEX32 | BGFX_BUFFER_COMPUTE_READ_WRITE);
+	}
 
-		void loadSmapTexture()
-		{
-			int w = dmap->m_width;
-			int h = dmap->m_height;
+	void configureUniforms()
+	{
+		float lodFactor = 2.0f * bx::tan(bx::toRad(m_fovy) / 2.0f)
+			/ m_width * (1 << (int)m_uniforms.gpuSubd)
+			* m_primitivePixelLengthTarget
+			;
+
+		m_uniforms.lodFactor = lodFactor;
+		m_uniforms.dmapFactor = m_dmap.scale;
+	}
+
+	/**
+	 * Load the Terrain Program
+	 *
+	 * This program renders an adaptive terrain using the implicit subdivision
+	 * technique described in GPU Zen 2.
+	 **/
+	void loadPrograms()
+	{
+		m_samplers[TERRAIN_DMAP_SAMPLER] = bgfx::createUniform("u_DmapSampler", bgfx::UniformType::Sampler);
+		m_samplers[TERRAIN_SMAP_SAMPLER] = bgfx::createUniform("u_SmapSampler", bgfx::UniformType::Sampler);
 
-			const uint16_t *texels = (const uint16_t *)dmap->m_data;
+		m_uniforms.init();
 
-			int mipcnt = dmap->m_numMips;
+		m_programsDraw[PROGRAM_TERRAIN] = loadProgram("vs_terrain_render", "fs_terrain_render");
+		m_programsDraw[PROGRAM_TERRAIN_NORMAL] = loadProgram("vs_terrain_render", "fs_terrain_render_normal");
 
-			const bgfx::Memory* mem = bgfx::alloc(w * h * 2 * sizeof(float) );
-			float* smap = (float*)mem->data;
+		m_programsCompute[PROGRAM_SUBD_CS_LOD] = bgfx::createProgram(loadShader("cs_terrain_lod"), true);
+		m_programsCompute[PROGRAM_UPDATE_INDIRECT] = bgfx::createProgram(loadShader("cs_terrain_update_indirect"), true);
+		m_programsCompute[PROGRAM_UPDATE_DRAW] = bgfx::createProgram(loadShader("cs_terrain_update_draw"), true);
+		m_programsCompute[PROGRAM_INIT_INDIRECT] = bgfx::createProgram(loadShader("cs_terrain_init"), true);
+	}
 
-			for (int j = 0; j < h; ++j)
-			{
-				for (int i = 0; i < w; ++i)
-				{
-					int i1 = bx::max(0, i - 1);
-					int i2 = bx::min(w - 1, i + 1);
-					int j1 = bx::max(0, j - 1);
-					int j2 = bx::min(h - 1, j + 1);
-					uint16_t px_l = texels[i1 + w * j]; // in [0,2^16-1]
-					uint16_t px_r = texels[i2 + w * j]; // in [0,2^16-1]
-					uint16_t px_b = texels[i + w * j1]; // in [0,2^16-1]
-					uint16_t px_t = texels[i + w * j2]; // in [0,2^16-1]
-					float z_l = (float)px_l / 65535.0f; // in [0, 1]
-					float z_r = (float)px_r / 65535.0f; // in [0, 1]
-					float z_b = (float)px_b / 65535.0f; // in [0, 1]
-					float z_t = (float)px_t / 65535.0f; // in [0, 1]
-					float slope_x = (float)w * 0.5f * (z_r - z_l);
-					float slope_y = (float)h * 0.5f * (z_t - z_b);
-
-					smap[2 * (i + w * j)] = slope_x;
-					smap[1 + 2 * (i + w * j)] = slope_y;
-				}
-			}
+	void loadSmapTexture()
+	{
+		int w = dmap->m_width;
+		int h = dmap->m_height;
 
-			m_textures[TEXTURE_SMAP] = bgfx::createTexture2D(
-				  (uint16_t)w
-				, (uint16_t)h
-				, mipcnt > 1
-				, 1
-				, bgfx::TextureFormat::RG32F
-				, BGFX_TEXTURE_NONE
-				, mem
-				);
-		}
+		const uint16_t *texels = (const uint16_t *)dmap->m_data;
 
-		/**
-		 * Load the Displacement Texture
-		 *
-		 * This loads an R16 texture used as a displacement map
-		 */
-		void loadDmapTexture()
-		{
-			dmap = imageLoad(m_dmap.pathToFile.getCPtr(), bgfx::TextureFormat::R16);
-
-			m_textures[TEXTURE_DMAP] = bgfx::createTexture2D(
-				  (uint16_t)dmap->m_width
-				, (uint16_t)dmap->m_height
-				, false
-				, 1
-				, bgfx::TextureFormat::R16
-				, BGFX_TEXTURE_NONE
-				, bgfx::makeRef(dmap->m_data, dmap->m_size)
-				);
-		}
+		int mipcnt = dmap->m_numMips;
 
-		/**
-		 * Load All Textures
-		 */
-		void loadTextures()
-		{
-			loadDmapTexture();
-			loadSmapTexture();
-		}
+		const bgfx::Memory* mem = bgfx::alloc(w * h * 2 * sizeof(float) );
+		float* smap = (float*)mem->data;
 
-		/**
-		 * Load the Geometry Buffer
-		 *
-		 * This procedure loads the scene geometry into an index and
-		 * vertex buffer. Here, we only load 2 triangles to define the
-		 * terrain.
-		 **/
-		void loadGeometryBuffers()
+		for (int j = 0; j < h; ++j)
 		{
-			const float vertices[] =
+			for (int i = 0; i < w; ++i)
 			{
-				-1.0f, -1.0f, 0.0f, 1.0f,
-				+1.0f, -1.0f, 0.0f, 1.0f,
-				+1.0f, +1.0f, 0.0f, 1.0f,
-				-1.0f, +1.0f, 0.0f, 1.0f,
-			};
-
-			const uint32_t indices[] = { 0, 1, 3, 2, 3, 1 };
-
-			m_geometryLayout.begin().add(bgfx::Attrib::Position, 4, bgfx::AttribType::Float).end();
-
-			m_geometryVertices = bgfx::createVertexBuffer(
-				  bgfx::copy(vertices, sizeof(vertices) )
-				, m_geometryLayout
-				, BGFX_BUFFER_COMPUTE_READ
-				);
-			m_geometryIndices = bgfx::createIndexBuffer(
-				  bgfx::copy(indices, sizeof(indices) )
-				, BGFX_BUFFER_COMPUTE_READ | BGFX_BUFFER_INDEX32
-				);
+				int i1 = bx::max(0, i - 1);
+				int i2 = bx::min(w - 1, i + 1);
+				int j1 = bx::max(0, j - 1);
+				int j2 = bx::min(h - 1, j + 1);
+				uint16_t px_l = texels[i1 + w * j]; // in [0,2^16-1]
+				uint16_t px_r = texels[i2 + w * j]; // in [0,2^16-1]
+				uint16_t px_b = texels[i + w * j1]; // in [0,2^16-1]
+				uint16_t px_t = texels[i + w * j2]; // in [0,2^16-1]
+				float z_l = (float)px_l / 65535.0f; // in [0, 1]
+				float z_r = (float)px_r / 65535.0f; // in [0, 1]
+				float z_b = (float)px_b / 65535.0f; // in [0, 1]
+				float z_t = (float)px_t / 65535.0f; // in [0, 1]
+				float slope_x = (float)w * 0.5f * (z_r - z_l);
+				float slope_y = (float)h * 0.5f * (z_t - z_b);
+
+				smap[2 * (i + w * j)] = slope_x;
+				smap[1 + 2 * (i + w * j)] = slope_y;
+			}
 		}
 
-		void loadSubdivisionBuffers()
+		m_textures[TEXTURE_SMAP] = bgfx::createTexture2D(
+			  (uint16_t)w
+			, (uint16_t)h
+			, mipcnt > 1
+			, 1
+			, bgfx::TextureFormat::RG32F
+			, BGFX_TEXTURE_NONE
+			, mem
+			);
+	}
+
+	/**
+	 * Load the Displacement Texture
+	 *
+	 * This loads an R16 texture used as a displacement map
+	 */
+	void loadDmapTexture()
+	{
+		dmap = imageLoad(m_dmap.pathToFile.getCPtr(), bgfx::TextureFormat::R16);
+
+		m_textures[TEXTURE_DMAP] = bgfx::createTexture2D(
+				(uint16_t)dmap->m_width
+			, (uint16_t)dmap->m_height
+			, false
+			, 1
+			, bgfx::TextureFormat::R16
+			, BGFX_TEXTURE_NONE
+			, bgfx::makeRef(dmap->m_data, dmap->m_size)
+			);
+	}
+
+	void loadTextures()
+	{
+		loadDmapTexture();
+		loadSmapTexture();
+	}
+
+	/**
+	 * Load the Geometry Buffer
+	 *
+	 * This procedure loads the scene geometry into an index and
+	 * vertex buffer. Here, we only load 2 triangles to define the
+	 * terrain.
+	 **/
+	void loadGeometryBuffers()
+	{
+		const float vertices[] =
 		{
-			const uint32_t bufferCapacity = 1 << 27;
+			-1.0f, -1.0f, 0.0f, 1.0f,
+			+1.0f, -1.0f, 0.0f, 1.0f,
+			+1.0f, +1.0f, 0.0f, 1.0f,
+			-1.0f, +1.0f, 0.0f, 1.0f,
+		};
 
-			m_bufferSubd[BUFFER_SUBD] = bgfx::createDynamicIndexBuffer(
-				  bufferCapacity
-				, BGFX_BUFFER_COMPUTE_READ_WRITE | BGFX_BUFFER_INDEX32
-				);
+		const uint32_t indices[] = { 0, 1, 3, 2, 3, 1 };
 
-			m_bufferSubd[BUFFER_SUBD + 1] = bgfx::createDynamicIndexBuffer(
-				  bufferCapacity
-				, BGFX_BUFFER_COMPUTE_READ_WRITE | BGFX_BUFFER_INDEX32
-				);
-
-			m_bufferCulledSubd = bgfx::createDynamicIndexBuffer(
-				  bufferCapacity
-				, BGFX_BUFFER_COMPUTE_READ_WRITE | BGFX_BUFFER_INDEX32
-				);
-		}
+		m_geometryLayout.begin().add(bgfx::Attrib::Position, 4, bgfx::AttribType::Float).end();
 
-		/**
-		 * Load All Buffers
-		 *
-		 */
-		void loadBuffers()
-		{
-			loadSubdivisionBuffers();
-			loadGeometryBuffers();
-			loadInstancedGeometryBuffers();
-		}
+		m_geometryVertices = bgfx::createVertexBuffer(
+				bgfx::copy(vertices, sizeof(vertices) )
+			, m_geometryLayout
+			, BGFX_BUFFER_COMPUTE_READ
+			);
+		m_geometryIndices = bgfx::createIndexBuffer(
+				bgfx::copy(indices, sizeof(indices) )
+			, BGFX_BUFFER_COMPUTE_READ | BGFX_BUFFER_INDEX32
+			);
+	}
 
-		/**
-		* This will be used to instantiate a triangle grid for each subdivision
-		* key present in the subd buffer.
+	void loadSubdivisionBuffers()
+	{
+		const uint32_t bufferCapacity = 1 << 27;
+
+		m_bufferSubd[BUFFER_SUBD] = bgfx::createDynamicIndexBuffer(
+			  bufferCapacity
+			, BGFX_BUFFER_COMPUTE_READ_WRITE | BGFX_BUFFER_INDEX32
+			);
+
+		m_bufferSubd[BUFFER_SUBD + 1] = bgfx::createDynamicIndexBuffer(
+			  bufferCapacity
+			, BGFX_BUFFER_COMPUTE_READ_WRITE | BGFX_BUFFER_INDEX32
+			);
+
+		m_bufferCulledSubd = bgfx::createDynamicIndexBuffer(
+			  bufferCapacity
+			, BGFX_BUFFER_COMPUTE_READ_WRITE | BGFX_BUFFER_INDEX32
+			);
+	}
+
+	/**
+		* Load All Buffers
+		*
 		*/
-		void loadInstancedGeometryBuffers()
-		{
-			const float* vertices;
-			const uint32_t* indexes;
+	void loadBuffers()
+	{
+		loadSubdivisionBuffers();
+		loadGeometryBuffers();
+		loadInstancedGeometryBuffers();
+	}
+
+	/**
+	* This will be used to instantiate a triangle grid for each subdivision
+	* key present in the subd buffer.
+	*/
+	void loadInstancedGeometryBuffers()
+	{
+		const float* vertices;
+		const uint32_t* indexes;
 
-			switch (int32_t(m_uniforms.gpuSubd) )
-			{
-			case 0:
-				m_instancedMeshVertexCount = 3;
-				m_instancedMeshPrimitiveCount = 1;
-				vertices = s_verticesL0;
-				indexes  = s_indexesL0;
-				break;
-
-			case 1:
-				m_instancedMeshVertexCount = 6;
-				m_instancedMeshPrimitiveCount = 4;
-				vertices = s_verticesL1;
-				indexes  = s_indexesL1;
-				break;
-
-			case 2:
-				m_instancedMeshVertexCount = 15;
-				m_instancedMeshPrimitiveCount = 16;
-				vertices = s_verticesL2;
-				indexes  = s_indexesL2;
-				break;
-
-			default:
-				m_instancedMeshVertexCount = 45;
-				m_instancedMeshPrimitiveCount = 64;
-				vertices = s_verticesL3;
-				indexes  = s_indexesL3;
-				break;
-			}
+		switch (int32_t(m_uniforms.gpuSubd) )
+		{
+		case 0:
+			m_instancedMeshVertexCount = 3;
+			m_instancedMeshPrimitiveCount = 1;
+			vertices = s_verticesL0;
+			indexes  = s_indexesL0;
+			break;
+
+		case 1:
+			m_instancedMeshVertexCount = 6;
+			m_instancedMeshPrimitiveCount = 4;
+			vertices = s_verticesL1;
+			indexes  = s_indexesL1;
+			break;
+
+		case 2:
+			m_instancedMeshVertexCount = 15;
+			m_instancedMeshPrimitiveCount = 16;
+			vertices = s_verticesL2;
+			indexes  = s_indexesL2;
+			break;
+
+		default:
+			m_instancedMeshVertexCount = 45;
+			m_instancedMeshPrimitiveCount = 64;
+			vertices = s_verticesL3;
+			indexes  = s_indexesL3;
+			break;
+		}
 
-			m_instancedGeometryLayout
-				.begin()
-				.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
-				.end();
+		m_instancedGeometryLayout
+			.begin()
+			.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
+			.end();
 
-			m_instancedGeometryVertices = bgfx::createVertexBuffer(
-				  bgfx::makeRef(vertices, sizeof(float) * 2 * m_instancedMeshVertexCount)
-				, m_instancedGeometryLayout
-				);
+		m_instancedGeometryVertices = bgfx::createVertexBuffer(
+			  bgfx::makeRef(vertices, sizeof(float) * 2 * m_instancedMeshVertexCount)
+			, m_instancedGeometryLayout
+			);
 
-			m_instancedGeometryIndices  = bgfx::createIndexBuffer(
-				  bgfx::makeRef(indexes, sizeof(uint32_t) * m_instancedMeshPrimitiveCount * 3)
-				, BGFX_BUFFER_INDEX32
-				);
-		}
+		m_instancedGeometryIndices  = bgfx::createIndexBuffer(
+			  bgfx::makeRef(indexes, sizeof(uint32_t) * m_instancedMeshPrimitiveCount * 3)
+			, BGFX_BUFFER_INDEX32
+			);
+	}
 
-		Uniforms m_uniforms;
+	Uniforms m_uniforms;
 
-		bgfx::ProgramHandle m_programsCompute[PROGRAM_COUNT];
-		bgfx::ProgramHandle m_programsDraw[SHADING_COUNT];
-		bgfx::TextureHandle m_textures[TEXTURE_COUNT];
-		bgfx::UniformHandle m_samplers[SAMPLER_COUNT];
+	bgfx::ProgramHandle m_programsCompute[PROGRAM_COUNT];
+	bgfx::ProgramHandle m_programsDraw[SHADING_COUNT];
+	bgfx::TextureHandle m_textures[TEXTURE_COUNT];
+	bgfx::UniformHandle m_samplers[SAMPLER_COUNT];
 
-		bgfx::DynamicIndexBufferHandle m_bufferSubd[2];
-		bgfx::DynamicIndexBufferHandle m_bufferCulledSubd;
+	bgfx::DynamicIndexBufferHandle m_bufferSubd[2];
+	bgfx::DynamicIndexBufferHandle m_bufferCulledSubd;
 
-		bgfx::DynamicIndexBufferHandle m_bufferCounter;
+	bgfx::DynamicIndexBufferHandle m_bufferCounter;
 
-		bgfx::IndexBufferHandle m_geometryIndices;
-		bgfx::VertexBufferHandle m_geometryVertices;
-		bgfx::VertexLayout m_geometryLayout;
+	bgfx::IndexBufferHandle m_geometryIndices;
+	bgfx::VertexBufferHandle m_geometryVertices;
+	bgfx::VertexLayout m_geometryLayout;
 
-		bgfx::IndexBufferHandle m_instancedGeometryIndices;
-		bgfx::VertexBufferHandle m_instancedGeometryVertices;
-		bgfx::VertexLayout m_instancedGeometryLayout;
+	bgfx::IndexBufferHandle m_instancedGeometryIndices;
+	bgfx::VertexBufferHandle m_instancedGeometryVertices;
+	bgfx::VertexLayout m_instancedGeometryLayout;
 
-		bgfx::IndirectBufferHandle m_dispatchIndirect;
+	bgfx::IndirectBufferHandle m_dispatchIndirect;
 
-		bimg::ImageContainer* dmap;
+	bimg::ImageContainer* dmap;
 
-		float m_viewMtx[16];
-		float m_projMtx[16];
+	float m_viewMtx[16];
+	float m_projMtx[16];
 
-		uint32_t m_width;
-		uint32_t m_height;
-		uint32_t m_debug;
-		uint32_t m_reset;
+	uint32_t m_width;
+	uint32_t m_height;
+	uint32_t m_debug;
+	uint32_t m_reset;
 
-		uint32_t m_oldWidth;
-		uint32_t m_oldHeight;
-		uint32_t m_oldReset;
+	uint32_t m_oldWidth;
+	uint32_t m_oldHeight;
+	uint32_t m_oldReset;
 
-		uint32_t m_instancedMeshVertexCount;
-		uint32_t m_instancedMeshPrimitiveCount;
+	uint32_t m_instancedMeshVertexCount;
+	uint32_t m_instancedMeshPrimitiveCount;
 
-		entry::MouseState m_mouseState;
+	entry::MouseState m_mouseState;
 
-		int64_t m_timeOffset;
+	int64_t m_timeOffset;
 
-		struct DMap
-		{
-			bx::FilePath pathToFile;
-			float scale;
-		};
+	struct DMap
+	{
+		bx::FilePath pathToFile;
+		float scale;
+	};
 
-		DMap m_dmap;
+	DMap m_dmap;
 
-		int m_computeThreadCount;
-		int m_shading;
-		int m_gpuSubd;
-		int m_pingPong;
+	int m_computeThreadCount;
+	int m_shading;
+	int m_gpuSubd;
+	int m_pingPong;
 
-		float m_primitivePixelLengthTarget;
-		float m_fovy;
+	float m_primitivePixelLengthTarget;
+	float m_fovy;
 
-		bool m_restart;
-		bool m_wireframe;
-		bool m_cull;
-		bool m_freeze;
-	};
+	bool m_restart;
+	bool m_wireframe;
+	bool m_cull;
+	bool m_freeze;
+};
 
 } // namespace
 

+ 2 - 0
examples/42-bunnylod/bunnylod.cpp

@@ -262,6 +262,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 4 - 3
examples/43-denoise/denoise.cpp

@@ -249,9 +249,10 @@ public:
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::Init init;
-		init.type = args.m_type;
-
-		init.vendorId          = args.m_pciId;
+		init.type     = args.m_type;
+		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;

+ 11 - 9
examples/44-sss/screen_space_shadows.cpp

@@ -261,12 +261,13 @@ public:
 		m_reset = BGFX_RESET_VSYNC;
 
 		bgfx::Init init;
-		init.type = args.m_type;
-
+		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
-		init.resolution.width = m_width;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
+		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
-		init.resolution.reset = m_reset;
+		init.resolution.reset  = m_reset;
 		bgfx::init(init);
 
 		// Enable debug text.
@@ -276,10 +277,10 @@ public:
 		m_uniforms.init();
 
 		// Create texture sampler uniforms (used when we bind textures)
-		s_albedo = bgfx::createUniform("s_albedo", bgfx::UniformType::Sampler); // Model's source albedo
-		s_color = bgfx::createUniform("s_color", bgfx::UniformType::Sampler); // Color (albedo) gbuffer, default color input
-		s_normal = bgfx::createUniform("s_normal", bgfx::UniformType::Sampler); // Normal gbuffer, Model's source normal
-		s_depth = bgfx::createUniform("s_depth", bgfx::UniformType::Sampler); // Depth gbuffer
+		s_albedo  = bgfx::createUniform("s_albedo", bgfx::UniformType::Sampler); // Model's source albedo
+		s_color   = bgfx::createUniform("s_color", bgfx::UniformType::Sampler); // Color (albedo) gbuffer, default color input
+		s_normal  = bgfx::createUniform("s_normal", bgfx::UniformType::Sampler); // Normal gbuffer, Model's source normal
+		s_depth   = bgfx::createUniform("s_depth", bgfx::UniformType::Sampler); // Depth gbuffer
 		s_shadows = bgfx::createUniform("s_shadows", bgfx::UniformType::Sampler);
 
 		// Create program from shaders.
@@ -382,7 +383,8 @@ public:
 		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState))
 		{
 			// skip processing when minimized, otherwise crashing
-			if (0 == m_width || 0 == m_height)
+			if (0 == m_width
+			||  0 == m_height)
 			{
 				return true;
 			}

+ 5 - 4
examples/45-bokeh/bokeh.cpp

@@ -243,12 +243,13 @@ public:
 		m_reset = BGFX_RESET_VSYNC;
 
 		bgfx::Init init;
-		init.type = args.m_type;
-
+		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
-		init.resolution.width = m_width;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
+		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
-		init.resolution.reset = m_reset;
+		init.resolution.reset  = m_reset;
 		bgfx::init(init);
 
 		// Enable debug text.

+ 640 - 639
examples/46-fsr/app.cpp

@@ -22,829 +22,830 @@ namespace
 #define FRAMEBUFFER_RT_DEPTH 1
 #define FRAMEBUFFER_RENDER_TARGETS 2
 
-	enum Meshes
-	{
-		MeshCube = 0,
-		MeshHollowCube,
-	};
+enum Meshes
+{
+	MeshCube = 0,
+	MeshHollowCube,
+};
 
-	static const char *s_meshPaths[] =
-	{
-		"meshes/cube.bin",
-		"meshes/hollowcube.bin",
-	};
+static const char *s_meshPaths[] =
+{
+	"meshes/cube.bin",
+	"meshes/hollowcube.bin",
+};
 
-	static const float s_meshScale[] =
-	{
-		0.45f,
-		0.30f,
-	};
+static const float s_meshScale[] =
+{
+	0.45f,
+	0.30f,
+};
+
+// Vertex decl for our screen space quad (used in deferred rendering)
+struct PosTexCoord0Vertex
+{
+	float m_x;
+	float m_y;
+	float m_z;
+	float m_u;
+	float m_v;
 
-	// Vertex decl for our screen space quad (used in deferred rendering)
-	struct PosTexCoord0Vertex
+	static void init()
 	{
-		float m_x;
-		float m_y;
-		float m_z;
-		float m_u;
-		float m_v;
+		ms_layout
+			.begin()
+			.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
+			.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
+			.end();
+	}
 
-		static void init()
-		{
-			ms_layout
-				.begin()
-				.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
-				.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
-				.end();
-		}
+	static bgfx::VertexLayout ms_layout;
+};
 
-		static bgfx::VertexLayout ms_layout;
-	};
+bgfx::VertexLayout PosTexCoord0Vertex::ms_layout;
 
-	bgfx::VertexLayout PosTexCoord0Vertex::ms_layout;
-
-	void screenSpaceTriangle(float _textureWidth, float _textureHeight, float _texelHalf, bool _originBottomLeft, float _width = 1.0f, float _height = 1.0f, float _offsetX = 0.0f, float _offsetY = 0.0f)
+void screenSpaceTriangle(float _textureWidth, float _textureHeight, float _texelHalf, bool _originBottomLeft, float _width = 1.0f, float _height = 1.0f, float _offsetX = 0.0f, float _offsetY = 0.0f)
+{
+	if (3 == bgfx::getAvailTransientVertexBuffer(3, PosTexCoord0Vertex::ms_layout) )
 	{
-		if (3 == bgfx::getAvailTransientVertexBuffer(3, PosTexCoord0Vertex::ms_layout) )
-		{
-			bgfx::TransientVertexBuffer vb;
-			bgfx::allocTransientVertexBuffer(&vb, 3, PosTexCoord0Vertex::ms_layout);
-			PosTexCoord0Vertex *vertex = (PosTexCoord0Vertex *)vb.data;
+		bgfx::TransientVertexBuffer vb;
+		bgfx::allocTransientVertexBuffer(&vb, 3, PosTexCoord0Vertex::ms_layout);
+		PosTexCoord0Vertex *vertex = (PosTexCoord0Vertex *)vb.data;
 
-			const float minx = -_width - _offsetX;
-			const float maxx = _width - _offsetX;
-			const float miny = 0.0f - _offsetY;
-			const float maxy = _height * 2.0f - _offsetY;
+		const float minx = -_width - _offsetX;
+		const float maxx = _width - _offsetX;
+		const float miny = 0.0f - _offsetY;
+		const float maxy = _height * 2.0f - _offsetY;
 
-			const float texelHalfW = _texelHalf / _textureWidth;
-			const float texelHalfH = _texelHalf / _textureHeight;
-			const float minu = -1.0f + texelHalfW;
-			const float maxu = 1.0f + texelHalfW;
+		const float texelHalfW = _texelHalf / _textureWidth;
+		const float texelHalfH = _texelHalf / _textureHeight;
+		const float minu = -1.0f + texelHalfW;
+		const float maxu = 1.0f + texelHalfW;
 
-			const float zz = 0.0f;
+		const float zz = 0.0f;
 
-			float minv = texelHalfH;
-			float maxv = 2.0f + texelHalfH;
+		float minv = texelHalfH;
+		float maxv = 2.0f + texelHalfH;
 
-			if (_originBottomLeft)
-			{
-				float temp = minv;
-				minv = maxv;
-				maxv = temp;
-
-				minv -= 1.0f;
-				maxv -= 1.0f;
-			}
+		if (_originBottomLeft)
+		{
+			float temp = minv;
+			minv = maxv;
+			maxv = temp;
 
-			vertex[0].m_x = minx;
-			vertex[0].m_y = miny;
-			vertex[0].m_z = zz;
-			vertex[0].m_u = minu;
-			vertex[0].m_v = minv;
-
-			vertex[1].m_x = maxx;
-			vertex[1].m_y = miny;
-			vertex[1].m_z = zz;
-			vertex[1].m_u = maxu;
-			vertex[1].m_v = minv;
-
-			vertex[2].m_x = maxx;
-			vertex[2].m_y = maxy;
-			vertex[2].m_z = zz;
-			vertex[2].m_u = maxu;
-			vertex[2].m_v = maxv;
-
-			bgfx::setVertexBuffer(0, &vb);
+			minv -= 1.0f;
+			maxv -= 1.0f;
 		}
+
+		vertex[0].m_x = minx;
+		vertex[0].m_y = miny;
+		vertex[0].m_z = zz;
+		vertex[0].m_u = minu;
+		vertex[0].m_v = minv;
+
+		vertex[1].m_x = maxx;
+		vertex[1].m_y = miny;
+		vertex[1].m_z = zz;
+		vertex[1].m_u = maxu;
+		vertex[1].m_v = minv;
+
+		vertex[2].m_x = maxx;
+		vertex[2].m_y = maxy;
+		vertex[2].m_z = zz;
+		vertex[2].m_u = maxu;
+		vertex[2].m_v = maxv;
+
+		bgfx::setVertexBuffer(0, &vb);
 	}
+}
 
-	struct ModelUniforms
+struct ModelUniforms
+{
+	enum
 	{
-		enum
-		{
-			NumVec4 = 2
-		};
+		NumVec4 = 2
+	};
 
-		void init()
-		{
-			u_params = bgfx::createUniform("u_modelParams", bgfx::UniformType::Vec4, NumVec4);
-		};
+	void init()
+	{
+		u_params = bgfx::createUniform("u_modelParams", bgfx::UniformType::Vec4, NumVec4);
+	};
 
-		void submit() const
-		{
-			bgfx::setUniform(u_params, m_params, NumVec4);
-		};
+	void submit() const
+	{
+		bgfx::setUniform(u_params, m_params, NumVec4);
+	};
 
-		void destroy()
-		{
-			bgfx::destroy(u_params);
-		}
+	void destroy()
+	{
+		bgfx::destroy(u_params);
+	}
 
-		union
+	union
+	{
+		struct
 		{
-			struct
+			/* 0 */ struct
 			{
-				/* 0 */ struct
-				{
-					float m_color[3];
-					float m_unused0;
-				};
-				/* 1 */ struct
-				{
-					float m_lightPosition[3];
-					float m_unused1;
-				};
+				float m_color[3];
+				float m_unused0;
+			};
+			/* 1 */ struct
+			{
+				float m_lightPosition[3];
+				float m_unused1;
 			};
-
-			float m_params[NumVec4 * 4];
 		};
 
-		bgfx::UniformHandle u_params;
+		float m_params[NumVec4 * 4];
 	};
 
-	struct AppState
-	{
-		uint32_t m_width;
-		uint32_t m_height;
-		uint32_t m_debug;
-		uint32_t m_reset;
+	bgfx::UniformHandle u_params;
+};
 
-		entry::MouseState m_mouseState;
+struct AppState
+{
+	uint32_t m_width;
+	uint32_t m_height;
+	uint32_t m_debug;
+	uint32_t m_reset;
 
-		// Resource handles
-		bgfx::ProgramHandle m_forwardProgram;
-		bgfx::ProgramHandle m_gridProgram;
-		bgfx::ProgramHandle m_copyLinearToGammaProgram;
+	entry::MouseState m_mouseState;
 
-		// Shader uniforms
-		ModelUniforms m_modelUniforms;
+	// Resource handles
+	bgfx::ProgramHandle m_forwardProgram;
+	bgfx::ProgramHandle m_gridProgram;
+	bgfx::ProgramHandle m_copyLinearToGammaProgram;
 
-		// Uniforms to identify texture samplers
-		bgfx::UniformHandle s_albedo;
-		bgfx::UniformHandle s_color;
-		bgfx::UniformHandle s_normal;
+	// Shader uniforms
+	ModelUniforms m_modelUniforms;
 
-		bgfx::FrameBufferHandle m_frameBuffer;
-		bgfx::TextureHandle m_frameBufferTex[FRAMEBUFFER_RENDER_TARGETS];
+	// Uniforms to identify texture samplers
+	bgfx::UniformHandle s_albedo;
+	bgfx::UniformHandle s_color;
+	bgfx::UniformHandle s_normal;
 
-		Mesh *m_meshes[BX_COUNTOF(s_meshPaths)];
-		bgfx::TextureHandle m_groundTexture;
-		bgfx::TextureHandle m_normalTexture;
+	bgfx::FrameBufferHandle m_frameBuffer;
+	bgfx::TextureHandle m_frameBufferTex[FRAMEBUFFER_RENDER_TARGETS];
 
-		uint32_t m_currFrame{UINT32_MAX};
-		float m_lightRotation = 0.0f;
-		float m_texelHalf = 0.0f;
-		float m_fovY = 60.0f;
-		float m_animationTime = 0.0f;
+	Mesh *m_meshes[BX_COUNTOF(s_meshPaths)];
+	bgfx::TextureHandle m_groundTexture;
+	bgfx::TextureHandle m_normalTexture;
 
-		float m_view[16];
-		float m_proj[16];
-		int32_t m_size[2];
+	uint32_t m_currFrame{UINT32_MAX};
+	float m_lightRotation = 0.0f;
+	float m_texelHalf = 0.0f;
+	float m_fovY = 60.0f;
+	float m_animationTime = 0.0f;
 
-		// UI parameters
-		bool m_renderNativeResolution = false;
-		bool m_animateScene = false;
-		int32_t m_antiAliasingSetting = 2;
+	float m_view[16];
+	float m_proj[16];
+	int32_t m_size[2];
 
-		Fsr m_fsr;
-	};
+	// UI parameters
+	bool m_renderNativeResolution = false;
+	bool m_animateScene = false;
+	int32_t m_antiAliasingSetting = 2;
+
+	Fsr m_fsr;
+};
 
-	struct RenderTarget
+struct RenderTarget
+{
+	void init(uint32_t _width, uint32_t _height, bgfx::TextureFormat::Enum _format, uint64_t _flags)
 	{
-		void init(uint32_t _width, uint32_t _height, bgfx::TextureFormat::Enum _format, uint64_t _flags)
-		{
-			m_width   = _width;
-			m_height  = _height;
-			m_texture = bgfx::createTexture2D(uint16_t(_width), uint16_t(_height), false, 1, _format, _flags);
-			m_buffer  = bgfx::createFrameBuffer(1, &m_texture, true);
-		}
+		m_width   = _width;
+		m_height  = _height;
+		m_texture = bgfx::createTexture2D(uint16_t(_width), uint16_t(_height), false, 1, _format, _flags);
+		m_buffer  = bgfx::createFrameBuffer(1, &m_texture, true);
+	}
 
-		void destroy()
-		{
-			// also responsible for destroying texture
-			bgfx::destroy(m_buffer);
-		}
+	void destroy()
+	{
+		// also responsible for destroying texture
+		bgfx::destroy(m_buffer);
+	}
 
-		uint32_t m_width;
-		uint32_t m_height;
-		bgfx::TextureHandle m_texture;
-		bgfx::FrameBufferHandle m_buffer;
-	};
+	uint32_t m_width;
+	uint32_t m_height;
+	bgfx::TextureHandle m_texture;
+	bgfx::FrameBufferHandle m_buffer;
+};
 
-	struct MagnifierWidget
+struct MagnifierWidget
+{
+	void init(uint32_t _width, uint32_t _height)
 	{
-		void init(uint32_t _width, uint32_t _height)
-		{
-			m_content.init(_width, _height, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT);
-			createWidgetTexture(_width + 6, _height + 6);
-		}
+		m_content.init(_width, _height, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT);
+		createWidgetTexture(_width + 6, _height + 6);
+	}
 
-		void destroy()
-		{
-			bgfx::destroy(m_widgetTexture);
-			m_content.destroy();
-		}
+	void destroy()
+	{
+		bgfx::destroy(m_widgetTexture);
+		m_content.destroy();
+	}
 
-		void setPosition(float x, float y)
-		{
-			m_position.x = x;
-			m_position.y = y;
-		}
+	void setPosition(float x, float y)
+	{
+		m_position.x = x;
+		m_position.y = y;
+	}
 
-		void drawToScreen(bgfx::ViewId &view, AppState const &state)
-		{
-			float invScreenScaleX = 1.0f / float(state.m_width);
-			float invScreenScaleY = 1.0f / float(state.m_height);
-			float scaleX = m_widgetWidth * invScreenScaleX;
-			float scaleY = m_widgetHeight * invScreenScaleY;
-			float offsetX = -bx::min(bx::max(m_position.x - m_widgetWidth * 0.5f, -3.0f), float(state.m_width - m_widgetWidth + 3) ) * invScreenScaleX;
-			float offsetY = -bx::min(bx::max(m_position.y - m_widgetHeight * 0.5f, -3.0f), float(state.m_height - m_widgetHeight + 3) ) * invScreenScaleY;
-
-			bgfx::setState(0 | BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A | BGFX_STATE_DEPTH_TEST_ALWAYS | BGFX_STATE_BLEND_ALPHA);
-			bgfx::setTexture(0, state.s_color, m_widgetTexture);
-			screenSpaceTriangle(float(m_widgetWidth), float(m_widgetHeight), state.m_texelHalf, false, scaleX, scaleY, offsetX, offsetY);
-			bgfx::submit(view, state.m_copyLinearToGammaProgram);
-		}
+	void drawToScreen(bgfx::ViewId &view, AppState const &state)
+	{
+		float invScreenScaleX = 1.0f / float(state.m_width);
+		float invScreenScaleY = 1.0f / float(state.m_height);
+		float scaleX = m_widgetWidth * invScreenScaleX;
+		float scaleY = m_widgetHeight * invScreenScaleY;
+		float offsetX = -bx::min(bx::max(m_position.x - m_widgetWidth * 0.5f, -3.0f), float(state.m_width - m_widgetWidth + 3) ) * invScreenScaleX;
+		float offsetY = -bx::min(bx::max(m_position.y - m_widgetHeight * 0.5f, -3.0f), float(state.m_height - m_widgetHeight + 3) ) * invScreenScaleY;
+
+		bgfx::setState(0 | BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A | BGFX_STATE_DEPTH_TEST_ALWAYS | BGFX_STATE_BLEND_ALPHA);
+		bgfx::setTexture(0, state.s_color, m_widgetTexture);
+		screenSpaceTriangle(float(m_widgetWidth), float(m_widgetHeight), state.m_texelHalf, false, scaleX, scaleY, offsetX, offsetY);
+		bgfx::submit(view, state.m_copyLinearToGammaProgram);
+	}
 
-		void updateContent(bgfx::ViewId &view, AppState const &state, const bgfx::Caps *caps, bgfx::TextureHandle srcTexture)
+	void updateContent(bgfx::ViewId &view, AppState const &state, const bgfx::Caps *caps, bgfx::TextureHandle srcTexture)
+	{
+		float orthoProj[16];
+		bx::mtxOrtho(orthoProj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, caps->homogeneousDepth);
 		{
-			float orthoProj[16];
-			bx::mtxOrtho(orthoProj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, caps->homogeneousDepth);
-			{
-				// clear out transform stack
-				float identity[16];
-				bx::mtxIdentity(identity);
-				bgfx::setTransform(identity);
-			}
-
-			const float verticalPos = caps->originBottomLeft ? state.m_height - m_position.y : m_position.y;
-			const float invMagScaleX = 1.0f / float(m_content.m_width);
-			const float invMagScaleY = 1.0f / float(m_content.m_height);
-			const float scaleX = state.m_width * invMagScaleX;
-			const float scaleY = state.m_height * invMagScaleY;
-			const float offsetX = bx::min(bx::max(m_position.x - m_content.m_width * 0.5f, 0.0f), float(state.m_width - m_content.m_width) ) * scaleX / state.m_width;
-			const float offsetY = bx::min(bx::max(verticalPos - m_content.m_height * 0.5f, 0.0f), float(state.m_height - m_content.m_height) ) * scaleY / state.m_height;
-
-			bgfx::setViewName(view, "magnifier");
-			bgfx::setViewRect(view, 0, 0, uint16_t(m_content.m_width), uint16_t(m_content.m_height) );
-			bgfx::setViewTransform(view, NULL, orthoProj);
-			bgfx::setViewFrameBuffer(view, m_content.m_buffer);
-			bgfx::setState(0 | BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A);
-			bgfx::setTexture(0, state.s_color, srcTexture, BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP);
-			screenSpaceTriangle(float(state.m_width), float(state.m_height), state.m_texelHalf, false, scaleX, scaleY, offsetX, offsetY);
-			bgfx::submit(view, state.m_copyLinearToGammaProgram);
-			++view;
+			// clear out transform stack
+			float identity[16];
+			bx::mtxIdentity(identity);
+			bgfx::setTransform(identity);
 		}
 
-		uint32_t m_widgetWidth{0};
-		uint32_t m_widgetHeight{0};
-		bgfx::TextureHandle m_widgetTexture;
-		RenderTarget m_content;
-		ImVec2 m_position;
+		const float verticalPos = caps->originBottomLeft ? state.m_height - m_position.y : m_position.y;
+		const float invMagScaleX = 1.0f / float(m_content.m_width);
+		const float invMagScaleY = 1.0f / float(m_content.m_height);
+		const float scaleX = state.m_width * invMagScaleX;
+		const float scaleY = state.m_height * invMagScaleY;
+		const float offsetX = bx::min(bx::max(m_position.x - m_content.m_width * 0.5f, 0.0f), float(state.m_width - m_content.m_width) ) * scaleX / state.m_width;
+		const float offsetY = bx::min(bx::max(verticalPos - m_content.m_height * 0.5f, 0.0f), float(state.m_height - m_content.m_height) ) * scaleY / state.m_height;
+
+		bgfx::setViewName(view, "magnifier");
+		bgfx::setViewRect(view, 0, 0, uint16_t(m_content.m_width), uint16_t(m_content.m_height) );
+		bgfx::setViewTransform(view, NULL, orthoProj);
+		bgfx::setViewFrameBuffer(view, m_content.m_buffer);
+		bgfx::setState(0 | BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A);
+		bgfx::setTexture(0, state.s_color, srcTexture, BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP);
+		screenSpaceTriangle(float(state.m_width), float(state.m_height), state.m_texelHalf, false, scaleX, scaleY, offsetX, offsetY);
+		bgfx::submit(view, state.m_copyLinearToGammaProgram);
+		++view;
+	}
 
-	private:
-		void createWidgetTexture(uint32_t _width, uint32_t _height)
-		{
-			const bgfx::Memory *mem = bgfx::alloc(_width * _height * sizeof(uint32_t) );
+	uint32_t m_widgetWidth{0};
+	uint32_t m_widgetHeight{0};
+	bgfx::TextureHandle m_widgetTexture;
+	RenderTarget m_content;
+	ImVec2 m_position;
 
-			uint32_t *pixels = (uint32_t*)mem->data;
-			bx::memSet(pixels, 0, mem->size);
+private:
+	void createWidgetTexture(uint32_t _width, uint32_t _height)
+	{
+		const bgfx::Memory *mem = bgfx::alloc(_width * _height * sizeof(uint32_t) );
 
-			const uint32_t white = 0xFFFFFFFF;
-			const uint32_t black = 0xFF000000;
+		uint32_t *pixels = (uint32_t*)mem->data;
+		bx::memSet(pixels, 0, mem->size);
 
-			const uint32_t y0 = 1;
-			const uint32_t y1 = _height - 3;
+		const uint32_t white = 0xFFFFFFFF;
+		const uint32_t black = 0xFF000000;
 
-			for (uint32_t x = 0; x < _width - 4; x++)
-			{
-				pixels[(y0 + 0) * _width + x + 1] = white;
-				pixels[(y0 + 1) * _width + x + 2] = black;
-				pixels[(y1 + 0) * _width + x + 1] = white;
-				pixels[(y1 + 1) * _width + x + 2] = black;
-			}
+		const uint32_t y0 = 1;
+		const uint32_t y1 = _height - 3;
 
-			const uint32_t x0 = 1;
-			const uint32_t x1 = _width - 3;
+		for (uint32_t x = 0; x < _width - 4; x++)
+		{
+			pixels[(y0 + 0) * _width + x + 1] = white;
+			pixels[(y0 + 1) * _width + x + 2] = black;
+			pixels[(y1 + 0) * _width + x + 1] = white;
+			pixels[(y1 + 1) * _width + x + 2] = black;
+		}
 
-			for (uint32_t y = 0; y < _height - 3; y++)
-			{
-				pixels[(y + 1) * _width + x0 + 0] = white;
-				pixels[(y + 2) * _width + x0 + 1] = black;
-				pixels[(y + 1) * _width + x1 + 0] = white;
-				pixels[(y + 2) * _width + x1 + 1] = black;
-			}
+		const uint32_t x0 = 1;
+		const uint32_t x1 = _width - 3;
 
-			pixels[(y1 + 0) * _width + 2] = white;
-
-			m_widgetWidth   = _width;
-			m_widgetHeight  = _height;
-			m_widgetTexture = bgfx::createTexture2D(
-				  uint16_t(_width)
-				, uint16_t(_height)
-				, false
-				, 1
-				, bgfx::TextureFormat::BGRA8
-				, BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP
-				, mem
-				);
+		for (uint32_t y = 0; y < _height - 3; y++)
+		{
+			pixels[(y + 1) * _width + x0 + 0] = white;
+			pixels[(y + 2) * _width + x0 + 1] = black;
+			pixels[(y + 1) * _width + x1 + 0] = white;
+			pixels[(y + 2) * _width + x1 + 1] = black;
 		}
-	};
 
-	class ExampleFsr : public entry::AppI
+		pixels[(y1 + 0) * _width + 2] = white;
+
+		m_widgetWidth   = _width;
+		m_widgetHeight  = _height;
+		m_widgetTexture = bgfx::createTexture2D(
+				uint16_t(_width)
+			, uint16_t(_height)
+			, false
+			, 1
+			, bgfx::TextureFormat::BGRA8
+			, BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP
+			, mem
+			);
+	}
+};
+
+class ExampleFsr : public entry::AppI
+{
+public:
+	ExampleFsr(const char *_name, const char *_description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
+	void init(int32_t _argc, const char *const *_argv, uint32_t _width, uint32_t _height) override
 	{
-	public:
-		ExampleFsr(const char *_name, const char *_description)
-			: entry::AppI(_name, _description)
+		Args args(_argc, _argv);
+
+		m_state.m_width  = _width;
+		m_state.m_height = _height;
+		m_state.m_debug  = BGFX_DEBUG_NONE;
+		m_state.m_reset  = 0
+			| BGFX_RESET_VSYNC
+			| BGFX_RESET_MAXANISOTROPY
+			;
+
+		bgfx::Init init;
+		init.type     = args.m_type;
+		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
+		init.resolution.width  = m_state.m_width;
+		init.resolution.height = m_state.m_height;
+		init.resolution.reset  = m_state.m_reset;
+		bgfx::init(init);
+
+		// Enable debug text.
+		bgfx::setDebug(m_state.m_debug);
+
+		// Create uniforms for screen passes and models
+		m_state.m_modelUniforms.init();
+
+		// Create texture sampler uniforms (used when we bind textures)
+		m_state.s_albedo = bgfx::createUniform("s_albedo", bgfx::UniformType::Sampler);
+		m_state.s_color  = bgfx::createUniform("s_color",  bgfx::UniformType::Sampler);
+		m_state.s_normal = bgfx::createUniform("s_normal", bgfx::UniformType::Sampler);
+
+		// Create program from shaders.
+		m_state.m_forwardProgram           = loadProgram("vs_fsr_forward",    "fs_fsr_forward");
+		m_state.m_gridProgram              = loadProgram("vs_fsr_forward",    "fs_fsr_forward_grid");
+		m_state.m_copyLinearToGammaProgram = loadProgram("vs_fsr_screenquad", "fs_fsr_copy_linear_to_gamma");
+
+		// Load some meshes
+		for (uint32_t ii = 0; ii < BX_COUNTOF(s_meshPaths); ++ii)
 		{
+			m_state.m_meshes[ii] = meshLoad(s_meshPaths[ii]);
 		}
 
-		void init(int32_t _argc, const char *const *_argv, uint32_t _width, uint32_t _height) override
-		{
-			Args args(_argc, _argv);
-
-			m_state.m_width  = _width;
-			m_state.m_height = _height;
-			m_state.m_debug  = BGFX_DEBUG_NONE;
-			m_state.m_reset  = 0
-				| BGFX_RESET_VSYNC
-				| BGFX_RESET_MAXANISOTROPY
-				;
-
-			bgfx::Init init;
-			init.type = args.m_type;
-
-			init.vendorId          = args.m_pciId;
-			init.resolution.width  = m_state.m_width;
-			init.resolution.height = m_state.m_height;
-			init.resolution.reset  = m_state.m_reset;
-			bgfx::init(init);
-
-			// Enable debug text.
-			bgfx::setDebug(m_state.m_debug);
-
-			// Create uniforms for screen passes and models
-			m_state.m_modelUniforms.init();
-
-			// Create texture sampler uniforms (used when we bind textures)
-			m_state.s_albedo = bgfx::createUniform("s_albedo", bgfx::UniformType::Sampler);
-			m_state.s_color  = bgfx::createUniform("s_color",  bgfx::UniformType::Sampler);
-			m_state.s_normal = bgfx::createUniform("s_normal", bgfx::UniformType::Sampler);
-
-			// Create program from shaders.
-			m_state.m_forwardProgram           = loadProgram("vs_fsr_forward",    "fs_fsr_forward");
-			m_state.m_gridProgram              = loadProgram("vs_fsr_forward",    "fs_fsr_forward_grid");
-			m_state.m_copyLinearToGammaProgram = loadProgram("vs_fsr_screenquad", "fs_fsr_copy_linear_to_gamma");
-
-			// Load some meshes
-			for (uint32_t ii = 0; ii < BX_COUNTOF(s_meshPaths); ++ii)
-			{
-				m_state.m_meshes[ii] = meshLoad(s_meshPaths[ii]);
-			}
+		m_state.m_groundTexture = loadTexture("textures/fieldstone-rgba.dds");
+		m_state.m_normalTexture = loadTexture("textures/fieldstone-n.dds");
 
-			m_state.m_groundTexture = loadTexture("textures/fieldstone-rgba.dds");
-			m_state.m_normalTexture = loadTexture("textures/fieldstone-n.dds");
+		createFramebuffers();
 
-			createFramebuffers();
+		// Vertex decl
+		PosTexCoord0Vertex::init();
 
-			// Vertex decl
-			PosTexCoord0Vertex::init();
+		// Init camera
+		cameraCreate();
+		cameraSetPosition({-10.0f, 2.5f, -0.0f});
+		cameraSetVerticalAngle(-0.2f);
+		cameraSetHorizontalAngle(0.8f);
 
-			// Init camera
-			cameraCreate();
-			cameraSetPosition({-10.0f, 2.5f, -0.0f});
-			cameraSetVerticalAngle(-0.2f);
-			cameraSetHorizontalAngle(0.8f);
+		// Init "prev" matrices, will be same for first frame
+		cameraGetViewMtx(m_state.m_view);
+		bx::mtxProj(m_state.m_proj, m_state.m_fovY, float(m_state.m_size[0]) / float(m_state.m_size[1]), 0.01f, 100.0f, bgfx::getCaps()->homogeneousDepth);
 
-			// Init "prev" matrices, will be same for first frame
-			cameraGetViewMtx(m_state.m_view);
-			bx::mtxProj(m_state.m_proj, m_state.m_fovY, float(m_state.m_size[0]) / float(m_state.m_size[1]), 0.01f, 100.0f, bgfx::getCaps()->homogeneousDepth);
+		// Get renderer capabilities info.
+		const bgfx::RendererType::Enum renderer = bgfx::getRendererType();
+		m_state.m_texelHalf = bgfx::RendererType::Direct3D9 == renderer ? 0.5f : 0.0f;
 
-			// Get renderer capabilities info.
-			const bgfx::RendererType::Enum renderer = bgfx::getRendererType();
-			m_state.m_texelHalf = bgfx::RendererType::Direct3D9 == renderer ? 0.5f : 0.0f;
+		const uint32_t magnifierSize = 32;
+		m_magnifierWidget.init(magnifierSize, magnifierSize);
+		m_magnifierWidget.setPosition(m_state.m_width * 0.5f, m_state.m_height * 0.5f);
 
-			const uint32_t magnifierSize = 32;
-			m_magnifierWidget.init(magnifierSize, magnifierSize);
-			m_magnifierWidget.setPosition(m_state.m_width * 0.5f, m_state.m_height * 0.5f);
+		imguiCreate();
 
-			imguiCreate();
+		m_state.m_fsr.init(_width, _height);
+	}
 
-			m_state.m_fsr.init(_width, _height);
-		}
+	int32_t shutdown() override
+	{
+		m_state.m_fsr.destroy();
 
-		int32_t shutdown() override
+		for (uint32_t ii = 0; ii < BX_COUNTOF(s_meshPaths); ++ii)
 		{
-			m_state.m_fsr.destroy();
-
-			for (uint32_t ii = 0; ii < BX_COUNTOF(s_meshPaths); ++ii)
-			{
-				meshUnload(m_state.m_meshes[ii]);
-			}
+			meshUnload(m_state.m_meshes[ii]);
+		}
 
-			bgfx::destroy(m_state.m_normalTexture);
-			bgfx::destroy(m_state.m_groundTexture);
+		bgfx::destroy(m_state.m_normalTexture);
+		bgfx::destroy(m_state.m_groundTexture);
 
-			bgfx::destroy(m_state.m_forwardProgram);
-			bgfx::destroy(m_state.m_gridProgram);
-			bgfx::destroy(m_state.m_copyLinearToGammaProgram);
+		bgfx::destroy(m_state.m_forwardProgram);
+		bgfx::destroy(m_state.m_gridProgram);
+		bgfx::destroy(m_state.m_copyLinearToGammaProgram);
 
-			m_state.m_modelUniforms.destroy();
+		m_state.m_modelUniforms.destroy();
 
-			m_magnifierWidget.destroy();
+		m_magnifierWidget.destroy();
 
-			bgfx::destroy(m_state.s_albedo);
-			bgfx::destroy(m_state.s_color);
-			bgfx::destroy(m_state.s_normal);
+		bgfx::destroy(m_state.s_albedo);
+		bgfx::destroy(m_state.s_color);
+		bgfx::destroy(m_state.s_normal);
 
-			destroyFramebuffers();
+		destroyFramebuffers();
 
-			cameraDestroy();
+		cameraDestroy();
 
-			imguiDestroy();
+		imguiDestroy();
 
-			bgfx::shutdown();
+		bgfx::shutdown();
 
-			return 0;
-		}
+		return 0;
+	}
 
-		bool update() override
+	bool update() override
+	{
+		if (!entry::processEvents(m_state.m_width, m_state.m_height, m_state.m_debug, m_state.m_reset, &m_state.m_mouseState) )
 		{
-			if (!entry::processEvents(m_state.m_width, m_state.m_height, m_state.m_debug, m_state.m_reset, &m_state.m_mouseState) )
+			// skip processing when minimized, otherwise crashing
+			if (0 == m_state.m_width
+			||  0 == m_state.m_height)
 			{
-				// skip processing when minimized, otherwise crashing
-				if (0 == m_state.m_width
-				||  0 == m_state.m_height)
-				{
-					return true;
-				}
+				return true;
+			}
 
-				if (m_state.m_mouseState.m_buttons[entry::MouseButton::Left]
-				&&  !ImGui::MouseOverArea() )
-				{
-					m_magnifierWidget.setPosition(
-						  float(m_state.m_mouseState.m_mx)
-						, float(m_state.m_mouseState.m_my)
-						);
-				}
+			if (m_state.m_mouseState.m_buttons[entry::MouseButton::Left]
+			&&  !ImGui::MouseOverArea() )
+			{
+				m_magnifierWidget.setPosition(
+						float(m_state.m_mouseState.m_mx)
+					, float(m_state.m_mouseState.m_my)
+					);
+			}
 
-				// Update frame timer
-				int64_t now = bx::getHPCounter();
-				static int64_t last = now;
-				const int64_t frameTime = now - last;
-				last = now;
-				const double freq = double(bx::getHPFrequency() );
-				const float deltaTime = float(frameTime / freq);
-				const bgfx::Caps* caps = bgfx::getCaps();
+			// Update frame timer
+			int64_t now = bx::getHPCounter();
+			static int64_t last = now;
+			const int64_t frameTime = now - last;
+			last = now;
+			const double freq = double(bx::getHPFrequency() );
+			const float deltaTime = float(frameTime / freq);
+			const bgfx::Caps* caps = bgfx::getCaps();
 
-				if (m_state.m_size[0] != (int32_t)m_state.m_width || m_state.m_size[1] != (int32_t)m_state.m_height)
-				{
-					resize();
-				}
+			if (m_state.m_size[0] != (int32_t)m_state.m_width || m_state.m_size[1] != (int32_t)m_state.m_height)
+			{
+				resize();
+			}
 
-				// update animation time
-				const float rotationSpeed = 0.25f;
-				if (m_state.m_animateScene)
+			// update animation time
+			const float rotationSpeed = 0.25f;
+			if (m_state.m_animateScene)
+			{
+				m_state.m_animationTime += deltaTime * rotationSpeed;
+				if (bx::kPi2 < m_state.m_animationTime)
 				{
-					m_state.m_animationTime += deltaTime * rotationSpeed;
-					if (bx::kPi2 < m_state.m_animationTime)
-					{
-						m_state.m_animationTime -= bx::kPi2;
-					}
+					m_state.m_animationTime -= bx::kPi2;
 				}
+			}
 
-				// Update camera
-				cameraUpdate(deltaTime * 0.15f, m_state.m_mouseState, ImGui::MouseOverArea() );
+			// Update camera
+			cameraUpdate(deltaTime * 0.15f, m_state.m_mouseState, ImGui::MouseOverArea() );
 
-				cameraGetViewMtx(m_state.m_view);
+			cameraGetViewMtx(m_state.m_view);
+
+			updateUniforms();
+
+			bx::mtxProj(
+					m_state.m_proj
+				, m_state.m_fovY
+				, float(m_state.m_size[0]) / float(m_state.m_size[1])
+				, 0.01f
+				, 100.0f
+				, caps->homogeneousDepth
+				);
+
+			bgfx::ViewId view = 0;
+
+			// Clear full frame buffer to avoid sampling into garbage during FSR pass
+			if (!m_state.m_renderNativeResolution)
+			{
+				bgfx::setViewRect(view, 0, 0, (uint16_t)m_state.m_width, (uint16_t)m_state.m_height);
+				bgfx::setViewClear(view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0);
+				bgfx::setViewFrameBuffer(view, m_state.m_frameBuffer);
+				bgfx::touch(view);
 
-				updateUniforms();
+				++view;
+			}
 
-				bx::mtxProj(
-					  m_state.m_proj
-					, m_state.m_fovY
-					, float(m_state.m_size[0]) / float(m_state.m_size[1])
-					, 0.01f
-					, 100.0f
-					, caps->homogeneousDepth
+			// Draw models into scene
+			{
+				bgfx::setViewName(view, "forward scene");
+				bgfx::setViewClear(view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x7fb8ffff, 1.0f, 0);
+
+				const float viewScale = m_state.m_renderNativeResolution
+					? 1.0f
+					: 1.0f / m_state.m_fsr.m_config.m_superSamplingFactor
+					;
+				const uint16_t viewRectWidth  = uint16_t(bx::ceil(m_state.m_size[0] * viewScale) );
+				const uint16_t viewRectHeight = uint16_t(bx::ceil(m_state.m_size[1] * viewScale) );
+				const uint16_t viewRectY      = uint16_t(caps->originBottomLeft ? m_state.m_size[1] - viewRectHeight : 0);
+
+				bgfx::setViewRect(view, 0, viewRectY, viewRectWidth, viewRectHeight);
+				bgfx::setViewTransform(view, m_state.m_view, m_state.m_proj);
+				bgfx::setViewFrameBuffer(view, m_state.m_frameBuffer);
+
+				bgfx::setState(0
+					| BGFX_STATE_WRITE_RGB
+					| BGFX_STATE_WRITE_A
+					| BGFX_STATE_WRITE_Z
+					| BGFX_STATE_DEPTH_TEST_LESS
 					);
 
-				bgfx::ViewId view = 0;
+				drawAllModels(view, m_state.m_forwardProgram, m_state.m_modelUniforms);
 
-				// Clear full frame buffer to avoid sampling into garbage during FSR pass
-				if (!m_state.m_renderNativeResolution)
-				{
-					bgfx::setViewRect(view, 0, 0, (uint16_t)m_state.m_width, (uint16_t)m_state.m_height);
-					bgfx::setViewClear(view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0);
-					bgfx::setViewFrameBuffer(view, m_state.m_frameBuffer);
-					bgfx::touch(view);
+				++view;
+			}
 
-					++view;
-				}
+			// optionally run FSR
+			if (!m_state.m_renderNativeResolution)
+			{
+				view = m_state.m_fsr.computeFsr(view, m_state.m_frameBufferTex[FRAMEBUFFER_RT_COLOR]);
+			}
 
-				// Draw models into scene
-				{
-					bgfx::setViewName(view, "forward scene");
-					bgfx::setViewClear(view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x7fb8ffff, 1.0f, 0);
-
-					const float viewScale = m_state.m_renderNativeResolution
-						? 1.0f
-						: 1.0f / m_state.m_fsr.m_config.m_superSamplingFactor
-						;
-					const uint16_t viewRectWidth  = uint16_t(bx::ceil(m_state.m_size[0] * viewScale) );
-					const uint16_t viewRectHeight = uint16_t(bx::ceil(m_state.m_size[1] * viewScale) );
-					const uint16_t viewRectY      = uint16_t(caps->originBottomLeft ? m_state.m_size[1] - viewRectHeight : 0);
-
-					bgfx::setViewRect(view, 0, viewRectY, viewRectWidth, viewRectHeight);
-					bgfx::setViewTransform(view, m_state.m_view, m_state.m_proj);
-					bgfx::setViewFrameBuffer(view, m_state.m_frameBuffer);
-
-					bgfx::setState(0
-						| BGFX_STATE_WRITE_RGB
-						| BGFX_STATE_WRITE_A
-						| BGFX_STATE_WRITE_Z
-						| BGFX_STATE_DEPTH_TEST_LESS
-						);
-
-					drawAllModels(view, m_state.m_forwardProgram, m_state.m_modelUniforms);
-
-					++view;
-				}
+			// render result to screen
+			{
+				bgfx::TextureHandle srcTexture = m_state.m_frameBufferTex[FRAMEBUFFER_RT_COLOR];
 
-				// optionally run FSR
 				if (!m_state.m_renderNativeResolution)
 				{
-					view = m_state.m_fsr.computeFsr(view, m_state.m_frameBufferTex[FRAMEBUFFER_RT_COLOR]);
+					srcTexture = m_state.m_fsr.getResultTexture();
 				}
 
-				// render result to screen
-				{
-					bgfx::TextureHandle srcTexture = m_state.m_frameBufferTex[FRAMEBUFFER_RT_COLOR];
+				m_magnifierWidget.updateContent(view, m_state, caps, srcTexture);
 
-					if (!m_state.m_renderNativeResolution)
-					{
-						srcTexture = m_state.m_fsr.getResultTexture();
-					}
+				float orthoProj[16];
+				bx::mtxOrtho(orthoProj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, caps->homogeneousDepth);
 
-					m_magnifierWidget.updateContent(view, m_state, caps, srcTexture);
+				bgfx::setViewName(view, "display");
+				bgfx::setViewClear(view, BGFX_CLEAR_NONE, 0, 1.0f, 0);
 
-					float orthoProj[16];
-					bx::mtxOrtho(orthoProj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, caps->homogeneousDepth);
+				bgfx::setViewRect(view, 0, 0, uint16_t(m_state.m_width), uint16_t(m_state.m_height) );
+				bgfx::setViewTransform(view, NULL, orthoProj);
+				bgfx::setViewFrameBuffer(view, BGFX_INVALID_HANDLE);
+				bgfx::setState(0 | BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A);
+				bgfx::setTexture(0, m_state.s_color, srcTexture, BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP);
+				screenSpaceTriangle(float(m_state.m_width), float(m_state.m_height), m_state.m_texelHalf, caps->originBottomLeft);
+				bgfx::submit(view, m_state.m_copyLinearToGammaProgram);
+			}
 
-					bgfx::setViewName(view, "display");
-					bgfx::setViewClear(view, BGFX_CLEAR_NONE, 0, 1.0f, 0);
+			m_magnifierWidget.drawToScreen(view, m_state);
 
-					bgfx::setViewRect(view, 0, 0, uint16_t(m_state.m_width), uint16_t(m_state.m_height) );
-					bgfx::setViewTransform(view, NULL, orthoProj);
-					bgfx::setViewFrameBuffer(view, BGFX_INVALID_HANDLE);
-					bgfx::setState(0 | BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A);
-					bgfx::setTexture(0, m_state.s_color, srcTexture, BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP);
-					screenSpaceTriangle(float(m_state.m_width), float(m_state.m_height), m_state.m_texelHalf, caps->originBottomLeft);
-					bgfx::submit(view, m_state.m_copyLinearToGammaProgram);
-				}
+			++view;
 
-				m_magnifierWidget.drawToScreen(view, m_state);
+			// Draw UI
+			imguiBeginFrame(m_state.m_mouseState.m_mx, m_state.m_mouseState.m_my, (m_state.m_mouseState.m_buttons[entry::MouseButton::Left] ? IMGUI_MBUT_LEFT : 0) | (m_state.m_mouseState.m_buttons[entry::MouseButton::Right] ? IMGUI_MBUT_RIGHT : 0) | (m_state.m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0), m_state.m_mouseState.m_mz, uint16_t(m_state.m_width), uint16_t(m_state.m_height) );
 
-				++view;
+			showExampleDialog(this);
+
+			ImGui::SetNextWindowPos(ImVec2(m_state.m_width - m_state.m_width / 4.0f - 10.0f, 10.0f), ImGuiCond_FirstUseEver);
+			ImGui::SetNextWindowSize(ImVec2(m_state.m_width / 4.0f, m_state.m_height / 1.2f), ImGuiCond_FirstUseEver);
+			ImGui::Begin("Settings", NULL, 0);
+			ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f);
 
-				// Draw UI
-				imguiBeginFrame(m_state.m_mouseState.m_mx, m_state.m_mouseState.m_my, (m_state.m_mouseState.m_buttons[entry::MouseButton::Left] ? IMGUI_MBUT_LEFT : 0) | (m_state.m_mouseState.m_buttons[entry::MouseButton::Right] ? IMGUI_MBUT_RIGHT : 0) | (m_state.m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0), m_state.m_mouseState.m_mz, uint16_t(m_state.m_width), uint16_t(m_state.m_height) );
+			const ImVec2 itemSize = ImGui::GetItemRectSize();
 
-				showExampleDialog(this);
+			{
+				ImGui::Checkbox("Animate scene", &m_state.m_animateScene);
 
-				ImGui::SetNextWindowPos(ImVec2(m_state.m_width - m_state.m_width / 4.0f - 10.0f, 10.0f), ImGuiCond_FirstUseEver);
-				ImGui::SetNextWindowSize(ImVec2(m_state.m_width / 4.0f, m_state.m_height / 1.2f), ImGuiCond_FirstUseEver);
-				ImGui::Begin("Settings", NULL, 0);
-				ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f);
+				if (ImGui::Combo("Antialiasing", &m_state.m_antiAliasingSetting, "none\0""4x\0""16x\0""\0") )
+				{
+					resize();
+				}
 
-				const ImVec2 itemSize = ImGui::GetItemRectSize();
+				ImGui::Checkbox("Render native resolution", &m_state.m_renderNativeResolution);
 
+				if (ImGui::IsItemHovered() )
 				{
-					ImGui::Checkbox("Animate scene", &m_state.m_animateScene);
+					ImGui::SetTooltip("Disable super sampling and FSR.");
+				}
 
-					if (ImGui::Combo("Antialiasing", &m_state.m_antiAliasingSetting, "none\0""4x\0""16x\0""\0") )
-					{
-						resize();
-					}
+				ImGui::Image(m_magnifierWidget.m_content.m_texture, ImVec2(itemSize.x * 0.94f, itemSize.x * 0.94f) );
 
-					ImGui::Checkbox("Render native resolution", &m_state.m_renderNativeResolution);
+				if (!m_state.m_renderNativeResolution)
+				{
+					ImGui::SliderFloat("Super sampling", &m_state.m_fsr.m_config.m_superSamplingFactor, 1.0f, 2.0f);
 
 					if (ImGui::IsItemHovered() )
 					{
-						ImGui::SetTooltip("Disable super sampling and FSR.");
+						ImGui::BeginTooltip();
+						ImGui::Text("2.0 means the scene is rendered at half window resolution.");
+						ImGui::Text("1.0 means the scene is rendered at native window resolution.");
+						ImGui::EndTooltip();
 					}
 
-					ImGui::Image(m_magnifierWidget.m_content.m_texture, ImVec2(itemSize.x * 0.94f, itemSize.x * 0.94f) );
+					ImGui::Separator();
 
-					if (!m_state.m_renderNativeResolution)
+					if (m_state.m_fsr.supports16BitPrecision() )
 					{
-						ImGui::SliderFloat("Super sampling", &m_state.m_fsr.m_config.m_superSamplingFactor, 1.0f, 2.0f);
+						ImGui::Checkbox("Use 16 Bit", &m_state.m_fsr.m_config.m_fsr16Bit);
 
 						if (ImGui::IsItemHovered() )
 						{
 							ImGui::BeginTooltip();
-							ImGui::Text("2.0 means the scene is rendered at half window resolution.");
-							ImGui::Text("1.0 means the scene is rendered at native window resolution.");
+							ImGui::Text("For better performance and less memory consumption use 16 Bit precision.");
+							ImGui::Text("If disabled use 32 Bit per channel precision for FSR which works better on older hardware.");
+							ImGui::Text("FSR in 16 Bit precision is also prone to be broken in Direct3D11, Direct3D12 works though.");
 							ImGui::EndTooltip();
 						}
+					}
 
-						ImGui::Separator();
+					ImGui::Checkbox("Apply FSR", &m_state.m_fsr.m_config.m_applyFsr);
 
-						if (m_state.m_fsr.supports16BitPrecision() )
-						{
-							ImGui::Checkbox("Use 16 Bit", &m_state.m_fsr.m_config.m_fsr16Bit);
-
-							if (ImGui::IsItemHovered() )
-							{
-								ImGui::BeginTooltip();
-								ImGui::Text("For better performance and less memory consumption use 16 Bit precision.");
-								ImGui::Text("If disabled use 32 Bit per channel precision for FSR which works better on older hardware.");
-								ImGui::Text("FSR in 16 Bit precision is also prone to be broken in Direct3D11, Direct3D12 works though.");
-								ImGui::EndTooltip();
-							}
-						}
+					if (ImGui::IsItemHovered() )
+					{
+						ImGui::SetTooltip("Compare between FSR and bilinear interpolation of source image.");
+					}
 
-						ImGui::Checkbox("Apply FSR", &m_state.m_fsr.m_config.m_applyFsr);
+					if (m_state.m_fsr.m_config.m_applyFsr)
+					{
+						ImGui::Checkbox("Apply FSR sharpening", &m_state.m_fsr.m_config.m_applyFsrRcas);
 
 						if (ImGui::IsItemHovered() )
 						{
-							ImGui::SetTooltip("Compare between FSR and bilinear interpolation of source image.");
+							ImGui::SetTooltip("Apply the FSR RCAS sharpening pass.");
 						}
 
-						if (m_state.m_fsr.m_config.m_applyFsr)
+						if (m_state.m_fsr.m_config.m_applyFsrRcas)
 						{
-							ImGui::Checkbox("Apply FSR sharpening", &m_state.m_fsr.m_config.m_applyFsrRcas);
+							ImGui::SliderFloat("Sharpening attenuation", &m_state.m_fsr.m_config.m_rcasAttenuation, 0.01f, 2.0f);
 
 							if (ImGui::IsItemHovered() )
 							{
-								ImGui::SetTooltip("Apply the FSR RCAS sharpening pass.");
-							}
-
-							if (m_state.m_fsr.m_config.m_applyFsrRcas)
-							{
-								ImGui::SliderFloat("Sharpening attenuation", &m_state.m_fsr.m_config.m_rcasAttenuation, 0.01f, 2.0f);
-
-								if (ImGui::IsItemHovered() )
-								{
-									ImGui::SetTooltip("Lower value means sharper.");
-								}
+								ImGui::SetTooltip("Lower value means sharper.");
 							}
 						}
 					}
 				}
+			}
 
-				ImGui::End();
-
-				imguiEndFrame();
+			ImGui::End();
 
-				// Advance to next frame. Rendering thread will be kicked to
-				// process submitted rendering primitives.
-				m_state.m_currFrame = bgfx::frame();
+			imguiEndFrame();
 
-				return true;
-			}
+			// Advance to next frame. Rendering thread will be kicked to
+			// process submitted rendering primitives.
+			m_state.m_currFrame = bgfx::frame();
 
-			return false;
+			return true;
 		}
 
-		void drawAllModels(bgfx::ViewId _pass, bgfx::ProgramHandle _program, ModelUniforms &_uniforms)
-		{
-			const int32_t width = 6;
-			const int32_t length = 20;
-
-			float c0[] = { 235.0f / 255.0f, 126.0f / 255.0f,  30.0f / 255.0f}; // orange
-			float c1[] = { 235.0f / 255.0f, 146.0f / 255.0f, 251.0f / 255.0f}; // purple
-			float c2[] = { 199.0f / 255.0f,   0.0f / 255.0f,  57.0f / 255.0f}; // pink
-
-			for (int32_t zz = 0; zz < length; ++zz)
-			{
-				// make a color gradient, nothing special about this for example
-				float *ca = c0;
-				float *cb = c1;
-				float lerpVal = float(zz) / float(length);
+		return false;
+	}
 
-				if (0.5f <= lerpVal)
-				{
-					ca = c1;
-					cb = c2;
-				}
-				lerpVal = bx::fract(2.0f * lerpVal);
+	void drawAllModels(bgfx::ViewId _pass, bgfx::ProgramHandle _program, ModelUniforms &_uniforms)
+	{
+		const int32_t width = 6;
+		const int32_t length = 20;
 
-				float r = bx::lerp(ca[0], cb[0], lerpVal);
-				float g = bx::lerp(ca[1], cb[1], lerpVal);
-				float b = bx::lerp(ca[2], cb[2], lerpVal);
+		float c0[] = { 235.0f / 255.0f, 126.0f / 255.0f,  30.0f / 255.0f}; // orange
+		float c1[] = { 235.0f / 255.0f, 146.0f / 255.0f, 251.0f / 255.0f}; // purple
+		float c2[] = { 199.0f / 255.0f,   0.0f / 255.0f,  57.0f / 255.0f}; // pink
 
-				for (int32_t xx = 0; xx < width; ++xx)
-				{
-					const float angle = m_state.m_animationTime + float(zz) * (bx::kPi2 / length) + float(xx) * (bx::kPiHalf / width);
+		for (int32_t zz = 0; zz < length; ++zz)
+		{
+			// make a color gradient, nothing special about this for example
+			float *ca = c0;
+			float *cb = c1;
+			float lerpVal = float(zz) / float(length);
 
-					const float posX = 2.0f * xx - width + 1.0f;
-					const float posY = bx::sin(angle);
-					const float posZ = 2.0f * zz - length + 1.0f;
+			if (0.5f <= lerpVal)
+			{
+				ca = c1;
+				cb = c2;
+			}
+			lerpVal = bx::fract(2.0f * lerpVal);
 
-					const float scale = s_meshScale[MeshHollowCube];
-					float mtx[16];
-					bx::mtxSRT(mtx, scale, scale, scale, 0.0f, 0.0f, 0.0f, posX, posY, posZ);
+			float r = bx::lerp(ca[0], cb[0], lerpVal);
+			float g = bx::lerp(ca[1], cb[1], lerpVal);
+			float b = bx::lerp(ca[2], cb[2], lerpVal);
 
-					bgfx::setTexture(0, m_state.s_albedo, m_state.m_groundTexture);
-					bgfx::setTexture(1, m_state.s_normal, m_state.m_normalTexture);
-					_uniforms.m_color[0] = r;
-					_uniforms.m_color[1] = g;
-					_uniforms.m_color[2] = b;
-					_uniforms.submit();
+			for (int32_t xx = 0; xx < width; ++xx)
+			{
+				const float angle = m_state.m_animationTime + float(zz) * (bx::kPi2 / length) + float(xx) * (bx::kPiHalf / width);
 
-					meshSubmit(m_state.m_meshes[MeshHollowCube], _pass, _program, mtx);
-				}
-			}
+				const float posX = 2.0f * xx - width + 1.0f;
+				const float posY = bx::sin(angle);
+				const float posZ = 2.0f * zz - length + 1.0f;
 
-			// draw box as ground plane
-			{
-				const float posY = -2.0f;
-				const float scale = length;
+				const float scale = s_meshScale[MeshHollowCube];
 				float mtx[16];
-				bx::mtxSRT(mtx, scale, scale, scale, 0.0f, 0.0f, 0.0f, 0.0f, -scale + posY, 0.0f);
+				bx::mtxSRT(mtx, scale, scale, scale, 0.0f, 0.0f, 0.0f, posX, posY, posZ);
 
-				_uniforms.m_color[0] = 0.5f;
-				_uniforms.m_color[1] = 0.5f;
-				_uniforms.m_color[2] = 0.5f;
+				bgfx::setTexture(0, m_state.s_albedo, m_state.m_groundTexture);
+				bgfx::setTexture(1, m_state.s_normal, m_state.m_normalTexture);
+				_uniforms.m_color[0] = r;
+				_uniforms.m_color[1] = g;
+				_uniforms.m_color[2] = b;
 				_uniforms.submit();
 
-				meshSubmit(m_state.m_meshes[MeshCube], _pass, m_state.m_gridProgram, mtx);
+				meshSubmit(m_state.m_meshes[MeshHollowCube], _pass, _program, mtx);
 			}
 		}
 
-		void resize()
+		// draw box as ground plane
 		{
-			destroyFramebuffers();
-			createFramebuffers();
-			m_state.m_fsr.resize(m_state.m_width, m_state.m_height);
-		}
+			const float posY = -2.0f;
+			const float scale = length;
+			float mtx[16];
+			bx::mtxSRT(mtx, scale, scale, scale, 0.0f, 0.0f, 0.0f, 0.0f, -scale + posY, 0.0f);
 
-		void createFramebuffers()
-		{
-			m_state.m_size[0] = m_state.m_width;
-			m_state.m_size[1] = m_state.m_height;
-
-			constexpr uint64_t msaaFlags[] =
-			{
-				BGFX_TEXTURE_NONE,
-				BGFX_TEXTURE_RT_MSAA_X4,
-				BGFX_TEXTURE_RT_MSAA_X16,
-			};
+			_uniforms.m_color[0] = 0.5f;
+			_uniforms.m_color[1] = 0.5f;
+			_uniforms.m_color[2] = 0.5f;
+			_uniforms.submit();
 
-			const uint64_t msaa = msaaFlags[m_state.m_antiAliasingSetting];
-			const uint64_t colorFlags = 0
-				| BGFX_TEXTURE_RT
-				| BGFX_SAMPLER_U_CLAMP
-				| BGFX_SAMPLER_V_CLAMP
-				| msaa
-				;
-			const uint64_t depthFlags = 0
-				| BGFX_TEXTURE_RT_WRITE_ONLY
-				| msaa
-				;
-
-			m_state.m_frameBufferTex[FRAMEBUFFER_RT_COLOR] = bgfx::createTexture2D(
-				  uint16_t(m_state.m_size[0])
-				, uint16_t(m_state.m_size[1])
-				, false
-				, 1
-				, bgfx::TextureFormat::RGBA16F
-				, colorFlags
-				);
+			meshSubmit(m_state.m_meshes[MeshCube], _pass, m_state.m_gridProgram, mtx);
+		}
+	}
 
-			m_state.m_frameBufferTex[FRAMEBUFFER_RT_DEPTH] = bgfx::createTexture2D(
-				  uint16_t(m_state.m_size[0])
-				, uint16_t(m_state.m_size[1])
-				, false
-				, 1
-				, bgfx::TextureFormat::D32F
-				, depthFlags
-				);
+	void resize()
+	{
+		destroyFramebuffers();
+		createFramebuffers();
+		m_state.m_fsr.resize(m_state.m_width, m_state.m_height);
+	}
 
-			m_state.m_frameBuffer = bgfx::createFrameBuffer(
-				  BX_COUNTOF(m_state.m_frameBufferTex)
-				, m_state.m_frameBufferTex
-				, true
-				);
-		}
+	void createFramebuffers()
+	{
+		m_state.m_size[0] = m_state.m_width;
+		m_state.m_size[1] = m_state.m_height;
 
-		// all buffers set to destroy their textures
-		void destroyFramebuffers()
+		constexpr uint64_t msaaFlags[] =
 		{
-			bgfx::destroy(m_state.m_frameBuffer);
-		}
+			BGFX_TEXTURE_NONE,
+			BGFX_TEXTURE_RT_MSAA_X4,
+			BGFX_TEXTURE_RT_MSAA_X16,
+		};
 
-		void updateUniforms()
-		{
-			m_state.m_modelUniforms.m_lightPosition[0] = 0.0f;
-			m_state.m_modelUniforms.m_lightPosition[1] = 6.0f;
-			m_state.m_modelUniforms.m_lightPosition[2] = 10.0f;
-		}
+		const uint64_t msaa = msaaFlags[m_state.m_antiAliasingSetting];
+		const uint64_t colorFlags = 0
+			| BGFX_TEXTURE_RT
+			| BGFX_SAMPLER_U_CLAMP
+			| BGFX_SAMPLER_V_CLAMP
+			| msaa
+			;
+		const uint64_t depthFlags = 0
+			| BGFX_TEXTURE_RT_WRITE_ONLY
+			| msaa
+			;
+
+		m_state.m_frameBufferTex[FRAMEBUFFER_RT_COLOR] = bgfx::createTexture2D(
+			  uint16_t(m_state.m_size[0])
+			, uint16_t(m_state.m_size[1])
+			, false
+			, 1
+			, bgfx::TextureFormat::RGBA16F
+			, colorFlags
+			);
+
+		m_state.m_frameBufferTex[FRAMEBUFFER_RT_DEPTH] = bgfx::createTexture2D(
+			  uint16_t(m_state.m_size[0])
+			, uint16_t(m_state.m_size[1])
+			, false
+			, 1
+			, bgfx::TextureFormat::D32F
+			, depthFlags
+			);
+
+		m_state.m_frameBuffer = bgfx::createFrameBuffer(
+			  BX_COUNTOF(m_state.m_frameBufferTex)
+			, m_state.m_frameBufferTex
+			, true
+			);
+	}
 
-		AppState m_state;
-		MagnifierWidget m_magnifierWidget;
-	};
+	// all buffers set to destroy their textures
+	void destroyFramebuffers()
+	{
+		bgfx::destroy(m_state.m_frameBuffer);
+	}
+
+	void updateUniforms()
+	{
+		m_state.m_modelUniforms.m_lightPosition[0] = 0.0f;
+		m_state.m_modelUniforms.m_lightPosition[1] = 6.0f;
+		m_state.m_modelUniforms.m_lightPosition[2] = 10.0f;
+	}
+
+	AppState m_state;
+	MagnifierWidget m_magnifierWidget;
+};
 
 } // namespace
 

+ 13 - 8
examples/47-pixelformats/pixelformats.cpp

@@ -19,12 +19,12 @@ namespace stl = tinystl;
 namespace
 {
 
-constexpr int32_t kCheckerboardSize = 128;
+constexpr int32_t kCheckerboardSize             = 128;
 constexpr int32_t kFirstUncompressedFormatIndex = bgfx::TextureFormat::Unknown + 1;
-constexpr int32_t kNumCompressedFormats = bgfx::TextureFormat::Unknown;
-constexpr int32_t kNumUncompressedFormats = bgfx::TextureFormat::UnknownDepth - kFirstUncompressedFormatIndex;
-constexpr int32_t kNumFormats = kNumCompressedFormats + kNumUncompressedFormats;
-const     int32_t kNumFormatsInRow = (int32_t)bx::ceil(1.2f * bx::sqrt(kNumFormats) );
+constexpr int32_t kNumCompressedFormats         = bgfx::TextureFormat::Unknown;
+constexpr int32_t kNumUncompressedFormats       = bgfx::TextureFormat::UnknownDepth - kFirstUncompressedFormatIndex;
+constexpr int32_t kNumFormats                   = kNumCompressedFormats + kNumUncompressedFormats;
+const     int32_t kNumFormatsInRow              = (int32_t)bx::ceil(1.2f * bx::sqrt(kNumFormats) );
 
 inline int32_t formatToIndex(bimg::TextureFormat::Enum format)
 {
@@ -428,6 +428,8 @@ public:
 		bgfx::Init init;
 		init.type     = args.m_type;
 		init.vendorId = args.m_pciId;
+		init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+		init.platformData.ndt  = entry::getNativeDisplayHandle();
 		init.resolution.width  = m_width;
 		init.resolution.height = m_height;
 		init.resolution.reset  = m_reset;
@@ -574,7 +576,10 @@ public:
 			if (bgfx::isValid(m_checkerboard) )
 			{
 				static int64_t timeOffset = bx::getHPCounter();
-				const float time = m_animateCheckerboard ? float( (bx::getHPCounter()-timeOffset)/double(bx::getHPFrequency() ) ) : 0.0f;
+				const float time = m_animate
+					? float( (bx::getHPCounter()-timeOffset)/double(bx::getHPFrequency() ) )
+					: 0.0f
+					;
 				const float xx = bx::sin(time * 0.17f);
 				const float yy = bx::cos(time * 0.13f);
 				const float uTile = bx::max(1.0f, previewSize.x / kCheckerboardSize);
@@ -655,7 +660,7 @@ public:
 			ImGui::SameLine();
 			ImGui::Checkbox("Alpha", &m_useAlpha);
 			ImGui::SameLine();
-			ImGui::Checkbox("Animate Checkerboard", &m_animateCheckerboard);
+			ImGui::Checkbox("Animate", &m_animate);
 			ImGui::BeginTable("Formats", kNumFormatsInRow, ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit);
 
 			for (int32_t i = m_currentTextureSet->m_hasCompressedTextures ? 0 : kNumCompressedFormats; i < kNumFormats; ++i)
@@ -797,7 +802,7 @@ public:
 	float    m_largestTextureSize = 256.0f;
 	float    m_previewSize = 50.0f;
 	bool     m_useAlpha = true;
-	bool     m_animateCheckerboard = true;
+	bool     m_animate = true;
 	bimg::TextureFormat::Enum m_selectedFormat = bimg::TextureFormat::RGBA8;
 
 	bgfx::TextureHandle m_checkerboard = BGFX_INVALID_HANDLE;

+ 50 - 17
examples/common/entry/entry.cpp

@@ -443,12 +443,27 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 		return bx::kExitFailure;
 	}
 
+	struct AppInternal
+	{
+		AppI* m_next;
+		const char* m_name;
+		const char* m_description;
+		const char* m_url;
+	};
+
+	static ptrdiff_t s_offset = 0;
+
 	AppI::AppI(const char* _name, const char* _description, const char* _url)
 	{
-		m_name        = _name;
-		m_description = _description;
-		m_url         = _url;
-		m_next        = s_apps;
+		BX_STATIC_ASSERT(sizeof(AppInternal) <= sizeof(m_internal) );
+		s_offset = BX_OFFSETOF(AppI, m_internal);
+
+		AppInternal* ai = (AppInternal*)m_internal;
+
+		ai->m_name        = _name;
+		ai->m_description = _description;
+		ai->m_url         = _url;
+		ai->m_next        = s_apps;
 
 		s_apps = this;
 		s_numApps++;
@@ -464,7 +479,8 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 			{
 				if (NULL != prev)
 				{
-					prev->m_next = next;
+					AppInternal* ai = bx::addressOf<AppInternal>(prev, s_offset);
+					ai->m_next = next;
 				}
 				else
 				{
@@ -480,22 +496,26 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 
 	const char* AppI::getName() const
 	{
-		return m_name;
+		AppInternal* ai = (AppInternal*)m_internal;
+		return ai->m_name;
 	}
 
 	const char* AppI::getDescription() const
 	{
-		return m_description;
+		AppInternal* ai = (AppInternal*)m_internal;
+		return ai->m_description;
 	}
 
 	const char* AppI::getUrl() const
 	{
-		return m_url;
+		AppInternal* ai = (AppInternal*)m_internal;
+		return ai->m_url;
 	}
 
 	AppI* AppI::getNext()
 	{
-		return m_next;
+		AppInternal* ai = (AppInternal*)m_internal;
+		return ai->m_next;
 	}
 
 	AppI* getFirstApp()
@@ -513,8 +533,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 		_app->init(_argc, _argv, s_width, s_height);
 		bgfx::frame();
 
-		WindowHandle defaultWindow = { 0 };
-		setWindowSize(defaultWindow, s_width, s_height);
+		setWindowSize(kDefaultWindowHandle, s_width, s_height);
 
 #if BX_PLATFORM_EMSCRIPTEN
 		s_app = _app;
@@ -560,9 +579,15 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 		for (ii = 1; ii < s_numApps; ++ii)
 		{
 			AppI* app = apps[ii-1];
-			app->m_next = apps[ii];
+
+			AppInternal* ai = bx::addressOf<AppInternal>(app, s_offset);
+			ai->m_next = apps[ii];
+		}
+
+		{
+			AppInternal* ai = bx::addressOf<AppInternal>(apps[s_numApps-1], s_offset);
+			ai->m_next = NULL;
 		}
-		apps[s_numApps-1]->m_next = NULL;
 
 		BX_FREE(g_allocator, apps);
 	}
@@ -583,14 +608,12 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 		inputInit();
 		inputAddBindings("bindings", s_bindings);
 
-		entry::WindowHandle defaultWindow = { 0 };
-
 		bx::FilePath fp(_argv[0]);
 		char title[bx::kMaxFilePath];
 		bx::strCopy(title, BX_COUNTOF(title), fp.getBaseName() );
 
-		entry::setWindowTitle(defaultWindow, title);
-		setWindowSize(defaultWindow, ENTRY_DEFAULT_WIDTH, ENTRY_DEFAULT_HEIGHT);
+		entry::setWindowTitle(kDefaultWindowHandle, title);
+		setWindowSize(kDefaultWindowHandle, ENTRY_DEFAULT_WIDTH, ENTRY_DEFAULT_HEIGHT);
 
 		sortApps();
 
@@ -1004,3 +1027,13 @@ extern "C" bool entry_process_events(uint32_t* _width, uint32_t* _height, uint32
 {
 	return entry::processEvents(*_width, *_height, *_debug, *_reset, NULL);
 }
+
+extern "C" void* entry_get_default_native_window_handle()
+{
+	return entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+}
+
+extern "C" void* entry_get_native_display_handle()
+{
+	return entry::getNativeDisplayHandle();
+}

+ 50 - 9
examples/common/entry/entry.h

@@ -35,14 +35,20 @@ extern "C" int _main_(int _argc, char** _argv);
 	_app s_ ## _app ## App(__VA_ARGS__)
 #endif // ENTRY_CONFIG_IMPLEMENT_MAIN
 
+///
+#define ENTRY_HANDLE(_name)                                                \
+	struct _name { uint16_t idx; };                                        \
+	inline bool isValid(_name _handle) { return UINT16_MAX != _handle.idx; }
+
 namespace entry
 {
-	struct WindowHandle  { uint16_t idx; };
-	inline bool isValid(WindowHandle _handle)  { return UINT16_MAX != _handle.idx; }
+	ENTRY_HANDLE(WindowHandle);
+	ENTRY_HANDLE(GamepadHandle);
 
-	struct GamepadHandle { uint16_t idx; };
-	inline bool isValid(GamepadHandle _handle) { return UINT16_MAX != _handle.idx; }
+	///
+	constexpr WindowHandle kDefaultWindowHandle = { 0 };
 
+	///
 	struct MouseButton
 	{
 		enum Enum
@@ -56,6 +62,7 @@ namespace entry
 		};
 	};
 
+	///
 	struct GamepadAxis
 	{
 		enum Enum
@@ -71,6 +78,7 @@ namespace entry
 		};
 	};
 
+	///
 	struct Modifier
 	{
 		enum Enum
@@ -87,6 +95,7 @@ namespace entry
 		};
 	};
 
+	///
 	struct Key
 	{
 		enum Enum
@@ -198,6 +207,7 @@ namespace entry
 		};
 	};
 
+	///
 	struct Suspend
 	{
 		enum Enum
@@ -211,8 +221,10 @@ namespace entry
 		};
 	};
 
+	///
 	const char* getName(Key::Enum _key);
 
+	///
 	struct MouseState
 	{
 		MouseState()
@@ -232,6 +244,7 @@ namespace entry
 		uint8_t m_buttons[entry::MouseButton::Count];
 	};
 
+	///
 	struct GamepadState
 	{
 		GamepadState()
@@ -242,22 +255,52 @@ namespace entry
 		int32_t m_axis[entry::GamepadAxis::Count];
 	};
 
+	///
 	bool processEvents(uint32_t& _width, uint32_t& _height, uint32_t& _debug, uint32_t& _reset, MouseState* _mouse = NULL);
 
+	///
 	bx::FileReaderI* getFileReader();
+
+	///
 	bx::FileWriterI* getFileWriter();
+
+	///
 	bx::AllocatorI*  getAllocator();
 
+	///
 	WindowHandle createWindow(int32_t _x, int32_t _y, uint32_t _width, uint32_t _height, uint32_t _flags = ENTRY_WINDOW_FLAG_NONE, const char* _title = "");
+
+	///
 	void destroyWindow(WindowHandle _handle);
+
+	///
 	void setWindowPos(WindowHandle _handle, int32_t _x, int32_t _y);
+
+	///
 	void setWindowSize(WindowHandle _handle, uint32_t _width, uint32_t _height);
+
+	///
 	void setWindowTitle(WindowHandle _handle, const char* _title);
+
+	///
 	void setWindowFlags(WindowHandle _handle, uint32_t _flags, bool _enabled);
+
+	///
 	void toggleFullscreen(WindowHandle _handle);
+
+	///
 	void setMouseLock(WindowHandle _handle, bool _lock);
+
+	///
+	void* getNativeWindowHandle(WindowHandle _handle);
+
+	///
+	void* getNativeDisplayHandle();
+
+	///
 	void setCurrentDir(const char* _dir);
 
+	///
 	struct WindowState
 	{
 		WindowState()
@@ -276,8 +319,10 @@ namespace entry
 		bx::FilePath m_dropFile;
 	};
 
+	///
 	bool processWindowEvents(WindowState& _state, uint32_t& _debug, uint32_t& _reset);
 
+	///
 	class BX_NO_VTABLE AppI
 	{
 	public:
@@ -308,12 +353,8 @@ namespace entry
 		///
 		AppI* getNext();
 
-		AppI* m_next;
-
 	private:
-		const char* m_name;
-		const char* m_description;
-		const char* m_url;
+		BX_ALIGN_DECL(16, uintptr_t) m_internal[4];
 	};
 
 	///

+ 15 - 15
examples/common/entry/entry_android.cpp

@@ -7,8 +7,6 @@
 
 #if ENTRY_CONFIG_USE_NATIVE && BX_PLATFORM_ANDROID
 
-#include <bgfx/platform.h>
-
 #include <bx/thread.h>
 #include <bx/file.h>
 
@@ -29,18 +27,6 @@ extern "C"
 
 namespace entry
 {
-	///
-	inline void androidSetWindow(::ANativeWindow* _window)
-	{
-		bgfx::PlatformData pd;
-		pd.ndt          = NULL;
-		pd.nwh          = _window;
-		pd.context      = NULL;
-		pd.backBuffer   = NULL;
-		pd.backBufferDS = NULL;
-		bgfx::setPlatformData(pd);
-	}
-
 	struct GamepadRemap
 	{
 		uint16_t  m_keyCode;
@@ -233,7 +219,6 @@ namespace entry
 					if (m_window != m_app->window)
 					{
 						m_window = m_app->window;
-						androidSetWindow(m_window);
 
 						int32_t width  = ANativeWindow_getWidth(m_window);
 						int32_t height = ANativeWindow_getHeight(m_window);
@@ -550,6 +535,21 @@ namespace entry
 		BX_UNUSED(_handle, _lock);
 	}
 
+	void* getNativeWindowHandle(WindowHandle _handle)
+	{
+		if (kDefaultWindowHandle.idx == _handle.idx)
+		{
+			return s_ctx.m_window;
+		}
+
+		return NULL;
+	}
+
+	void* getNativeDisplayHandle()
+	{
+		return NULL;
+	}
+
 	int32_t MainThreadEntry::threadFunc(bx::Thread* _thread, void* _userData)
 	{
 		BX_UNUSED(_thread);

+ 40 - 44
examples/common/entry/entry_glfw.cpp

@@ -85,27 +85,6 @@ namespace entry
 		glfwDestroyWindow(_window);
 	}
 
-	static void glfwSetWindow(GLFWwindow* _window)
-	{
-		bgfx::PlatformData pd;
-#	if BX_PLATFORM_LINUX || BX_PLATFORM_BSD
-# 		if ENTRY_CONFIG_USE_WAYLAND
-		pd.ndt      = glfwGetWaylandDisplay();
-#		else
-		pd.ndt      = glfwGetX11Display();
-		#endif
-#	elif BX_PLATFORM_OSX
-		pd.ndt      = NULL;
-#	elif BX_PLATFORM_WINDOWS
-		pd.ndt      = NULL;
-#	endif // BX_PLATFORM_WINDOWS
-		pd.nwh          = glfwNativeWindowHandle(_window);
-		pd.context      = NULL;
-		pd.backBuffer   = NULL;
-		pd.backBufferDS = NULL;
-		bgfx::setPlatformData(pd);
-	}
-
 	static uint8_t translateKeyModifiers(int _glfw)
 	{
 		uint8_t modifiers = 0;
@@ -453,29 +432,28 @@ namespace entry
 			glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
 
 			WindowHandle handle = { m_windowAlloc.alloc() };
-			m_windows[0] = glfwCreateWindow(ENTRY_DEFAULT_WIDTH
+			m_window[0] = glfwCreateWindow(ENTRY_DEFAULT_WIDTH
 				, ENTRY_DEFAULT_HEIGHT
 				, "bgfx"
 				, NULL
 				, NULL
 				);
 
-			if (!m_windows[0])
+			if (!m_window[0])
 			{
 				DBG("glfwCreateWindow failed!");
 				glfwTerminate();
 				return bx::kExitFailure;
 			}
 
-			glfwSetKeyCallback(m_windows[0], keyCb);
-			glfwSetCharCallback(m_windows[0], charCb);
-			glfwSetScrollCallback(m_windows[0], scrollCb);
-			glfwSetCursorPosCallback(m_windows[0], cursorPosCb);
-			glfwSetMouseButtonCallback(m_windows[0], mouseButtonCb);
-			glfwSetWindowSizeCallback(m_windows[0], windowSizeCb);
-			glfwSetDropCallback(m_windows[0], dropFileCb);
+			glfwSetKeyCallback(m_window[0], keyCb);
+			glfwSetCharCallback(m_window[0], charCb);
+			glfwSetScrollCallback(m_window[0], scrollCb);
+			glfwSetCursorPosCallback(m_window[0], cursorPosCb);
+			glfwSetMouseButtonCallback(m_window[0], mouseButtonCb);
+			glfwSetWindowSizeCallback(m_window[0], windowSizeCb);
+			glfwSetDropCallback(m_window[0], dropFileCb);
 
-			glfwSetWindow(m_windows[0]);
 			m_eventQueue.postSizeEvent(handle, ENTRY_DEFAULT_WIDTH, ENTRY_DEFAULT_HEIGHT);
 
 			for (uint32_t ii = 0; ii < ENTRY_CONFIG_MAX_GAMEPADS; ++ii)
@@ -492,8 +470,8 @@ namespace entry
 
 			m_thread.init(MainThreadEntry::threadFunc, &m_mte);
 
-			while (NULL != m_windows[0]
-			&&     !glfwWindowShouldClose(m_windows[0]))
+			while (NULL != m_window[0]
+			&&     !glfwWindowShouldClose(m_window[0]))
 			{
 				glfwWaitEventsTimeout(0.016);
 
@@ -535,7 +513,7 @@ namespace entry
 							glfwSetWindowSizeCallback(window, windowSizeCb);
 							glfwSetDropCallback(window, dropFileCb);
 
-							m_windows[msg->m_handle.idx] = window;
+							m_window[msg->m_handle.idx] = window;
 							m_eventQueue.postSizeEvent(msg->m_handle, msg->m_width, msg->m_height);
 							m_eventQueue.postWindowEvent(msg->m_handle, glfwNativeWindowHandle(window));
 						}
@@ -545,31 +523,31 @@ namespace entry
 						{
 							if (isValid(msg->m_handle) )
 							{
-								GLFWwindow* window = m_windows[msg->m_handle.idx];
+								GLFWwindow* window = m_window[msg->m_handle.idx];
 								m_eventQueue.postWindowEvent(msg->m_handle);
 								glfwDestroyWindowImpl(window);
-								m_windows[msg->m_handle.idx] = NULL;
+								m_window[msg->m_handle.idx] = NULL;
 							}
 						}
 						break;
 
 					case GLFW_WINDOW_SET_TITLE:
 						{
-							GLFWwindow* window = m_windows[msg->m_handle.idx];
+							GLFWwindow* window = m_window[msg->m_handle.idx];
 							glfwSetWindowTitle(window, msg->m_title.c_str());
 						}
 						break;
 
 					case GLFW_WINDOW_SET_POS:
 						{
-							GLFWwindow* window = m_windows[msg->m_handle.idx];
+							GLFWwindow* window = m_window[msg->m_handle.idx];
 							glfwSetWindowPos(window, msg->m_x, msg->m_y);
 						}
 						break;
 
 					case GLFW_WINDOW_SET_SIZE:
 						{
-							GLFWwindow* window = m_windows[msg->m_handle.idx];
+							GLFWwindow* window = m_window[msg->m_handle.idx];
 							glfwSetWindowSize(window, msg->m_width, msg->m_height);
 						}
 						break;
@@ -582,7 +560,7 @@ namespace entry
 
 					case GLFW_WINDOW_TOGGLE_FULL_SCREEN:
 						{
-							GLFWwindow* window = m_windows[msg->m_handle.idx];
+							GLFWwindow* window = m_window[msg->m_handle.idx];
 							if (glfwGetWindowMonitor(window) )
 							{
 								glfwSetWindowMonitor(window
@@ -619,7 +597,7 @@ namespace entry
 
 					case GLFW_WINDOW_MOUSE_LOCK:
 						{
-							GLFWwindow* window = m_windows[msg->m_handle.idx];
+							GLFWwindow* window = m_window[msg->m_handle.idx];
 							if (msg->m_value)
 							{
 								glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
@@ -639,7 +617,7 @@ namespace entry
 			m_eventQueue.postExitEvent();
 			m_thread.shutdown();
 
-			glfwDestroyWindowImpl(m_windows[0]);
+			glfwDestroyWindowImpl(m_window[0]);
 			glfwTerminate();
 
 			return m_thread.getExitCode();
@@ -651,7 +629,7 @@ namespace entry
 			for (uint32_t ii = 0, num = m_windowAlloc.getNumHandles(); ii < num; ++ii)
 			{
 				uint16_t idx = m_windowAlloc.getHandleAt(ii);
-				if (_window == m_windows[idx])
+				if (_window == m_window[idx])
 				{
 					WindowHandle handle = { idx };
 					return handle;
@@ -676,7 +654,7 @@ namespace entry
 		EventQueue m_eventQueue;
 		bx::Mutex m_lock;
 
-		GLFWwindow* m_windows[ENTRY_CONFIG_MAX_WINDOWS];
+		GLFWwindow* m_window[ENTRY_CONFIG_MAX_WINDOWS];
 		bx::HandleAllocT<ENTRY_CONFIG_MAX_WINDOWS> m_windowAlloc;
 
 		GamepadGLFW m_gamepad[ENTRY_CONFIG_MAX_GAMEPADS];
@@ -879,6 +857,24 @@ namespace entry
 		s_ctx.m_msgs.push(msg);
 	}
 
+	void* getNativeWindowHandle(WindowHandle _handle)
+	{
+		return glfwNativeWindowHandle(s_ctx.m_window[_handle.idx]);
+	}
+
+	void* getNativeDisplayHandle()
+	{
+#	if BX_PLATFORM_LINUX || BX_PLATFORM_BSD
+#		if ENTRY_CONFIG_USE_WAYLAND
+		return glfwGetWaylandDisplay();
+#		else
+		return glfwGetX11Display();
+#		endif // ENTRY_CONFIG_USE_WAYLAND
+#	else
+		return NULL;
+#	endif // BX_PLATFORM_*
+	}
+
 	int32_t MainThreadEntry::threadFunc(bx::Thread* _thread, void* _userData)
 	{
 		BX_UNUSED(_thread);

+ 25 - 17
examples/common/entry/entry_html5.cpp

@@ -28,8 +28,6 @@ extern "C" void entry_emscripten_yield()
 
 namespace entry
 {
-	static WindowHandle s_defaultWindow = { 0 };
-
 	static uint8_t s_translateKey[256];
 
 	struct Context
@@ -126,11 +124,6 @@ namespace entry
 			EMSCRIPTEN_CHECK(emscripten_set_focusin_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, this, true, focusCb) );
 			EMSCRIPTEN_CHECK(emscripten_set_focusout_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, this, true, focusCb) );
 
-			bgfx::PlatformData pd;
-			bx::memSet(&pd, 0, sizeof(pd) );
-			pd.nwh = (void*)canvas;
-			bgfx::setPlatformData(pd);
-
 			int32_t result = main(_argc, _argv);
 			return result;
 		}
@@ -163,7 +156,7 @@ namespace entry
 				case EMSCRIPTEN_EVENT_MOUSEMOVE:
 					s_ctx.m_mx = _event->targetX;
 					s_ctx.m_my = _event->targetY;
-					s_ctx.m_eventQueue.postMouseEvent(s_defaultWindow, s_ctx.m_mx, s_ctx.m_my, s_ctx.m_scroll);
+					s_ctx.m_eventQueue.postMouseEvent(kDefaultWindowHandle, s_ctx.m_mx, s_ctx.m_my, s_ctx.m_scroll);
 					return true;
 
 				case EMSCRIPTEN_EVENT_MOUSEDOWN:
@@ -176,7 +169,7 @@ namespace entry
 						? MouseButton::Middle : MouseButton::Left)
 						;
 					s_ctx.m_eventQueue.postMouseEvent(
-						  s_defaultWindow
+						  kDefaultWindowHandle
 						, s_ctx.m_mx
 						, s_ctx.m_my
 						, s_ctx.m_scroll
@@ -203,7 +196,7 @@ namespace entry
 					s_ctx.m_scrollf += _event->deltaY;
 
 					s_ctx.m_scroll = (int32_t)s_ctx.m_scrollf;
-					s_ctx.m_eventQueue.postMouseEvent(s_defaultWindow, s_ctx.m_mx, s_ctx.m_my, s_ctx.m_scroll);
+					s_ctx.m_eventQueue.postMouseEvent(kDefaultWindowHandle, s_ctx.m_mx, s_ctx.m_my, s_ctx.m_scroll);
 					return true;
 				}
 			}
@@ -303,14 +296,14 @@ namespace entry
 						else
 						{
 							enum { ShiftMask = Modifier::LeftShift|Modifier::RightShift };
-							s_ctx.m_eventQueue.postCharEvent(s_defaultWindow, 1, pressedChar);
-							s_ctx.m_eventQueue.postKeyEvent(s_defaultWindow, key, modifiers, true);
+							s_ctx.m_eventQueue.postCharEvent(kDefaultWindowHandle, 1, pressedChar);
+							s_ctx.m_eventQueue.postKeyEvent(kDefaultWindowHandle, key, modifiers, true);
 							return true;
 						}
 						break;
 
 					case EMSCRIPTEN_EVENT_KEYUP:
-						s_ctx.m_eventQueue.postKeyEvent(s_defaultWindow, key, modifiers, false);
+						s_ctx.m_eventQueue.postKeyEvent(kDefaultWindowHandle, key, modifiers, false);
 						return true;
 				}
 			}
@@ -340,19 +333,19 @@ namespace entry
 			switch (_eventType)
 			{
 				case EMSCRIPTEN_EVENT_BLUR:
-					s_ctx.m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::DidSuspend);
+					s_ctx.m_eventQueue.postSuspendEvent(kDefaultWindowHandle, Suspend::DidSuspend);
 					return true;
 
 				case EMSCRIPTEN_EVENT_FOCUS:
-					s_ctx.m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::DidResume);
+					s_ctx.m_eventQueue.postSuspendEvent(kDefaultWindowHandle, Suspend::DidResume);
 					return true;
 
 				case EMSCRIPTEN_EVENT_FOCUSIN:
-					s_ctx.m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::WillResume);
+					s_ctx.m_eventQueue.postSuspendEvent(kDefaultWindowHandle, Suspend::WillResume);
 					return true;
 
 				case EMSCRIPTEN_EVENT_FOCUSOUT:
-					s_ctx.m_eventQueue.postSuspendEvent(s_defaultWindow, Suspend::WillSuspend);
+					s_ctx.m_eventQueue.postSuspendEvent(kDefaultWindowHandle, Suspend::WillSuspend);
 					return true;
 			}
 		}
@@ -419,6 +412,21 @@ namespace entry
 	{
 		BX_UNUSED(_handle, _lock);
 	}
+
+	void* getNativeWindowHandle(WindowHandle _handle)
+	{
+		if (kDefaultWindowHandle.idx == _handle.idx)
+		{
+			return (void*)"#canvas";
+		}
+
+		return NULL;
+	}
+
+	void* getNativeDisplayHandle()
+	{
+		return NULL;
+	}
 }
 
 int main(int _argc, const char* const* _argv)

+ 22 - 17
examples/common/entry/entry_ios.mm

@@ -57,6 +57,7 @@ namespace entry
 
 		MainThreadEntry m_mte;
 		bx::Thread m_thread;
+		void* m_window;
 
 		EventQueue m_eventQueue;
 	};
@@ -145,16 +146,25 @@ namespace entry
 		BX_UNUSED(_handle, _lock);
 	}
 
+	void* getNativeWindowHandle(WindowHandle _handle)
+	{
+		if (kDefaultWindowHandle.idx == _handle.idx)
+		{
+			return s_ctx.m_window;
+		}
+
+		return NULL;
+	}
+
+	void* getNativeDisplayHandle()
+	{
+		return NULL;
+	}
+
 } // namespace entry
 
 using namespace entry;
 
-#ifdef HAS_METAL_SDK
-static	id<MTLDevice>  m_device = NULL;
-#else
-static	void* m_device = NULL;
-#endif
-
 @interface ViewController : UIViewController
 @end
 @implementation ViewController
@@ -177,13 +187,14 @@ static	void* m_device = NULL;
 + (Class)layerClass
 {
 #ifdef HAS_METAL_SDK
+	static id<MTLDevice> device = NULL;
 	Class metalClass = NSClassFromString(@"CAMetalLayer");    //is metal runtime sdk available
 	if ( metalClass != nil)
 	{
-		m_device = MTLCreateSystemDefaultDevice(); // is metal supported on this device (is there a better way to do this - without creating device ?)
-		if (m_device)
+		device = MTLCreateSystemDefaultDevice(); // is metal supported on this device (is there a better way to do this - without creating device ?)
+		if (NULL != device)
 		{
-			[m_device retain];
+			[device retain];
 			return metalClass;
 		}
 	}
@@ -201,13 +212,7 @@ static	void* m_device = NULL;
 		return nil;
 	}
 
-	bgfx::PlatformData pd;
-	pd.ndt          = NULL;
-	pd.nwh          = self.layer;
-	pd.context      = m_device;
-	pd.backBuffer   = NULL;
-	pd.backBufferDS = NULL;
-	bgfx::setPlatformData(pd);
+	s_ctx->m_window = self.layer;
 
 	return self;
 }
@@ -226,7 +231,7 @@ static	void* m_device = NULL;
 		m_displayLink = [self.window.screen displayLinkWithTarget:self selector:@selector(renderFrame)];
 		//[m_displayLink setFrameInterval:1];
 		//[m_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
-		//		[m_displayLink addToRunLoop:[NSRunLoop currentRunLoop]];
+		//[m_displayLink addToRunLoop:[NSRunLoop currentRunLoop]];
 		[m_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
 	}
 }

+ 11 - 0
examples/common/entry/entry_noop.cpp

@@ -67,6 +67,17 @@ namespace entry
 		BX_UNUSED(_handle, _lock);
 	}
 
+	void* getNativeWindowHandle(WindowHandle _handle)
+	{
+		BX_UNUSED(_handle);
+		return NULL;
+	}
+
+	void* getNativeDisplayHandle()
+	{
+		return NULL;
+	}
+
 } // namespace entry
 
 int main(int _argc, const char* const* _argv)

+ 10 - 14
examples/common/entry/entry_osx.mm

@@ -45,18 +45,6 @@
 
 namespace entry
 {
-	///
-	inline void osxSetNSWindow(void* _window, void* _nsgl = NULL)
-	{
-		bgfx::PlatformData pd;
-		pd.ndt          = NULL;
-		pd.nwh          = _window;
-		pd.context      = _nsgl;
-		pd.backBuffer   = NULL;
-		pd.backBufferDS = NULL;
-		bgfx::setPlatformData(pd);
-	}
-
 	static uint8_t s_translateKey[256];
 
 	struct MainThreadEntry
@@ -507,8 +495,6 @@ namespace entry
 
 			m_windowFrame = [m_window[0] frame];
 
-			osxSetNSWindow(m_window[0]);
-
 			MainThreadEntry mte;
 			mte.m_argc = _argc;
 			mte.m_argv = _argv;
@@ -729,6 +715,16 @@ namespace entry
 			});
 	}
 
+	void* getNativeWindowHandle(WindowHandle _handle)
+	{
+		return s_ctx.m_window[_handle.idx];
+	}
+
+	void* getNativeDisplayHandle()
+	{
+		return NULL;
+	}
+
 } // namespace entry
 
 @implementation AppDelegate

+ 25 - 30
examples/common/entry/entry_sdl.cpp

@@ -74,35 +74,6 @@ namespace entry
 #	endif // BX_PLATFORM_
 	}
 
-	inline bool sdlSetWindow(SDL_Window* _window)
-	{
-		SDL_SysWMinfo wmi;
-		SDL_VERSION(&wmi.version);
-		if (!SDL_GetWindowWMInfo(_window, &wmi) )
-		{
-			return false;
-		}
-
-		bgfx::PlatformData pd;
-#	if BX_PLATFORM_LINUX || BX_PLATFORM_BSD
-#		if ENTRY_CONFIG_USE_WAYLAND
-		pd.ndt          = wmi.info.wl.display;
-#		else
-		pd.ndt          = wmi.info.x11.display;
-#		endif
-#	else
-		pd.ndt          = NULL;
-#	endif // BX_PLATFORM_
-		pd.nwh          = sdlNativeWindowHandle(_window);
-
-		pd.context      = NULL;
-		pd.backBuffer   = NULL;
-		pd.backBufferDS = NULL;
-		bgfx::setPlatformData(pd);
-
-		return true;
-	}
-
 	static void sdlDestroyWindow(SDL_Window* _window)
 	{
 		if(!_window)
@@ -513,7 +484,6 @@ namespace entry
 
 			s_userEventStart = SDL_RegisterEvents(7);
 
-			sdlSetWindow(m_window[0]);
 			bgfx::renderFrame();
 
 			m_thread.init(MainThreadEntry::threadFunc, &m_mte);
@@ -1162,6 +1132,31 @@ namespace entry
 		sdlPostEvent(SDL_USER_WINDOW_MOUSE_LOCK, _handle, NULL, _lock);
 	}
 
+	void* getNativeWindowHandle(WindowHandle _handle)
+	{
+		return sdlNativeWindowHandle(s_ctx.m_window[_handle.idx]);
+	}
+
+	void* getNativeDisplayHandle()
+	{
+		SDL_SysWMinfo wmi;
+		SDL_VERSION(&wmi.version);
+		if (!SDL_GetWindowWMInfo(s_ctx.m_window[0], &wmi) )
+		{
+			return NULL;
+		}
+
+#	if BX_PLATFORM_LINUX || BX_PLATFORM_BSD
+#		if ENTRY_CONFIG_USE_WAYLAND
+		return wmi.info.wl.display;
+#		else
+		return wmi.info.x11.display;
+#		endif // ENTRY_CONFIG_USE_WAYLAND
+#	else
+		return NULL;
+#	endif // BX_PLATFORM_*
+	}
+
 	int32_t MainThreadEntry::threadFunc(bx::Thread* _thread, void* _userData)
 	{
 		BX_UNUSED(_thread);

+ 10 - 11
examples/common/entry/entry_windows.cpp

@@ -45,15 +45,6 @@ namespace entry
 		return utf16;
 	}
 
-	///
-	inline void winSetHwnd(::HWND _window)
-	{
-		bgfx::PlatformData pd;
-		bx::memSet(&pd, 0, sizeof(pd) );
-		pd.nwh = _window;
-		bgfx::setPlatformData(pd);
-	}
-
 	typedef DWORD (WINAPI* PFN_XINPUT_GET_STATE)(DWORD dwUserIndex, XINPUT_STATE* pState);
 	typedef void  (WINAPI* PFN_XINPUT_ENABLE)(BOOL enable); // 1.4+
 
@@ -502,8 +493,6 @@ namespace entry
 				| ENTRY_WINDOW_FLAG_FRAME
 				;
 
-			winSetHwnd(m_hwnd[0]);
-
 			adjust(m_hwnd[0], ENTRY_DEFAULT_WIDTH, ENTRY_DEFAULT_HEIGHT, true);
 			clear(m_hwnd[0]);
 
@@ -1170,6 +1159,16 @@ namespace entry
 		PostMessage(s_ctx.m_hwnd[0], WM_USER_WINDOW_MOUSE_LOCK, _handle.idx, _lock);
 	}
 
+	void* getNativeWindowHandle(WindowHandle _handle)
+	{
+		return s_ctx.m_hwnd[_handle.idx];
+	}
+
+	void* getNativeDisplayHandle()
+	{
+		return NULL;
+	}
+
 	int32_t MainThreadEntry::threadFunc(bx::Thread* /*_thread*/, void* _userData)
 	{
 		MainThreadEntry* self = (MainThreadEntry*)_userData;

+ 0 - 237
examples/common/entry/entry_winrt.cx

@@ -1,237 +0,0 @@
-/*
- * Copyright 2011-2016 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
- */
-
-#include "entry_p.h"
-
-#if BX_PLATFORM_WINRT || BX_PLATFORM_XBOXONE
-
-#include <bgfx/platform.h>
-#include <bx/thread.h>
-#include <bx/math.h>
-#include <Unknwn.h>
-#include <cmath>
-
-using namespace Windows::ApplicationModel;
-using namespace Windows::ApplicationModel::Core;
-using namespace Windows::ApplicationModel::Activation;
-using namespace Windows::UI::Core;
-using namespace Windows::UI::Input;
-using namespace Windows::System;
-using namespace Windows::Foundation;
-#if BX_PLATFORM_WINRT
-using namespace Windows::Graphics::Display;
-#endif // BX_PLATFORM_WINRT
-using namespace Platform;
-
-static const char* const g_emptyArgs[] = { "app.exe", "", "" };
-static entry::WindowHandle g_defaultWindow = { 0 };
-static entry::EventQueue g_eventQueue;
-
-///
-inline void winrtSetWindow(::IUnknown* _window)
-{
-	bgfx::PlatformData pd;
-	pd.ndt          = NULL;
-	pd.nwh          = _window;
-	pd.context      = NULL;
-	pd.backBuffer   = NULL;
-	pd.backBufferDS = NULL;
-	bgfx::setPlatformData(pd);
-}
-
-ref class App sealed : public IFrameworkView
-{
-public:
-	App()
-		: m_windowVisible(true)
-		, m_windowClosed(false)
-	{
-	}
-
-	// IFrameworkView Methods.
-	virtual void Initialize(CoreApplicationView^ applicationView)
-	{
-		applicationView->Activated += ref new
-			TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &App::OnActivated);
-
-		CoreApplication::Suspending += ref new
-			EventHandler<SuspendingEventArgs^>(this, &App::OnSuspending);
-
-		CoreApplication::Resuming += ref new
-			EventHandler<Platform::Object^>(this, &App::OnResuming);
-	}
-
-	virtual void SetWindow(CoreWindow^ window)
-	{
-		window->VisibilityChanged += ref new
-			TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &App::OnVisibilityChanged);
-
-		window->Closed += ref new
-			TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &App::OnWindowClosed);
-
-		winrtSetWindow(reinterpret_cast<IUnknown*>(window) );
-	}
-
-	virtual void Load(String^ entryPoint)
-	{
-	}
-
-	virtual void Run()
-	{
-		bgfx::renderFrame();
-
-		bx::Thread thread;
-		thread.init(MainThreadFunc, nullptr);
-
-		CoreWindow^ window = CoreWindow::GetForCurrentThread();
-		auto bounds = window->Bounds;
-
-#if BX_PLATFORM_WINRT
-		auto dpi = DisplayInformation::GetForCurrentView()->LogicalDpi;
-		static const float dipsPerInch = 96.0f;
-		g_eventQueue.postSizeEvent(g_defaultWindow
-			, std::lround(bx::floor(bounds.Width  * dpi / dipsPerInch + 0.5f) )
-			, std::lround(bx::floor(bounds.Height * dpi / dipsPerInch + 0.5f) )
-			);
-#endif // BX_PLATFORM_WINRT
-
-		while (!m_windowClosed)
-		{
-			if (m_windowVisible)
-			{
-				window->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
-			}
-			else
-			{
-				window->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
-			}
-
-			bgfx::renderFrame();
-		}
-
-		g_eventQueue.postExitEvent();
-
-		while (bgfx::RenderFrame::NoContext != bgfx::renderFrame() ) {};
-
-		thread.shutdown();
-	}
-
-	virtual void Uninitialize()
-	{
-	}
-
-private:
-	bool m_windowVisible;
-	bool m_windowClosed;
-
-	void OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
-	{
-		CoreWindow::GetForCurrentThread()->Activate();
-	}
-
-	void OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
-	{
-		m_windowVisible = args->Visible;
-	}
-
-	void OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
-	{
-		SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
-		BX_UNUSED(deferral);
-	}
-
-	void OnResuming(Platform::Object^ sender, Platform::Object^ args)
-	{
-	}
-
-	void OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
-	{
-		m_windowClosed = true;
-	}
-
-	static int32_t MainThreadFunc(bx::Thread*, void*)
-	{
-		return entry::main(BX_COUNTOF(g_emptyArgs), g_emptyArgs);
-	}
-};
-
-ref class AppSource sealed : IFrameworkViewSource
-{
-public:
-	virtual IFrameworkView^ CreateView()
-	{
-		return ref new App();
-	}
-};
-
-namespace entry
-{
-	const Event* poll()
-	{
-		return g_eventQueue.poll();
-	}
-
-	const Event* poll(WindowHandle _handle)
-	{
-		return g_eventQueue.poll(_handle);
-	}
-
-	void release(const Event* _event)
-	{
-		g_eventQueue.release(_event);
-	}
-
-	WindowHandle createWindow(int32_t _x, int32_t _y, uint32_t _width, uint32_t _height, uint32_t _flags, const char* _title)
-	{
-		BX_UNUSED(_x, _y, _width, _height, _flags, _title);
-		WindowHandle handle = { UINT16_MAX };
-		return handle;
-	}
-
-	void destroyWindow(WindowHandle _handle)
-	{
-		BX_UNUSED(_handle);
-	}
-
-	void setWindowPos(WindowHandle _handle, int32_t _x, int32_t _y)
-	{
-		BX_UNUSED(_handle, _x, _y);
-	}
-
-	void setWindowSize(WindowHandle _handle, uint32_t _width, uint32_t _height)
-	{
-		BX_UNUSED(_handle, _width, _height);
-	}
-
-	void setWindowTitle(WindowHandle _handle, const char* _title)
-	{
-		BX_UNUSED(_handle, _title);
-	}
-
-	void setWindowFlags(WindowHandle _handle, uint32_t _flags, bool _enabled)
-	{
-		BX_UNUSED(_handle, _flags, _enabled);
-	}
-
-	void toggleFullscreen(WindowHandle _handle)
-	{
-		BX_UNUSED(_handle);
-	}
-
-	void setMouseLock(WindowHandle _handle, bool _lock)
-	{
-		BX_UNUSED(_handle, _lock);
-	}
-}
-
-[MTAThread]
-int main(Array<String^>^)
-{
-	auto appSource = ref new AppSource();
-	CoreApplication::Run(appSource);
-	return 0;
-}
-
-#endif // BX_PLATFORM_WINRT || BX_PLATFORM_XBOXONE

+ 54 - 59
examples/common/entry/entry_x11.cpp

@@ -12,8 +12,6 @@
 #include <X11/keysymdef.h>
 #include <X11/Xlib.h> // will include X11 which #defines None... Don't mess with order of includes.
 #include <X11/Xutil.h>
-#include <bgfx/platform.h>
-
 #include <unistd.h> // syscall
 
 #undef None
@@ -31,18 +29,6 @@ namespace entry
 	static const char* s_applicationName  = "BGFX";
 	static const char* s_applicationClass = "bgfx";
 
-	///
-	inline void x11SetDisplayWindow(void* _display, uint32_t _window, void* _glx = NULL)
-	{
-		bgfx::PlatformData pd;
-		pd.ndt          = _display;
-		pd.nwh          = (void*)(uintptr_t)_window;
-		pd.context      = _glx;
-		pd.backBuffer   = NULL;
-		pd.backBufferDS = NULL;
-		bgfx::setPlatformData(pd);
-	}
-
 #define JS_EVENT_BUTTON 0x01 /* button pressed/released */
 #define JS_EVENT_AXIS   0x02 /* joystick moved */
 #define JS_EVENT_INIT   0x80 /* initial state of device */
@@ -355,29 +341,29 @@ namespace entry
 
 			bx::memSet(&m_windowAttrs, 0, sizeof(m_windowAttrs) );
 			m_windowAttrs.background_pixel = 0;
-			m_windowAttrs.border_pixel = 0;
+			m_windowAttrs.border_pixel     = 0;
 			m_windowAttrs.bit_gravity = StaticGravity;
-			m_windowAttrs.event_mask = 0
-					| ButtonPressMask
-					| ButtonReleaseMask
-					| ExposureMask
-					| KeyPressMask
-					| KeyReleaseMask
-					| PointerMotionMask
-					| StructureNotifyMask
-					;
+			m_windowAttrs.event_mask  = 0
+				| ButtonPressMask
+				| ButtonReleaseMask
+				| ExposureMask
+				| KeyPressMask
+				| KeyReleaseMask
+				| PointerMotionMask
+				| StructureNotifyMask
+				;
 
 			m_windowAlloc.alloc();
-			m_window[0] = XCreateWindow(m_display
-									, m_root
-									, 0, 0
-									, 1, 1, 0
-									, m_depth
-									, InputOutput
-									, m_visual
-									, CWBorderPixel|CWEventMask|CWBackPixel|CWBitGravity
-									, &m_windowAttrs
-									);
+			m_window[0] = XCreateWindow(
+				  m_display
+				, m_root
+				, 0, 0, 1, 1, 0
+				, m_depth
+				, InputOutput
+				, m_visual
+				, CWBorderPixel|CWEventMask|CWBackPixel|CWBitGravity
+				, &m_windowAttrs
+				);
 
 			const char* wmDeleteWindowName = "WM_DELETE_WINDOW";
 			Atom wmDeleteWindow;
@@ -397,18 +383,16 @@ namespace entry
 			im = XOpenIM(m_display, NULL, NULL, NULL);
 
 			XIC ic;
-			ic = XCreateIC(im
-					, XNInputStyle
-					, 0
-					| XIMPreeditNothing
-					| XIMStatusNothing
-					, XNClientWindow
-					, m_window[0]
-					, NULL
-					);
-
-			//
-			x11SetDisplayWindow(m_display, m_window[0]);
+			ic = XCreateIC(
+				  im
+				, XNInputStyle
+				, 0
+				| XIMPreeditNothing
+				| XIMStatusNothing
+				, XNClientWindow
+				, m_window[0]
+				, NULL
+				);
 
 			MainThreadEntry mte;
 			mte.m_argc = _argc;
@@ -585,19 +569,20 @@ namespace entry
 
 		void createWindow(WindowHandle _handle, Msg* msg)
 		{
-			Window window = XCreateWindow(m_display
-									, m_root
-									, msg->m_x
-									, msg->m_y
-									, msg->m_width
-									, msg->m_height
-									, 0
-									, m_depth
-									, InputOutput
-									, m_visual
-									, CWBorderPixel|CWEventMask|CWBackPixel|CWBitGravity
-									, &m_windowAttrs
-									);
+			Window window = XCreateWindow(
+				  m_display
+				, m_root
+				, msg->m_x
+				, msg->m_y
+				, msg->m_width
+				, msg->m_height
+				, 0
+				, m_depth
+				, InputOutput
+				, m_visual
+				, CWBorderPixel|CWEventMask|CWBackPixel|CWBitGravity
+				, &m_windowAttrs
+				);
 			m_window[_handle.idx] = window;
 
 			const char* wmDeleteWindowName = "WM_DELETE_WINDOW";
@@ -767,6 +752,16 @@ namespace entry
 		BX_UNUSED(_handle, _lock);
 	}
 
+	void* getNativeWindowHandle(WindowHandle _handle)
+	{
+		return (void*)(uintptr_t)s_ctx.m_window[_handle.idx];
+	}
+
+	void* getNativeDisplayHandle()
+	{
+		return s_ctx.m_display;
+	}
+
 } // namespace entry
 
 int main(int _argc, const char* const* _argv)

+ 2 - 2
examples/common/entry/input.cpp

@@ -375,8 +375,8 @@ void inputSetMouseLock(bool _lock)
 	if (s_input->m_mouse.m_lock != _lock)
 	{
 		s_input->m_mouse.m_lock = _lock;
-		entry::WindowHandle defaultWindow = { 0 };
-		entry::setMouseLock(defaultWindow, _lock);
+
+		entry::setMouseLock(entry::kDefaultWindowHandle, _lock);
 		if (_lock)
 		{
 			s_input->m_mouse.m_norm[0] = 0.0f;

+ 2 - 14
src/bgfx.cpp

@@ -1878,21 +1878,7 @@ namespace bgfx
 		m_init.resolution.maxFrameLatency = bx::min<uint8_t>(_init.resolution.maxFrameLatency, BGFX_CONFIG_MAX_FRAME_LATENCY);
 		dump(m_init.resolution);
 
-		if (g_platformData.ndt          == NULL
-		&&  g_platformData.nwh          == NULL
-		&&  g_platformData.context      == NULL
-		&&  g_platformData.backBuffer   == NULL
-		&&  g_platformData.backBufferDS == NULL)
-		{
-			bx::memCopy(&g_platformData, &m_init.platformData, sizeof(PlatformData) );
-		}
-		else
-		{
-			bx::memCopy(&m_init.platformData, &g_platformData, sizeof(PlatformData) );
-		}
-
 		if (true
-		&&  !BX_ENABLED(BX_PLATFORM_EMSCRIPTEN || BX_PLATFORM_PS4)
 		&&  RendererType::Noop != m_init.type
 		&&  NULL == m_init.platformData.ndt
 		&&  NULL == m_init.platformData.nwh
@@ -1904,6 +1890,8 @@ namespace bgfx
 			BX_TRACE("bgfx platform data like window handle or backbuffer is not set, creating headless device.");
 		}
 
+		bx::memCopy(&g_platformData, &m_init.platformData, sizeof(PlatformData) );
+
 		m_exit    = false;
 		m_flipped = true;
 		m_frames  = 0;

+ 6 - 19
src/renderer_gl.cpp

@@ -2384,7 +2384,7 @@ namespace bgfx { namespace gl
 				if (NULL != extensions)
 				{
 					bx::StringView ext(extensions);
-					uint32_t index = 0;
+
 					while (!ext.isEmpty() )
 					{
 						const bx::StringView space = bx::strFind(ext, ' ');
@@ -2392,8 +2392,6 @@ namespace bgfx { namespace gl
 						updateExtension(token);
 
 						ext.set(space.getPtr() + (space.isEmpty() ? 0 : 1), ext.getTerm() );
-
-						++index;
 					}
 				}
 				else if (NULL != glGetStringi)
@@ -5880,22 +5878,11 @@ namespace bgfx { namespace gl
 			if (s_renderGL->m_textureSwizzleSupport
 			&& (-1 != mapping[0] || -1 != mapping[1] || -1 != mapping[2] || -1 != mapping[3]) )
 			{
-				if (-1 == mapping[0])
-				{
-					mapping[0] = GL_RED;
-				}
-				if (-1 == mapping[1])
-				{
-					mapping[1] = GL_GREEN;
-				}
-				if (-1 == mapping[2])
-				{
-					mapping[2] = GL_BLUE;
-				}
-				if (-1 == mapping[3])
-				{
-					mapping[3] = GL_ALPHA;
-				}
+				mapping[0] = -1 == mapping[0] ? GL_RED   : mapping[0];
+				mapping[1] = -1 == mapping[1] ? GL_GREEN : mapping[1];
+				mapping[2] = -1 == mapping[2] ? GL_BLUE  : mapping[2];
+				mapping[3] = -1 == mapping[3] ? GL_ALPHA : mapping[3];
+
 				GL_CHECK(glTexParameteriv(m_target, GL_TEXTURE_SWIZZLE_RGBA, mapping));
 			}
 

+ 5 - 4
tools/geometryv/geometryv.cpp

@@ -715,10 +715,12 @@ int _main_(int _argc, char** _argv)
 	View view;
 	cmdAdd("view", cmdView, &view);
 
-	entry::setWindowFlags(entry::WindowHandle{0}, ENTRY_WINDOW_FLAG_ASPECT_RATIO, false);
-	entry::setWindowSize(entry::WindowHandle{0}, view.m_width, view.m_height);
+	entry::setWindowFlags(entry::kDefaultWindowHandle, ENTRY_WINDOW_FLAG_ASPECT_RATIO, false);
+	entry::setWindowSize(entry::kDefaultWindowHandle, view.m_width, view.m_height);
 
 	bgfx::Init init;
+	init.platformData.nwh = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+	init.platformData.ndt = entry::getNativeDisplayHandle();
 	init.resolution.width = view.m_width;
 	init.resolution.width = view.m_height;
 	init.resolution.reset = 0
@@ -1248,8 +1250,7 @@ int _main_(int _argc, char** _argv)
 					bx::stringPrintf(title, "Failed to load %s!", filePath);
 				}
 
-				entry::WindowHandle handle = { 0 };
-				entry::setWindowTitle(handle, title.c_str() );
+				entry::setWindowTitle(entry::kDefaultWindowHandle, title.c_str() );
 			}
 
 			int64_t now = bx::getHPCounter();

+ 5 - 4
tools/texturev/texturev.cpp

@@ -1311,11 +1311,13 @@ int _main_(int _argc, char** _argv)
 	View view;
 	cmdAdd("view", cmdView, &view);
 
-	entry::setWindowFlags(entry::WindowHandle{0}, ENTRY_WINDOW_FLAG_ASPECT_RATIO, false);
-	entry::setWindowSize(entry::WindowHandle{0}, view.m_width, view.m_height);
+	entry::setWindowFlags(entry::kDefaultWindowHandle, ENTRY_WINDOW_FLAG_ASPECT_RATIO, false);
+	entry::setWindowSize(entry::kDefaultWindowHandle, view.m_width, view.m_height);
 
 	bgfx::Init init;
 	init.type = view.m_rendererType;
+	init.platformData.nwh  = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
+	init.platformData.ndt  = entry::getNativeDisplayHandle();
 	init.resolution.width  = view.m_width;
 	init.resolution.height = view.m_height;
 	init.resolution.reset  = BGFX_RESET_VSYNC;
@@ -2064,8 +2066,7 @@ int _main_(int _argc, char** _argv)
 					bx::stringPrintf(title, "Failed to load %s!", filePath);
 				}
 
-				entry::WindowHandle handle = { 0 };
-				entry::setWindowTitle(handle, title.c_str() );
+				entry::setWindowTitle(entry::kDefaultWindowHandle, title.c_str() );
 			}
 
 			int64_t now = bx::getHPCounter();