Browse Source

Combined all examples. Issue #1143.

Branimir Karadžić 8 years ago
parent
commit
5f666a5ee2
38 changed files with 1299 additions and 753 deletions
  1. 55 25
      examples/00-helloworld/helloworld.cpp
  2. 35 16
      examples/01-cubes/cubes.cpp
  3. 36 9
      examples/02-metaballs/metaballs.cpp
  4. 38 29
      examples/03-raymarch/raymarch.cpp
  5. 36 16
      examples/04-mesh/mesh.cpp
  6. 39 18
      examples/05-instancing/instancing.cpp
  7. 37 18
      examples/06-bump/bump.cpp
  8. 20 43
      examples/07-callback/callback.cpp
  9. 35 22
      examples/08-update/update.cpp
  10. 17 16
      examples/09-hdr/hdr.cpp
  11. 39 12
      examples/10-font/font.cpp
  12. 18 18
      examples/11-fontsdf/fontsdf.cpp
  13. 16 16
      examples/12-lod/lod.cpp
  14. 20 15
      examples/13-stencil/stencil.cpp
  15. 21 14
      examples/14-shadowvolumes/shadowvolumes.cpp
  16. 33 15
      examples/15-shadowmaps-simple/shadowmaps_simple.cpp
  17. 42 34
      examples/16-shadowmaps/shadowmaps.cpp
  18. 16 9
      examples/17-drawstress/drawstress.cpp
  19. 16 10
      examples/18-ibl/ibl.cpp
  20. 16 13
      examples/19-oit/oit.cpp
  21. 32 20
      examples/20-nanovg/nanovg.cpp
  22. 29 23
      examples/21-deferred/deferred.cpp
  23. 40 19
      examples/22-windows/windows.cpp
  24. 65 46
      examples/23-vectordisplay/main.cpp
  25. 32 28
      examples/24-nbody/nbody.cpp
  26. 46 22
      examples/26-occlusion/occlusion.cpp
  27. 16 10
      examples/27-terrain/terrain.cpp
  28. 36 31
      examples/28-wireframe/wireframe.cpp
  29. 34 11
      examples/29-debugdraw/debugdraw.cpp
  30. 18 17
      examples/30-picking/picking.cpp
  31. 68 67
      examples/31-rsm/reflectiveshadowmap.cpp
  32. 17 11
      examples/32-particles/particles.cpp
  33. 16 13
      examples/33-pom/pom.cpp
  34. 112 7
      examples/common/entry/entry.cpp
  35. 46 27
      examples/common/entry/entry.h
  36. 96 33
      examples/common/imgui/imgui.cpp
  37. 3 0
      examples/common/imgui/imgui.h
  38. 8 0
      scripts/genie.lua

+ 55 - 25
examples/00-helloworld/helloworld.cpp

@@ -7,9 +7,19 @@
 #include "common.h"
 #include "bgfx_utils.h"
 #include "logo.h"
+#include "imgui/imgui.h"
+
+namespace
+{
 
 class ExampleHelloWorld : public entry::AppI
 {
+public:
+	ExampleHelloWorld(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
@@ -27,15 +37,19 @@ class ExampleHelloWorld : public entry::AppI
 
 		// Set view 0 clear state.
 		bgfx::setViewClear(0
-				, BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
-				, 0x303030ff
-				, 1.0f
-				, 0
-				);
+			, BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
+			, 0x303030ff
+			, 1.0f
+			, 0
+			);
+
+		imguiCreate();
 	}
 
 	virtual int shutdown() BX_OVERRIDE
 	{
+		imguiDestroy();
+
 		// Shutdown bgfx.
 		bgfx::shutdown();
 
@@ -44,8 +58,22 @@ class ExampleHelloWorld : public entry::AppI
 
 	bool update() BX_OVERRIDE
 	{
-		if (!entry::processEvents(m_width, m_height, m_debug, m_reset) )
+		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
 		{
+			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)
+				);
+
+			bool restart = showExampleDialog(this);
+
+			imguiEndFrame();
+
 			// Set view 0 default viewport.
 			bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) );
 
@@ -55,40 +83,42 @@ class ExampleHelloWorld : public entry::AppI
 
 			// Use debug font to print information about this example.
 			bgfx::dbgTextClear();
-			bgfx::dbgTextImage(bx::uint16_max(uint16_t(m_width /2/8 ), 20)-20
-							 , bx::uint16_max(uint16_t(m_height/2/16), 6)-6
-							 , 40
-							 , 12
-							 , s_logo
-							 , 160
-							 );
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/00-helloworld");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Initialization and debug text.");
-
-			bgfx::dbgTextPrintf(0, 4, 0x0f, "Color can be changed with ANSI \x1b[9;me\x1b[10;ms\x1b[11;mc\x1b[12;ma\x1b[13;mp\x1b[14;me\x1b[0m code too.");
+			bgfx::dbgTextImage(
+				  bx::uint16_max(uint16_t(m_width /2/8 ), 20)-20
+				, bx::uint16_max(uint16_t(m_height/2/16),  6)-6
+				, 40
+				, 12
+				, s_logo
+				, 160
+				);
+			bgfx::dbgTextPrintf(0, 1, 0x0f, "Color can be changed with ANSI \x1b[9;me\x1b[10;ms\x1b[11;mc\x1b[12;ma\x1b[13;mp\x1b[14;me\x1b[0m code too.");
 
 			const bgfx::Stats* stats = bgfx::getStats();
-			bgfx::dbgTextPrintf(0, 6, 0x0f, "Backbuffer %dW x %dH in pixels, debug text %dW x %dH in characters."
-					, stats->width
-					, stats->height
-					, stats->textWidth
-					, stats->textHeight
-					);
+			bgfx::dbgTextPrintf(0, 2, 0x0f, "Backbuffer %dW x %dH in pixels, debug text %dW x %dH in characters."
+				, stats->width
+				, stats->height
+				, stats->textWidth
+				, stats->textHeight
+				);
 
 			// Advance to next frame. Rendering thread will be kicked to
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
 	}
 
+	entry::MouseState m_mouseState;
+
 	uint32_t m_width;
 	uint32_t m_height;
 	uint32_t m_debug;
 	uint32_t m_reset;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleHelloWorld);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleHelloWorld, "00-helloworld", "Initialization and debug text.");

+ 35 - 16
examples/01-cubes/cubes.cpp

@@ -5,6 +5,10 @@
 
 #include "common.h"
 #include "bgfx_utils.h"
+#include "imgui/imgui.h"
+
+namespace
+{
 
 struct PosColorVertex
 {
@@ -73,6 +77,12 @@ static const uint16_t s_cubeTriStrip[] =
 
 class ExampleCubes : public entry::AppI
 {
+public:
+	ExampleCubes(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		BX_UNUSED(s_cubeTriList, s_cubeTriStrip);
@@ -81,7 +91,7 @@ class ExampleCubes : public entry::AppI
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -118,10 +128,14 @@ class ExampleCubes : public entry::AppI
 		m_program = loadProgram("vs_cubes", "fs_cubes");
 
 		m_timeOffset = bx::getHPCounter();
+
+		imguiCreate();
 	}
 
 	virtual int shutdown() BX_OVERRIDE
 	{
+		imguiDestroy();
+
 		// Cleanup.
 		bgfx::destroyIndexBuffer(m_ibh);
 		bgfx::destroyVertexBuffer(m_vbh);
@@ -135,22 +149,23 @@ class ExampleCubes : public entry::AppI
 
 	bool update() BX_OVERRIDE
 	{
-		if (!entry::processEvents(m_width, m_height, m_debug, m_reset) )
+		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 double toMs = 1000.0/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)
+				);
+
+			bool restart = showExampleDialog(this);
 
-			float time = (float)( (now-m_timeOffset)/double(bx::getHPFrequency() ) );
+			imguiEndFrame();
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/01-cube");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Rendering simple static mesh.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
+			float time = (float)( (bx::getHPCounter()-m_timeOffset)/double(bx::getHPFrequency() ) );
 
 			float at[3]  = { 0.0f, 0.0f,   0.0f };
 			float eye[3] = { 0.0f, 0.0f, -35.0f };
@@ -219,12 +234,14 @@ class ExampleCubes : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
 	}
 
+	entry::MouseState m_mouseState;
+
 	uint32_t m_width;
 	uint32_t m_height;
 	uint32_t m_debug;
@@ -235,4 +252,6 @@ class ExampleCubes : public entry::AppI
 	int64_t m_timeOffset;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleCubes);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleCubes, "01-cube", "Rendering simple static mesh.");

+ 36 - 9
examples/02-metaballs/metaballs.cpp

@@ -5,6 +5,7 @@
 
 #include "common.h"
 #include "bgfx_utils.h"
+#include "imgui/imgui.h"
 
 #include <bgfx/embedded_shader.h>
 
@@ -12,6 +13,9 @@
 #include "vs_metaballs.bin.h"
 #include "fs_metaballs.bin.h"
 
+namespace
+{
+
 static const bgfx::EmbeddedShader s_embeddedShaders[] =
 {
 	BGFX_EMBEDDED_SHADER(vs_metaballs),
@@ -474,13 +478,19 @@ uint32_t triangulate(uint8_t* _result, uint32_t _stride, const float* __restrict
 
 class ExampleMetaballs : public entry::AppI
 {
+public:
+	ExampleMetaballs(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -510,10 +520,14 @@ class ExampleMetaballs : public entry::AppI
 
 		m_grid = new Grid[DIMS*DIMS*DIMS];
 		m_timeOffset = bx::getHPCounter();
+
+		imguiCreate();
 	}
 
 	int shutdown() BX_OVERRIDE
 	{
+		imguiDestroy();
+
 		delete [] m_grid;
 
 		// Cleanup.
@@ -531,8 +545,22 @@ class ExampleMetaballs : public entry::AppI
 		const uint32_t zpitch = DIMS*DIMS;
 		const float invdim = 1.0f/float(DIMS-1);
 
-		if (!entry::processEvents(m_width, m_height, m_debug, m_reset) )
+		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
 		{
+			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)
+				);
+
+			bool restart = showExampleDialog(this);
+
+			imguiEndFrame();
+
 			// Set view 0 default viewport.
 			bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) );
 
@@ -548,11 +576,6 @@ class ExampleMetaballs : public entry::AppI
 			const double toMs = 1000.0/freq;
 			float time = (float)( (now - m_timeOffset)/double(bx::getHPFrequency() ) );
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/02-metaball");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Rendering with transient buffers and embedding shaders.");
-
 			float at[3]  = { 0.0f, 0.0f,   0.0f };
 			float eye[3] = { 0.0f, 0.0f, -50.0f };
 
@@ -745,12 +768,14 @@ class ExampleMetaballs : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
 	}
 
+	entry::MouseState m_mouseState;
+
 	uint32_t m_width;
 	uint32_t m_height;
 	uint32_t m_debug;
@@ -761,4 +786,6 @@ class ExampleMetaballs : public entry::AppI
 	int64_t m_timeOffset;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleMetaballs);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleMetaballs, "02-metaball", "Rendering with transient buffers and embedding shaders.");

+ 38 - 29
examples/03-raymarch/raymarch.cpp

@@ -5,6 +5,10 @@
 
 #include "common.h"
 #include "bgfx_utils.h"
+#include "imgui/imgui.h"
+
+namespace
+{
 
 struct PosColorTexCoord0Vertex
 {
@@ -30,13 +34,6 @@ struct PosColorTexCoord0Vertex
 
 bgfx::VertexDecl PosColorTexCoord0Vertex::ms_decl;
 
-static bool s_oglNdc = false;
-
-inline void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far)
-{
-	bx::mtxProj(_result, _fovy, _aspect, _near, _far, s_oglNdc);
-}
-
 void renderScreenSpaceQuad(uint8_t _view, bgfx::ProgramHandle _program, float _x, float _y, float _width, float _height)
 {
 	bgfx::TransientVertexBuffer tvb;
@@ -104,13 +101,19 @@ void renderScreenSpaceQuad(uint8_t _view, bgfx::ProgramHandle _program, float _x
 
 class ExampleRaymarch : public entry::AppI
 {
+public:
+	ExampleRaymarch(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -127,9 +130,6 @@ class ExampleRaymarch : public entry::AppI
 				, 0
 				);
 
-		const bgfx::Caps* caps = bgfx::getCaps();
-		s_oglNdc = caps->homogeneousDepth;
-
 		// Create vertex stream declaration.
 		PosColorTexCoord0Vertex::init();
 
@@ -140,10 +140,14 @@ class ExampleRaymarch : public entry::AppI
 		m_program = loadProgram("vs_raymarching", "fs_raymarching");
 
 		m_timeOffset = bx::getHPCounter();
+
+		imguiCreate();
 	}
 
 	int shutdown() BX_OVERRIDE
 	{
+		imguiDestroy();
+
 		// Cleanup.
 		bgfx::destroyProgram(m_program);
 
@@ -158,8 +162,21 @@ class ExampleRaymarch : public entry::AppI
 
 	bool update() BX_OVERRIDE
 	{
-		if (!entry::processEvents(m_width, m_height, m_debug, m_reset) )
+		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
 		{
+			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)
+				);
+
+			bool restart = showExampleDialog(this);
+
+			imguiEndFrame();
 			// Set view 0 default viewport.
 			bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) );
 
@@ -170,31 +187,19 @@ class ExampleRaymarch : public entry::AppI
 			// if no other draw calls are submitted to viewZ 0.
 			bgfx::touch(0);
 
-			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 double toMs = 1000.0/freq;
-
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/03-raymarch");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Updating shader uniforms.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			float at[3]  = { 0.0f, 0.0f,   0.0f };
 			float eye[3] = { 0.0f, 0.0f, -15.0f };
 
 			float view[16];
 			float proj[16];
 			bx::mtxLookAt(view, eye, at);
-			mtxProj(proj, 60.0f, float(m_width)/float(m_height), 0.1f, 100.0f);
+
+			const bgfx::Caps* caps = bgfx::getCaps();
+			bx::mtxProj(proj, 60.0f, float(m_width)/float(m_height), 0.1f, 100.0f, caps->homogeneousDepth);
 
 			// Set view and projection matrix for view 1.
 			bgfx::setViewTransform(0, view, proj);
 
-			const bgfx::Caps* caps = bgfx::getCaps();
 			float ortho[16];
 			bx::mtxOrtho(ortho, 0.0f, 1280.0f, 720.0f, 0.0f, 0.0f, 100.0f, 0.0, caps->homogeneousDepth);
 
@@ -235,12 +240,14 @@ class ExampleRaymarch : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
 	}
 
+	entry::MouseState m_mouseState;
+
 	uint32_t m_width;
 	uint32_t m_height;
 	uint32_t m_debug;
@@ -252,4 +259,6 @@ class ExampleRaymarch : public entry::AppI
 	bgfx::ProgramHandle m_program;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleRaymarch);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleRaymarch, "03-raymarch", "Description: Updating shader uniforms.");

