diff --git a/examples/helloworld/helloworld.cpp b/examples/helloworld/helloworld.cpp new file mode 100644 index 00000000..16ecf76c --- /dev/null +++ b/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 +#include + +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; +} diff --git a/include/bgfx.h b/include/bgfx.h index baf12c7d..0a441ebe 100644 --- a/include/bgfx.h +++ b/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(); diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 22219d26..5ee89e3a 100644 --- a/src/bgfx.cpp +++ b/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) diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 7a6182b4..fee1dadd 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -12,7 +12,6 @@ #include #include #include -#include 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 #include @@ -47,18 +54,18 @@ extern void dbgPrintfData(const void* _data, uint32_t _size, const char* _format #if BX_PLATFORM_WINDOWS # include -extern HWND bgfxHwnd; +extern HWND g_bgfxHwnd; #elif BX_PLATFORM_XBOX360 # include #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); @@ -924,13 +957,23 @@ namespace bgfx Frame() { - m_constantBuffer = ConstantBuffer::create(BGFX_CONFIG_MAX_CONSTANT_BUFFER_SIZE); - reset(); } ~Frame() + { + } + + void create() + { + m_constantBuffer = ConstantBuffer::create(BGFX_CONFIG_MAX_CONSTANT_BUFFER_SIZE); + reset(); + m_textVideoMem = new TextVideoMem; + } + + 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; diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index 5c76fb3c..2f75c774 100644 --- a/src/renderer_d3d9.cpp +++ b/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(); } diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index b375b7ef..927851f6 100644 --- a/src/renderer_gl.cpp +++ b/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() ); }