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

This commit is contained in:
bkaradzic 2012-04-14 20:36:17 -07:00
parent dee3fe5266
commit 911ce4d775
6 changed files with 210 additions and 40 deletions

View file

@ -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;
}

View file

@ -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();

View file

@ -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)

View file

@ -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);
@ -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)
if (NULL == g_bgfxHwnd)
{
bgfxHwnd = CreateWindow( "EDIT"
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;

View file

@ -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();
}

View file

@ -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() );
}