+ 36 - 16
examples/04-mesh/mesh.cpp

@@ -5,16 +5,26 @@
 
 #include "common.h"
 #include "bgfx_utils.h"
+#include "imgui/imgui.h"
+
+namespace
+{
 
 class ExampleMesh : public entry::AppI
 {
+public:
+	ExampleMesh(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -39,10 +49,14 @@ class ExampleMesh : public entry::AppI
 		m_mesh = meshLoad("meshes/bunny.bin");
 
 		m_timeOffset = bx::getHPCounter();
+
+		imguiCreate();
 	}
 
 	int shutdown() BX_OVERRIDE
 	{
+		imguiDestroy();
+
 		meshUnload(m_mesh);
 
 		// Cleanup.
@@ -58,8 +72,22 @@ class ExampleMesh : public entry::AppI
 
 	bool update() BX_OVERRIDE
 	{
-		if (!entry::processEvents(m_width, m_height, m_debug, m_reset) )
+		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
 		{
+			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)
+				);
+
+			bool restart = showExampleDialog(this);
+
+			imguiEndFrame();
+
 			// Set view 0 default viewport.
 			bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) );
 
@@ -67,21 +95,9 @@ class ExampleMesh : public entry::AppI
 			// if no other draw calls are submitted to view 0.
 			bgfx::touch(0);
 
-			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 double toMs = 1000.0/freq;
 			float time = (float)( (bx::getHPCounter()-m_timeOffset)/double(bx::getHPFrequency() ) );
 			bgfx::setUniform(u_time, &time);
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/04-mesh");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Loading meshes.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			float at[3]  = { 0.0f, 1.0f,  0.0f };
 			float eye[3] = { 0.0f, 1.0f, -2.5f };
 
@@ -124,12 +140,14 @@ class ExampleMesh : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
 	}
 
+	entry::MouseState m_mouseState;
+
 	uint32_t m_width;
 	uint32_t m_height;
 	uint32_t m_debug;
@@ -141,4 +159,6 @@ class ExampleMesh : public entry::AppI
 	bgfx::UniformHandle u_time;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleMesh);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleMesh, "04-mesh", "Description: Loading meshes.");

+ 39 - 18
examples/05-instancing/instancing.cpp

@@ -5,6 +5,10 @@
 
 #include "common.h"
 #include "bgfx_utils.h"
+#include "imgui/imgui.h"
+
+namespace
+{
 
 struct PosColorVertex
 {
@@ -57,13 +61,19 @@ static const uint16_t s_cubeIndices[36] =
 
 class ExampleInstancing : public entry::AppI
 {
+public:
+	ExampleInstancing(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -98,10 +108,14 @@ class ExampleInstancing : public entry::AppI
 		m_program = loadProgram("vs_instancing", "fs_instancing");
 
 		m_timeOffset = bx::getHPCounter();
+
+		imguiCreate();
 	}
 
 	int shutdown() BX_OVERRIDE
 	{
+		imguiDestroy();
+
 		// Cleanup.
 		bgfx::destroyIndexBuffer(m_ibh);
 		bgfx::destroyVertexBuffer(m_vbh);
@@ -115,8 +129,22 @@ class ExampleInstancing : public entry::AppI
 
 	bool update() BX_OVERRIDE
 	{
-		if (!entry::processEvents(m_width, m_height, m_debug, m_reset) )
+		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
 		{
+			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)
+				);
+
+			bool restart = showExampleDialog(this);
+
+			imguiEndFrame();
+
 			// Set view 0 default viewport.
 			bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) );
 
@@ -124,19 +152,7 @@ class ExampleInstancing : public entry::AppI
 			// if no other draw calls are submitted to view 0.
 			bgfx::touch(0);
 
-			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 double toMs = 1000.0/freq;
-			float time = (float)( (now - m_timeOffset)/double(bx::getHPFrequency() ) );
-
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/05-instancing");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Geometry instancing.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
+			float time = (float)( (bx::getHPCounter() - m_timeOffset)/double(bx::getHPFrequency() ) );
 
 			// Get renderer capabilities info.
 			const bgfx::Caps* caps = bgfx::getCaps();
@@ -147,7 +163,7 @@ class ExampleInstancing : public entry::AppI
 				// When instancing is not supported by GPU, implement alternative
 				// code path that doesn't use instancing.
 				bool blink = uint32_t(time*3.0f)&1;
-				bgfx::dbgTextPrintf(0, 5, blink ? 0x1f : 0x01, " Instancing is not supported by GPU. ");
+				bgfx::dbgTextPrintf(0, 0, blink ? 0x1f : 0x01, " Instancing is not supported by GPU. ");
 			}
 			else
 			{
@@ -226,12 +242,15 @@ class ExampleInstancing : public entry::AppI
 			// Advance to next frame. Rendering thread will be kicked to
 			// process submitted rendering primitives.
 			bgfx::frame();
-			return true;
+
+			return !restart;
 		}
 
 		return false;
 	}
 
+	entry::MouseState m_mouseState;
+
 	uint32_t m_width;
 	uint32_t m_height;
 	uint32_t m_debug;
@@ -243,4 +262,6 @@ class ExampleInstancing : public entry::AppI
 	int64_t m_timeOffset;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleInstancing);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleInstancing, "05-instancing", "Description: Geometry instancing.");

+ 37 - 18
examples/06-bump/bump.cpp

@@ -5,6 +5,10 @@
 
 #include "common.h"
 #include "bgfx_utils.h"
+#include "imgui/imgui.h"
+
+namespace
+{
 
 struct PosNormalTangentTexcoordVertex
 {
@@ -80,13 +84,19 @@ static const uint16_t s_cubeIndices[36] =
 
 class ExampleBump : public entry::AppI
 {
+public:
+	ExampleBump(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -144,10 +154,14 @@ class ExampleBump : public entry::AppI
 		m_textureNormal = loadTexture("textures/fieldstone-n.dds");
 
 		m_timeOffset = bx::getHPCounter();
+
+		imguiCreate();
 	}
 
 	virtual int shutdown() BX_OVERRIDE
 	{
+		imguiDestroy();
+
 		// Cleanup.
 		bgfx::destroyIndexBuffer(m_ibh);
 		bgfx::destroyVertexBuffer(m_vbh);
@@ -167,8 +181,22 @@ class ExampleBump : public entry::AppI
 
 	bool update() BX_OVERRIDE
 	{
-		if (!entry::processEvents(m_width, m_height, m_debug, m_reset) )
+		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
 		{
+			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)
+				);
+
+			bool restart = showExampleDialog(this);
+
+			imguiEndFrame();
+
 			// Set view 0 default viewport.
 			bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) );
 
@@ -176,20 +204,7 @@ class ExampleBump : public entry::AppI
 			// if no other draw calls are submitted to view 0.
 			bgfx::touch(0);
 
-			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 double toMs = 1000.0/freq;
-
-			float time = (float)( (now-m_timeOffset)/freq);
-
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/06-bump");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Loading textures.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
+			float time = (float)( (bx::getHPCounter()-m_timeOffset)/double(bx::getHPFrequency() ));
 
 			float at[3]  = { 0.0f, 0.0f,  0.0f };
 			float eye[3] = { 0.0f, 0.0f, -7.0f };
@@ -333,12 +348,14 @@ class ExampleBump : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
 	}
 
+	entry::MouseState m_mouseState;
+
 	bgfx::VertexBufferHandle m_vbh;
 	bgfx::IndexBufferHandle  m_ibh;
 	bgfx::UniformHandle s_texColor;
@@ -358,4 +375,6 @@ class ExampleBump : public entry::AppI
 	int64_t m_timeOffset;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleBump);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleBump, "06-bump", "Description: Loading textures.");

+ 20 - 43
examples/07-callback/callback.cpp

@@ -14,6 +14,9 @@
 
 #include <inttypes.h>
 
