Browse Source

Added fatal error codes and callback. Fixed shutdown. Added helloworld example.

bkaradzic 13 years ago
parent
commit
911ce4d775
6 changed files with 209 additions and 39 deletions
  1. 29 0
      examples/helloworld/helloworld.cpp
  2. 11 1
      include/bgfx.h
  3. 37 4
      src/bgfx.cpp
  4. 103 27
      src/bgfx_p.h
  5. 24 7
      src/renderer_d3d9.cpp
  6. 5 0
      src/renderer_gl.cpp

+ 29 - 0
examples/helloworld/helloworld.cpp

@@ -0,0 +1,29 @@
+/*
+ * Copyright 2011-2012 Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#include <bgfx.h>
+#include <conio.h>
+
+int main(int _argc, const char** _argv)
+{
+	bgfx::init(true);
+	bgfx::reset(1280, 720);
+
+	bgfx::setDebug(BGFX_DEBUG_TEXT);
+
+	while (!_kbhit() )
+	{
+		bgfx::dbgTextClear();
+		bgfx::dbgTextPrintf(0, 0, 0x4f, "Hello world!");
+
+		bgfx::dbgTextPrintf(0, 5, 0x6f, "BGFX initialization and debug text.");
+
+		bgfx::frame();
+	}
+
+	bgfx::shutdown();
+
+	return 0;
+}

+ 11 - 1
include/bgfx.h

@@ -133,6 +133,15 @@ namespace bgfx
 
 #define BGFX_INVALID_HANDLE { bgfx::invalidHandle }
 
+	struct Fatal
+	{
+		enum Enum
+		{
+			D3D9_UnableToCreateInterface = 1,
+			D3D9_UnableToCreateDevice
+		};
+	};
+
 	struct Attrib
 	{
 		enum Enum
@@ -224,6 +233,7 @@ namespace bgfx
 		};
 	};
 
+	typedef void (*fatalFn)(Fatal::Enum _code, const char* _str);
 	typedef void* (*reallocFn)(void* _ptr, size_t _size);
 	typedef void (*freeFn)(void* _ptr);
 
@@ -241,7 +251,7 @@ namespace bgfx
 	};
 
 	///
-	void init(bool _createRenderThread = true, reallocFn _realloc = NULL, freeFn _free = NULL);
+	void init(bool _createRenderThread = true, fatalFn _fatal = NULL, reallocFn _realloc = NULL, freeFn _free = NULL);
 
 	///
 	void shutdown();

+ 37 - 4
src/bgfx.cpp

@@ -5,6 +5,11 @@
 
 #include "bgfx_p.h"
 
+BX_NO_INLINE void bgfxFatalStub(bgfx::Fatal::Enum _code, const char* _str)
+{
+	BX_TRACE("0x%08x: %s", _code, _str);
+}
+
 BX_NO_INLINE void* bgfxReallocStub(void* _ptr, size_t _size)
 {
 	void* ptr = ::realloc(_ptr, _size);
@@ -15,10 +20,14 @@ BX_NO_INLINE void* bgfxReallocStub(void* _ptr, size_t _size)
 
 BX_NO_INLINE void bgfxFreeStub(void* _ptr)
 {
-// 	BX_TRACE("free %p", _ptr);
+//	BX_TRACE("free %p", _ptr);
 	::free(_ptr);
 }
 
+#if BX_PLATFORM_WINDOWS
+HWND g_bgfxHwnd = NULL;
+#endif // BX_PLATFORM_WINDOWS
+
 namespace bgfx
 {
 #define BGFX_MAIN_THREAD_MAGIC 0x78666762
@@ -31,6 +40,7 @@ namespace bgfx
 #	define BGFX_RENDER_THREAD()
 #endif // BGFX_CONFIG_MULTITHREADED
 
+	fatalFn g_fatal = bgfxFatalStub;
 	reallocFn g_realloc = bgfxReallocStub;
 	freeFn g_free = bgfxFreeStub;
 
@@ -285,7 +295,7 @@ namespace bgfx
 
 		setup();
 
-		for (;xx < _mem.m_width && yy < _mem.m_height;)
+		for (;yy < _mem.m_height;)
 		{
 			FontVertex* vertex = (FontVertex*)m_vb->data;
 			uint16_t* indices = (uint16_t*)m_ib->data;
@@ -444,8 +454,13 @@ namespace bgfx
 		radixSort(m_sortKeys, s_ctx.m_tempKeys, m_sortValues, s_ctx.m_tempValues, m_num);
 	}
 
-	void init(bool _createRenderThread, reallocFn _realloc, freeFn _free)
+	void init(bool _createRenderThread, fatalFn _fatal, reallocFn _realloc, freeFn _free)
 	{
+		if (NULL != _fatal)
+		{
+			g_fatal = _fatal;
+		}
+
 		if (NULL != _realloc
 		&&  NULL != _free)
 		{
@@ -609,15 +624,20 @@ namespace bgfx
 	{
 		BX_TRACE("init");
 
+		m_submit->create();
+		m_render->create();
+
 #if BX_PLATFORM_WINDOWS
 		m_window.init();
 #endif // BX_PLATFORM_WINDOWS
 
 #if BGFX_CONFIG_MULTITHREADED
+		m_renderThread = NULL;
+
 		if (_createRenderThread)
 		{
 #	if BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360
-			CreateThread(NULL, 16<<10, renderThread, NULL, 0, NULL);
+			m_renderThread = CreateThread(NULL, 16<<10, renderThread, NULL, 0, NULL);
 #	endif // BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360
 		}
 #endif // BGFX_CONFIG_MULTITHREADED
@@ -650,6 +670,19 @@ namespace bgfx
 		getCommandBuffer(CommandBuffer::RendererShutdown);
 		frame();
 		m_initialized = false;
+
+#if BGFX_CONFIG_MULTITHREADED
+		if (NULL != m_renderThread)
+		{
+#	if BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360
+			WaitForSingleObject(m_renderThread, INFINITE);
+			m_renderThread = NULL;
+#	endif // BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360
+		}
+#endif // BGFX_CONFIG_MULTITHREADED
+
+		m_submit->destroy();
+		m_render->destroy();
 	}
 
 	const Memory* alloc(uint32_t _size)

+ 103 - 27
src/bgfx_p.h

@@ -12,7 +12,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <alloca.h>
 
 extern void dbgPrintf(const char* _format, ...);
 extern void dbgPrintfData(const void* _data, uint32_t _size, const char* _format, ...);
@@ -35,6 +34,14 @@ extern void dbgPrintfData(const void* _data, uint32_t _size, const char* _format
 				} while(0)
 #endif // 0
 
+#define BGFX_FATAL(_condition, _err, _str) \
+			do { \
+				if (!(_condition) ) \
+				{ \
+					g_fatal(_err, _str); \
+				} \
+			} while(0)
+
 #define BX_NAMESPACE 1
 #include <bx/bx.h>
 #include <bx/countof.h>
@@ -47,18 +54,18 @@ extern void dbgPrintfData(const void* _data, uint32_t _size, const char* _format
 
 #if BX_PLATFORM_WINDOWS
 #	include <windows.h>
-extern HWND bgfxHwnd;
+extern HWND g_bgfxHwnd;
 #elif BX_PLATFORM_XBOX360
 #	include <xtl.h>
 #endif // BX_PLATFORM_WINDOWS
 
 #ifndef MAKEFOURCC
 #	define MAKEFOURCC(_a, _b, _c, _d) (0 \
-	| ( (uint32_t)(_a) \
-	| ( (uint32_t)(_b) << 8) \
-	| ( (uint32_t)(_c) << 16) \
-	| ( (uint32_t)(_d) << 24) \
-	) )
+				| ( (uint32_t)(_a) \
+				| ( (uint32_t)(_b) << 8) \
+				| ( (uint32_t)(_c) << 16) \
+				| ( (uint32_t)(_d) << 24) \
+				) )
 #endif // MAKEFOURCC
 
 #include "dds.h"
@@ -193,6 +200,7 @@ namespace std
 namespace bgfx
 {
 	extern const uint32_t g_constantTypeSize[ConstantType::Count];
+	extern fatalFn g_fatal;
 	extern reallocFn g_realloc;
 	extern freeFn g_free;
 	extern void free(Memory* _mem);
@@ -258,8 +266,14 @@ namespace bgfx
 	struct TextVideoMem
 	{
 		TextVideoMem()
+			: m_mem(NULL)
+			, m_size(0)
+			, m_width(0)
+			, m_height(0)
+			, m_small(false)
 		{
 			resize();
+			clear();
 		}
 
 		~TextVideoMem()
@@ -269,19 +283,32 @@ namespace bgfx
 
 		void resize(bool _small = false, uint16_t _width = BGFX_DEFAULT_WIDTH, uint16_t _height = BGFX_DEFAULT_HEIGHT)
 		{
-			m_small = _small;
-			m_width = uint32_max(1, _width/8);
-			m_height = uint32_max(1, _height/(_small ? 8 : 16) );
-			m_size = m_width * m_height * 2;
+			uint32_t width = uint32_max(1, _width/8);
+			uint32_t height = uint32_max(1, _height/(_small ? 8 : 16) );
 
-			m_mem = (uint8_t*)g_realloc(m_mem, m_size);
+			if (NULL == m_mem
+			||  m_width != width
+			||  m_height != height
+			||  m_small != _small)
+			{
+				m_small = _small;
+				m_width = width;
+				m_height = height;
+				m_size = m_width * m_height * 2;
 
-			clear();
+				m_mem = (uint8_t*)g_realloc(m_mem, m_size);
+			}
 		}
 
-		void clear()
+		void clear(uint8_t _attr = 0)
 		{
-			memset(m_mem, 0, m_size);
+			uint8_t* mem = m_mem;
+			for (uint32_t ii = 0, num = m_size/2; ii < num; ++ii)
+			{
+				mem[0] = 0;
+				mem[1] = _attr;
+				mem += 2;
+			}
 		}
 
 		void printfVargs(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, va_list _argList)
@@ -320,6 +347,12 @@ namespace bgfx
 	struct TextVideoMemBlitter
 	{
 		void init();
+
+		void blit(const TextVideoMem* _mem)
+		{
+			blit(*_mem);
+		}
+
 		void blit(const TextVideoMem& _mem);
 		void setup();
 		void render(uint32_t _numIndices);
@@ -923,14 +956,24 @@ namespace bgfx
 		BX_CACHE_LINE_ALIGN_MARKER();
 
 		Frame()
+		{
+		}
+
+		~Frame()
+		{
+		}
+
+		void create()
 		{
 			m_constantBuffer = ConstantBuffer::create(BGFX_CONFIG_MAX_CONSTANT_BUFFER_SIZE);
 			reset();
+			m_textVideoMem = new TextVideoMem;
 		}
 
-		~Frame()
+		void destroy()
 		{
 			ConstantBuffer::destroy(m_constantBuffer);
+			delete m_textVideoMem;
 		}
 
 		void reset()
@@ -1257,6 +1300,7 @@ namespace bgfx
 		TextureHandle m_freeTextureHandle[BGFX_CONFIG_MAX_TEXTURES];
 		RenderTargetHandle m_freeRenderTargetHandle[BGFX_CONFIG_MAX_RENDER_TARGETS];
 		UniformHandle m_freeUniformHandle[BGFX_CONFIG_MAX_UNIFORMS];
+		TextVideoMem* m_textVideoMem;
 
 		int64_t m_waitSubmit;
 		int64_t m_waitRender;
@@ -1373,6 +1417,10 @@ namespace bgfx
 
 		void frame()
 		{
+#if BX_PLATFORM_WINDOWS
+			m_window.update();
+#endif // BX_PLATFORM_WINDOWS
+
 			// wait for render thread to finish
 			renderSemWait();
 
@@ -1410,10 +1458,13 @@ namespace bgfx
 
 		void dbgTextClear(uint8_t _attr, bool _small)
 		{
+			m_submit->m_textVideoMem->resize(_small, m_resolution.m_width, m_resolution.m_height);
+			m_submit->m_textVideoMem->clear(_attr);
 		}
 
 		void dbgTextPrintfVargs(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, va_list _argList)
 		{
+			m_submit->m_textVideoMem->printfVargs(_x, _y, _attr, _format, _argList);
 		}
 
 		IndexBufferHandle createIndexBuffer(const Memory* _mem)
@@ -1902,6 +1953,8 @@ namespace bgfx
 			m_submit = temp;
 			m_frames++;
 			m_submit->reset();
+
+			m_submit->m_textVideoMem->resize(m_render->m_textVideoMem->m_small, m_resolution.m_width, m_resolution.m_height);
 		}
 
 		void flip();
@@ -2330,6 +2383,13 @@ namespace bgfx
 
 		Semaphore m_renderSem;
 		Semaphore m_gameSem;
+
+#	if BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360
+		HANDLE m_renderThread;
+#	else
+		void* m_renderThread;
+#	endif // BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360
+
 #else
 		void gameSemPost()
 		{
@@ -2384,14 +2444,15 @@ namespace bgfx
 		{
 			Window()
 				: m_frame(true)
+				, m_update(false)
 			{
 			}
 
 			void init()
 			{
-				if (NULL == bgfxHwnd)
-				{
-					bgfxHwnd = CreateWindow( "EDIT"
+				if (NULL == g_bgfxHwnd)
+				{					
+					g_bgfxHwnd = CreateWindow( "EDIT"
 						, NULL
 						, WS_OVERLAPPEDWINDOW|WS_VISIBLE
 						, 0
@@ -2403,21 +2464,35 @@ namespace bgfx
 						, 0
 						, 0
 						);
+
+					m_update = true;
+				}
+			}
+
+			void update()
+			{
+				if (m_update)
+				{
+					MSG msg;
+					msg.message = WM_NULL;
+					PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);
+					TranslateMessage( &msg );
+					DispatchMessage( &msg );
 				}
 			}
 
 			void adjust(uint32_t _width, uint32_t _height, bool _windowFrame)
 			{
 
-				ShowWindow(bgfxHwnd, SW_SHOWNORMAL);
+				ShowWindow(g_bgfxHwnd, SW_SHOWNORMAL);
 				RECT rect;
 				RECT newrect = {0, 0, (LONG)_width, (LONG)_height};
 				DWORD style = WS_POPUP|WS_SYSMENU;
 
 				if (m_frame)
 				{
-					GetWindowRect(bgfxHwnd, &m_rect);
-					m_style = GetWindowLong(bgfxHwnd, GWL_STYLE);
+					GetWindowRect(g_bgfxHwnd, &m_rect);
+					m_style = GetWindowLong(g_bgfxHwnd, GWL_STYLE);
 				}
 
 				if (_windowFrame)
@@ -2431,7 +2506,7 @@ namespace bgfx
 					rect = m_rect;
 					style = m_style;
 #else
-					HMONITOR monitor = MonitorFromWindow(bgfxHwnd, MONITOR_DEFAULTTONEAREST);
+					HMONITOR monitor = MonitorFromWindow(g_bgfxHwnd, MONITOR_DEFAULTTONEAREST);
 					MONITORINFO mi;
 					mi.cbSize = sizeof(mi);
 					GetMonitorInfo(monitor, &mi);
@@ -2440,9 +2515,9 @@ namespace bgfx
 #endif // !defined(__MINGW__)
 				}
 
-				SetWindowLong(bgfxHwnd, GWL_STYLE, style);
+				SetWindowLong(g_bgfxHwnd, GWL_STYLE, style);
 				AdjustWindowRect(&newrect, style, FALSE);
-				UpdateWindow(bgfxHwnd);
+				UpdateWindow(g_bgfxHwnd);
 
 				if (rect.left == -32000
 				||  rect.top == -32000)
@@ -2451,7 +2526,7 @@ namespace bgfx
 					rect.top = 0;
 				}
 
-				SetWindowPos(bgfxHwnd
+				SetWindowPos(g_bgfxHwnd
 					, HWND_TOP
 					, rect.left
 					, rect.top
@@ -2460,7 +2535,7 @@ namespace bgfx
 					, SWP_SHOWWINDOW
 					);
 
-				ShowWindow(bgfxHwnd, SW_RESTORE);
+				ShowWindow(g_bgfxHwnd, SW_RESTORE);
 
 				m_frame = _windowFrame;
 			}
@@ -2468,6 +2543,7 @@ namespace bgfx
 			RECT m_rect;
 			DWORD m_style;
 			bool m_frame;
+			bool m_update;
 		};
 
 		Window m_window;

+ 24 - 7
src/renderer_d3d9.cpp

@@ -124,11 +124,11 @@ namespace bgfx
 			m_params.FullScreen_RefreshRateInHz = 0;
 			m_params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
 			m_params.SwapEffect = D3DSWAPEFFECT_DISCARD;
-			m_params.hDeviceWindow = bgfxHwnd;
+			m_params.hDeviceWindow = g_bgfxHwnd;
 			m_params.Windowed = true;
 
 			RECT rect;
-			GetWindowRect(bgfxHwnd, &rect);
+			GetWindowRect(g_bgfxHwnd, &rect);
 			m_params.BackBufferWidth = rect.right-rect.left;
 			m_params.BackBufferHeight = rect.bottom-rect.top;
 
@@ -149,6 +149,8 @@ namespace bgfx
 			m_d3d9 = direct3DCreate9(D3D_SDK_VERSION);
 #endif // defined(D3D_DISABLE_9EX)
 
+			BGFX_FATAL(m_d3d9, bgfx::Fatal::D3D9_UnableToCreateInterface, "Unable to create Direct3D.");
+
 			uint32_t behaviorFlags[] =
 			{
 				D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE,
@@ -161,7 +163,7 @@ namespace bgfx
 #if BGFX_CONFIG_RENDERER_DIRECT3D_EX
 				DX_CHECK(m_d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT
 						, D3DDEVTYPE_HAL
-						, bgfxHwnd
+						, g_bgfxHwnd
 						, behaviorFlags[ii]
 						, &m_params
 						, NULL
@@ -170,7 +172,7 @@ namespace bgfx
 #else
 				DX_CHECK(m_d3d9->CreateDevice(D3DADAPTER_DEFAULT
 					, D3DDEVTYPE_HAL
-					, bgfxHwnd
+					, g_bgfxHwnd
 					, behaviorFlags[ii]
 					, &m_params
 					, &m_device
@@ -178,6 +180,8 @@ namespace bgfx
 #endif // BGFX_CONFIG_RENDERER_DIRECT3D_EX
 			}
 
+			BGFX_FATAL(m_device, bgfx::Fatal::D3D9_UnableToCreateDevice, "Unable to create Direct3D9 device.");
+
 			m_fmtNULL = SUCCEEDED(m_d3d9->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, D3DFMT_NULL) );
 			m_fmtDF16 = SUCCEEDED(m_d3d9->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, D3DFMT_DF16) );
 			m_fmtDF24 = SUCCEEDED(m_d3d9->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, D3DFMT_DF24) );
@@ -224,12 +228,16 @@ namespace bgfx
 
 		void shutdown()
 		{
+			preReset();
+
 			DX_RELEASE(m_device, 0);
 			DX_RELEASE(m_d3d9, 0);
 
 #if BX_PLATFORM_WINDOWS
 			FreeLibrary(m_d3d9dll);
 #endif // BX_PLATFORM_WINDOWS
+
+			m_initialized = false;
 		}
 
 		void updateResolution(const Resolution& _resolution)
@@ -241,6 +249,7 @@ namespace bgfx
 				m_flags = _resolution.m_flags;
 
 				m_textVideoMem.resize(false, _resolution.m_width, _resolution.m_height);
+				m_textVideoMem.clear();
 
 #if BX_PLATFORM_WINDOWS
 				D3DDEVICE_CREATION_PARAMETERS dcp;
@@ -439,11 +448,11 @@ namespace bgfx
 				) );
 
 			RECT rc;
-			GetClientRect(bgfxHwnd, &rc);
+			GetClientRect(g_bgfxHwnd, &rc);
 			POINT point;
 			point.x = rc.left;
 			point.y = rc.top;
-			ClientToScreen(bgfxHwnd, &point);
+			ClientToScreen(g_bgfxHwnd, &point);
 			uint8_t* data = (uint8_t*)rect.pBits;
 			uint32_t bpp = rect.Pitch/dm.Width;
 			saveTga( (const char*)_mem->data, m_params.BackBufferWidth, m_params.BackBufferHeight, rect.Pitch, &data[point.y*rect.Pitch+point.x*bpp]);
@@ -1825,7 +1834,7 @@ namespace bgfx
 
 		if (m_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
 		{
-			PIX_BEGINEVENT(D3DCOLOR_RGBA(0x40, 0x40, 0x40, 0xff), "debug");
+			PIX_BEGINEVENT(D3DCOLOR_RGBA(0x40, 0x40, 0x40, 0xff), "debugstats");
 
 			TextVideoMem& tvm = s_renderCtx.m_textVideoMem;
 
@@ -1857,6 +1866,14 @@ namespace bgfx
 
 			PIX_ENDEVENT();
 		}
+		else if (m_render->m_debug & BGFX_DEBUG_TEXT)
+		{
+			PIX_BEGINEVENT(D3DCOLOR_RGBA(0x40, 0x40, 0x40, 0xff), "debugtext");
+
+			g_textVideoMemBlitter.blit(m_render->m_textVideoMem);
+
+			PIX_ENDEVENT();
+		}
 
 		s_renderCtx.m_device->EndScene();
 	}

+ 5 - 0
src/renderer_gl.cpp

@@ -31,6 +31,7 @@ namespace bgfx
 			||  m_resolution.m_flags != _resolution.m_flags)
 			{
 				m_textVideoMem.resize(false, _resolution.m_width, _resolution.m_height);
+				m_textVideoMem.clear();
 
 				m_resolution = _resolution;
 #if BX_PLATFORM_NACL
@@ -1722,6 +1723,10 @@ namespace bgfx
 
 			g_textVideoMemBlitter.blit(tvm);
 		}
+		else if (m_render->m_debug & BGFX_DEBUG_TEXT)
+		{
+			g_textVideoMemBlitter.blit(m_render->m_textVideoMem);
+		}
 
 		GL_CHECK(glFlush() );
 	}