diff --git a/examples/00-helloworld/helloworld.cpp b/examples/00-helloworld/helloworld.cpp index a3109dd23..97a794633 100644 --- a/examples/00-helloworld/helloworld.cpp +++ b/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; diff --git a/examples/01-cubes/cubes.cpp b/examples/01-cubes/cubes.cpp index 5ab97d5bc..de4566739 100644 --- a/examples/01-cubes/cubes.cpp +++ b/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; diff --git a/examples/02-metaballs/metaballs.cpp b/examples/02-metaballs/metaballs.cpp index 79d8e339d..305bf53b3 100644 --- a/examples/02-metaballs/metaballs.cpp +++ b/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; diff --git a/examples/03-raymarch/raymarch.cpp b/examples/03-raymarch/raymarch.cpp index fb26059d6..6fb30b91a 100644 --- a/examples/03-raymarch/raymarch.cpp +++ b/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; diff --git a/examples/04-mesh/mesh.cpp b/examples/04-mesh/mesh.cpp index 7af05f185..59c6c0706 100644 --- a/examples/04-mesh/mesh.cpp +++ b/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; diff --git a/examples/05-instancing/instancing.cpp b/examples/05-instancing/instancing.cpp index 042cb29c0..6b066c16d 100644 --- a/examples/05-instancing/instancing.cpp +++ b/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; diff --git a/examples/06-bump/bump.cpp b/examples/06-bump/bump.cpp index 0b1e2a052..bbfe793fe 100644 --- a/examples/06-bump/bump.cpp +++ b/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; diff --git a/examples/07-callback/callback.cpp b/examples/07-callback/callback.cpp index 160d86acb..418b2a96e 100644 --- a/examples/07-callback/callback.cpp +++ b/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; diff --git a/examples/08-update/update.cpp b/examples/08-update/update.cpp index bd4047589..9e9f63fcb 100644 --- a/examples/08-update/update.cpp +++ b/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; diff --git a/examples/09-hdr/hdr.cpp b/examples/09-hdr/hdr.cpp index 2854d419f..6184611b4 100644 --- a/examples/09-hdr/hdr.cpp +++ b/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; diff --git a/examples/10-font/font.cpp b/examples/10-font/font.cpp index 0814ec4a4..34daca64e 100644 --- a/examples/10-font/font.cpp +++ b/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; diff --git a/examples/11-fontsdf/fontsdf.cpp b/examples/11-fontsdf/fontsdf.cpp index 2452f8ae6..a7e7362a5 100644 --- a/examples/11-fontsdf/fontsdf.cpp +++ b/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; diff --git a/examples/12-lod/lod.cpp b/examples/12-lod/lod.cpp index e1a53197b..b717c961e 100644 --- a/examples/12-lod/lod.cpp +++ b/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; diff --git a/examples/13-stencil/stencil.cpp b/examples/13-stencil/stencil.cpp index 737c81fd0..3acd5d501 100644 --- a/examples/13-stencil/stencil.cpp +++ b/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; diff --git a/examples/14-shadowvolumes/shadowvolumes.cpp b/examples/14-shadowvolumes/shadowvolumes.cpp index fa93a6b58..2df07dec0 100644 --- a/examples/14-shadowvolumes/shadowvolumes.cpp +++ b/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; diff --git a/examples/15-shadowmaps-simple/shadowmaps_simple.cpp b/examples/15-shadowmaps-simple/shadowmaps_simple.cpp index 746a5caf5..236b859e0 100644 --- a/examples/15-shadowmaps-simple/shadowmaps_simple.cpp +++ b/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; diff --git a/examples/16-shadowmaps/shadowmaps.cpp b/examples/16-shadowmaps/shadowmaps.cpp index 2c642fc8d..4ab7b7e60 100644 --- a/examples/16-shadowmaps/shadowmaps.cpp +++ b/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; diff --git a/examples/17-drawstress/drawstress.cpp b/examples/17-drawstress/drawstress.cpp index ad25c4340..5dd17370c 100644 --- a/examples/17-drawstress/drawstress.cpp +++ b/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; diff --git a/examples/18-ibl/ibl.cpp b/examples/18-ibl/ibl.cpp index 1a98c16d9..a2d15492e 100644 --- a/examples/18-ibl/ibl.cpp +++ b/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; diff --git a/examples/19-oit/oit.cpp b/examples/19-oit/oit.cpp index f721851b3..576cd091f 100644 --- a/examples/19-oit/oit.cpp +++ b/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; diff --git a/examples/20-nanovg/nanovg.cpp b/examples/20-nanovg/nanovg.cpp index e5edce67b..144d21b8b 100644 --- a/examples/20-nanovg/nanovg.cpp +++ b/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; diff --git a/examples/21-deferred/deferred.cpp b/examples/21-deferred/deferred.cpp index dbd94dd73..6c379fd3f 100644 --- a/examples/21-deferred/deferred.cpp +++ b/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; diff --git a/examples/22-windows/windows.cpp b/examples/22-windows/windows.cpp index c7ef8d4fc..03a5259e9 100644 --- a/examples/22-windows/windows.cpp +++ b/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; diff --git a/examples/23-vectordisplay/main.cpp b/examples/23-vectordisplay/main.cpp index f3765873d..213f917b6 100644 --- a/examples/23-vectordisplay/main.cpp +++ b/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; diff --git a/examples/24-nbody/nbody.cpp b/examples/24-nbody/nbody.cpp index d902c6fbe..620470542 100644 --- a/examples/24-nbody/nbody.cpp +++ b/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; diff --git a/examples/25-c99/helloworld.c b/examples/25-c99/helloworld.c index 1e3e79c99..29b1a65d0 100644 --- a/examples/25-c99/helloworld.c +++ b/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); diff --git a/examples/26-occlusion/occlusion.cpp b/examples/26-occlusion/occlusion.cpp index e133b28d3..d0149838d 100644 --- a/examples/26-occlusion/occlusion.cpp +++ b/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; diff --git a/examples/27-terrain/terrain.cpp b/examples/27-terrain/terrain.cpp index 1819d7277..3b493304a 100644 --- a/examples/27-terrain/terrain.cpp +++ b/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; diff --git a/examples/28-wireframe/wireframe.cpp b/examples/28-wireframe/wireframe.cpp index d7e39bbba..905ab2c6a 100644 --- a/examples/28-wireframe/wireframe.cpp +++ b/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; diff --git a/examples/29-debugdraw/debugdraw.cpp b/examples/29-debugdraw/debugdraw.cpp index 05a03b95f..fb13bb7e3 100644 --- a/examples/29-debugdraw/debugdraw.cpp +++ b/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; diff --git a/examples/30-picking/picking.cpp b/examples/30-picking/picking.cpp index f14b63958..a77395e8d 100644 --- a/examples/30-picking/picking.cpp +++ b/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; diff --git a/examples/31-rsm/reflectiveshadowmap.cpp b/examples/31-rsm/reflectiveshadowmap.cpp index cebc5efb9..358893f9b 100644 --- a/examples/31-rsm/reflectiveshadowmap.cpp +++ b/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; diff --git a/examples/32-particles/particles.cpp b/examples/32-particles/particles.cpp index a556ff3f9..d5642b4b8 100644 --- a/examples/32-particles/particles.cpp +++ b/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; diff --git a/examples/33-pom/pom.cpp b/examples/33-pom/pom.cpp index 0965bc07d..71e7e1d85 100644 --- a/examples/33-pom/pom.cpp +++ b/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; diff --git a/examples/34-mvs/mvs.cpp b/examples/34-mvs/mvs.cpp index 86ecaf040..bbe469b95 100644 --- a/examples/34-mvs/mvs.cpp +++ b/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; diff --git a/examples/35-dynamic/dynamic.cpp b/examples/35-dynamic/dynamic.cpp index 923344e23..76544852f 100644 --- a/examples/35-dynamic/dynamic.cpp +++ b/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; diff --git a/examples/36-sky/sky.cpp b/examples/36-sky/sky.cpp index 764410906..3648881c6 100644 --- a/examples/36-sky/sky.cpp +++ b/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[] = +// 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; +}; + +// 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 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 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 }, +}; + + +// Performs piecewise linear interpolation of a Color parameter. +class DynamicValueController +{ + typedef Color ValueType; + typedef std::map KeyMap; + +public: + DynamicValueController() { - 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) + ~DynamicValueController() { - 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 sunLuminanceXYZTable = + void SetMap(const KeyMap& keymap) { - { 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 } }, - }; + m_keyMap = 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 skyLuminanceXYZTable = + ValueType GetValue(float time) const { - { 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 } }, - }; + typename KeyMap::const_iterator itUpper = m_keyMap.upper_bound(time + 1e-6f); + typename KeyMap::const_iterator itLower = itUpper; + --itLower; - - // 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 }, - }; - - - // Performs piecewise linear interpolation of a Color parameter. - class DynamicValueController - { - typedef Color ValueType; - typedef std::map KeyMap; - - public: - DynamicValueController() + if (itLower == m_keyMap.end()) { + return itUpper->second; } - ~DynamicValueController() + if (itUpper == m_keyMap.end()) { + return itLower->second; } - void SetMap(const KeyMap& keymap) + float lowerTime = itLower->first; + const ValueType& lowerVal = itLower->second; + float upperTime = itUpper->first; + const ValueType& upperVal = itUpper->second; + + if (lowerTime == upperTime) { - m_keyMap = keymap; + return lowerVal; } - ValueType GetValue(float time) const + return interpolate(lowerTime, lowerVal, upperTime, upperVal, time); + }; + + 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; + }; + + 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 + }; + + 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 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; + + static void init() + { + ms_layout + .begin() + .add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float) + .end(); + } + + static bgfx::VertexLayout ms_layout; +}; + +bgfx::VertexLayout ScreenPosVertex::ms_layout; + +// 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(); + + m_skyProgram = loadProgram("vs_sky", "fs_sky"); + m_skyProgram_colorBandingFix = loadProgram("vs_sky", "fs_sky_color_banding_fix"); + + m_preventBanding = true; + + bx::AllocatorI* allocator = entry::getAllocator(); + + ScreenPosVertex* vertices = (ScreenPosVertex*)BX_ALLOC(allocator + , verticalCount * horizontalCount * sizeof(ScreenPosVertex) + ); + + for (int i = 0; i < verticalCount; i++) { - typename KeyMap::const_iterator itUpper = m_keyMap.upper_bound(time + 1e-6f); - typename KeyMap::const_iterator itLower = itUpper; - --itLower; - - if (itLower == m_keyMap.end()) + for (int j = 0; j < horizontalCount; j++) { - return itUpper->second; + 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; } + } - if (itUpper == m_keyMap.end()) + uint16_t* indices = (uint16_t*)BX_ALLOC(allocator + , (verticalCount - 1) * (horizontalCount - 1) * 6 * sizeof(uint16_t) + ); + + int k = 0; + for (int i = 0; i < verticalCount - 1; i++) + { + for (int j = 0; j < horizontalCount - 1; j++) { - return itLower->second; + 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)); } + } - float lowerTime = itLower->first; - const ValueType& lowerVal = itLower->second; - float upperTime = itUpper->first; - const ValueType& upperVal = itUpper->second; + 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)); - if (lowerTime == upperTime) - { - return lowerVal; - } + BX_FREE(allocator, indices); + BX_FREE(allocator, vertices); + } - return interpolate(lowerTime, lowerVal, upperTime, upperVal, time); + void shutdown() + { + bgfx::destroy(m_ibh); + bgfx::destroy(m_vbh); + bgfx::destroy(m_skyProgram); + bgfx::destroy(m_skyProgram_colorBandingFix); + } + + 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); + } + + bgfx::VertexBufferHandle m_vbh; + bgfx::IndexBufferHandle m_ibh; + + bgfx::ProgramHandle m_skyProgram; + bgfx::ProgramHandle m_skyProgram_colorBandingFix; + + bool m_preventBanding; +}; + +class ExampleProceduralSky : public entry::AppI +{ +public: + ExampleProceduralSky(const char* _name, const char* _description, const char* _url) + : entry::AppI(_name, _description, _url) + { + } + + 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.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); + + // 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 + ); + + m_sunLuminanceXYZ.SetMap(sunLuminanceXYZTable); + m_skyLuminanceXYZ.SetMap(skyLuminanceXYZTable); + + m_mesh = meshLoad("meshes/test_scene.bin"); + + m_lightmapTexture = loadTexture("textures/lightmap.ktx"); + + // Imgui. + imguiCreate(); + + 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); + + m_landscapeProgram = loadProgram("vs_sky_landscape", "fs_sky_landscape"); + + m_sky.init(32, 32); + + m_sun.Update(0); + + cameraCreate(); + + cameraSetPosition({ 5.0f, 3.0, 0.0f }); + cameraSetVerticalAngle(bx::kPi / 8.0f); + cameraSetHorizontalAngle(-bx::kPi / 3.0f); + + m_turbidity = 2.15f; + } + + virtual int shutdown() override + { + // Cleanup. + cameraDestroy(); + imguiDestroy(); + + meshUnload(m_mesh); + + 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(m_lightmapTexture); + bgfx::destroy(m_landscapeProgram); + + bgfx::frame(); + + // Shutdown bgfx. + bgfx::shutdown(); + + return 0; + } + + 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[] = + { + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December" }; - void Clear() - { - m_keyMap.clear(); - }; + ImGui::Combo("Month", (int*)&m_sun.m_month, items, 12); - 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; - }; + ImGui::End(); + } - 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 + bool update() override { - public: - enum Month : int + if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState)) { - January = 0, - February, - March, - April, - May, - June, - July, - August, - September, - October, - November, - December - }; + 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); - 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 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) + 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) ); - const float altitude = bx::asin( - bx::sin(latitude) * bx::sin(m_delta) + bx::cos(latitude) * bx::cos(m_delta) * bx::cos(hh) + showExampleDialog(this); + + ImGui::SetNextWindowPos( + ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f) + , ImGuiCond_FirstUseEver ); - 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); + imgui(m_width / 5.0f - 10.0f); - const bx::Quaternion rot1 = bx::fromAxisAngle(uxd, altitude); - m_sunDir = bx::mul(dir, rot1); - } + imguiEndFrame(); - float m_eclipticObliquity; - float m_delta; - }; + // Update camera. + cameraUpdate(deltaTime, m_mouseState, ImGui::MouseOverArea() ); - struct ScreenPosVertex - { - float m_x; - float m_y; + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height)); - static void init() - { - ms_layout - .begin() - .add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float) - .end(); - } + float view[16]; + cameraGetViewMtx(view); - static bgfx::VertexLayout ms_layout; - }; + float proj[16]; + bx::mtxProj(proj, 60.0f, float(m_width) / float(m_height), 0.1f, 2000.0f, bgfx::getCaps()->homogeneousDepth); - bgfx::VertexLayout ScreenPosVertex::ms_layout; + bgfx::setViewTransform(0, view, proj); - // 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(); + Color sunLuminanceXYZ = m_sunLuminanceXYZ.GetValue(m_time); + Color sunLuminanceRGB = xyzToRgb(sunLuminanceXYZ); - m_skyProgram = loadProgram("vs_sky", "fs_sky"); - m_skyProgram_colorBandingFix = loadProgram("vs_sky", "fs_sky_color_banding_fix"); + Color skyLuminanceXYZ = m_skyLuminanceXYZ.GetValue(m_time); + Color skyLuminanceRGB = xyzToRgb(skyLuminanceXYZ); - m_preventBanding = true; + bgfx::setUniform(u_sunLuminance, &sunLuminanceRGB.x); + bgfx::setUniform(u_skyLuminanceXYZ, &skyLuminanceXYZ.x); + bgfx::setUniform(u_skyLuminance, &skyLuminanceRGB.x); - bx::AllocatorI* allocator = entry::getAllocator(); + bgfx::setUniform(u_sunDirection, &m_sun.m_sunDir.x); - ScreenPosVertex* vertices = (ScreenPosVertex*)BX_ALLOC(allocator - , verticalCount * horizontalCount * sizeof(ScreenPosVertex) - ); + float exposition[4] = { 0.02f, 3.0f, 0.1f, m_time }; + bgfx::setUniform(u_parameters, exposition); - 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; - } - } + float perezCoeff[4 * 5]; + computePerezCoeff(m_turbidity, perezCoeff); + bgfx::setUniform(u_perezCoeff, perezCoeff, 5); - uint16_t* indices = (uint16_t*)BX_ALLOC(allocator - , (verticalCount - 1) * (horizontalCount - 1) * 6 * sizeof(uint16_t) - ); + bgfx::setTexture(0, s_texLightmap, m_lightmapTexture); + meshSubmit(m_mesh, 0, m_landscapeProgram, NULL); - 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)); - } - } - - 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)); - - BX_FREE(allocator, indices); - BX_FREE(allocator, vertices); - } - - void shutdown() - { - bgfx::destroy(m_ibh); - bgfx::destroy(m_vbh); - bgfx::destroy(m_skyProgram); - bgfx::destroy(m_skyProgram_colorBandingFix); - } - - 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); - } - - bgfx::VertexBufferHandle m_vbh; - bgfx::IndexBufferHandle m_ibh; - - bgfx::ProgramHandle m_skyProgram; - bgfx::ProgramHandle m_skyProgram_colorBandingFix; - - bool m_preventBanding; - }; - - class ExampleProceduralSky : public entry::AppI - { - public: - ExampleProceduralSky(const char* _name, const char* _description, const char* _url) - : entry::AppI(_name, _description, _url) - { - } - - 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 - ); - - m_sunLuminanceXYZ.SetMap(sunLuminanceXYZTable); - m_skyLuminanceXYZ.SetMap(skyLuminanceXYZTable); - - m_mesh = meshLoad("meshes/test_scene.bin"); - - m_lightmapTexture = loadTexture("textures/lightmap.ktx"); - - // Imgui. - imguiCreate(); - - 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); - - m_landscapeProgram = loadProgram("vs_sky_landscape", "fs_sky_landscape"); - - m_sky.init(32, 32); - - m_sun.Update(0); - - cameraCreate(); - - cameraSetPosition({ 5.0f, 3.0, 0.0f }); - cameraSetVerticalAngle(bx::kPi / 8.0f); - cameraSetHorizontalAngle(-bx::kPi / 3.0f); - - m_turbidity = 2.15f; - } - - virtual int shutdown() override - { - // Cleanup. - cameraDestroy(); - imguiDestroy(); - - meshUnload(m_mesh); - - 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(m_lightmapTexture); - bgfx::destroy(m_landscapeProgram); + m_sky.draw(); bgfx::frame(); - // Shutdown bgfx. - bgfx::shutdown(); - - return 0; + return true; } - void imgui(float _width) + return false; + } + + void computePerezCoeff(float _turbidity, float* _outPerezCoeff) + { + const bx::Vec3 turbidity = { _turbidity, _turbidity, _turbidity }; + for (uint32_t ii = 0; ii < 5; ++ii) { - 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(); + 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; } + } - 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); + bgfx::ProgramHandle m_landscapeProgram; + bgfx::UniformHandle s_texLightmap; + bgfx::TextureHandle m_lightmapTexture; - 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) - ); + bgfx::UniformHandle u_sunLuminance; + bgfx::UniformHandle u_skyLuminanceXYZ; + bgfx::UniformHandle u_skyLuminance; + bgfx::UniformHandle u_sunDirection; + bgfx::UniformHandle u_parameters; + bgfx::UniformHandle u_perezCoeff; - showExampleDialog(this); + ProceduralSky m_sky; + SunController m_sun; - ImGui::SetNextWindowPos( - ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f) - , ImGuiCond_FirstUseEver - ); + DynamicValueController m_sunLuminanceXYZ; + DynamicValueController m_skyLuminanceXYZ; - imgui(m_width / 5.0f - 10.0f); + uint32_t m_width; + uint32_t m_height; + uint32_t m_debug; + uint32_t m_reset; - imguiEndFrame(); + Mesh* m_mesh; - // Update camera. - cameraUpdate(deltaTime, m_mouseState, ImGui::MouseOverArea() ); + entry::MouseState m_mouseState; - // Set view 0 default viewport. - bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height)); + float m_time; + float m_timeScale; + int64_t m_timeOffset; - float view[16]; - cameraGetViewMtx(view); - - float proj[16]; - bx::mtxProj(proj, 60.0f, float(m_width) / float(m_height), 0.1f, 2000.0f, bgfx::getCaps()->homogeneousDepth); - - bgfx::setViewTransform(0, view, proj); - - Color sunLuminanceXYZ = m_sunLuminanceXYZ.GetValue(m_time); - Color sunLuminanceRGB = xyzToRgb(sunLuminanceXYZ); - - Color skyLuminanceXYZ = m_skyLuminanceXYZ.GetValue(m_time); - Color skyLuminanceRGB = xyzToRgb(skyLuminanceXYZ); - - bgfx::setUniform(u_sunLuminance, &sunLuminanceRGB.x); - bgfx::setUniform(u_skyLuminanceXYZ, &skyLuminanceXYZ.x); - bgfx::setUniform(u_skyLuminance, &skyLuminanceRGB.x); - - bgfx::setUniform(u_sunDirection, &m_sun.m_sunDir.x); - - float exposition[4] = { 0.02f, 3.0f, 0.1f, m_time }; - bgfx::setUniform(u_parameters, exposition); - - float perezCoeff[4 * 5]; - computePerezCoeff(m_turbidity, perezCoeff); - bgfx::setUniform(u_perezCoeff, perezCoeff, 5); - - bgfx::setTexture(0, s_texLightmap, m_lightmapTexture); - meshSubmit(m_mesh, 0, m_landscapeProgram, NULL); - - m_sky.draw(); - - bgfx::frame(); - - return true; - } - - 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 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::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; - - DynamicValueController m_sunLuminanceXYZ; - DynamicValueController m_skyLuminanceXYZ; - - uint32_t m_width; - uint32_t m_height; - uint32_t m_debug; - uint32_t m_reset; - - Mesh* m_mesh; - - entry::MouseState m_mouseState; - - float m_time; - float m_timeScale; - int64_t m_timeOffset; - - float m_turbidity; - }; + float m_turbidity; +}; } // namespace diff --git a/examples/37-gpudrivenrendering/gpudrivenrendering.cpp b/examples/37-gpudrivenrendering/gpudrivenrendering.cpp index 7e338d1ff..312ef4898 100644 --- a/examples/37-gpudrivenrendering/gpudrivenrendering.cpp +++ b/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; diff --git a/examples/38-bloom/bloom.cpp b/examples/38-bloom/bloom.cpp index 61d2118ff..312eef0e7 100644 --- a/examples/38-bloom/bloom.cpp +++ b/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; diff --git a/examples/39-assao/assao.cpp b/examples/39-assao/assao.cpp index ec7842cad..45d1e92b7 100644 --- a/examples/39-assao/assao.cpp +++ b/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. diff --git a/examples/40-svt/svt.cpp b/examples/40-svt/svt.cpp index 95ff7c9d5..caab49c34 100644 --- a/examples/40-svt/svt.cpp +++ b/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. diff --git a/examples/41-tess/tess.cpp b/examples/41-tess/tess.cpp index 9ab5dc8bf..45566ddcd 100644 --- a/examples/41-tess/tess.cpp +++ b/examples/41-tess/tess.cpp @@ -23,902 +23,903 @@ namespace { - static const char* s_shaderOptions[] = +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 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 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, + + SHADING_COUNT +}; + +enum +{ + BUFFER_SUBD +}; + +enum +{ + PROGRAM_SUBD_CS_LOD, + PROGRAM_UPDATE_INDIRECT, + PROGRAM_INIT_INDIRECT, + PROGRAM_UPDATE_DRAW, + + PROGRAM_COUNT +}; + +enum +{ + TERRAIN_DMAP_SAMPLER, + TERRAIN_SMAP_SAMPLER, + + SAMPLER_COUNT +}; + +enum +{ + TEXTURE_DMAP, + TEXTURE_SMAP, + + TEXTURE_COUNT +}; + +constexpr int32_t kNumVec4 = 2; + +struct Uniforms +{ + void init() { - "Normal", - "Diffuse" - }; + u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4, kNumVec4); - static const float s_verticesL0[] = + cull = 1; + freeze = 0; + gpuSubd = 3; + + } + + void submit() { - 0.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - }; + bgfx::setUniform(u_params, params, kNumVec4); + } - static const uint32_t s_indexesL0[] = { 0u, 1u, 2u }; - - static const float s_verticesL1[] = + void destroy() { - 0.0f, 1.0f, - 0.5f, 0.5f, - 0.0f, 0.5f, - 0.0f, 0.0f, - 0.5f, 0.0f, - 1.0f, 0.0f, - }; + bgfx::destroy(u_params); + } - static const uint32_t s_indexesL1[] = + union { - 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, - - SHADING_COUNT - }; - - enum - { - BUFFER_SUBD - }; - - enum - { - PROGRAM_SUBD_CS_LOD, - PROGRAM_UPDATE_INDIRECT, - PROGRAM_INIT_INDIRECT, - PROGRAM_UPDATE_DRAW, - - PROGRAM_COUNT - }; - - enum - { - TERRAIN_DMAP_SAMPLER, - TERRAIN_SMAP_SAMPLER, - - SAMPLER_COUNT - }; - - enum - { - TEXTURE_DMAP, - TEXTURE_SMAP, - - TEXTURE_COUNT - }; - - constexpr int32_t kNumVec4 = 2; - - struct Uniforms - { - void init() + struct { - u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4, kNumVec4); + float dmapFactor; + float lodFactor; + float cull; + float freeze; - cull = 1; - freeze = 0; - gpuSubd = 3; - - } - - void submit() - { - bgfx::setUniform(u_params, params, kNumVec4); - } - - void destroy() - { - bgfx::destroy(u_params); - } - - union - { - struct - { - float dmapFactor; - float lodFactor; - float cull; - float freeze; - - float gpuSubd; - float padding0; - float padding1; - float padding2; - }; - - float params[kNumVec4 * 4]; + float gpuSubd; + float padding0; + float padding1; + float padding2; }; - bgfx::UniformHandle u_params; + float params[kNumVec4 * 4]; }; - class ExampleTessellation : public entry::AppI + + 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) { - public: - ExampleTessellation(const char* _name, const char* _description, const char* _url) - : entry::AppI(_name, _description, _url) + } + + 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(m_programsCompute[i]); } - void init(int32_t _argc, const char* const* _argv, uint32_t _width, uint32_t _height) override + for (uint32_t i = 0; i < SHADING_COUNT; ++i) { - Args args(_argc, _argv); + bgfx::destroy(m_programsDraw[i]); + } - m_width = _width; - m_height = _height; - m_debug = BGFX_DEBUG_NONE; - m_reset = BGFX_RESET_NONE; + for (uint32_t i = 0; i < SAMPLER_COUNT; ++i) + { + bgfx::destroy(m_samplers[i]); + } - 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); + for (uint32_t i = 0; i < TEXTURE_COUNT; ++i) + { + bgfx::destroy(m_textures[i]); + } - 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; + // Shutdown bgfx. + bgfx::shutdown(); - // Enable m_debug text. - bgfx::setDebug(m_debug); + return 0; + } - // Set view 0 clear state. - bgfx::setViewClear(0 - , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH - , 0x303030ff - , 1.0f - , 0 + 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) ); - bgfx::setViewClear(1 - , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH - , 0x303030ff - , 1.0f - , 0 + 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); - // 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) + if (ImGui::Checkbox("Debug wireframe", &m_wireframe) ) { - bgfx::destroy(m_programsCompute[i]); - } - - for (uint32_t i = 0; i < SHADING_COUNT; ++i) - { - bgfx::destroy(m_programsDraw[i]); - } - - for (uint32_t i = 0; i < SAMPLER_COUNT; ++i) - { - bgfx::destroy(m_samplers[i]); - } - - for (uint32_t i = 0; i < TEXTURE_COUNT; ++i) - { - bgfx::destroy(m_textures[i]); - } - - // Shutdown bgfx. - bgfx::shutdown(); - - return 0; - } - - 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) + bgfx::setDebug(m_wireframe + ? BGFX_DEBUG_WIREFRAME + : BGFX_DEBUG_NONE ); + } - showExampleDialog(this); + ImGui::SameLine(); - 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("Cull", &m_cull) ) + { + m_uniforms.cull = m_cull ? 1.0f : 0.0f; + } - if (ImGui::Checkbox("Debug wireframe", &m_wireframe) ) - { - bgfx::setDebug(m_wireframe - ? BGFX_DEBUG_WIREFRAME - : BGFX_DEBUG_NONE - ); - } + ImGui::SameLine(); - 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; - } + 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); + ImGui::SliderFloat("Pixels per edge", &m_primitivePixelLengthTarget, 1, 20); - int gpuSlider = (int)m_uniforms.gpuSubd; + int gpuSlider = (int)m_uniforms.gpuSubd; - if (ImGui::SliderInt("Triangle Patch level", &gpuSlider, 0, 3) ) - { - m_restart = true; - m_uniforms.gpuSubd = float(gpuSlider); - } + 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::Combo("Shading", &m_shading, s_shaderOptions, 2); - ImGui::Text("Some variables require rebuilding the subdivide buffers and causes a stutter."); + ImGui::Text("Some variables require rebuilding the subdivide buffers and causes a stutter."); - ImGui::End(); + ImGui::End(); - // Update camera. - cameraUpdate(deltaTime*0.01f, m_mouseState, ImGui::MouseOverArea() ); + // Update camera. + cameraUpdate(deltaTime*0.01f, m_mouseState, ImGui::MouseOverArea() ); - bgfx::touch(0); - bgfx::touch(1); + bgfx::touch(0); + bgfx::touch(1); - configureUniforms(); + configureUniforms(); - cameraGetViewMtx(m_viewMtx); + cameraGetViewMtx(m_viewMtx); - float model[16]; + float model[16]; - bx::mtxRotateX(model, bx::toRad(90) ); + bx::mtxRotateX(model, bx::toRad(90) ); - bx::mtxProj(m_projMtx, m_fovy, float(m_width) / float(m_height), 0.0001f, 2000.0f, bgfx::getCaps()->homogeneousDepth); + bx::mtxProj(m_projMtx, m_fovy, float(m_width) / float(m_height), 0.0001f, 2000.0f, bgfx::getCaps()->homogeneousDepth); - // Set view 0 - bgfx::setViewTransform(0, m_viewMtx, m_projMtx); + // Set view 0 + bgfx::setViewTransform(0, m_viewMtx, m_projMtx); - // Set view 1 - bgfx::setViewRect(1, 0, 0, uint16_t(m_width), uint16_t(m_height) ); - bgfx::setViewTransform(1, m_viewMtx, m_projMtx); + // Set view 1 + bgfx::setViewRect(1, 0, 0, uint16_t(m_width), uint16_t(m_height) ); + bgfx::setViewTransform(1, m_viewMtx, m_projMtx); - m_uniforms.submit(); + m_uniforms.submit(); - // update the subd buffers - if (m_restart) - { - m_pingPong = 1; + // update the subd buffers + if (m_restart) + { + m_pingPong = 1; - bgfx::destroy(m_instancedGeometryVertices); - bgfx::destroy(m_instancedGeometryIndices); + 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); + bgfx::destroy(m_bufferSubd[BUFFER_SUBD]); + bgfx::destroy(m_bufferSubd[BUFFER_SUBD + 1]); + bgfx::destroy(m_bufferCulledSubd); - 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(8, m_bufferSubd[1 - m_pingPong], bgfx::Access::ReadWrite); - bgfx::dispatch(0, m_programsCompute[PROGRAM_INIT_INDIRECT], 1, 1, 1); - - - 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(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(); - - // update the subd buffer - bgfx::dispatch(0, m_programsCompute[PROGRAM_SUBD_CS_LOD], m_dispatchIndirect, 1); - - // update draw 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); - m_uniforms.submit(); - bgfx::dispatch(1, m_programsCompute[PROGRAM_UPDATE_DRAW], 1, 1, 1); - - // 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); - - 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); - - m_uniforms.submit(); - - bgfx::submit(1, m_programsDraw[m_shading], m_dispatchIndirect); - - m_pingPong = 1 - m_pingPong; - - imguiEndFrame(); - - // Advance to next frame. Rendering thread will be kicked to - // process submitted rendering primitives. - bgfx::frame(false); - - return true; + 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); } - return false; + 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::setTexture(0, m_samplers[TERRAIN_DMAP_SAMPLER], m_textures[TEXTURE_DMAP], BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP); + + m_uniforms.submit(); + + // update the subd buffer + bgfx::dispatch(0, m_programsCompute[PROGRAM_SUBD_CS_LOD], m_dispatchIndirect, 1); + + // update draw + bgfx::setBuffer(3, m_dispatchIndirect, bgfx::Access::ReadWrite); + bgfx::setBuffer(4, m_bufferCounter, bgfx::Access::ReadWrite); + + m_uniforms.submit(); + + bgfx::dispatch(1, m_programsCompute[PROGRAM_UPDATE_DRAW], 1, 1, 1); + + // 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); + + 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); + + m_uniforms.submit(); + + bgfx::submit(1, m_programsDraw[m_shading], m_dispatchIndirect); + + m_pingPong = 1 - m_pingPong; + + imguiEndFrame(); + + // Advance to next frame. Rendering thread will be kicked to + // process submitted rendering primitives. + bgfx::frame(false); + + return true; } - void createAtomicCounters() + return false; + } + + void createAtomicCounters() + { + m_bufferCounter = bgfx::createDynamicIndexBuffer(3, BGFX_BUFFER_INDEX32 | BGFX_BUFFER_COMPUTE_READ_WRITE); + } + + 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); + + m_uniforms.init(); + + m_programsDraw[PROGRAM_TERRAIN] = loadProgram("vs_terrain_render", "fs_terrain_render"); + m_programsDraw[PROGRAM_TERRAIN_NORMAL] = loadProgram("vs_terrain_render", "fs_terrain_render_normal"); + + 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 loadSmapTexture() + { + int w = dmap->m_width; + int h = dmap->m_height; + + const uint16_t *texels = (const uint16_t *)dmap->m_data; + + int mipcnt = dmap->m_numMips; + + const bgfx::Memory* mem = bgfx::alloc(w * h * 2 * sizeof(float) ); + float* smap = (float*)mem->data; + + for (int j = 0; j < h; ++j) { - m_bufferCounter = bgfx::createDynamicIndexBuffer(3, BGFX_BUFFER_INDEX32 | BGFX_BUFFER_COMPUTE_READ_WRITE); - } - - 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); - - m_uniforms.init(); - - m_programsDraw[PROGRAM_TERRAIN] = loadProgram("vs_terrain_render", "fs_terrain_render"); - m_programsDraw[PROGRAM_TERRAIN_NORMAL] = loadProgram("vs_terrain_render", "fs_terrain_render_normal"); - - 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 loadSmapTexture() - { - int w = dmap->m_width; - int h = dmap->m_height; - - const uint16_t *texels = (const uint16_t *)dmap->m_data; - - int mipcnt = dmap->m_numMips; - - const bgfx::Memory* mem = bgfx::alloc(w * h * 2 * sizeof(float) ); - float* smap = (float*)mem->data; - - for (int j = 0; j < h; ++j) + for (int i = 0; i < w; ++i) { - 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); + 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; - } + smap[2 * (i + w * j)] = slope_x; + smap[1 + 2 * (i + w * j)] = slope_y; } - - 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() + 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[] = { - 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) - ); - } - - /** - * Load All Textures - */ - 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[] = - { - -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 - ); - } - - 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 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; - } - - 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_instancedGeometryIndices = bgfx::createIndexBuffer( - bgfx::makeRef(indexes, sizeof(uint32_t) * m_instancedMeshPrimitiveCount * 3) - , BGFX_BUFFER_INDEX32 - ); - } - - 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::DynamicIndexBufferHandle m_bufferSubd[2]; - bgfx::DynamicIndexBufferHandle m_bufferCulledSubd; - - bgfx::DynamicIndexBufferHandle m_bufferCounter; - - 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::IndirectBufferHandle m_dispatchIndirect; - - bimg::ImageContainer* dmap; - - 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_oldWidth; - uint32_t m_oldHeight; - uint32_t m_oldReset; - - uint32_t m_instancedMeshVertexCount; - uint32_t m_instancedMeshPrimitiveCount; - - entry::MouseState m_mouseState; - - int64_t m_timeOffset; - - struct DMap - { - bx::FilePath pathToFile; - float scale; + -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, }; - DMap m_dmap; + const uint32_t indices[] = { 0, 1, 3, 2, 3, 1 }; - int m_computeThreadCount; - int m_shading; - int m_gpuSubd; - int m_pingPong; + m_geometryLayout.begin().add(bgfx::Attrib::Position, 4, bgfx::AttribType::Float).end(); - float m_primitivePixelLengthTarget; - float m_fovy; + 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 + ); + } - bool m_restart; - bool m_wireframe; - bool m_cull; - bool m_freeze; + 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 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; + } + + 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_instancedGeometryIndices = bgfx::createIndexBuffer( + bgfx::makeRef(indexes, sizeof(uint32_t) * m_instancedMeshPrimitiveCount * 3) + , BGFX_BUFFER_INDEX32 + ); + } + + 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::DynamicIndexBufferHandle m_bufferSubd[2]; + bgfx::DynamicIndexBufferHandle m_bufferCulledSubd; + + bgfx::DynamicIndexBufferHandle m_bufferCounter; + + 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::IndirectBufferHandle m_dispatchIndirect; + + bimg::ImageContainer* dmap; + + 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_oldWidth; + uint32_t m_oldHeight; + uint32_t m_oldReset; + + uint32_t m_instancedMeshVertexCount; + uint32_t m_instancedMeshPrimitiveCount; + + entry::MouseState m_mouseState; + + int64_t m_timeOffset; + + struct DMap + { + bx::FilePath pathToFile; + float scale; }; + DMap m_dmap; + + int m_computeThreadCount; + int m_shading; + int m_gpuSubd; + int m_pingPong; + + float m_primitivePixelLengthTarget; + float m_fovy; + + bool m_restart; + bool m_wireframe; + bool m_cull; + bool m_freeze; +}; + } // namespace ENTRY_IMPLEMENT_MAIN( diff --git a/examples/42-bunnylod/bunnylod.cpp b/examples/42-bunnylod/bunnylod.cpp index ddd62570f..bd44b1f8e 100644 --- a/examples/42-bunnylod/bunnylod.cpp +++ b/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; diff --git a/examples/43-denoise/denoise.cpp b/examples/43-denoise/denoise.cpp index f4e1ca819..3c9c2ef29 100644 --- a/examples/43-denoise/denoise.cpp +++ b/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; diff --git a/examples/44-sss/screen_space_shadows.cpp b/examples/44-sss/screen_space_shadows.cpp index 7903b13a2..7a142baa3 100644 --- a/examples/44-sss/screen_space_shadows.cpp +++ b/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; } diff --git a/examples/45-bokeh/bokeh.cpp b/examples/45-bokeh/bokeh.cpp index a16e544f3..b1ed78f42 100644 --- a/examples/45-bokeh/bokeh.cpp +++ b/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. diff --git a/examples/46-fsr/app.cpp b/examples/46-fsr/app.cpp index b22e5ee08..4049d3e1e 100644 --- a/examples/46-fsr/app.cpp +++ b/examples/46-fsr/app.cpp @@ -22,829 +22,830 @@ namespace #define FRAMEBUFFER_RT_DEPTH 1 #define FRAMEBUFFER_RENDER_TARGETS 2 - enum Meshes +enum Meshes +{ + MeshCube = 0, + MeshHollowCube, +}; + +static const char *s_meshPaths[] = +{ + "meshes/cube.bin", + "meshes/hollowcube.bin", +}; + +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; + + static void init() { - MeshCube = 0, - MeshHollowCube, - }; - - static const char *s_meshPaths[] = - { - "meshes/cube.bin", - "meshes/hollowcube.bin", - }; - - 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; - - 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; - }; - - 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) - { - if (3 == bgfx::getAvailTransientVertexBuffer(3, PosTexCoord0Vertex::ms_layout) ) - { - 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 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; - - float minv = texelHalfH; - float maxv = 2.0f + texelHalfH; - - if (_originBottomLeft) - { - float temp = minv; - minv = maxv; - maxv = temp; - - 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); - } + ms_layout + .begin() + .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) + .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float) + .end(); } - struct ModelUniforms + static bgfx::VertexLayout 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) +{ + if (3 == bgfx::getAvailTransientVertexBuffer(3, PosTexCoord0Vertex::ms_layout) ) { - enum - { - NumVec4 = 2 - }; + bgfx::TransientVertexBuffer vb; + bgfx::allocTransientVertexBuffer(&vb, 3, PosTexCoord0Vertex::ms_layout); + PosTexCoord0Vertex *vertex = (PosTexCoord0Vertex *)vb.data; - void init() - { - u_params = bgfx::createUniform("u_modelParams", bgfx::UniformType::Vec4, NumVec4); - }; + const float minx = -_width - _offsetX; + const float maxx = _width - _offsetX; + const float miny = 0.0f - _offsetY; + const float maxy = _height * 2.0f - _offsetY; - void submit() const - { - bgfx::setUniform(u_params, m_params, NumVec4); - }; + const float texelHalfW = _texelHalf / _textureWidth; + const float texelHalfH = _texelHalf / _textureHeight; + const float minu = -1.0f + texelHalfW; + const float maxu = 1.0f + texelHalfW; - void destroy() + const float zz = 0.0f; + + float minv = texelHalfH; + float maxv = 2.0f + texelHalfH; + + if (_originBottomLeft) { - bgfx::destroy(u_params); + float temp = minv; + minv = maxv; + maxv = temp; + + minv -= 1.0f; + maxv -= 1.0f; } - union + 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 +{ + enum + { + NumVec4 = 2 + }; + + void init() + { + u_params = bgfx::createUniform("u_modelParams", bgfx::UniformType::Vec4, NumVec4); + }; + + void submit() const + { + bgfx::setUniform(u_params, m_params, NumVec4); + }; + + void destroy() + { + bgfx::destroy(u_params); + } + + 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 + bgfx::UniformHandle u_params; +}; + +struct AppState +{ + uint32_t m_width; + uint32_t m_height; + uint32_t m_debug; + uint32_t m_reset; + + entry::MouseState m_mouseState; + + // Resource handles + bgfx::ProgramHandle m_forwardProgram; + bgfx::ProgramHandle m_gridProgram; + bgfx::ProgramHandle m_copyLinearToGammaProgram; + + // Shader uniforms + ModelUniforms m_modelUniforms; + + // Uniforms to identify texture samplers + bgfx::UniformHandle s_albedo; + bgfx::UniformHandle s_color; + bgfx::UniformHandle s_normal; + + bgfx::FrameBufferHandle m_frameBuffer; + bgfx::TextureHandle m_frameBufferTex[FRAMEBUFFER_RENDER_TARGETS]; + + Mesh *m_meshes[BX_COUNTOF(s_meshPaths)]; + bgfx::TextureHandle m_groundTexture; + bgfx::TextureHandle m_normalTexture; + + 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; + + float m_view[16]; + float m_proj[16]; + int32_t m_size[2]; + + // UI parameters + bool m_renderNativeResolution = false; + bool m_animateScene = false; + int32_t m_antiAliasingSetting = 2; + + Fsr m_fsr; +}; + +struct RenderTarget +{ + void init(uint32_t _width, uint32_t _height, bgfx::TextureFormat::Enum _format, uint64_t _flags) { - uint32_t m_width; - uint32_t m_height; - uint32_t m_debug; - uint32_t m_reset; + 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); + } - entry::MouseState m_mouseState; - - // Resource handles - bgfx::ProgramHandle m_forwardProgram; - bgfx::ProgramHandle m_gridProgram; - bgfx::ProgramHandle m_copyLinearToGammaProgram; - - // Shader uniforms - ModelUniforms m_modelUniforms; - - // Uniforms to identify texture samplers - bgfx::UniformHandle s_albedo; - bgfx::UniformHandle s_color; - bgfx::UniformHandle s_normal; - - bgfx::FrameBufferHandle m_frameBuffer; - bgfx::TextureHandle m_frameBufferTex[FRAMEBUFFER_RENDER_TARGETS]; - - Mesh *m_meshes[BX_COUNTOF(s_meshPaths)]; - bgfx::TextureHandle m_groundTexture; - bgfx::TextureHandle m_normalTexture; - - 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; - - float m_view[16]; - float m_proj[16]; - int32_t m_size[2]; - - // UI parameters - bool m_renderNativeResolution = false; - bool m_animateScene = false; - int32_t m_antiAliasingSetting = 2; - - Fsr m_fsr; - }; - - struct RenderTarget + void destroy() { - 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); - } + // 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); + } + + void destroy() + { + bgfx::destroy(m_widgetTexture); + m_content.destroy(); + } + + 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 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); { - m_content.init(_width, _height, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT); - createWidgetTexture(_width + 6, _height + 6); + // clear out transform stack + float identity[16]; + bx::mtxIdentity(identity); + bgfx::setTransform(identity); } - void destroy() + 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; + } + + uint32_t m_widgetWidth{0}; + uint32_t m_widgetHeight{0}; + bgfx::TextureHandle m_widgetTexture; + RenderTarget m_content; + ImVec2 m_position; + +private: + void createWidgetTexture(uint32_t _width, uint32_t _height) + { + const bgfx::Memory *mem = bgfx::alloc(_width * _height * sizeof(uint32_t) ); + + uint32_t *pixels = (uint32_t*)mem->data; + bx::memSet(pixels, 0, mem->size); + + const uint32_t white = 0xFFFFFFFF; + const uint32_t black = 0xFF000000; + + const uint32_t y0 = 1; + const uint32_t y1 = _height - 3; + + for (uint32_t x = 0; x < _width - 4; x++) { - bgfx::destroy(m_widgetTexture); - m_content.destroy(); + 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; } - void setPosition(float x, float y) + const uint32_t x0 = 1; + const uint32_t x1 = _width - 3; + + for (uint32_t y = 0; y < _height - 3; y++) { - m_position.x = x; - m_position.y = 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; } - 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; + pixels[(y1 + 0) * _width + 2] = white; - 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); + 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 + { + 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 updateContent(bgfx::ViewId &view, AppState const &state, const bgfx::Caps *caps, bgfx::TextureHandle srcTexture) + m_state.m_groundTexture = loadTexture("textures/fieldstone-rgba.dds"); + m_state.m_normalTexture = loadTexture("textures/fieldstone-n.dds"); + + createFramebuffers(); + + // Vertex decl + PosTexCoord0Vertex::init(); + + // 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); + + // 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); + + imguiCreate(); + + m_state.m_fsr.init(_width, _height); + } + + int32_t shutdown() override + { + m_state.m_fsr.destroy(); + + for (uint32_t ii = 0; ii < BX_COUNTOF(s_meshPaths); ++ii) { - float orthoProj[16]; - bx::mtxOrtho(orthoProj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, caps->homogeneousDepth); + meshUnload(m_state.m_meshes[ii]); + } + + 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); + + m_state.m_modelUniforms.destroy(); + + m_magnifierWidget.destroy(); + + bgfx::destroy(m_state.s_albedo); + bgfx::destroy(m_state.s_color); + bgfx::destroy(m_state.s_normal); + + destroyFramebuffers(); + + cameraDestroy(); + + imguiDestroy(); + + bgfx::shutdown(); + + return 0; + } + + 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) ) + { + // skip processing when minimized, otherwise crashing + if (0 == m_state.m_width + || 0 == m_state.m_height) { - // clear out transform stack - float identity[16]; - bx::mtxIdentity(identity); - bgfx::setTransform(identity); + return true; } - 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; - } - - uint32_t m_widgetWidth{0}; - uint32_t m_widgetHeight{0}; - bgfx::TextureHandle m_widgetTexture; - RenderTarget m_content; - ImVec2 m_position; - - private: - void createWidgetTexture(uint32_t _width, uint32_t _height) - { - const bgfx::Memory *mem = bgfx::alloc(_width * _height * sizeof(uint32_t) ); - - uint32_t *pixels = (uint32_t*)mem->data; - bx::memSet(pixels, 0, mem->size); - - const uint32_t white = 0xFFFFFFFF; - const uint32_t black = 0xFF000000; - - const uint32_t y0 = 1; - const uint32_t y1 = _height - 3; - - for (uint32_t x = 0; x < _width - 4; x++) + if (m_state.m_mouseState.m_buttons[entry::MouseButton::Left] + && !ImGui::MouseOverArea() ) { - 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; + m_magnifierWidget.setPosition( + float(m_state.m_mouseState.m_mx) + , float(m_state.m_mouseState.m_my) + ); } - const uint32_t x0 = 1; - const uint32_t x1 = _width - 3; + // 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(); - for (uint32_t y = 0; y < _height - 3; y++) + if (m_state.m_size[0] != (int32_t)m_state.m_width || m_state.m_size[1] != (int32_t)m_state.m_height) { - 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; + resize(); } - 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 - { - 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) + // update animation time + const float rotationSpeed = 0.25f; + if (m_state.m_animateScene) { - m_state.m_meshes[ii] = meshLoad(s_meshPaths[ii]); + m_state.m_animationTime += deltaTime * rotationSpeed; + if (bx::kPi2 < m_state.m_animationTime) + { + m_state.m_animationTime -= bx::kPi2; + } } - m_state.m_groundTexture = loadTexture("textures/fieldstone-rgba.dds"); - m_state.m_normalTexture = loadTexture("textures/fieldstone-n.dds"); + // Update camera + cameraUpdate(deltaTime * 0.15f, m_state.m_mouseState, ImGui::MouseOverArea() ); - createFramebuffers(); - - // Vertex decl - PosTexCoord0Vertex::init(); - - // 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); - // Get renderer capabilities info. - const bgfx::RendererType::Enum renderer = bgfx::getRendererType(); - m_state.m_texelHalf = bgfx::RendererType::Direct3D9 == renderer ? 0.5f : 0.0f; + updateUniforms(); - 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); + 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 + ); - imguiCreate(); + bgfx::ViewId view = 0; - m_state.m_fsr.init(_width, _height); - } - - int32_t shutdown() override - { - m_state.m_fsr.destroy(); - - for (uint32_t ii = 0; ii < BX_COUNTOF(s_meshPaths); ++ii) + // Clear full frame buffer to avoid sampling into garbage during FSR pass + if (!m_state.m_renderNativeResolution) { - meshUnload(m_state.m_meshes[ii]); + 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; } - 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); - - m_state.m_modelUniforms.destroy(); - - m_magnifierWidget.destroy(); - - bgfx::destroy(m_state.s_albedo); - bgfx::destroy(m_state.s_color); - bgfx::destroy(m_state.s_normal); - - destroyFramebuffers(); - - cameraDestroy(); - - imguiDestroy(); - - bgfx::shutdown(); - - return 0; - } - - 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) ) + // Draw models into scene { - // skip processing when minimized, otherwise crashing - if (0 == m_state.m_width - || 0 == m_state.m_height) + 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; + } + + // optionally run FSR + if (!m_state.m_renderNativeResolution) + { + view = m_state.m_fsr.computeFsr(view, m_state.m_frameBufferTex[FRAMEBUFFER_RT_COLOR]); + } + + // render result to screen + { + bgfx::TextureHandle srcTexture = m_state.m_frameBufferTex[FRAMEBUFFER_RT_COLOR]; + + if (!m_state.m_renderNativeResolution) { - return true; + srcTexture = m_state.m_fsr.getResultTexture(); } - 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) - ); - } + m_magnifierWidget.updateContent(view, m_state, caps, srcTexture); - // 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(); + float orthoProj[16]; + bx::mtxOrtho(orthoProj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, caps->homogeneousDepth); - if (m_state.m_size[0] != (int32_t)m_state.m_width || m_state.m_size[1] != (int32_t)m_state.m_height) + bgfx::setViewName(view, "display"); + bgfx::setViewClear(view, BGFX_CLEAR_NONE, 0, 1.0f, 0); + + 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); + } + + m_magnifierWidget.drawToScreen(view, m_state); + + ++view; + + // 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) ); + + 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); + + const ImVec2 itemSize = ImGui::GetItemRectSize(); + + { + ImGui::Checkbox("Animate scene", &m_state.m_animateScene); + + if (ImGui::Combo("Antialiasing", &m_state.m_antiAliasingSetting, "none\0""4x\0""16x\0""\0") ) { resize(); } - // update animation time - const float rotationSpeed = 0.25f; - if (m_state.m_animateScene) + ImGui::Checkbox("Render native resolution", &m_state.m_renderNativeResolution); + + if (ImGui::IsItemHovered() ) { - m_state.m_animationTime += deltaTime * rotationSpeed; - if (bx::kPi2 < m_state.m_animationTime) - { - m_state.m_animationTime -= bx::kPi2; - } + ImGui::SetTooltip("Disable super sampling and FSR."); } - // Update camera - cameraUpdate(deltaTime * 0.15f, m_state.m_mouseState, ImGui::MouseOverArea() ); + ImGui::Image(m_magnifierWidget.m_content.m_texture, ImVec2(itemSize.x * 0.94f, itemSize.x * 0.94f) ); - 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); - - ++view; - } - - // 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; - } - - // optionally run FSR - if (!m_state.m_renderNativeResolution) - { - view = m_state.m_fsr.computeFsr(view, m_state.m_frameBufferTex[FRAMEBUFFER_RT_COLOR]); - } - - // render result to screen - { - bgfx::TextureHandle srcTexture = m_state.m_frameBufferTex[FRAMEBUFFER_RT_COLOR]; - - if (!m_state.m_renderNativeResolution) - { - srcTexture = m_state.m_fsr.getResultTexture(); - } - - m_magnifierWidget.updateContent(view, m_state, caps, srcTexture); - - float orthoProj[16]; - bx::mtxOrtho(orthoProj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, caps->homogeneousDepth); - - bgfx::setViewName(view, "display"); - bgfx::setViewClear(view, BGFX_CLEAR_NONE, 0, 1.0f, 0); - - 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); - } - - m_magnifierWidget.drawToScreen(view, m_state); - - ++view; - - // 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) ); - - 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); - - const ImVec2 itemSize = ImGui::GetItemRectSize(); - - { - ImGui::Checkbox("Animate scene", &m_state.m_animateScene); - - if (ImGui::Combo("Antialiasing", &m_state.m_antiAliasingSetting, "none\0""4x\0""16x\0""\0") ) - { - resize(); - } - - ImGui::Checkbox("Render native resolution", &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::SetTooltip("Compare between FSR and bilinear interpolation of source image."); + } - 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(); - } - } - - 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(); - - // Advance to next frame. Rendering thread will be kicked to - // process submitted rendering primitives. - m_state.m_currFrame = bgfx::frame(); - - return true; } - return false; + ImGui::End(); + + imguiEndFrame(); + + // Advance to next frame. Rendering thread will be kicked to + // process submitted rendering primitives. + m_state.m_currFrame = bgfx::frame(); + + return true; } - void drawAllModels(bgfx::ViewId _pass, bgfx::ProgramHandle _program, ModelUniforms &_uniforms) + return false; + } + + 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) { - const int32_t width = 6; - const int32_t length = 20; + // make a color gradient, nothing special about this for example + float *ca = c0; + float *cb = c1; + float lerpVal = float(zz) / float(length); - 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) + if (0.5f <= lerpVal) { - // make a color gradient, nothing special about this for example - float *ca = c0; - float *cb = c1; - float lerpVal = float(zz) / float(length); - - if (0.5f <= lerpVal) - { - ca = c1; - cb = c2; - } - lerpVal = bx::fract(2.0f * lerpVal); - - 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); - - 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); - - const float posX = 2.0f * xx - width + 1.0f; - const float posY = bx::sin(angle); - const float posZ = 2.0f * zz - length + 1.0f; - - const float scale = s_meshScale[MeshHollowCube]; - float mtx[16]; - bx::mtxSRT(mtx, scale, scale, scale, 0.0f, 0.0f, 0.0f, posX, posY, posZ); - - 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[MeshHollowCube], _pass, _program, mtx); - } + ca = c1; + cb = c2; } + lerpVal = bx::fract(2.0f * lerpVal); - // draw box as ground plane + 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); + + for (int32_t xx = 0; xx < width; ++xx) { - 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); + const float angle = m_state.m_animationTime + float(zz) * (bx::kPi2 / length) + float(xx) * (bx::kPiHalf / width); - _uniforms.m_color[0] = 0.5f; - _uniforms.m_color[1] = 0.5f; - _uniforms.m_color[2] = 0.5f; + const float posX = 2.0f * xx - width + 1.0f; + const float posY = bx::sin(angle); + const float posZ = 2.0f * zz - length + 1.0f; + + const float scale = s_meshScale[MeshHollowCube]; + float mtx[16]; + bx::mtxSRT(mtx, scale, scale, scale, 0.0f, 0.0f, 0.0f, posX, posY, posZ); + + 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() + _uniforms.m_color[0] = 0.5f; + _uniforms.m_color[1] = 0.5f; + _uniforms.m_color[2] = 0.5f; + _uniforms.submit(); + + meshSubmit(m_state.m_meshes[MeshCube], _pass, m_state.m_gridProgram, mtx); + } + } + + void resize() + { + destroyFramebuffers(); + createFramebuffers(); + m_state.m_fsr.resize(m_state.m_width, m_state.m_height); + } + + void createFramebuffers() + { + m_state.m_size[0] = m_state.m_width; + m_state.m_size[1] = m_state.m_height; + + constexpr uint64_t msaaFlags[] = { - m_state.m_size[0] = m_state.m_width; - m_state.m_size[1] = m_state.m_height; + BGFX_TEXTURE_NONE, + BGFX_TEXTURE_RT_MSAA_X4, + BGFX_TEXTURE_RT_MSAA_X16, + }; - constexpr uint64_t msaaFlags[] = - { - BGFX_TEXTURE_NONE, - BGFX_TEXTURE_RT_MSAA_X4, - BGFX_TEXTURE_RT_MSAA_X16, - }; + 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 + ; - 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_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_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 + ); + } - m_state.m_frameBuffer = bgfx::createFrameBuffer( - BX_COUNTOF(m_state.m_frameBufferTex) - , m_state.m_frameBufferTex - , true - ); - } + // all buffers set to destroy their textures + void destroyFramebuffers() + { + bgfx::destroy(m_state.m_frameBuffer); + } - // 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; + } - 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; - }; + AppState m_state; + MagnifierWidget m_magnifierWidget; +}; } // namespace diff --git a/examples/47-pixelformats/pixelformats.cpp b/examples/47-pixelformats/pixelformats.cpp index 88aff7ba1..0aa2a23d7 100644 --- a/examples/47-pixelformats/pixelformats.cpp +++ b/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; diff --git a/examples/common/entry/entry.cpp b/examples/common/entry/entry.cpp index d4144a97f..58a671e6a 100644 --- a/examples/common/entry/entry.cpp +++ b/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(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(app, s_offset); + ai->m_next = apps[ii]; + } + + { + AppInternal* ai = bx::addressOf(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(); +} diff --git a/examples/common/entry/entry.h b/examples/common/entry/entry.h index 1025ae473..2dc7acc7b 100644 --- a/examples/common/entry/entry.h +++ b/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]; }; /// diff --git a/examples/common/entry/entry_android.cpp b/examples/common/entry/entry_android.cpp index 9adfcee61..3a6ac8561 100644 --- a/examples/common/entry/entry_android.cpp +++ b/examples/common/entry/entry_android.cpp @@ -7,8 +7,6 @@ #if ENTRY_CONFIG_USE_NATIVE && BX_PLATFORM_ANDROID -#include - #include #include @@ -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); diff --git a/examples/common/entry/entry_glfw.cpp b/examples/common/entry/entry_glfw.cpp index 22ac7edc2..da1550240 100644 --- a/examples/common/entry/entry_glfw.cpp +++ b/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 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); diff --git a/examples/common/entry/entry_html5.cpp b/examples/common/entry/entry_html5.cpp index 96db49338..884a563b7 100644 --- a/examples/common/entry/entry_html5.cpp +++ b/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) diff --git a/examples/common/entry/entry_ios.mm b/examples/common/entry/entry_ios.mm index 2575bdad5..f123b6684 100644 --- a/examples/common/entry/entry_ios.mm +++ b/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 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 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]; } } diff --git a/examples/common/entry/entry_noop.cpp b/examples/common/entry/entry_noop.cpp index 067fcb676..22d160f59 100644 --- a/examples/common/entry/entry_noop.cpp +++ b/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) diff --git a/examples/common/entry/entry_osx.mm b/examples/common/entry/entry_osx.mm index 0576337d4..948483ca9 100644 --- a/examples/common/entry/entry_osx.mm +++ b/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 diff --git a/examples/common/entry/entry_sdl.cpp b/examples/common/entry/entry_sdl.cpp index e037f1a6b..8744b98e7 100644 --- a/examples/common/entry/entry_sdl.cpp +++ b/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); diff --git a/examples/common/entry/entry_windows.cpp b/examples/common/entry/entry_windows.cpp index 855a35c18..5d60573d0 100644 --- a/examples/common/entry/entry_windows.cpp +++ b/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; diff --git a/examples/common/entry/entry_winrt.cx b/examples/common/entry/entry_winrt.cx deleted file mode 100644 index 4c7f12776..000000000 --- a/examples/common/entry/entry_winrt.cx +++ /dev/null @@ -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 -#include -#include -#include -#include - -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(this, &App::OnActivated); - - CoreApplication::Suspending += ref new - EventHandler(this, &App::OnSuspending); - - CoreApplication::Resuming += ref new - EventHandler(this, &App::OnResuming); - } - - virtual void SetWindow(CoreWindow^ window) - { - window->VisibilityChanged += ref new - TypedEventHandler(this, &App::OnVisibilityChanged); - - window->Closed += ref new - TypedEventHandler(this, &App::OnWindowClosed); - - winrtSetWindow(reinterpret_cast(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^) -{ - auto appSource = ref new AppSource(); - CoreApplication::Run(appSource); - return 0; -} - -#endif // BX_PLATFORM_WINRT || BX_PLATFORM_XBOXONE diff --git a/examples/common/entry/entry_x11.cpp b/examples/common/entry/entry_x11.cpp index 6876ac15d..af3faab24 100644 --- a/examples/common/entry/entry_x11.cpp +++ b/examples/common/entry/entry_x11.cpp @@ -12,8 +12,6 @@ #include #include // will include X11 which #defines None... Don't mess with order of includes. #include -#include - #include // 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) diff --git a/examples/common/entry/input.cpp b/examples/common/entry/input.cpp index e060960b4..770922d6f 100644 --- a/examples/common/entry/input.cpp +++ b/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; diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 830731d0f..ad63f3601 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -1878,21 +1878,7 @@ namespace bgfx m_init.resolution.maxFrameLatency = bx::min(_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; diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 2065c9fb9..2b98fc81e 100644 --- a/src/renderer_gl.cpp +++ b/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)); } diff --git a/tools/geometryv/geometryv.cpp b/tools/geometryv/geometryv.cpp index 3663f1828..ea3e075fa 100644 --- a/tools/geometryv/geometryv.cpp +++ b/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(); diff --git a/tools/texturev/texturev.cpp b/tools/texturev/texturev.cpp index c34ac825a..40ebd918a 100644 --- a/tools/texturev/texturev.cpp +++ b/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();