+namespace
+{
+
 struct PosColorVertex
 {
 	float m_x;
@@ -312,6 +315,12 @@ private:
 
 class ExampleCallback : public entry::AppI
 {
+public:
+	ExampleCallback(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
@@ -319,17 +328,13 @@ class ExampleCallback : public entry::AppI
 		m_width = 1280;
 		m_height = 720;
 
-		// Enumerate supported backend renderers.
-		m_numRenderers = bgfx::getSupportedRenderers(BX_COUNTOF(m_renderers), m_renderers);
-
-		bgfx::init(bgfx::RendererType::Count == args.m_type
-				   ? m_renderers[bx::getHPCounter() % m_numRenderers] /* randomize renderer */
-				   : args.m_type
-				   , args.m_pciId
-				   , 0
-				   , &m_callback  // custom callback handler
-				   , &m_allocator // custom allocator
-				   );
+		bgfx::init(
+			  args.m_type
+			, args.m_pciId
+			, 0
+			, &m_callback  // custom callback handler
+			, &m_allocator // custom allocator
+			);
 		bgfx::reset(m_width, m_height, BGFX_RESET_CAPTURE|BGFX_RESET_MSAA_X16);
 
 		// Enable debug text.
@@ -382,42 +387,16 @@ class ExampleCallback : public entry::AppI
 
 	bool update() BX_OVERRIDE
 	{
-
-
 		// 5 second 60Hz video
-		if ( m_frame < 300)
+		if (m_frame < 300)
 		{
 			++m_frame;
-			const bgfx::RendererType::Enum rendererType = bgfx::getRendererType();
 
 			// This dummy draw call is here to make sure that view 0 is cleared
 			// if no other draw calls are submitted to view 0.
 			bgfx::touch(0);
 
-			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 double toMs = 1000.0/freq;
-
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf( 0, 1, 0x4f, "bgfx/examples/07-callback");
-			bgfx::dbgTextPrintf( 0, 2, 0x6f, "Description: Implementing application specific callbacks for taking screen shots,");
-			bgfx::dbgTextPrintf(13, 3, 0x6f, "caching OpenGL binary shaders, and video capture.");
-			bgfx::dbgTextPrintf( 0, 4, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
-			bgfx::dbgTextPrintf( 2, 6, 0x0e, "Supported renderers:");
-			for (uint8_t ii = 0; ii < m_numRenderers; ++ii)
-			{
-				bgfx::dbgTextPrintf( 2, 7+ii, 0x0c, "[%c] %s"
-									, m_renderers[ii] == rendererType ? '\xfe' : ' '
-									, bgfx::getRendererName(m_renderers[ii])
-									);
-			}
-
-			float at[3] = { 0.0f, 0.0f, 0.0f };
+			float at[3]  = { 0.0f, 0.0f,   0.0f };
 			float eye[3] = { 0.0f, 0.0f, -35.0f };
 
 			float view[16];
@@ -479,9 +458,6 @@ class ExampleCallback : public entry::AppI
 	uint32_t m_width;
 	uint32_t m_height;
 
-	bgfx::RendererType::Enum m_renderers[bgfx::RendererType::Count];
-	uint8_t m_numRenderers;
-
 	bgfx::VertexBufferHandle m_vbh;
 	bgfx::IndexBufferHandle m_ibh;
 	bgfx::ProgramHandle m_program;
@@ -489,5 +465,6 @@ class ExampleCallback : public entry::AppI
 	uint32_t m_frame;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleCallback);
+} // namespace
 
+ENTRY_IMPLEMENT_MAIN(ExampleCallback, "07-callback", "Implementing application specific callbacks for taking screen shots, caching OpenGL binary shaders, and video capture.");

+ 35 - 22
examples/08-update/update.cpp

@@ -5,12 +5,15 @@
 
 #include "common.h"
 #include "bgfx_utils.h"
-
-#include <bx/uint32_t.h>
 #include "packrect.h"
+#include "imgui/imgui.h"
 
+#include <bx/uint32_t.h>
 #include <list>
 
+namespace
+{
+
 struct PosTexcoordVertex
 {
 	float m_x;
@@ -118,8 +121,9 @@ static const uint32_t texture2dSize = 256;
 class ExampleUpdate : public entry::AppI
 {
 public:
-	ExampleUpdate()
-		: m_cube(textureside)
+	ExampleUpdate(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+		, m_cube(textureside)
 	{
 	}
 
@@ -129,7 +133,7 @@ public:
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -284,10 +288,14 @@ public:
 
 		m_updateTime = 0;
 		m_timeOffset = bx::getHPCounter();
+
+		imguiCreate();
 	}
 
 	virtual int shutdown() BX_OVERRIDE
 	{
+		imguiDestroy();
+
 		// m_texture2dData is managed from main thread, and it's passed to renderer
 		// just as MemoryRef. At this point render might be using it. We must wait
 		// previous frame to finish before we can free it.
@@ -340,8 +348,22 @@ public:
 
 	bool update() BX_OVERRIDE
 	{
-		if (!entry::processEvents(m_width, m_height, m_debug, m_reset) )
+		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
 		{
+			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)
+				);
+
+			bool restart = showExampleDialog(this);
+
+			imguiEndFrame();
+
 			float borderColor[4] = { float(rand()%255)/255.0f, float(rand()%255)/255.0f, float(rand()%255)/255.0f, float(rand()%255)/255.0f };
 			bgfx::setPaletteColor(1, borderColor);
 
@@ -354,20 +376,9 @@ public:
 			bgfx::touch(0);
 
 			int64_t now = bx::getHPCounter();
-			static int64_t last = now;
-			const int64_t frameTime = now - last;
-			last = now;
-			const int64_t freq = bx::getHPFrequency();
-			const double toMs = 1000.0/double(freq);
 			float time = (float)( (now - m_timeOffset)/double(bx::getHPFrequency() ) );
 			bgfx::setUniform(u_time, &time);
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/08-update");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Updating m_textures.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			if (now > m_updateTime)
 			{
 				PackCube face;
@@ -444,8 +455,6 @@ public:
 				}
 			}
 
-			bgfx::dbgTextPrintf(0, 4, 0x0f, "m_hit: %d, m_miss %d", m_hit, m_miss);
-
 			float at[3] = { 0.0f, 0.0f, 0.0f };
 			float eye[3] = { 0.0f, 0.0f, -5.0f };
 
@@ -583,19 +592,21 @@ public:
 			// Advance to next frame. Rendering thread will be kicked to
 			// process submitted rendering primitives.
 			bgfx::frame();
-			return true;
+
+			return !restart;
 		}
 
 		return false;
 	}
 
-	uint8_t* m_texture2dData;
+	entry::MouseState m_mouseState;
 
 	uint32_t m_width;
 	uint32_t m_height;
 	uint32_t m_debug;
 	uint32_t m_reset;
 
+	uint8_t* m_texture2dData;
 	uint32_t m_numTextures3d;
 	bool m_texture3DSupported;
 	bool m_blitSupported;
@@ -629,4 +640,6 @@ public:
 
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleUpdate);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleUpdate, "08-update", "Updating m_textures.");

+ 17 - 16
examples/09-hdr/hdr.cpp

@@ -8,6 +8,9 @@
 #include "imgui/imgui.h"
 #include <bx/rng.h>
 
+namespace
+{
+
 static float s_texelHalf = 0.0f;
 
 struct PosColorTexCoord0Vertex
@@ -134,20 +137,21 @@ void setOffsets4x4Lum(bgfx::UniformHandle _handle, uint32_t _width, uint32_t _he
 	bgfx::setUniform(_handle, offsets, num);
 }
 
-inline float square(float _x)
-{
-	return _x*_x;
-}
-
 class ExampleHDR : public entry::AppI
 {
+public:
+	ExampleHDR(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -301,6 +305,8 @@ class ExampleHDR : public entry::AppI
 					, uint16_t(m_height)
 					);
 
+			bool restart = showExampleDialog(this);
+
 			ImGui::SetNextWindowPos(ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f) );
 			ImGui::Begin("HDR Settings"
 				, NULL
@@ -336,16 +342,9 @@ class ExampleHDR : public entry::AppI
 			const int64_t frameTime = now - last;
 			last = now;
 			const double freq = double(bx::getHPFrequency() );
-			const double toMs = 1000.0/freq;
 
 			m_time += (float)(frameTime*m_speed/freq);
 
-			// Use m_debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/09-hdr");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Using multiple views with frame buffers, and view order remapping.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			uint8_t shuffle[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
 			bx::shuffle(&m_rng, shuffle, BX_COUNTOF(shuffle) );
 
@@ -448,7 +447,7 @@ class ExampleHDR : public entry::AppI
 			// Set view and projection matrix for view hdrMesh.
 			bgfx::setViewTransform(hdrMesh, view, proj);
 
-			float tonemap[4] = { m_middleGray, square(m_white), m_threshold, m_time };
+			float tonemap[4] = { m_middleGray, bx::fsq(m_white), m_threshold, m_time };
 
 			// Render skybox into view hdrSkybox.
 			bgfx::setTexture(0, s_texCube, m_uffizi);
@@ -531,7 +530,7 @@ class ExampleHDR : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -588,4 +587,6 @@ class ExampleHDR : public entry::AppI
 	float m_time;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleHDR);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleHDR, "09-hdr", "Description: Using multiple views with frame buffers, and view order remapping.");

+ 39 - 12
examples/10-font/font.cpp

@@ -19,6 +19,11 @@
 
 #include <wchar.h>
 
+#include "imgui/imgui.h"
+
+namespace
+{
+
 TrueTypeHandle loadTtf(FontManager* _fm, const char* _filePath)
 {
 	uint32_t size;
@@ -48,14 +53,20 @@ static const char* s_fontFilePath[] =
 
 class ExampleFont : public entry::AppI
 {
+public:
+	ExampleFont(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
-		m_width = 1280;
+		m_width  = 1280;
 		m_height = 720;
-		m_debug = BGFX_DEBUG_TEXT;
-		m_reset = BGFX_RESET_VSYNC;
+		m_debug  = BGFX_DEBUG_NONE;
+		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
 		bgfx::reset(m_width, m_height, m_reset);
@@ -170,10 +181,14 @@ class ExampleFont : public entry::AppI
 
 		// Create a transient buffer for real-time data.
 		m_transientText = m_textBufferManager->createTextBuffer(FONT_TYPE_ALPHA, BufferType::Transient);
+
+		imguiCreate();
 	}
 
 	virtual int shutdown() BX_OVERRIDE
 	{
+		imguiDestroy();
+
 		m_fontManager->destroyTtf(m_fontKenneyTtf);
 		m_fontManager->destroyTtf(m_fontAwesomeTtf);
 		m_fontManager->destroyTtf(m_visitorTtf);
@@ -201,8 +216,22 @@ class ExampleFont : public entry::AppI
 
 	bool update() BX_OVERRIDE
 	{
-		if (!entry::processEvents(m_width, m_height, m_debug, m_reset) )
+		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
 		{
+			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)
+				);
+
+			bool restart = showExampleDialog(this);
+
+			imguiEndFrame();
+
 			// This dummy draw call is here to make sure that view 0 is cleared
 			// if no other draw calls are submitted to view 0.
 			bgfx::touch(0);
@@ -214,12 +243,6 @@ class ExampleFont : public entry::AppI
 			const double freq = double(bx::getHPFrequency() );
 			const double toMs = 1000.0 / freq;
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/10-font");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Use the font system to display text and styled text.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			// Use transient text to display debug information.
 			wchar_t fpsText[64];
 			bx::swnprintf(fpsText, BX_COUNTOF(fpsText), L"Frame: % 7.3f[ms]", double(frameTime) * toMs);
@@ -309,12 +332,14 @@ class ExampleFont : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
 	}
 
+	entry::MouseState m_mouseState;
+
 	uint32_t m_width;
 	uint32_t m_height;
 	uint32_t m_debug;
@@ -339,4 +364,6 @@ class ExampleFont : public entry::AppI
 	FontHandle m_fonts[numFonts];
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleFont);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleFont, "10-font", "Use the font system to display text and styled text.");

+ 18 - 18
examples/11-fontsdf/fontsdf.cpp

@@ -15,6 +15,9 @@
 #include "font/text_buffer_manager.h"
 #include "imgui/imgui.h"
 
+namespace
+{
+
 TrueTypeHandle loadTtf(FontManager* _fm, const char* _filePath)
 {
 	uint32_t size;
@@ -33,13 +36,19 @@ TrueTypeHandle loadTtf(FontManager* _fm, const char* _filePath)
 
 class ExampleFontSDF : public entry::AppI
 {
+public:
+	ExampleFontSDF(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width = 1280;
 		m_height = 720;
-		m_debug = BGFX_DEBUG_TEXT;
+		m_debug = BGFX_DEBUG_NONE;
 		m_reset = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -129,6 +138,8 @@ class ExampleFontSDF : public entry::AppI
 				, uint16_t(m_height)
 				);
 
+			bool restart = showExampleDialog(this);
+
 			const float guiPanelWidth  = 325.0f;
 			const float guiPanelHeight = 200.0f;
 
@@ -174,21 +185,8 @@ class ExampleFontSDF : public entry::AppI
 			// if no other draw calls are submitted to view 0.
 			bgfx::touch(0);
 
-			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 double toMs = 1000.0 / freq;
-
-			// Use debug font to print32_t information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/11-fontsdf");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Use a single distance field font to render text of various size.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime) * toMs);
-
-			float at[3]  = { 0, 0, 0.0f };
-			float eye[3] = {0, 0, -1.0f };
+			float at[3]  = { 0.0f, 0.0f,  0.0f };
+			float eye[3] = { 0.0f, 0.0f, -1.0f };
 
 			float view[16];
 			bx::mtxLookAt(view, eye, at);
@@ -260,7 +258,7 @@ class ExampleFontSDF : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -296,4 +294,6 @@ class ExampleFontSDF : public entry::AppI
 	float m_textSize;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleFontSDF);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleFontSDF, "11-fontsdf", "Use a single distance field font to render text of various size.");

+ 16 - 16
examples/12-lod/lod.cpp

@@ -9,6 +9,9 @@
 
 #include <bx/readerwriter.h>
 
+namespace
+{
+
 struct KnightPos
 {
 	int32_t m_x;
@@ -25,13 +28,19 @@ static const KnightPos knightTour[8*4] =
 
 class ExampleLod : public entry::AppI
 {
+public:
+	ExampleLod(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -131,6 +140,8 @@ class ExampleLod : public entry::AppI
 				, uint16_t(m_height)
 			);
 
+			bool restart = showExampleDialog(this);
+
 			ImGui::SetNextWindowPos(ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f) );
 			ImGui::Begin("LOD Settings"
 				, NULL
@@ -154,19 +165,6 @@ class ExampleLod : public entry::AppI
 			// if no other draw calls are submitted to view 0.
 			bgfx::touch(0);
 
-			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 double toMs = 1000.0/freq;
-
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/12-lod");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Mesh LOD transitions.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			float at[3]  = { 0.0f, 1.0f,      0.0f };
 			float eye[3] = { 0.0f, 2.0f, -distance };
 
@@ -283,7 +281,7 @@ class ExampleLod : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -314,4 +312,6 @@ class ExampleLod : public entry::AppI
 	bool    m_transitions;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleLod);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleLod, "12-lod", "Mesh LOD transitions.");

+ 20 - 15
examples/13-stencil/stencil.cpp

@@ -13,6 +13,14 @@
 #include "camera.h"
 #include "imgui/imgui.h"
 
+namespace bgfx
+{
+	int32_t read(bx::ReaderI* _reader, bgfx::VertexDecl& _decl, bx::Error* _err = NULL);
+}
+
+namespace
+{
+
 #define RENDER_VIEWID_RANGE1_PASS_0  1
 #define RENDER_VIEWID_RANGE1_PASS_1  2
 #define RENDER_VIEWID_RANGE1_PASS_2  3
@@ -613,11 +621,6 @@ struct Group
 	PrimitiveArray m_prims;
 };
 
-namespace bgfx
-{
-	int32_t read(bx::ReaderI* _reader, bgfx::VertexDecl& _decl, bx::Error* _err = NULL);
-}
-
 struct Mesh
 {
 	void load(const void* _vertices, uint32_t _numVertices, const bgfx::VertexDecl _decl, const uint16_t* _indices, uint32_t _numIndices)
@@ -787,6 +790,11 @@ struct Mesh
 class ExampleStencil : public entry::AppI
 {
 public:
+	ExampleStencil(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	virtual void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
@@ -794,7 +802,7 @@ public:
 		m_viewState = ViewState(1280, 720);
 		m_clearValues = ClearValues(0x30303000, 1.0f, 0);
 
-		m_debug = BGFX_DEBUG_TEXT;
+		m_debug = BGFX_DEBUG_NONE;
 		m_reset = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -914,6 +922,8 @@ public:
 				, uint16_t(m_viewState.m_height)
 				);
 
+			bool restart = showExampleDialog(this);
+
 			ImGui::SetNextWindowPos(ImVec2(m_viewState.m_width - m_viewState.m_width / 5.0f - 10.0f, 10.0f) );
 			ImGui::Begin("Stencil Settings"
 				, NULL
@@ -968,17 +978,10 @@ public:
 			const int64_t frameTime = now - last;
 			last = now;
 			const double freq = double(bx::getHPFrequency() );
-			const double toMs = 1000.0/freq;
 			const float time = (float)( (now - m_timeOffset)/double(bx::getHPFrequency() ) );
 			const float deltaTime = float(frameTime/freq);
 			s_uniforms.m_time = time;
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/13-stencil");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Stencil reflections and shadows.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			// Update camera.
 			cameraUpdate(deltaTime, m_mouseState);
 			cameraGetViewMtx(m_viewState.m_view);
@@ -1348,7 +1351,7 @@ public:
 			clearViewMask(s_clearMask, BGFX_CLEAR_NONE, m_clearValues);
 			s_clearMask = 0;
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -1395,4 +1398,6 @@ public:
 
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleStencil);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleStencil, "13-stencil", "Stencil reflections and shadows.");

+ 21 - 14
examples/14-shadowvolumes/shadowvolumes.cpp

@@ -24,6 +24,14 @@ namespace stl = tinystl;
 #include "camera.h"
 #include "imgui/imgui.h"
 
+namespace bgfx
+{
+	int32_t read(bx::ReaderI* _reader, bgfx::VertexDecl& _decl, bx::Error* _err = NULL);
+}
+
+namespace
+{
+
 #define SV_USE_SIMD 1
 #define MAX_INSTANCE_COUNT 25
 #define MAX_LIGHTS_COUNT 5
@@ -956,11 +964,6 @@ struct Group
 
 typedef std::vector<Group> GroupArray;
 
-namespace bgfx
-{
-	int32_t read(bx::ReaderI* _reader, bgfx::VertexDecl& _decl, bx::Error* _err = NULL);
-}
-
 struct Mesh
 {
 	void load(const void* _vertices, uint16_t _numVertices, const bgfx::VertexDecl _decl, const uint16_t* _indices, uint32_t _numIndices)
@@ -1866,6 +1869,12 @@ enum Scene
 
 class ExampleShadowVolumes : public entry::AppI
 {
+public:
+	ExampleShadowVolumes(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
@@ -1873,7 +1882,7 @@ class ExampleShadowVolumes : public entry::AppI
 		m_viewState = ViewState(1280, 720);
 		m_clearValues = { 0x00000000, 1.0f, 0 };
 
-		m_debug = BGFX_DEBUG_TEXT;
+		m_debug = BGFX_DEBUG_NONE;
 		m_reset = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -2153,6 +2162,8 @@ class ExampleShadowVolumes : public entry::AppI
 				, uint16_t(m_viewState.m_height)
 				);
 
+			bool restart = showExampleDialog(this);
+
 			ImGui::SetNextWindowPos(ImVec2(m_viewState.m_width - 256.0f, 10.0f) );
 			ImGui::Begin("Settings"
 				, NULL
@@ -2316,12 +2327,6 @@ class ExampleShadowVolumes : public entry::AppI
 				}
 			}
 
-			//use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/14-shadowvolumes");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Shadow volumes.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			if (m_showHelp)
 			{
 				uint8_t row = 5;
@@ -2855,7 +2860,7 @@ class ExampleShadowVolumes : public entry::AppI
 				, m_clearValues.m_clearStencil
 				);
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -2930,4 +2935,6 @@ class ExampleShadowVolumes : public entry::AppI
 	entry::MouseState m_mouseState;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleShadowVolumes);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleShadowVolumes, "14-shadowvolumes", "Shadow volumes.");

+ 33 - 15
examples/15-shadowmaps-simple/shadowmaps_simple.cpp

@@ -15,6 +15,10 @@
 #include <bx/fpumath.h>
 #include "entry/entry.h"
 #include "bgfx_utils.h"
+#include "imgui/imgui.h"
+
+namespace
+{
 
 #define RENDER_SHADOW_PASS_ID 0
 #define RENDER_SCENE_PASS_ID  1
@@ -56,13 +60,19 @@ static const uint16_t s_planeIndices[] =
 
 class ExampleShadowmapsSimple : public entry::AppI
 {
+public:
+	ExampleShadowmapsSimple(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width = 1280;
 		m_height = 720;
-		m_debug = BGFX_DEBUG_TEXT;
+		m_debug = BGFX_DEBUG_NONE;
 		m_reset = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -207,10 +217,14 @@ class ExampleShadowmapsSimple : public entry::AppI
 		bx::mtxProj(m_proj, 60.0f, aspect, 0.1f, 1000.0f, bgfx::getCaps()->homogeneousDepth);
 
 		m_timeOffset = bx::getHPCounter();
+
+		imguiCreate();
 	}
 
 	virtual int shutdown() BX_OVERRIDE
 	{
+		imguiDestroy();
+
 		meshUnload(m_bunny);
 		meshUnload(m_cube);
 		meshUnload(m_hollowcube);
@@ -239,23 +253,26 @@ class ExampleShadowmapsSimple : public entry::AppI
 
 	bool update() BX_OVERRIDE
 	{
-		while (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
+		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
 		{
+			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)
+				);
+
+			bool restart = showExampleDialog(this);
+
+			imguiEndFrame();
+
 			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 double toMs = 1000.0/freq;
-
 			float time = float( (now-m_timeOffset)/freq);
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/15-shadowmaps-simple");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Shadow maps example (technique: %s).", m_shadowSamplerSupported ? "depth texture and shadow samplers" : "shadow depth packed into color texture");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			// Setup lights.
 			float lightPos[4];
 			lightPos[0] = -bx::fcos(time);
@@ -392,7 +409,7 @@ class ExampleShadowmapsSimple : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -433,5 +450,6 @@ class ExampleShadowmapsSimple : public entry::AppI
 	int64_t m_timeOffset;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleShadowmapsSimple);
+} // namespace
 
+ENTRY_IMPLEMENT_MAIN(ExampleShadowmapsSimple, "15-shadowmaps-simple", "Shadow maps example");

+ 42 - 34
examples/16-shadowmaps/shadowmaps.cpp

@@ -18,6 +18,14 @@
 #include "camera.h"
 #include "imgui/imgui.h"
 
+namespace bgfx
+{
+	int32_t read(bx::ReaderI* _reader, bgfx::VertexDecl& _decl, bx::Error* _err = NULL);
+}
+
+namespace
+{
+
 #define RENDERVIEW_SHADOWMAP_0_ID 1
 #define RENDERVIEW_SHADOWMAP_1_ID 2
 #define RENDERVIEW_SHADOWMAP_2_ID 3
@@ -802,11 +810,6 @@ struct Group
 	PrimitiveArray m_prims;
 };
 
-namespace bgfx
-{
-	int32_t read(bx::ReaderI* _reader, bgfx::VertexDecl& _decl, bx::Error* _err = NULL);
-}
-
 struct Mesh
 {
 	void load(const void* _vertices, uint32_t _numVertices, const bgfx::VertexDecl _decl, const uint16_t* _indices, uint32_t _numIndices)
@@ -1059,12 +1062,12 @@ void screenSpaceQuad(float _textureWidth, float _textureHeight, bool _originBott
 }
 
 void worldSpaceFrustumCorners(float* _corners24f
-		, float _near
-		, float _far
-		, float _projWidth
-		, float _projHeight
-		, const float* __restrict _invViewMtx
-		)
+	, float _near
+	, float _far
+	, float _projWidth
+	, float _projHeight
+	, const float* __restrict _invViewMtx
+	)
 {
 	// Define frustum corners in view space.
 	const float nw = _near * _projWidth;
@@ -1278,15 +1281,19 @@ struct SceneSettings
 	bool m_stabilize;
 };
 
-
-
 class ExampleShadowmaps : public entry::AppI
 {
+public:
+	ExampleShadowmaps(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
-		m_debug = BGFX_DEBUG_TEXT;
+		m_debug = BGFX_DEBUG_NONE;
 		m_reset = BGFX_RESET_VSYNC;
 
 		m_viewState = ViewState(1280, 720);
@@ -1332,10 +1339,10 @@ class ExampleShadowmaps : public entry::AppI
 		// Vertex declarations.
 		bgfx::VertexDecl PosNormalTexcoordDecl;
 		PosNormalTexcoordDecl.begin()
-		.add(bgfx::Attrib::Position,  3, bgfx::AttribType::Float)
-		.add(bgfx::Attrib::Normal,    4, bgfx::AttribType::Uint8, true, true)
-		.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
-		.end();
+			.add(bgfx::Attrib::Position,  3, bgfx::AttribType::Float)
+			.add(bgfx::Attrib::Normal,    4, bgfx::AttribType::Uint8, true, true)
+			.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
+			.end();
 
 		m_posDecl.begin();
 		m_posDecl.add(bgfx::Attrib::Position,  3, bgfx::AttribType::Float);
@@ -1971,6 +1978,8 @@ class ExampleShadowmaps : public entry::AppI
 							, m_viewState.m_height
 							);
 
+			bool restart = showExampleDialog(this);
+
 			ImGui::SetNextWindowPos(ImVec2(float(m_viewState.m_width) - 300.0f - 10.0f, 10.0f) );
 			ImGui::Begin("Settings"
 						 , NULL
@@ -1979,13 +1988,17 @@ class ExampleShadowmaps : public entry::AppI
 						 );
 
 #define IMGUI_FLOAT_SLIDER(_name, _val) \
-ImGui::SliderFloat(_name \
-, &_val \
-, *( ((float*)&_val)+1) \
-, *( ((float*)&_val)+2) \
-)
-#define IMGUI_RADIO_BUTTON(_name, _var, _val) \
-if ( ImGui::RadioButton(_name, _var == _val )) _var = _val;
+	ImGui::SliderFloat(_name            \
+			, &_val                     \
+			, *( ((float*)&_val)+1)     \
+			, *( ((float*)&_val)+2)     \
+			)
+
+#define IMGUI_RADIO_BUTTON(_name, _var, _val)     \
+	if (ImGui::RadioButton(_name, _var == _val) ) \
+	{                                             \
+		_var = _val;                              \
+	}
 
 			ImGui::Checkbox("Update lights", &m_settings.m_updateLights);
 			ImGui::Checkbox("Update scene", &m_settings.m_updateScene);
@@ -2160,15 +2173,8 @@ if ( ImGui::RadioButton(_name, _var == _val )) _var = _val;
 			const int64_t frameTime = now - last;
 			last = now;
 			const double freq = double(bx::getHPFrequency() );
-			const double toMs = 1000.0/freq;
 			const float deltaTime = float(frameTime/freq);
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/16-shadowmaps");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Shadow maps example.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			// Update camera.
 			cameraUpdate(deltaTime, m_mouseState);
 
@@ -3189,7 +3195,7 @@ if ( ImGui::RadioButton(_name, _var == _val )) _var = _val;
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -3234,4 +3240,6 @@ if ( ImGui::RadioButton(_name, _var == _val )) _var = _val;
 	float m_timeAccumulatorScene;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleShadowmaps);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleShadowmaps, "16-shadowmaps", "Shadow maps example.");

+ 16 - 9
examples/17-drawstress/drawstress.cpp

@@ -15,6 +15,9 @@
 #include "vs_drawstress.bin.h"
 #include "fs_drawstress.bin.h"
 
+namespace
+{
+
 static const bgfx::EmbeddedShader s_embeddedShaders[] =
 {
 	BGFX_EMBEDDED_SHADER(vs_drawstress),
@@ -82,13 +85,19 @@ static const int64_t lowwm  = 1000000/57;
 
 class ExampleDrawStress : public entry::AppI
 {
+public:
+	ExampleDrawStress(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_NONE;
 
 		m_autoAdjust = true;
@@ -209,6 +218,8 @@ class ExampleDrawStress : public entry::AppI
 				, uint16_t(m_height)
 				);
 
+			bool restart = showExampleDialog(this);
+
 			ImGui::SetNextWindowPos(ImVec2((float)m_width - (float)m_width / 4.0f - 10.0f, 10.0f) );
 			ImGui::SetNextWindowSize(ImVec2((float)m_width / 4.0f, (float)m_height / 2.0f) );
 			ImGui::Begin("Settings"
@@ -258,12 +269,6 @@ class ExampleDrawStress : public entry::AppI
 			// if no other draw calls are submitted to view 0.
 			bgfx::touch(0);
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/17-drawstress");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Draw stress, maximizing number of draw calls.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: %7.3f[ms]", double(frameTime)*toMs);
-
 			float mtxS[16];
 			const float scale = 0 == m_transform ? 0.25f : 0.0f;
 			bx::mtxScale(mtxS, scale, scale, scale);
@@ -310,7 +315,7 @@ class ExampleDrawStress : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -340,4 +345,6 @@ class ExampleDrawStress : public entry::AppI
 	bgfx::IndexBufferHandle  m_ibh;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleDrawStress);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleDrawStress, "17-drawstress", "Draw stress, maximizing number of draw calls.");

+ 16 - 10
examples/18-ibl/ibl.cpp

@@ -14,6 +14,9 @@
 #include <bx/readerwriter.h>
 #include <bx/string.h>
 
+namespace
+{
+
 static float s_texelHalf = 0.0f;
 
 struct Uniforms
@@ -480,13 +483,19 @@ struct Settings
 
 class ExampleIbl : public entry::AppI
 {
+public:
+	ExampleIbl(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width = 1280;
 		m_height = 720;
-		m_debug = BGFX_DEBUG_TEXT;
+		m_debug = BGFX_DEBUG_NONE;
 		m_reset  = 0
 			| BGFX_RESET_VSYNC
 			| BGFX_RESET_MSAA_X16
@@ -579,6 +588,8 @@ class ExampleIbl : public entry::AppI
 				, uint16_t(m_height)
 				);
 
+			bool restart = showExampleDialog(this);
+
 			ImGui::SetNextWindowPos(ImVec2(m_width - 320.0f - 10.0f, 10.0f) );
 			ImGui::Begin("Settings"
 				, NULL
@@ -759,15 +770,8 @@ class ExampleIbl : public entry::AppI
 			const int64_t frameTime = now - last;
 			last = now;
 			const double freq = double(bx::getHPFrequency() );
-			const double toMs = 1000.0/freq;
 			const float deltaTimeSec = float(double(frameTime)/freq);
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/18-ibl");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Image-based lighting.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			// Camera.
 			const bool mouseOverGui = ImGui::MouseOverArea();
 			m_mouse.update(float(m_mouseState.m_mx), float(m_mouseState.m_my), m_mouseState.m_mz, m_width, m_height);
@@ -883,7 +887,7 @@ class ExampleIbl : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -918,4 +922,6 @@ class ExampleIbl : public entry::AppI
 	Settings m_settings;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleIbl);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleIbl, "18-ibl", "Image-based lighting.");

+ 16 - 13
examples/19-oit/oit.cpp

@@ -7,6 +7,9 @@
 #include "bgfx_utils.h"
 #include "imgui/imgui.h"
 
+namespace
+{
+
 struct PosColorVertex
 {
 	float m_x;
@@ -148,13 +151,19 @@ void screenSpaceQuad(float _textureWidth, float _textureHeight, bool _originBott
 
 class ExampleOIT : public entry::AppI
 {
+public:
+	ExampleOIT(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -278,6 +287,8 @@ class ExampleOIT : public entry::AppI
 				, uint16_t(m_height)
 				);
 
+			bool restart = showExampleDialog(this);
+
 			ImGui::SetNextWindowPos(ImVec2((float)m_width - (float)m_width / 4.0f - 10.0f, 10.0f) );
 			ImGui::SetNextWindowSize(ImVec2((float)m_width / 4.0f, (float)m_height / 3.0f) );
 			ImGui::Begin("Settings"
@@ -307,23 +318,13 @@ class ExampleOIT : public entry::AppI
 			bgfx::setViewRect(1, 0, 0, uint16_t(m_width), uint16_t(m_height) );
 
 			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 double toMs = 1000.0/freq;
-
 			float time = (float)( (now-m_timeOffset)/freq);
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
 			// Reference:
 			// Weighted, Blended Order-Independent Transparency
 			// http://jcgt.org/published/0002/02/09/
 			// http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/19-oit");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Weighted, Blended Order Independent Transparency.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
 
 			float at[3] = { 0.0f, 0.0f, 0.0f };
 			float eye[3] = { 0.0f, 0.0f, -7.0f };
@@ -478,7 +479,7 @@ class ExampleOIT : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -518,4 +519,6 @@ class ExampleOIT : public entry::AppI
 	bgfx::FrameBufferHandle m_fbh;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleOIT);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleOIT, "19-oit", "Weighted, Blended Order Independent Transparency.");

+ 32 - 20
examples/20-nanovg/nanovg.cpp

@@ -41,6 +41,9 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wunused-parameter");
 #include "blendish.h"
 BX_PRAGMA_DIAGNOSTIC_POP();
 
+namespace
+{
+
 #define ICON_SEARCH 0x1F50D
 #define ICON_CIRCLED_CROSS 0x2716
 #define ICON_CHEVRON_RIGHT 0xE75E
@@ -80,7 +83,6 @@ static char* cpToUTF8(int cp, char* str)
 	return str;
 }
 
-
 void drawWindow(struct NVGcontext* vg, const char* title, float x, float y, float w, float h)
 {
 	float cornerRadius = 3.0f;
@@ -1025,13 +1027,6 @@ void freeDemoData(struct NVGcontext* vg, struct DemoData* data)
 		nvgDeleteImage(vg, data->images[i]);
 }
 
-#if defined(_MSC_VER) && (_MSC_VER < 1800)
-inline float round(float _f)
-{
-	return float(int(_f) );
-}
-#endif
-
 void drawParagraph(struct NVGcontext* vg, float x, float y, float width, float height, float mx, float my)
 {
 	struct NVGtextRow rows[3];
@@ -1113,10 +1108,10 @@ void drawParagraph(struct NVGcontext* vg, float x, float y, float width, float h
 		nvgBeginPath(vg);
 		nvgFillColor(vg, nvgRGBA(255,192,0,255) );
 		nvgRoundedRect(vg
-			, bx::fround(bounds[0])-4.0f
-			, bx::fround(bounds[1])-2.0f
-			, bx::fround(bounds[2]-bounds[0])+8.0f
-			, bx::fround(bounds[3]-bounds[1])+4.0f
+			,  bx::fround(bounds[0])-4.0f
+			,  bx::fround(bounds[1])-2.0f
+			,  bx::fround(bounds[2]-bounds[0])+8.0f
+			,  bx::fround(bounds[3]-bounds[1])+4.0f
 			, (bx::fround(bounds[3]-bounds[1])+4.0f)/2.0f-1.0f
 			);
 		nvgFill(vg);
@@ -1240,13 +1235,19 @@ void renderDemo(struct NVGcontext* vg, float mx, float my, float width, float he
 
 class ExampleNanoVG : public entry::AppI
 {
+public:
+	ExampleNanoVG(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -1294,6 +1295,20 @@ class ExampleNanoVG : public entry::AppI
 	{
 		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
 		{
+			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)
+				);
+
+			bool restart = showExampleDialog(this);
+
+			imguiEndFrame();
+
 			int64_t now = bx::getHPCounter();
 			const double freq = double(bx::getHPFrequency() );
 			float time = (float)( (now-m_timeOffset)/freq);
@@ -1305,11 +1320,6 @@ class ExampleNanoVG : public entry::AppI
 			// if no other draw calls are submitted to view 0.
 			bgfx::touch(0);
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/20-nanovg");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: NanoVG is small antialiased vector graphics rendering library.");
-
 			nvgBeginFrame(m_nvg, m_width, m_height, 1.0f);
 
 			renderDemo(m_nvg, float(m_mouseState.m_mx), float(m_mouseState.m_my), float(m_width), float(m_height), time, 0, &m_data);
@@ -1320,7 +1330,7 @@ class ExampleNanoVG : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -1339,4 +1349,6 @@ class ExampleNanoVG : public entry::AppI
 	DemoData m_data;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleNanoVG);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleNanoVG, "20-nanovg", "NanoVG is small antialiased vector graphics rendering library.");

+ 29 - 23
examples/21-deferred/deferred.cpp

@@ -9,6 +9,9 @@
 #include "camera.h"
 #include "bounds.h"
 
+namespace
+{
+
 #define RENDER_PASS_GEOMETRY_ID       0
 #define RENDER_PASS_LIGHT_ID          1
 #define RENDER_PASS_COMBINE_ID        2
@@ -189,13 +192,19 @@ void screenSpaceQuad(float _textureWidth, float _textureHeight, float _texelHalf
 
 class ExampleDeferred : public entry::AppI
 {
+public:
+	ExampleDeferred(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -352,28 +361,33 @@ class ExampleDeferred : public entry::AppI
 	{
 		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
 		{
+			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)
+					);
+
+			bool restart = showExampleDialog(this);
+
 			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 double toMs = 1000.0/freq;
 			const float deltaTime = float(frameTime/freq);
 
 			float time = (float)( (now-m_timeOffset)/freq);
 
-			// Use m_debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/21-deferred");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: MRT rendering and deferred shading.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			if (2 > m_caps->limits.maxFBAttachments)
 			{
 				// When multiple render targets (MRT) is not supported by GPU,
 				// implement alternative code path that doesn't use MRT.
 				bool blink = uint32_t(time*3.0f)&1;
-				bgfx::dbgTextPrintf(0, 5, blink ? 0x1f : 0x01, " MRT not supported by GPU. ");
+				bgfx::dbgTextPrintf(0, 0, blink ? 0x1f : 0x01, " MRT not supported by GPU. ");
 
 				// Set view 0 default viewport.
 				bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) );
@@ -420,16 +434,6 @@ class ExampleDeferred : public entry::AppI
 					m_lightBuffer = bgfx::createFrameBuffer(uint16_t(m_width), uint16_t(m_height), bgfx::TextureFormat::BGRA8, samplerFlags);
 				}
 
-				imguiBeginFrame(m_mouseState.m_mx
-						, m_mouseState.m_my
-						, (m_mouseState.m_buttons[entry::MouseButton::Left  ] ? IMGUI_MBUT_LEFT   : 0)
-						| (m_mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT  : 0)
-						| (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0)
-						, m_mouseState.m_mz
-						, uint16_t(m_width)
-						, uint16_t(m_height)
-						);
-
 				ImGui::SetNextWindowPos(ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f) );
 				ImGui::Begin("Deferred Rendering Settings"
 					, NULL
@@ -445,8 +449,6 @@ class ExampleDeferred : public entry::AppI
 
 				ImGui::End();
 
-				imguiEndFrame();
-
 				// Update camera.
 				cameraUpdate(deltaTime, m_mouseState);
 
@@ -701,11 +703,13 @@ class ExampleDeferred : public entry::AppI
 				}
 			}
 
+			imguiEndFrame();
+
 			// Advance to next frame. Rendering thread will be kicked to
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -759,4 +763,6 @@ class ExampleDeferred : public entry::AppI
 	int64_t m_timeOffset;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleDeferred);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleDeferred, "21-deferred", "MRT rendering and deferred shading.");

+ 40 - 19
examples/22-windows/windows.cpp

@@ -7,6 +7,13 @@
 #include "bgfx_utils.h"
 #include <entry/input.h>
 #include <bx/string.h>
+#include "imgui/imgui.h"
+
+void cmdCreateWindow(const void* _userData);
+void cmdDestroyWindow(const void* _userData);
+
+namespace
+{
 
 #define MAX_WINDOWS 8
 
@@ -59,19 +66,21 @@ static const uint16_t s_cubeIndices[36] =
 	6, 3, 7,
 };
 
-void cmdCreateWindow(const void* _userData);
-void cmdDestroyWindow(const void* _userData);
-
 class ExampleWindows : public entry::AppI
 {
 public:
+	ExampleWindows(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -127,10 +136,14 @@ public:
 		m_timeOffset = bx::getHPCounter();
 
 		bx::memSet(m_fbh, 0xff, sizeof(m_fbh) );
+
+		imguiCreate();
 	}
 
 	virtual int shutdown() BX_OVERRIDE
 	{
+		imguiDestroy();
+
 		for (uint32_t ii = 0; ii < MAX_WINDOWS; ++ii)
 		{
 			if (bgfx::isValid(m_fbh[ii]) )
@@ -157,6 +170,22 @@ public:
 		entry::WindowState state;
 		if (!entry::processWindowEvents(state, m_debug, m_reset) )
 		{
+			m_mouseState = state.m_mouse;
+
+			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)
+				);
+
+			bool restart = showExampleDialog(this);
+
+			imguiEndFrame();
+
 			if (isValid(state.m_handle) )
 			{
 				if (0 == state.m_handle.idx)
@@ -237,20 +266,8 @@ public:
 			}
 
 			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 double toMs = 1000.0/freq;
-
 			float time = (float)( (now-m_timeOffset)/double(bx::getHPFrequency() ) );
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/22-windows");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Rendering into multiple windows.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			if (NULL != m_bindings)
 			{
 				bgfx::dbgTextPrintf(0, 5, 0x2f, "Press 'c' to create or 'd' to destroy window.");
@@ -258,7 +275,7 @@ public:
 			else
 			{
 				bool blink = uint32_t(time*3.0f)&1;
-				bgfx::dbgTextPrintf(0, 5, blink ? 0x1f : 0x01, " Multiple windows is not supported by `%s` renderer. ", bgfx::getRendererName(bgfx::getCaps()->rendererType) );
+				bgfx::dbgTextPrintf(0, 0, blink ? 0x1f : 0x01, " Multiple windows is not supported by `%s` renderer. ", bgfx::getRendererName(bgfx::getCaps()->rendererType) );
 			}
 
 			uint32_t count = 0;
@@ -294,7 +311,7 @@ public:
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -335,6 +352,8 @@ public:
 		}
 	}
 
+	entry::MouseState m_mouseState;
+
 	uint32_t m_width;
 	uint32_t m_height;
 	uint32_t m_debug;
@@ -352,7 +371,9 @@ public:
 	int64_t m_timeOffset;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleWindows);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleWindows, "22-windows", "Rendering into multiple windows.");
 
 void cmdCreateWindow(const void* _userData)
 {

+ 65 - 46
examples/23-vectordisplay/main.cpp

@@ -8,6 +8,10 @@
 #include "bgfx_utils.h"
 
 #include "vectordisplay.h"
+#include "imgui/imgui.h"
+
+namespace
+{
 
 struct PosColorVertex
 {
@@ -32,101 +36,111 @@ bgfx::VertexDecl PosColorVertex::ms_decl;
 
 class ExampleVectorDisplay : public entry::AppI
 {
+public:
+	ExampleVectorDisplay(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 		m_width = 1280;
 		m_height = 720;
-		m_debug = BGFX_DEBUG_TEXT;
+		m_debug = BGFX_DEBUG_NONE;
 		m_reset = BGFX_RESET_VSYNC;
-		
+
 		bgfx::init(args.m_type, args.m_pciId);
 		bgfx::reset(m_width, m_height, m_reset);
-		
+
 		const bgfx::RendererType::Enum renderer = bgfx::getRendererType();
 		float texelHalf = bgfx::RendererType::Direct3D9 == renderer ? 0.5f : 0.0f;
 		bool originBottomLeft = bgfx::RendererType::OpenGL == renderer
 		|| bgfx::RendererType::OpenGLES == renderer;
 		m_vd.init(originBottomLeft, texelHalf);
 		m_vd.setup(uint16_t(m_width), uint16_t(m_height) );
-		
+
 		// Enable debug text.
 		bgfx::setDebug(m_debug);
-		
+
 		// Set view 0 clear state.
 		bgfx::setViewClear(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x303030ff, 1.0f, 0);
-		
+
 		// Create vertex stream declaration.
 		PosColorVertex::init();
-		
-		
+
 		m_oldWidth = m_width;
 		m_oldHeight = m_height;
+
+		imguiCreate();
 	}
 
 	virtual int shutdown() BX_OVERRIDE
 	{
+		imguiDestroy();
+
 		// Cleanup.
 		m_vd.teardown();
-		
+
 		// Shutdown bgfx.
 		bgfx::shutdown();
-		
+
 		return 0;
 	}
-	
+
 	bool update() BX_OVERRIDE
 	{
-		if (!entry::processEvents(m_width, m_height, m_debug, m_reset) )
+		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
 		{
+			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)
+				);
+
+			bool restart = showExampleDialog(this);
+
+			imguiEndFrame();
+
 			if (m_oldWidth  != m_width
-				||  m_oldHeight != m_height)
+			||  m_oldHeight != m_height)
 			{
 				m_oldWidth  = m_width;
 				m_oldHeight = m_height;
 				m_vd.resize(uint16_t(m_width), uint16_t(m_height) );
 			}
-			
-			const float at[3] = { 0.0f, 0.0f, 0.0f };
+
+			const float at[3]  = { 0.0f, 0.0f,   0.0f };
 			const float eye[3] = { 0.0f, 0.0f, -35.0f };
-			
+
 			float view[16];
 			float proj[16];
 			bx::mtxLookAt(view, eye, at);
 			bx::mtxProj(proj, 60.0f, float(m_width) / float(m_height), 0.1f, 100.0f, bgfx::getCaps()->homogeneousDepth);
 			// Set view and projection matrix for view 0.
 			bgfx::setViewTransform(0, view, proj);
-			
+
 			// Set view 0 default viewport.
 			bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) );
-			
+
 			// This dummy draw call is here to make sure that view 0 is cleared
 			// if no other draw calls are submitted to view 0.
 			bgfx::touch(0);
-			
-			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 double toMs = 1000.0 / freq;
-			
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/23-vectordisplay");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Rendering lines as oldschool vectors.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime) * toMs);
-			
+
 			m_vd.beginFrame();
-			
+
 			//simplex test
 			m_vd.setDrawColor(0.7f, 0.7f, 1.0f);
 			m_vd.drawSimplexFont(50.0f,  80.0f, 1.5f, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
 			m_vd.drawSimplexFont(50.0f, 140.0f, 1.5f, "abcdefghijklmnopqrstuvwxyz");
 			m_vd.drawSimplexFont(50.0f, 200.0f, 1.5f, "!@#$%^&*()-=<>/?;:'\"{}[]|\\+=-_");
-			
+
 			m_vd.setDrawColor(1.0f, 0.7f, 0.7f);
-			
+
 			//test pattern for lines
 			for (int ii = 0; ii < 4; ii++)
 			{
@@ -135,7 +149,7 @@ class ExampleVectorDisplay : public entry::AppI
 					m_vd.drawLine(50.0f, 350.0f + 40 * ii, 200.0f, 350.0f + 40 * ii);
 				}
 			}
-			
+
 			for (int ii = 0; ii < 4; ii++)
 			{
 				for (int jj = 0; jj <= ii; jj++)
@@ -143,7 +157,7 @@ class ExampleVectorDisplay : public entry::AppI
 					m_vd.drawLine(50.0f + 40 * ii, 600.0f, 50.0f + 40 * ii, 700.0f);
 				}
 			}
-			
+
 			//
 			// test pattern for shapes
 			//
@@ -152,45 +166,50 @@ class ExampleVectorDisplay : public entry::AppI
 			m_vd.drawCircle(300.0f, 450.0f, 30.0f, 32.0f);
 			m_vd.drawCircle(400.0f, 450.0f, 60.0f, 32.0f);
 			m_vd.drawCircle(500.0f, 450.0f, 80.0f, 64.0f);
-			
+
 			m_vd.setDrawColor(0.7f, 1.0f, 0.7f);
 			m_vd.drawBox(250.0f, 600.0f, 10.0f, 10.0f);
 			m_vd.drawBox(300.0f, 600.0f, 30.0f, 30.0f);
 			m_vd.drawBox(350.0f, 600.0f, 60.0f, 60.0f);
 			m_vd.drawBox(450.0f, 600.0f, 80.0f, 80.0f);
-			
+
 			m_vd.setDrawColor(1.0f, 0.7f, 1.0f);
 			m_vd.drawWheel(bx::kPi, 800.0f, 450.0f, 80.0f);
 			m_vd.drawWheel(3.0f * bx::kPi / 4.0f, 95.0f, 450.0f, 60.0f);
 			m_vd.drawWheel(bx::kPi / 2.0f, 1150.0f, 450.0f, 30.0f);
 			m_vd.drawWheel(bx::kPi / 4.0f, 1250.0f, 450.0f, 10.0f);
-			
+
 			// draw moving shape
 			static float counter = 0.0f;
 			counter += 0.01f;
 			float posX = m_width  / 2.0f + bx::fsin(counter * 3.18378f) * (m_width / 2.0f);
 			float posY = m_height / 2.0f + bx::fcos(counter) * (m_height / 2.0f);
 			m_vd.drawCircle(posX, posY, 5.0f, 10.0f);
-			
+
 			m_vd.endFrame();
-			
+
 			// Advance to next frame. Rendering thread will be kicked to
 			// process submitted rendering primitives.
 			bgfx::frame();
-			
-			return true;
+
+			return !restart;
 		}
+
 		return false;
 	}
 
+	entry::MouseState m_mouseState;
+
 	uint32_t m_width;
 	uint32_t m_height;
 	uint32_t m_debug;
 	uint32_t m_reset;
 	VectorDisplay m_vd;
-	
+
 	uint32_t m_oldWidth;
 	uint32_t m_oldHeight;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleVectorDisplay);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleVectorDisplay, "23-vectordisplay", "Rendering lines as oldschool vectors.");

+ 32 - 28
examples/24-nbody/nbody.cpp

@@ -9,6 +9,9 @@
 #include "camera.h"
 #include <bgfx/bgfx.h>
 
+namespace
+{
+
 static const char* s_shapeNames[] =
 {
 	"Point",
@@ -109,13 +112,19 @@ const uint32_t kMaxParticleCount      = 32 * 1024;
 
 class ExampleNbody : public entry::AppI
 {
+public:
+	ExampleNbody(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -238,6 +247,19 @@ class ExampleNbody : public entry::AppI
 	{
 		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
 		{
+			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)
+				);
+
+			bool restart = showExampleDialog(this);
+
 			const bgfx::Caps* caps = bgfx::getCaps();
 			const bool computeSupported  = !!(caps->supported & BGFX_CAPS_COMPUTE);
 			const bool indirectSupported = !!(caps->supported & BGFX_CAPS_DRAW_INDIRECT);
@@ -255,22 +277,6 @@ class ExampleNbody : public entry::AppI
 
 			if (computeSupported)
 			{
-				// Use debug font to print information about this example.
-				bgfx::dbgTextClear();
-				bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/24-nbody");
-				bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: N-body simulation with compute shaders using buffers.");
-
-				imguiBeginFrame(
-					   m_mouseState.m_mx
-					,  m_mouseState.m_my
-					, (m_mouseState.m_buttons[entry::MouseButton::Left  ] ? IMGUI_MBUT_LEFT   : 0)
-					| (m_mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT  : 0)
-					| (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0)
-					,  m_mouseState.m_mz
-					, uint16_t(m_width)
-					, uint16_t(m_height)
-					);
-
 				ImGui::SetNextWindowPos(ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f) );
 				ImGui::Begin("N-body Settings"
 					, NULL
@@ -317,8 +323,6 @@ class ExampleNbody : public entry::AppI
 
 				ImGui::End();
 
-				imguiEndFrame();
-
 				if (reset)
 				{
 					bgfx::setBuffer(0, m_prevPositionBuffer0, bgfx::Access::Write);
@@ -428,26 +432,26 @@ class ExampleNbody : public entry::AppI
 			{
 				bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) );
 
-				bgfx::dbgTextClear();
-				bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/24-nbody");
-				bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: N-body simulation with compute shaders using buffers.");
-
 				bool blink = uint32_t(time*3.0f)&1;
-				bgfx::dbgTextPrintf(0, 5, blink ? 0x1f : 0x01, " Compute is not supported by GPU. ");
+				bgfx::dbgTextPrintf(0, 0, blink ? 0x1f : 0x01, " Compute is not supported by GPU. ");
 
 				bgfx::touch(0);
 			}
 
+			imguiEndFrame();
+
 			// Advance to next frame. Rendering thread will be kicked to
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
 	}
 
+	entry::MouseState m_mouseState;
+
 	uint32_t m_width;
 	uint32_t m_height;
 	uint32_t m_debug;
@@ -469,9 +473,9 @@ class ExampleNbody : public entry::AppI
 	bgfx::DynamicVertexBufferHandle m_prevPositionBuffer1;
 	bgfx::UniformHandle u_params;
 
-	entry::MouseState m_mouseState;
-
 	int64_t m_timeOffset;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleNbody);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleNbody, "24-nbody", "N-body simulation with compute shaders using buffers.");

+ 46 - 22
examples/26-occlusion/occlusion.cpp

@@ -6,6 +6,10 @@
 #include "common.h"
 #include "bgfx_utils.h"
 #include "camera.h"
+#include "imgui/imgui.h"
+
+namespace
+{
 
 #define CUBES_DIM 10
 
@@ -60,17 +64,23 @@ static const uint16_t s_cubeIndices[36] =
 
 class ExampleOcclusion : public entry::AppI
 {
+public:
+	ExampleOcclusion(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
-		uint32_t width  = 1280;
-		uint32_t height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_width  = 1280;
+		m_height = 720;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
-		bgfx::reset(width, height, m_reset);
+		bgfx::reset(m_width, m_height, m_reset);
 
 		// Enable debug text.
 		bgfx::setDebug(m_debug);
@@ -121,10 +131,14 @@ class ExampleOcclusion : public entry::AppI
 		cameraSetHorizontalAngle(bx::toRad(-45.0f) );
 
 		m_timeOffset = bx::getHPCounter();
+
+		imguiCreate();
 	}
 
 	virtual int shutdown() BX_OVERRIDE
 	{
+		imguiDestroy();
+
 		// Cleanup.
 		cameraDestroy();
 
@@ -145,26 +159,30 @@ class ExampleOcclusion : public entry::AppI
 
 	bool update() BX_OVERRIDE
 	{
-		if (!entry::processWindowEvents(m_state, m_debug, m_reset) )
+		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
 		{
+			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)
+				);
+
+			bool restart = showExampleDialog(this);
+
+			imguiEndFrame();
+
 			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 double toMs = 1000.0/freq;
 			const float time = (float)( (now-m_timeOffset)/double(bx::getHPFrequency() ) );
 			const float deltaTime = float(frameTime/freq);
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/26-occlusion");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Using occlusion query for conditional rendering.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
-			uint32_t width  = m_state.m_width;
-			uint32_t height = m_state.m_height;
-
 			// Update camera.
 			float view[16];
 			cameraUpdate(deltaTime, m_state.m_mouse);
@@ -190,20 +208,20 @@ class ExampleOcclusion : public entry::AppI
 			else
 			{
 				float proj[16];
-				bx::mtxProj(proj, 90.0f, float(width)/float(height), 0.1f, 10000.0f, bgfx::getCaps()->homogeneousDepth);
+				bx::mtxProj(proj, 90.0f, float(m_width)/float(m_height), 0.1f, 10000.0f, bgfx::getCaps()->homogeneousDepth);
 
 				bgfx::setViewTransform(0, view, proj);
-				bgfx::setViewRect(0, 0, 0, uint16_t(width), uint16_t(height) );
+				bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) );
 
 				bgfx::setViewTransform(1, view, proj);
-				bgfx::setViewRect(1, 0, 0, uint16_t(width), uint16_t(height) );
+				bgfx::setViewRect(1, 0, 0, uint16_t(m_width), uint16_t(m_height) );
 
 				float at[3]  = {  0.0f,  0.0f,   0.0f };
 				float eye[3] = { 17.5f, 10.0f, -17.5f };
 				bx::mtxLookAt(view, eye, at);
 
 				bgfx::setViewTransform(2, view, proj);
-				bgfx::setViewRect(2, 10, uint16_t(height - height/4 - 10), uint16_t(width/4), uint16_t(height/4) );
+				bgfx::setViewRect(2, 10, uint16_t(m_height - m_height/4 - 10), uint16_t(m_width/4), uint16_t(m_height/4) );
 			}
 
 			bgfx::touch(0);
@@ -264,14 +282,18 @@ class ExampleOcclusion : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
 	}
 
-	uint32_t m_reset;
+	entry::MouseState m_mouseState;
+
+	uint32_t m_width;
+	uint32_t m_height;
 	uint32_t m_debug;
+	uint32_t m_reset;
 
 	bgfx::VertexBufferHandle m_vbh;
 	bgfx::IndexBufferHandle m_ibh;
@@ -283,4 +305,6 @@ class ExampleOcclusion : public entry::AppI
 	entry::WindowState m_state;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleOcclusion);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleOcclusion, "26-occlusion", "Using occlusion query for conditional rendering.");

+ 16 - 10
examples/27-terrain/terrain.cpp

@@ -12,6 +12,9 @@
 #include <bx/debug.h>
 #include <bx/fpumath.h>
 
+namespace
+{
+
 static const uint16_t s_terrainSize = 256;
 
 struct PosTexCoord0Vertex
@@ -58,13 +61,19 @@ struct BrushData
 
 class ExampleTerrain : public entry::AppI
 {
+public:
+	ExampleTerrain(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -381,15 +390,8 @@ class ExampleTerrain : public entry::AppI
 			const int64_t frameTime = now - last;
 			last = now;
 			const double freq = double(bx::getHPFrequency() );
-			const double toMs = 1000.0/freq;
 			const float deltaTime = float(frameTime/freq);
 
-			// Use m_debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/27-terrain");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Terrain painting example.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			imguiBeginFrame(m_mouseState.m_mx
 				,  m_mouseState.m_my
 				, (m_mouseState.m_buttons[entry::MouseButton::Left  ] ? IMGUI_MBUT_LEFT   : 0)
@@ -400,6 +402,8 @@ class ExampleTerrain : public entry::AppI
 				, uint16_t(m_height)
 				);
 
+			bool restart = showExampleDialog(this);
+
 			ImGui::SetNextWindowPos(ImVec2((float)m_width - (float)m_width / 5.0f - 10.0f, 10.0f) );
 			ImGui::SetNextWindowSize(ImVec2((float)m_width / 5.0f, (float)m_height / 3.0f) );
 			ImGui::Begin("Settings"
@@ -477,7 +481,7 @@ class ExampleTerrain : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -512,4 +516,6 @@ class ExampleTerrain : public entry::AppI
 	int64_t m_timeOffset;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleTerrain);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleTerrain, "27-terrain", "Terrain painting example.");

+ 36 - 31
examples/28-wireframe/wireframe.cpp

@@ -7,6 +7,9 @@
 #include "bgfx_utils.h"
 #include "imgui/imgui.h"
 
+namespace
+{
+
 struct DrawMode
 {
 	enum
@@ -225,27 +228,27 @@ struct MeshMtx
 	}
 
 	void init(const char* _path
-			, float _scale = 1.0f
-			, float _rotX = 0.0f
-			, float _rotY = 0.0f
-			, float _rotZ = 0.0f
-			, float _transX = 0.0f
-			, float _transY = 0.0f
-			, float _transZ = 0.0f
-			)
+		, float _scale = 1.0f
+		, float _rotX = 0.0f
+		, float _rotY = 0.0f
+		, float _rotZ = 0.0f
+		, float _transX = 0.0f
+		, float _transY = 0.0f
+		, float _transZ = 0.0f
+		)
 	{
 		m_mesh = meshLoad(_path);
 		bx::mtxSRT(m_mtx
-					, _scale
-					, _scale
-					, _scale
-					, _rotX
-					, _rotY
-					, _rotZ
-					, _transX
-					, _transY
-					, _transZ
-					);
+			, _scale
+			, _scale
+			, _scale
+			, _rotX
+			, _rotY
+			, _rotZ
+			, _transX
+			, _transY
+			, _transZ
+			);
 	}
 
 	void destroy()
@@ -272,7 +275,7 @@ struct Uniforms
 		m_wfColor[0] = 1.0f;
 		m_wfColor[1] = 0.0f;
 		m_wfColor[2] = 0.0f;
-		m_wfOpacity = 0.7f;
+		m_wfColor[3] = 1.0f;
 		m_drawEdges = 0.0f;
 		m_wfThickness = 1.5f;
 
@@ -294,7 +297,7 @@ struct Uniforms
 		struct
 		{
 			/*0*/struct { float m_camPos[3], m_unused0; };
-			/*1*/struct { float m_wfColor[3], m_wfOpacity; };
+			/*1*/struct { float m_wfColor[4]; };
 			/*2*/struct { float m_drawEdges, m_wfThickness, m_unused2[2]; };
 		};
 
@@ -306,13 +309,19 @@ struct Uniforms
 
 class ExampleWireframe : public entry::AppI
 {
+public:
+	ExampleWireframe(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = 0
 			| BGFX_RESET_VSYNC
 			| BGFX_RESET_MSAA_X16
@@ -396,6 +405,8 @@ class ExampleWireframe : public entry::AppI
 					, uint16_t(m_height)
 					);
 
+			bool restart = showExampleDialog(this);
+
 			ImGui::SetNextWindowPos(ImVec2((float)m_width - (float)m_width / 5.0f - 10.0f, 10.0f) );
 			ImGui::SetNextWindowSize(ImVec2((float)m_width / 5.0f, (float)m_height * 0.75f) );
 			ImGui::Begin("Settings"
@@ -416,7 +427,6 @@ class ExampleWireframe : public entry::AppI
 				ImGui::Separator();
 
 				ImGui::ColorWheel("Color", m_uniforms.m_wfColor, 0.6f);
-				ImGui::SliderFloat("Opacity",   &m_uniforms.m_wfOpacity,   0.1f, 1.0f);
 				ImGui::SliderFloat("Thickness", &m_uniforms.m_wfThickness, 0.6f, 2.2f);
 			}
 
@@ -446,15 +456,8 @@ class ExampleWireframe : public entry::AppI
 			const int64_t frameTime = now - last;
 			last = now;
 			const double freq = double(bx::getHPFrequency() );
-			const double toMs = 1000.0/freq;
 			const float deltaTimeSec = float(double(frameTime)/freq);
 
-			// Use m_debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/28-wirefame");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Drawing wireframe mesh.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			// Setup view.
 			bgfx::setViewRect(0, 0, 0, bgfx::BackbufferRatio::Equal);
 			bgfx::setViewClear(0, BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH, 0x303030ff, 1.0f, 0);
@@ -517,7 +520,7 @@ class ExampleWireframe : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -545,4 +548,6 @@ class ExampleWireframe : public entry::AppI
 	int32_t m_drawMode; // Holds data for 'DrawMode'.
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleWireframe);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleWireframe, "28-wirefame", "Drawing wireframe mesh.");

+ 34 - 11
examples/29-debugdraw/debugdraw.cpp

@@ -9,9 +9,13 @@
 #include <entry/input.h>
 #include <debugdraw/debugdraw.h>
 #include "camera.h"
+#include "imgui/imgui.h"
 
 #include <bx/uint32_t.h>
 
+namespace
+{
+
 void imageCheckerboard(void* _dst, uint32_t _width, uint32_t _height, uint32_t _step, uint32_t _0, uint32_t _1)
 {
 	uint32_t* dst = (uint32_t*)_dst;
@@ -25,15 +29,21 @@ void imageCheckerboard(void* _dst, uint32_t _width, uint32_t _height, uint32_t _
 	}
 }
 
-class DebugDrawApp : public entry::AppI
+class ExampleDebugDraw : public entry::AppI
 {
+public:
+	ExampleDebugDraw(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC | BGFX_RESET_MSAA_X16;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -64,10 +74,14 @@ class DebugDrawApp : public entry::AppI
 		imageCheckerboard(data, 32, 32, 4, 0xff808080, 0xffc0c0c0);
 
 		m_sprite = ddCreateSprite(32, 32, data);
+
+		imguiCreate();
 	}
 
 	virtual int shutdown() BX_OVERRIDE
 	{
+		imguiDestroy();
+
 		ddDestroy(m_sprite);
 
 		ddShutdown();
@@ -84,20 +98,27 @@ class DebugDrawApp : public entry::AppI
 	{
 		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
 		{
+			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)
+				);
+
+			bool restart = showExampleDialog(this);
+
+			imguiEndFrame();
+
 			int64_t now = bx::getHPCounter() - m_timeOffset;
 			static int64_t last = now;
 			const int64_t frameTime = now - last;
 			last = now;
 			const double freq = double(bx::getHPFrequency() );
-			const double toMs = 1000.0/freq;
 			const float deltaTime = float(frameTime/freq);
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/29-debugdraw");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Debug draw.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			// Update camera.
 			cameraUpdate(deltaTime, m_mouseState);
 
@@ -269,7 +290,7 @@ class DebugDrawApp : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -286,4 +307,6 @@ class DebugDrawApp : public entry::AppI
 	uint32_t m_reset;
 };
 
-ENTRY_IMPLEMENT_MAIN(DebugDrawApp);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleDebugDraw, "29-debugdraw", "Debug draw.");

+ 18 - 17
examples/30-picking/picking.cpp

@@ -9,6 +9,9 @@
 #include <bx/rng.h>
 #include <map>
 
+namespace
+{
+
 #define RENDER_PASS_SHADING 0  // Default forward rendered geo with simple shading
 #define RENDER_PASS_ID      1  // ID buffer for picking
 #define RENDER_PASS_BLIT    2  // Blit GPU render target to CPU texture
@@ -17,13 +20,19 @@
 
 class ExamplePicking : public entry::AppI
 {
+public:
+	ExamplePicking(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -177,20 +186,8 @@ class ExamplePicking : public entry::AppI
 		{
 			bgfx::setViewFrameBuffer(RENDER_PASS_ID, m_pickingFB);
 
-			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 double toMs = 1000.0 / freq;
 			float time = (float)( (bx::getHPCounter() - m_timeOffset) / double(bx::getHPFrequency() ) );
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/30-picking");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Mouse picking via GPU texture readback.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			// Set up matrices for basic forward renderer
 			const float camSpeed = 0.25;
 			float cameraSpin = (float)m_cameraSpin;
@@ -368,6 +365,8 @@ class ExamplePicking : public entry::AppI
 				, uint16_t(m_height)
 				);
 
+			bool restart = showExampleDialog(this);
+
 			ImGui::SetNextWindowPos(ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f) );
 			ImGui::Begin("Picking Render Target"
 				, NULL
@@ -387,20 +386,20 @@ class ExamplePicking : public entry::AppI
 			// process submitted rendering primitives.
 			m_currFrame = bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
 	}
 
+	entry::MouseState m_mouseState;
+
 	uint32_t m_width;
 	uint32_t m_height;
 	uint32_t m_debug;
 	uint32_t m_reset;
 	int64_t m_timeOffset;
 
-	entry::MouseState m_mouseState;
-
 	Mesh* m_meshes[12];
 	float m_meshScale[12];
 	float m_idsF[12][4];
@@ -426,4 +425,6 @@ class ExamplePicking : public entry::AppI
 	bool  m_cameraSpin;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExamplePicking);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExamplePicking, "30-picking", "Mouse picking via GPU texture readback.");

+ 68 - 67
examples/31-rsm/reflectiveshadowmap.cpp

@@ -9,6 +9,9 @@
 #include <imgui/imgui.h>
 #include <bx/rng.h>
 
+namespace
+{
+
 /*
  * Intro
  * =====
@@ -183,8 +186,9 @@ void screenSpaceQuad(float _textureWidth, float _textureHeight, float _texelHalf
 class ExampleRSM : public entry::AppI
 {
 public:
-	ExampleRSM()
-		: m_reading(0)
+	ExampleRSM(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+		, m_reading(0)
 		, m_currFrame(UINT32_MAX)
 		, m_cameraSpin(false)
 		, m_lightElevation(35.0f)
@@ -201,7 +205,7 @@ public:
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -219,25 +223,25 @@ public:
 
 		// Set up screen clears
 		bgfx::setViewClear(RENDER_PASS_GBUFFER
-				, BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
-				, 0
-				, 1.0f
-				, 0
-				);
+			, BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
+			, 0
+			, 1.0f
+			, 0
+			);
 
 		bgfx::setViewClear(RENDER_PASS_LIGHT_BUFFER
-				, BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
-				, 0
-				, 1.0f
-				, 0
-				);
+			, BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
+			, 0
+			, 1.0f
+			, 0
+			);
 
 		bgfx::setViewClear(RENDER_PASS_SHADOW_MAP
-				, BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
-				, 0
-				, 1.0f
-				, 0
-				);
+			, BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
+			, 0
+			, 1.0f
+			, 0
+			);
 
 		// Create uniforms
 		u_tint          = bgfx::createUniform("u_tint",          bgfx::UniformType::Vec4);  // Tint for when you click on items
@@ -437,15 +441,8 @@ public:
 			const int64_t frameTime = now - last;
 			last = now;
 			const double freq = double(bx::getHPFrequency());
-			const double toMs = 1000.0 / freq;
 			const float deltaTime = float(frameTime/freq);
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/31-rsm");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Global Illumination with Reflective Shadow Map.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			// Update camera
 			cameraUpdate(deltaTime*0.15f, m_mouseState);
 
@@ -505,10 +502,10 @@ public:
 			bx::mtxInverse(invMvpShadow, lightMtx);
 
 			// Draw some lights (these should really be instanced but for this example they aren't...)
-			const unsigned MAX_SPHERE = 32;
-			for (uint32_t i = 0; i < MAX_SPHERE; i++)
+			const uint32_t kMaxSpheres = 32;
+			for (uint32_t i = 0; i < kMaxSpheres; i++)
 			{
-				for (uint32_t j = 0; j < MAX_SPHERE; j++)
+				for (uint32_t j = 0; j < kMaxSpheres; j++)
 				{
 					// These are used in the fragment shader
 					bgfx::setTexture(0, s_normal, bgfx::getTexture(m_gbuffer, GBUFFER_RT_NORMAL) );  // Normal for lighting calculations
@@ -521,8 +518,8 @@ public:
 					bgfx::setUniform(u_invMvp, invMvp);
 					bgfx::setUniform(u_invMvpShadow, invMvpShadow);
 					float sphereInfo[4];
-					sphereInfo[0] = ((float)i/(MAX_SPHERE-1));
-					sphereInfo[1] = ((float)j/(MAX_SPHERE-1));
+					sphereInfo[0] = ((float)i/(kMaxSpheres-1));
+					sphereInfo[1] = ((float)j/(kMaxSpheres-1));
 					sphereInfo[2] = m_vplRadius;
 					sphereInfo[3] = 0.0;  // Unused
 					bgfx::setUniform(u_sphereInfo, sphereInfo);
@@ -535,12 +532,12 @@ public:
 						;
 
 					meshSubmit(
-							m_lightSphere,
-							RENDER_PASS_LIGHT_BUFFER,
-							m_lightProgram,
-							NULL,
-							lightDrawState
-							);
+						  m_lightSphere
+						, RENDER_PASS_LIGHT_BUFFER
+						, m_lightProgram
+						, NULL
+						, lightDrawState
+						);
 				}
 			}
 
@@ -568,9 +565,9 @@ public:
 			// Set up state for combine pass
 			// point of this is to avoid doing depth test, which is in the default state
 			bgfx::setState(0
-					| BGFX_STATE_RGB_WRITE
-					| BGFX_STATE_ALPHA_WRITE
-					);
+				| BGFX_STATE_RGB_WRITE
+				| BGFX_STATE_ALPHA_WRITE
+				);
 
 			// Set up transform matrix for fullscreen quad
 			float orthoProj[16];
@@ -583,14 +580,16 @@ public:
 
 			// Draw UI
 			imguiBeginFrame(m_mouseState.m_mx
-					, m_mouseState.m_my
-					, (m_mouseState.m_buttons[entry::MouseButton::Left] ? IMGUI_MBUT_LEFT : 0)
-					| (m_mouseState.m_buttons[entry::MouseButton::Right] ? IMGUI_MBUT_RIGHT : 0)
-					| (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0)
-					, m_mouseState.m_mz
-					, uint16_t(m_width)
-					, uint16_t(m_height)
-					);
+				,  m_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)
+				);
+
+			bool restart = showExampleDialog(this);
 
 			ImGui::Begin("Reflective Shadow Map"
 				, NULL
@@ -613,7 +612,7 @@ public:
 			// process submitted rendering primitives.
 			m_currFrame = bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -629,16 +628,16 @@ public:
 			float scale = s_meshScale[model.mesh];
 			float mtx[16];
 			bx::mtxSRT(mtx
-					, scale
-					, scale
-					, scale
-					, 0.0f
-					, 0.0f
-					, 0.0f
-					, model.position[0]
-					, model.position[1]
-					, model.position[2]
-					);
+				, scale
+				, scale
+				, scale
+				, 0.0f
+				, 0.0f
+				, 0.0f
+				, model.position[0]
+				, model.position[1]
+				, model.position[2]
+				);
 
 			// Submit mesh to gbuffer
 			bgfx::setUniform(u_tint, model.color);
@@ -651,16 +650,16 @@ public:
 		float mtxScale[16];
 		float scale = 10.0;
 		bx::mtxScale(mtxScale
-				, scale
-				, scale
-				, scale
-				);
+			, scale
+			, scale
+			, scale
+			);
 		float mtxTrans[16];
 		bx::mtxTranslate(mtxTrans
-				, 0.0f
-				, -10.0f
-				, 0.0f
-				);
+			, 0.0f
+			, -10.0f
+			, 0.0f
+			);
 		float mtx[16];
 		bx::mtxMul(mtx, mtxScale, mtxTrans);
 		meshSubmit(m_ground, _pass, _program, mtx);
@@ -747,4 +746,6 @@ public:
 	float m_texelHalf;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExampleRSM);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleRSM, "31-rsm", "Global Illumination with Reflective Shadow Map.");

+ 17 - 11
examples/32-particles/particles.cpp

@@ -17,6 +17,9 @@
 
 #include <ps/particle_system.h>
 
+namespace
+{
+
 static const char* s_shapeNames[] =
 {
 	"Sphere",
@@ -224,15 +227,21 @@ struct Emitter
 	}
 };
 
-class Particles : public entry::AppI
+class ExampleParticles : public entry::AppI
 {
+public:
+	ExampleParticles(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -318,15 +327,8 @@ class Particles : public entry::AppI
 			const int64_t frameTime = now - last;
 			last = now;
 			const double freq = double(bx::getHPFrequency() );
-			const double toMs = 1000.0/freq;
 			const float deltaTime = float(frameTime/freq);
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/32-particles");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Particles.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			cameraUpdate(deltaTime, m_mouseState);
 
 			float view[16];
@@ -363,6 +365,8 @@ class Particles : public entry::AppI
 				, uint16_t(m_height)
 				);
 
+			bool restart = showExampleDialog(this);
+
 			ImGui::Begin("Properties"
 				, NULL
 				, ImVec2(400.0f, 600.0f)
@@ -426,7 +430,7 @@ class Particles : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -444,4 +448,6 @@ class Particles : public entry::AppI
 	Emitter m_emitter[4];
 };
 
-ENTRY_IMPLEMENT_MAIN(Particles);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleParticles, "32-particles", "Particles.");

+ 16 - 13
examples/33-pom/pom.cpp

@@ -8,6 +8,9 @@
 
 #include <imgui/imgui.h>
 
+namespace
+{
+
 struct PosTangentBitangentTexcoordVertex
 {
 	float m_x;
@@ -107,13 +110,19 @@ static const uint16_t s_cubeIndices[36] =
 
 class ExamplePom : public entry::AppI
 {
+public:
+	ExamplePom(const char* _name, const char* _description)
+		: entry::AppI(_name, _description)
+	{
+	}
+
 	void init(int _argc, char** _argv) BX_OVERRIDE
 	{
 		Args args(_argc, _argv);
 
 		m_width  = 1280;
 		m_height = 720;
-		m_debug  = BGFX_DEBUG_TEXT;
+		m_debug  = BGFX_DEBUG_NONE;
 		m_reset  = BGFX_RESET_VSYNC;
 
 		bgfx::init(args.m_type, args.m_pciId);
@@ -207,20 +216,10 @@ class ExamplePom : public entry::AppI
 			bgfx::touch(0);
 
 			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 double toMs = 1000.0/freq;
 
 			float time = (float)( (now-m_timeOffset)/freq);
 
-			// Use debug font to print information about this example.
-			bgfx::dbgTextClear();
-			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/33-pom");
-			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Parallax mapping.");
-			bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
 			float at[3]  = { 0.0f, 0.0f, 1.0f };
 			float eye[3] = { 0.0f, 0.0f, 0.0f };
 
@@ -262,6 +261,8 @@ class ExamplePom : public entry::AppI
 				, uint16_t(m_height)
 				);
 
+			bool restart = showExampleDialog(this);
+
 			ImGui::SetNextWindowPos(ImVec2(m_width - 240.0f, 20.0f));
 			ImGui::Begin("Properties");
 
@@ -348,7 +349,7 @@ class ExamplePom : public entry::AppI
 			// process submitted rendering primitives.
 			bgfx::frame();
 
-			return true;
+			return !restart;
 		}
 
 		return false;
@@ -381,4 +382,6 @@ class ExamplePom : public entry::AppI
 	int32_t m_num_steps;
 };
 
-ENTRY_IMPLEMENT_MAIN(ExamplePom);
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExamplePom, "33-pom", "Parallax mapping.");

+ 112 - 7
examples/common/entry/entry.cpp

@@ -7,6 +7,7 @@
 #include <bgfx/bgfx.h>
 #include <bx/string.h>
 #include <bx/crtimpl.h>
+#include <bx/sort.h>
 
 #include <time.h>
 
@@ -378,24 +379,50 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 	}
 #endif // BX_PLATFORM_EMSCRIPTEN
 
-	static App* s_apps = NULL;
+	static AppI*    s_apps    = NULL;
+	static uint32_t s_numApps = 0;
+	static char     s_restartArgs[1024] = { '\0' };
 
-	App::App(const char* _name)
+	AppI::AppI(const char* _name, const char* _description)
 	{
-		m_name = _name;
-		m_next = s_apps;
+		m_name        = _name;
+		m_description = _description;
+		m_next        = s_apps;
+
 		s_apps = this;
+		s_numApps++;
+	}
+
+	const char* AppI::getName() const
+	{
+		return m_name;
+	}
+
+	const char* AppI::getDescription() const
+	{
+		return m_description;
 	}
 
-	App::~App()
+	AppI* AppI::getNext()
 	{
+		return m_next;
 	}
 
-	App* getFirstApp()
+	AppI* getFirstApp()
 	{
 		return s_apps;
 	}
 
+	uint32_t getNumApps()
+	{
+		return s_numApps;
+	}
+
+	void setRestartArgs(const char* _args)
+	{
+		bx::strCopy(s_restartArgs, BX_COUNTOF(s_restartArgs), _args);
+	}
+
 	int runApp(AppI* _app, int _argc, char** _argv)
 	{
 		_app->init(_argc, _argv);
@@ -414,6 +441,41 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 		return _app->shutdown();
 	}
 
+	static int32_t sortApp(const void* _lhs, const void* _rhs)
+	{
+		const AppI* lhs = *(const AppI**)_lhs;
+		const AppI* rhs = *(const AppI**)_rhs;
+
+		return bx::strCmpI(lhs->getName(), rhs->getName() );
+	}
+
+	static void sortApps()
+	{
+		if (2 > s_numApps)
+		{
+			return;
+		}
+
+		AppI** apps = (AppI**)BX_ALLOC(g_allocator, s_numApps*sizeof(AppI*) );
+
+		uint32_t ii = 0;
+		for (AppI* app = getFirstApp(); NULL != app; app = app->getNext() )
+		{
+			apps[ii++] = app;
+		}
+		bx::quickSort(apps, s_numApps, sizeof(AppI*), sortApp);
+
+		s_apps = apps[0];
+		for (ii = 1; ii < s_numApps; ++ii)
+		{
+			AppI* app = apps[ii-1];
+			app->m_next = apps[ii];
+		}
+		apps[s_numApps-1]->m_next = NULL;
+
+		BX_FREE(g_allocator, apps);
+	}
+
 	int main(int _argc, char** _argv)
 	{
 		//DBG(BX_COMPILER_NAME " / " BX_CPU_NAME " / " BX_ARCH_NAME " / " BX_PLATFORM_NAME);
@@ -456,7 +518,50 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 		entry::setWindowTitle(defaultWindow, bx::baseName(_argv[0]) );
 		setWindowSize(defaultWindow, ENTRY_DEFAULT_WIDTH, ENTRY_DEFAULT_HEIGHT);
 
-		int32_t result = ::_main_(_argc, _argv);
+		sortApps();
+
+		const char* find = "";
+		if (1 < _argc)
+		{
+			find = _argv[_argc-1];
+		}
+
+restart:
+		AppI* selected = NULL;
+
+		for (AppI* app = getFirstApp(); NULL != app; app = app->getNext() )
+		{
+			if (NULL == selected
+			&&  bx::strFindI(app->getName(), find) )
+			{
+				selected = app;
+			}
+#if 0
+			DBG("%c %s, %s"
+				, app == selected ? '>' : ' '
+				, app->getName()
+				, app->getDescription()
+				);
+#endif // 0
+		}
+
+		int32_t result = bx::kExitSuccess;
+		s_restartArgs[0] = '\0';
+		if (0 == s_numApps)
+		{
+			result = ::_main_(_argc, _argv);
+		}
+		else
+		{
+			result = runApp(NULL == selected ? getFirstApp() : selected, _argc, _argv);
+		}
+
+		if (0 != bx::strLen(s_restartArgs) )
+		{
+			find = s_restartArgs;
+			goto restart;
+		}
+
 		setCurrentDir("");
 
 		inputRemoveBindings("bindings");

+ 46 - 27
examples/common/entry/entry.h

@@ -18,12 +18,21 @@ extern "C" int _main_(int _argc, char** _argv);
 #define ENTRY_WINDOW_FLAG_ASPECT_RATIO UINT32_C(0x00000001)
 #define ENTRY_WINDOW_FLAG_FRAME        UINT32_C(0x00000002)
 
-#define ENTRY_IMPLEMENT_MAIN(_app)                        \
-			int _main_(int _argc, char** _argv)           \
-			{                                             \
-				_app app;                                 \
-				return entry::runApp(&app, _argc, _argv); \
-			}
+#ifndef ENTRY_CONFIG_IMPLEMENT_MAIN
+#	define ENTRY_CONFIG_IMPLEMENT_MAIN 0
+#endif // ENTRY_CONFIG_IMPLEMENT_MAIN
+
+#if ENTRY_CONFIG_IMPLEMENT_MAIN
+#define ENTRY_IMPLEMENT_MAIN(_app, _name, _description) \
+	int _main_(int _argc, char** _argv)                 \
+	{                                                   \
+			_app app(_name, _description);              \
+			return entry::runApp(&app, _argc, _argv);   \
+	}
+#else
+#define ENTRY_IMPLEMENT_MAIN(_app, _name, _description) \
+	_app s_ ## _app ## App(_name, _description)
+#endif // ENTRY_CONFIG_IMPLEMENT_MAIN
 
 namespace entry
 {
@@ -267,42 +276,52 @@ namespace entry
 
 	bool processWindowEvents(WindowState& _state, uint32_t& _debug, uint32_t& _reset);
 
-	struct BX_NO_VTABLE AppI
+	class BX_NO_VTABLE AppI
 	{
+	public:
+		///
+		AppI(const char* _name, const char* _description);
+
+		///
 		virtual ~AppI() = 0;
+
+		///
 		virtual void init(int _argc, char** _argv) = 0;
+
+		///
 		virtual int  shutdown() = 0;
-		virtual bool update() = 0;
-	};
 
-	inline AppI::~AppI()
-	{
-	}
+		///
+		virtual bool update() = 0;
 
-	class App : public AppI
-	{
-	public:
-		App(const char* _name);
+		///
+		const char* getName() const;
 
-		virtual ~App();
+		///
+		const char* getDescription() const;
 
-		const char* getName() const
-		{
-			return m_name;
-		}
+		///
+		AppI* getNext();
 
-		AppI* getNext()
-		{
-			return m_next;
-		}
+		AppI* m_next;
 
 	private:
 		const char* m_name;
-		App* m_next;
+		const char* m_description;
 	};
 
+	inline AppI::~AppI()
+	{
+	}
+
+	///
+	AppI* getFirstApp();
+
+	///
+	uint32_t getNumApps();
+
 	///
-	App* getFirstApp();
+	void setRestartArgs(const char* _args);
 
 	///
 	int runApp(AppI* _app, int _argc, char** _argv);

+ 96 - 33
examples/common/imgui/imgui.cpp

@@ -34,6 +34,7 @@
 #include "ocornut_imgui.h"
 #include "../bgfx_utils.h"
 #include "../nanovg/nanovg.h"
+#include "../entry/entry.h"
 
 #include <bgfx/embedded_shader.h>
 
@@ -72,8 +73,6 @@ static const bgfx::EmbeddedShader s_embeddedShaders[] =
 
 BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4244); // warning C4244: '=' : conversion from '' to '', possible loss of data
 
-#define USE_NANOVG_FONT 0
-
 #define IMGUI_CONFIG_MAX_FONTS 20
 
 #define MAX_TEMP_COORDS 100
@@ -422,7 +421,6 @@ namespace
 
 } // namespace
 
-#if !USE_NANOVG_FONT
 static float getTextLength(stbtt_bakedchar* _chardata, const char* _text, uint32_t& _numVertices)
 {
 	float xpos = 0;
@@ -460,7 +458,6 @@ static float getTextLength(stbtt_bakedchar* _chardata, const char* _text, uint32
 
 	return len;
 }
-#endif // !USE_NANOVG_FONT
 
 struct Imgui
 {
@@ -515,7 +512,6 @@ struct Imgui
 
 	ImguiFontHandle createFont(const void* _data, float _fontSize)
 	{
-#if !USE_NANOVG_FONT
 		const ImguiFontHandle handle = { m_fontHandle.alloc() };
 		const bgfx::Memory* mem = bgfx::alloc(m_textureWidth * m_textureHeight);
 		stbtt_BakeFontBitmap( (uint8_t*)_data, 0, _fontSize, mem->data, m_textureWidth, m_textureHeight, 32, 96, m_fonts[handle.idx].m_cdata);
@@ -529,9 +525,6 @@ struct Imgui
 			, mem
 			);
 		m_fonts[handle.idx].m_size = _fontSize;
-#else
-		const ImguiFontHandle handle = { bgfx::kInvalidHandle };
-#endif // !USE_NANOVG_FONT
 		return handle;
 	}
 
@@ -650,12 +643,8 @@ struct Imgui
 
 		m_missingTexture = genMissingTexture(256, 256, 0.04f);
 
-#if !USE_NANOVG_FONT
 		const ImguiFontHandle handle = createFont(s_robotoRegularTtf, _fontSize);
 		m_currentFontIdx = handle.idx;
-#else
-		const ImguiFontHandle handle = { bgfx::kInvalidHandle };
-#endif // !USE_NANOVG_FONT
 		return handle;
 	}
 
@@ -664,14 +653,12 @@ struct Imgui
 		bgfx::destroyUniform(u_imageLodEnabled);
 		bgfx::destroyUniform(u_imageSwizzle);
 		bgfx::destroyUniform(s_texColor);
-#if !USE_NANOVG_FONT
 		for (uint16_t ii = 0, num = m_fontHandle.getNumHandles(); ii < num; ++ii)
 		{
 			uint16_t idx = m_fontHandle.getHandleAt(0);
 			bgfx::destroyTexture(m_fonts[idx].m_texture);
 			m_fontHandle.free(idx);
 		}
-#endif // !USE_NANOVG_FONT
 		bgfx::destroyTexture(m_missingTexture);
 		bgfx::destroyProgram(m_colorProgram);
 		bgfx::destroyProgram(m_textureProgram);
@@ -2649,7 +2636,6 @@ struct Imgui
 		}
 	}
 
-#if !USE_NANOVG_FONT
 	void getBakedQuad(stbtt_bakedchar* _chardata, int32_t char_index, float* _xpos, float* _ypos, stbtt_aligned_quad* _quad)
 	{
 		stbtt_bakedchar* b = _chardata + char_index;
@@ -2668,7 +2654,6 @@ struct Imgui
 
 		*_xpos += b->xadvance;
 	}
-#endif // !USE_NANOVG_FONT
 
 	void drawText(int32_t _x, int32_t _y, ImguiTextAlign::Enum _align, const char* _text, uint32_t _abgr)
 	{
@@ -2683,20 +2668,6 @@ struct Imgui
 			return;
 		}
 
-#if USE_NANOVG_FONT
-		static uint32_t textAlign[ImguiTextAlign::Count] =
-		{
-			NVG_ALIGN_LEFT,
-			NVG_ALIGN_CENTER,
-			NVG_ALIGN_RIGHT,
-		};
-
-		nvgTextAlign(m_nvg, textAlign[_align]);
-
-		nvgFontBlur(m_nvg, 0.0f);
-		nvgFillColor(m_nvg, nvgRGBAu(_abgr) );
-		nvgText(m_nvg, _x, _y, _text, NULL);
-#else
 		uint32_t numVertices = 0;
 		if (_align == ImguiTextAlign::Center)
 		{
@@ -2796,7 +2767,6 @@ struct Imgui
 			setCurrentScissor();
 			bgfx::submit(m_view, m_textureProgram);
 		}
-#endif // USE_NANOVG_FONT
 	}
 
 	bool screenQuad(int32_t _x, int32_t _y, int32_t _width, uint32_t _height, bool _originBottomLeft = false)
@@ -3274,7 +3244,6 @@ struct Imgui
 	uint16_t m_viewWidth;
 	uint16_t m_viewHeight;
 
-#if !USE_NANOVG_FONT
 	struct Font
 	{
 		stbtt_bakedchar m_cdata[96]; // ASCII 32..126 is 95 glyphs
@@ -3285,7 +3254,6 @@ struct Imgui
 	uint16_t m_currentFontIdx;
 	bx::HandleAllocT<IMGUI_CONFIG_MAX_FONTS> m_fontHandle;
 	Font m_fonts[IMGUI_CONFIG_MAX_FONTS];
-#endif // !USE_NANOVG_FONT
 
 	bgfx::UniformHandle u_imageLodEnabled;
 	bgfx::UniformHandle u_imageSwizzle;
@@ -3342,3 +3310,98 @@ bgfx::ProgramHandle imguiGetImageProgram(uint8_t _mip)
 	bgfx::setUniform(s_imgui.u_imageLodEnabled, lodEnabled);
 	return s_imgui.m_imageProgram;
 }
+
+static const char* s_rendererNames[] =
+{
+	"Noop",
+	"Direct3D9",
+	"Direct3D11",
+	"Direct3D12",
+	"Gnm",
+	"Metal",
+	"OpenGLES",
+	"OpenGL",
+	"Vulkan",
+};
+BX_STATIC_ASSERT(bgfx::RendererType::Count == BX_COUNTOF(s_rendererNames) );
+
+bool showExampleDialog(entry::AppI* _app)
+{
+	bool restart = false;
+
+	char temp[1024];
+	bx::snprintf(temp, BX_COUNTOF(temp), "Example: %s", _app->getName() );
+
+	ImGui::Begin(temp
+		, NULL
+		, ImVec2(256.0f, 200.0f)
+		, ImGuiWindowFlags_AlwaysAutoResize
+		);
+
+	ImGui::TextWrapped("%s", _app->getDescription() );
+	ImGui::Separator();
+
+	{
+		uint32_t num = entry::getNumApps();
+		const char** items = (const char**)alloca(num*sizeof(void*) );
+
+		uint32_t ii = 0;
+		int32_t current = 0;
+		for (entry::AppI* app = entry::getFirstApp(); NULL != app; app = app->getNext() )
+		{
+			if (app == _app)
+			{
+				current = ii;
+			}
+
+			items[ii++] = app->getName();
+		}
+
+		if (1 < num
+		&&  ImGui::Combo("Example", &current, items, num) )
+		{
+			entry::setRestartArgs(items[current]);
+			restart = true;
+		}
+	}
+
+#if 0
+	{
+		bgfx::RendererType::Enum supportedRenderers[bgfx::RendererType::Count];
+		uint8_t num = bgfx::getSupportedRenderers(BX_COUNTOF(supportedRenderers), supportedRenderers);
+
+		const bgfx::Caps* caps = bgfx::getCaps();
+
+		const char* items[bgfx::RendererType::Count];
+
+		int32_t current = 0;
+		for (uint8_t ii = 0; ii < num; ++ii)
+		{
+			items[ii] = s_rendererNames[supportedRenderers[ii] ];
+			if (supportedRenderers[ii] == caps->rendererType)
+			{
+				current = ii;
+			}
+		}
+
+		if (ImGui::Combo("Renderer", &current, items, num) )
+		{
+			restart = true;
+		}
+	}
+#endif // 0
+
+	const bgfx::Stats* stats = bgfx::getStats();
+	ImGui::Text("CPU %0.3f"
+		, double(stats->cpuTimeEnd-stats->cpuTimeBegin)/stats->cpuTimerFreq*1000.0
+		);
+
+	ImGui::Text("GPU %0.3f (latency: %d)"
+		, double(stats->gpuTimeEnd-stats->gpuTimeBegin)/stats->gpuTimerFreq*1000.0
+		, stats->maxGpuLatency
+		);
+
+	ImGui::End();
+
+	return restart;
+}

+ 3 - 0
examples/common/imgui/imgui.h

@@ -54,6 +54,9 @@ void imguiBeginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll,
 void imguiBeginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, uint16_t _width, uint16_t _height, uint16_t _surfaceWidth, uint16_t _surfaceHeight, char _inputChar = 0, uint8_t _view = 255);
 void imguiEndFrame();
 
+namespace entry { class AppI; }
+bool showExampleDialog(entry::AppI* _app);
+
 namespace ImGui
 {
 #define IMGUI_FLAGS_NONE        UINT8_C(0x00)

+ 8 - 0
scripts/genie.lua

@@ -370,6 +370,10 @@ function exampleProject(_combined, ...)
 
 		end
 
+		files {
+			path.join(BGFX_DIR, "examples/25-c99/helloworld.c"), -- hack for _main_
+		}
+
 		exampleProjectDefaults()
 
 	else
@@ -389,6 +393,10 @@ function exampleProject(_combined, ...)
 				path.join(BGFX_DIR, "examples", name, "**.bin.h"),
 			}
 
+			defines {
+				"ENTRY_CONFIG_IMPLEMENT_MAIN=1",
+			}
+
 			exampleProjectDefaults()
 		end
 	end