diff --git a/examples/common/dbg.cpp b/examples/common/dbg.cpp new file mode 100644 index 000000000..1d3862cd5 --- /dev/null +++ b/examples/common/dbg.cpp @@ -0,0 +1,102 @@ +/* + * Copyright 2011-2012 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#include + +#include +#include +#include +#include // isprint + +#include "dbg.h" + +#if BX_COMPILER_MSVC +# define snprintf _snprintf +#endif // BX_COMPILER_MSVC + +#if BX_PLATFORM_WINDOWS +extern "C" +{ + __declspec(dllimport) void __stdcall OutputDebugStringA(const char* _str); +} +#endif // BX_PLATFORM_WINDOWS + +void dbgOutput(const char* _out) +{ +#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 + OutputDebugStringA(_out); +#elif BX_PLATFORM_NACL || BX_PLATFORM_LINUX + fputs(_out, stderr); + fflush(stderr); +#endif // BX_PLATFORM_ +} + +void dbgPrintfVargs(const char* _format, va_list _argList) +{ + char temp[8192]; + vsnprintf(temp, sizeof(temp), _format, _argList); + temp[sizeof(temp)-1] = '\0'; + dbgOutput(temp); +} + +void dbgPrintf(const char* _format, ...) +{ + va_list argList; + va_start(argList, _format); + dbgPrintfVargs(_format, argList); + va_end(argList); +} + +#define DBG_ADDRESS "%" PRIxPTR + +void dbgPrintfData(const void* _data, uint32_t _size, const char* _format, ...) +{ +#define HEX_DUMP_WIDTH 16 +#define HEX_DUMP_SPACE_WIDTH 48 +#define HEX_DUMP_FORMAT "%-" DBG_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "." DBG_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "s" + + va_list argList; + va_start(argList, _format); + dbgPrintf(_format, argList); + va_end(argList); + + dbgPrintf("\ndata: " DBG_ADDRESS ", size: %d\n", _data, _size); + + if (NULL != _data) + { + const uint8_t* data = reinterpret_cast(_data); + char hex[HEX_DUMP_WIDTH*3+1]; + char ascii[HEX_DUMP_WIDTH+1]; + uint32_t hexPos = 0; + uint32_t asciiPos = 0; + for (uint32_t ii = 0; ii < _size; ++ii) + { + snprintf(&hex[hexPos], sizeof(hex)-hexPos, "%02x ", data[asciiPos]); + hexPos += 3; + + ascii[asciiPos] = isprint(data[asciiPos]) ? data[asciiPos] : '.'; + asciiPos++; + + if (HEX_DUMP_WIDTH == asciiPos) + { + ascii[asciiPos] = '\0'; + dbgPrintf("\t" DBG_ADDRESS "\t" HEX_DUMP_FORMAT "\t%s\n", data, hex, ascii); + data += asciiPos; + hexPos = 0; + asciiPos = 0; + } + } + + if (0 != asciiPos) + { + ascii[asciiPos] = '\0'; + dbgPrintf("\t" DBG_ADDRESS "\t" HEX_DUMP_FORMAT "\t%s\n", data, hex, ascii); + } + } + +#undef HEX_DUMP_WIDTH +#undef HEX_DUMP_SPACE_WIDTH +#undef HEX_DUMP_FORMAT +} diff --git a/examples/common/dbg.h b/examples/common/dbg.h new file mode 100644 index 000000000..5d63f191d --- /dev/null +++ b/examples/common/dbg.h @@ -0,0 +1,21 @@ +/* + * Copyright 2011-2012 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef __DBG_H__ +#define __DBG_H__ + +#include // va_list + +#define DBG_STRINGIZE(_x) DBG_STRINGIZE_(_x) +#define DBG_STRINGIZE_(_x) #_x +#define DBG_FILE_LINE_LITERAL "" __FILE__ "(" DBG_STRINGIZE(__LINE__) "): " +#define DBG(_format, ...) dbgPrintf(DBG_FILE_LINE_LITERAL "" _format "\n", ##__VA_ARGS__) + +extern void dbgOutput(const char* _out); +extern void dbgPrintfVargs(const char* _format, va_list _argList); +extern void dbgPrintf(const char* _format, ...); +extern void dbgPrintfData(const void* _data, uint32_t _size, const char* _format, ...); + +#endif // __DBG_H__ diff --git a/examples/common/entry_nacl.cpp b/examples/common/entry_nacl.cpp new file mode 100644 index 000000000..3e91580a6 --- /dev/null +++ b/examples/common/entry_nacl.cpp @@ -0,0 +1,130 @@ +/* + * Copyright 2011-2012 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#include +#include +#include "dbg.h" +#include + +#if BX_PLATFORM_NACL + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace bgfx +{ + typedef void (*PostSwapBuffersFn)(uint32_t _width, uint32_t _height); + extern void naclSetIntefraces(PP_Instance, const PPB_Instance*, const PPB_Graphics3D*, PostSwapBuffersFn); +} + +extern int _main_(int _argc, char** _argv); + +static void* _entry_(void*) +{ + const char* argv[1] = { "nacl.nexe" }; + _main_(1, const_cast(argv) ); + return NULL; +} + +struct NaclContext +{ + NaclContext() + : m_thread(0) + { + } + + const PPB_Instance* m_instInterface; + const PPB_Graphics3D* m_graphicsInterface; + + pthread_t m_thread; + PP_Module m_module; + PP_Instance m_instance; +}; + +static NaclContext s_ctx; + +static PP_Bool naclInstanceDidCreate(PP_Instance _instance, uint32_t _argc, const char* _argn[], const char* _argv[]) +{ + s_ctx.m_instance = _instance; + + bgfx::naclSetIntefraces(s_ctx.m_instance, s_ctx.m_instInterface, s_ctx.m_graphicsInterface, NULL); + pthread_create(&s_ctx.m_thread, NULL, _entry_, NULL); + + return PP_TRUE; +} + +static void naclInstanceDidDestroy(PP_Instance _instance) +{ + if (s_ctx.m_thread) + { + pthread_join(s_ctx.m_thread, NULL); + } +} + +static void naclInstanceDidChangeView(PP_Instance _instance, PP_Resource _view) +{ +} + +static void naclInstanceDidChangeFocus(PP_Instance _instance, PP_Bool _focus) +{ +} + +static PP_Bool naclInstanceHandleDocumentLoad(PP_Instance _instance, PP_Resource _urlLoader) +{ + return PP_FALSE; +} + +PP_EXPORT const void* PPP_GetInterface(const char* _name) +{ + if (0 == strcmp(_name, PPP_INSTANCE_INTERFACE) ) + { + static PPP_Instance instanceInterface = + { + &naclInstanceDidCreate, + &naclInstanceDidDestroy, + &naclInstanceDidChangeView, + &naclInstanceDidChangeFocus, + &naclInstanceHandleDocumentLoad, + }; + + return &instanceInterface; + } + + return NULL; +} + +template +bool initializeInterface(const Type*& _result, PPB_GetInterface _interface, const char* _name) +{ + _result = reinterpret_cast(_interface(_name) ); + return NULL != _result; +} + +PP_EXPORT int32_t PPP_InitializeModule(PP_Module _module, PPB_GetInterface _interface) +{ + s_ctx.m_module = _module; + + bool result = true; + result &= initializeInterface(s_ctx.m_instInterface, _interface, PPB_INSTANCE_INTERFACE); + result &= initializeInterface(s_ctx.m_graphicsInterface, _interface, PPB_GRAPHICS_3D_INTERFACE); + result &= glInitializePPAPI(_interface); + + return result ? PP_OK : PP_ERROR_NOINTERFACE; +} + +PP_EXPORT void PPP_ShutdownModule() +{ +} + +#endif // BX_PLATFROM_NACL diff --git a/examples/common/entry_windows.cpp b/examples/common/entry_windows.cpp new file mode 100644 index 000000000..226bee298 --- /dev/null +++ b/examples/common/entry_windows.cpp @@ -0,0 +1,17 @@ +/* + * Copyright 2011-2012 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#include + +#if BX_PLATFORM_WINDOWS + +extern int _main_(int _argc, char** _argv); + +int main(int _argc, char** _argv) +{ + return _main_(_argc, _argv); +} + +#endif // BX_PLATFORM_WINDOWS diff --git a/examples/helloworld/helloworld.cpp b/examples/helloworld/helloworld.cpp index 16ecf76c8..bec342656 100644 --- a/examples/helloworld/helloworld.cpp +++ b/examples/helloworld/helloworld.cpp @@ -4,21 +4,32 @@ */ #include -#include +#include +#include "../common/dbg.h" -int main(int _argc, const char** _argv) +void fatalCb(bgfx::Fatal::Enum _code, const char* _str) { - bgfx::init(true); + DBG("%x: %s", _code, _str); +} + +int _main_(int _argc, char** _argv) +{ + bgfx::init(BX_PLATFORM_WINDOWS, fatalCb); bgfx::reset(1280, 720); bgfx::setDebug(BGFX_DEBUG_TEXT); - while (!_kbhit() ) - { - bgfx::dbgTextClear(); - bgfx::dbgTextPrintf(0, 0, 0x4f, "Hello world!"); + bgfx::setViewRect(0, 0, 0, 1280, 720); + bgfx::setViewClear(0, BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT, 0x000000ff, 0.0f, 0); - bgfx::dbgTextPrintf(0, 5, 0x6f, "BGFX initialization and debug text."); + while (true) + { + bgfx::submit(0); + + bgfx::dbgTextClear(); + bgfx::dbgTextPrintf(0, 1, 0x4f, "BGFX: Hello, World!"); + + bgfx::dbgTextPrintf(0, 2, 0x6f, "Initialization and debug text."); bgfx::frame(); } diff --git a/examples/helloworld/helloworld.nmf b/examples/helloworld/helloworld.nmf new file mode 100644 index 000000000..3b83681a7 --- /dev/null +++ b/examples/helloworld/helloworld.nmf @@ -0,0 +1,6 @@ +{ + "program": { + "x86-32": {"url": "nacl-x86/helloworldRelease.nexe"}, + "x86-64": {"url": "nacl-x64/helloworldRelease.nexe"} + } +} diff --git a/examples/helloworld/index.htm b/examples/helloworld/index.htm new file mode 100644 index 000000000..c904dc088 --- /dev/null +++ b/examples/helloworld/index.htm @@ -0,0 +1,15 @@ + + + + BGFX: Hello, World! + + + + + diff --git a/examples/helloworld/nacl-chrome.bat b/examples/helloworld/nacl-chrome.bat new file mode 100644 index 000000000..62676c309 --- /dev/null +++ b/examples/helloworld/nacl-chrome.bat @@ -0,0 +1,10 @@ +@echo off +setlocal +set NACL_DEBUG=%~dp0..\..\.debug\nacl +set NACL_EXE_STDERR=%NACL_DEBUG%\stderr.txt +set NACL_EXE_STDOUT=%NACL_DEBUG%\stdout.txt +set NACL_DANGEROUS_ENABLE_FILE_ACCESS=1 +mkdir %NACL_DEBUG% > nul +rm -rf %NACL_EXE_STDERR% > nul +rm -rf %NACL_EXE_STDOUT% > nul +start %LOCALAPPDATA%\Google\Chrome\Application\chrome.exe --incognito --no-sandbox --show-fps-counter http://localhost:8080 %* diff --git a/premake/premake4.lua b/premake/premake4.lua index 81134fcca..1d6ab8c0a 100644 --- a/premake/premake4.lua +++ b/premake/premake4.lua @@ -23,6 +23,7 @@ newoption { description = "Choose GCC flavor", allowed = { { "mingw", "MinGW" }, + { "nacl", "Google Native Client" }, } } @@ -40,6 +41,10 @@ location (BUILD_DIR .. "projects/" .. _ACTION) if _ACTION == "gmake" then + flags { + "ExtraWarnings", + } + if "linux" ~= os.get() and nil == _OPTIONS["gcc"] then print("GCC flavor must be specified!") os.exit(1) @@ -50,6 +55,18 @@ if _ACTION == "gmake" then premake.gcc.cxx = "$(MINGW)/bin/mingw32-g++" premake.gcc.ar = "$(MINGW)/bin/ar" end + + if "nacl" == _OPTIONS["gcc"] then + + if not os.getenv("NACL") then + print("Set NACL enviroment variables.") + end + + premake.gcc.cc = "$(NACL)/bin/x86_64-nacl-gcc" + premake.gcc.cxx = "$(NACL)/bin/x86_64-nacl-g++" + premake.gcc.ar = "$(NACL)/bin/x86_64-nacl-ar" + location (BUILD_DIR .. "projects/" .. _ACTION .. "-nacl") + end end flags { @@ -57,25 +74,22 @@ flags { "NoMinimalRebuild", "NoPCH", "NativeWChar", --- "ExtraWarnings", "NoRTTI", "NoExceptions", + "NoEditAndContinue", "Symbols", } includedirs { - ROOT_DIR .. "../_bx/include", + ROOT_DIR .. "../bx/include", } configuration "Debug" - defines { - "BGFX_BUILD_DEBUG=1", - } targetsuffix "Debug" configuration "Release" - defines { - "BGFX_BUILD_RELEASE=1", + flags { + "OptimizeSpeed", } targetsuffix "Release" @@ -115,6 +129,46 @@ configuration { "x64", "mingw" } objdir (BUILD_DIR .. "win64_mingw" .. "/obj") includedirs { THIRD_PARTY_DIR .. "compiler/mingw" } +configuration { "nacl" } + defines { "_BSD_SOURCE=1", "_POSIX_C_SOURCE=199506", "_XOPEN_SOURCE=600" } + links { + "ppapi", + "ppapi_gles2", + } + includedirs { THIRD_PARTY_DIR .. "compiler/nacl" } + buildoptions { + "-std=c++0x", + "-U__STRICT_ANSI__", + "-pthread", + "-fno-stack-protector", + "-fdiagnostics-show-option", + "-Wunused-value", + "-fdata-sections", + "-ffunction-sections", + "-mfpmath=sse", -- force SSE to get 32-bit and 64-bit builds deterministic. + "-msse2", +-- "-fmerge-all-constants", + } + linkoptions { + "-Wl,--gc-sections", + } + +configuration { "x32", "nacl" } + targetdir (BUILD_DIR .. "nacl-x86" .. "/bin") + objdir (BUILD_DIR .. "nacl-x86" .. "/obj") + libdirs { THIRD_PARTY_DIR .. "lib/nacl-x86" } + linkoptions { + "-melf32_nacl", + } + +configuration { "x64", "nacl" } + targetdir (BUILD_DIR .. "nacl-x64" .. "/bin") + objdir (BUILD_DIR .. "nacl-x64" .. "/obj") + libdirs { THIRD_PARTY_DIR .. "lib/nacl-x64" } + linkoptions { + "-melf64_nacl", + } + configuration { "x32", "linux" } targetdir (BUILD_DIR .. "linux32" .. "/bin") objdir (BUILD_DIR .. "linux32" .. "/obj") @@ -236,16 +290,29 @@ project "makedisttex" project "helloworld" uuid "ff2c8450-ebf4-11e0-9572-0800200c9a66" - kind "ConsoleApp" + kind "WindowedApp" includedirs { ROOT_DIR .. "include", } files { - ROOT_DIR .. "examples/helloworld/**", + ROOT_DIR .. "examples/common/**.cpp", + ROOT_DIR .. "examples/common/**.h", + ROOT_DIR .. "examples/helloworld/**.cpp", + ROOT_DIR .. "examples/helloworld/**.h", } links { "bgfx", } + + configuration { "nacl" } + targetextension ".nexe" + + configuration { "nacl", "Release" } + postbuildcommands { + "@echo Stripping symbols.", + "@$(NACL)/bin/x86_64-nacl-strip -s \"$(TARGET)\"" + } + diff --git a/src/bgfx_p.h b/src/bgfx_p.h index a2cb5fed6..915792446 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -293,8 +293,8 @@ namespace bgfx || m_small != _small) { m_small = _small; - m_width = width; - m_height = height; + m_width = (uint16_t)width; + m_height = (uint16_t)height; m_size = m_width * m_height * 2; m_mem = (uint8_t*)g_realloc(m_mem, m_size); @@ -2445,8 +2445,22 @@ namespace bgfx { if (NULL == g_bgfxHwnd) { - g_bgfxHwnd = CreateWindow( "EDIT" - , NULL + HINSTANCE instance = (HINSTANCE)GetModuleHandle(NULL); + + WNDCLASSEX wnd; + memset(&wnd, 0, sizeof(wnd) ); + wnd.cbSize = sizeof(wnd); + wnd.style = CS_HREDRAW | CS_VREDRAW; + wnd.lpfnWndProc = wndProc; + wnd.hInstance = instance; + wnd.hIcon = LoadIcon(instance, IDI_APPLICATION); + wnd.hCursor = LoadCursor(instance, IDC_ARROW); + wnd.lpszClassName = "bgfx"; + wnd.hIconSm = LoadIcon(instance, IDI_APPLICATION); + RegisterClassExA(&wnd); + + g_bgfxHwnd = CreateWindowA("bgfx" + , "BGFX" , WS_OVERLAPPEDWINDOW|WS_VISIBLE , 0 , 0 @@ -2462,15 +2476,32 @@ namespace bgfx } } + static LRESULT CALLBACK wndProc(HWND _hwnd, UINT _id, WPARAM _wparam, LPARAM _lparam) + { + switch (_id) + { + case WM_CLOSE: + TerminateProcess(GetCurrentProcess(), 0); + break; + + default: + break; + } + + return DefWindowProc(_hwnd, _id, _wparam, _lparam); + } + void update() { if (m_update) { MSG msg; msg.message = WM_NULL; - PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE); - TranslateMessage( &msg ); - DispatchMessage( &msg ); + if (0 != PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE) ) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } } } diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 70afe1090..824bf5f9b 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -65,7 +65,6 @@ namespace bgfx void setRenderContextSize(uint32_t _width, uint32_t _height) { - BX_TRACE("1"); if (_width != 0 || _height != 0) { @@ -1019,18 +1018,18 @@ namespace bgfx Material& material = s_renderCtx.m_materials[m_material.idx]; GL_CHECK(glUseProgram(material.m_id) ); + GL_CHECK(glUniform1i(material.m_sampler[0], 0) ); float proj[16]; matrix_ortho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f); - PredefinedUniform& predefined = material.m_predefined[0]; - - GL_CHECK(glUniformMatrix4fv(predefined.m_loc + GL_CHECK(glUniformMatrix4fv(material.m_predefined[0].m_loc , 1 , GL_FALSE , proj ) ); + GL_CHECK(glActiveTexture(GL_TEXTURE0) ); GL_CHECK(glBindTexture(GL_TEXTURE_2D, s_renderCtx.m_textures[m_texture.idx].m_id) ); }