diff --git a/examples/00-helloworld/helloworld.cpp b/examples/00-helloworld/helloworld.cpp index f88465fb0..6927f61f7 100644 --- a/examples/00-helloworld/helloworld.cpp +++ b/examples/00-helloworld/helloworld.cpp @@ -7,17 +7,19 @@ #include #include "../common/entry.h" #include "../common/dbg.h" +#include "../common/processevents.h" int _main_(int _argc, char** _argv) { - bgfx::init(); - bgfx::reset(1280, 720); - - // Enable debug text. - bgfx::setDebug(BGFX_DEBUG_TEXT); - - // Set view 0 default viewport. - bgfx::setViewRect(0, 0, 0, 1280, 720); + uint32_t width = 1280; + uint32_t height = 720; + uint32_t debug = BGFX_DEBUG_TEXT; + + bgfx::init(); + bgfx::reset(width, height); + + // Enable debug text. + bgfx::setDebug(debug); // Set view 0 clear state. bgfx::setViewClear(0 @@ -27,8 +29,11 @@ int _main_(int _argc, char** _argv) , 0 ); - while (entry::Event::Exit != entry::poll() ) - { + while (!processEvents(width, height, debug) ) + { + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, width, 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::submit(0); diff --git a/examples/01-cubes/cubes.cpp b/examples/01-cubes/cubes.cpp index 91d567917..e8d1d305b 100644 --- a/examples/01-cubes/cubes.cpp +++ b/examples/01-cubes/cubes.cpp @@ -9,6 +9,7 @@ #include "../common/entry.h" #include "../common/dbg.h" #include "../common/math.h" +#include "../common/processevents.h" #include #include @@ -95,15 +96,16 @@ static const bgfx::Memory* loadShader(const char* _name) int _main_(int _argc, char** _argv) { - bgfx::init(); - bgfx::reset(1280, 720); - - // Enable debug text. - bgfx::setDebug(BGFX_DEBUG_TEXT); - - // Set view 0 default viewport. - bgfx::setViewRect(0, 0, 0, 1280, 720); - + uint32_t width = 1280; + uint32_t height = 720; + uint32_t debug = BGFX_DEBUG_TEXT; + + bgfx::init(); + bgfx::reset(width, height); + + // Enable debug text. + bgfx::setDebug(debug); + // Set view 0 clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT @@ -169,8 +171,11 @@ int _main_(int _argc, char** _argv) bgfx::destroyVertexShader(vsh); bgfx::destroyFragmentShader(fsh); - while (entry::Event::Exit != entry::poll() ) - { + while (!processEvents(width, height, debug) ) + { + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, width, 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::submit(0); diff --git a/examples/02-metaballs/metaballs.cpp b/examples/02-metaballs/metaballs.cpp index 49d2cb838..0afb46cb9 100644 --- a/examples/02-metaballs/metaballs.cpp +++ b/examples/02-metaballs/metaballs.cpp @@ -9,6 +9,7 @@ #include "../common/entry.h" #include "../common/dbg.h" #include "../common/math.h" +#include "../common/processevents.h" #include #include @@ -495,14 +496,15 @@ uint32_t triangulate(uint8_t* _result, uint32_t _stride, const float* __restrict int _main_(int _argc, char** _argv) { + uint32_t width = 1280; + uint32_t height = 720; + uint32_t debug = BGFX_DEBUG_TEXT; + bgfx::init(); - bgfx::reset(1280, 720); + bgfx::reset(width, height); // Enable debug text. - bgfx::setDebug(BGFX_DEBUG_TEXT); - - // Set view 0 default viewport. - bgfx::setViewRect(0, 0, 0, 1280, 720); + bgfx::setDebug(debug); // Set view 0 clear state. bgfx::setViewClear(0 @@ -569,8 +571,11 @@ int _main_(int _argc, char** _argv) const uint32_t zpitch = DIMS*DIMS; const float invdim = 1.0f/float(DIMS-1); - while (entry::Event::Exit != entry::poll() ) - { + while (!processEvents(width, height, debug) ) + { + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, width, 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::submit(0); diff --git a/examples/03-raymarch/raymarch.cpp b/examples/03-raymarch/raymarch.cpp index 2a7d870d9..6e85243de 100644 --- a/examples/03-raymarch/raymarch.cpp +++ b/examples/03-raymarch/raymarch.cpp @@ -9,6 +9,7 @@ #include "../common/entry.h" #include "../common/dbg.h" #include "../common/math.h" +#include "../common/processevents.h" #include #include @@ -174,18 +175,16 @@ void renderScreenSpaceQuad(uint32_t _view, bgfx::ProgramHandle _program, float _ int _main_(int _argc, char** _argv) { - bgfx::init(); - bgfx::reset(1280, 720); - - // Enable debug text. - bgfx::setDebug(BGFX_DEBUG_TEXT); - - // Set view 0 default viewport. - bgfx::setViewRect(0, 0, 0, 1280, 720); - - // Set view 1 default viewport. - bgfx::setViewRect(1, 0, 0, 1280, 720); - + uint32_t width = 1280; + uint32_t height = 720; + uint32_t debug = BGFX_DEBUG_TEXT; + + bgfx::init(); + bgfx::reset(width, height); + + // Enable debug text. + bgfx::setDebug(debug); + // Set view 0 clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT @@ -232,8 +231,14 @@ int _main_(int _argc, char** _argv) bgfx::ProgramHandle raymarching = loadProgram("vs_raymarching", "fs_raymarching"); - while (entry::Event::Exit != entry::poll() ) - { + while (!processEvents(width, height, debug) ) + { + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, width, height); + + // Set view 1 default viewport. + bgfx::setViewRect(1, 0, 0, width, height); + // This dummy draw call is here to make sure that view 0 is cleared // if no other draw calls are submitted to viewZ 0. bgfx::submit(0); diff --git a/examples/04-mesh/mesh.cpp b/examples/04-mesh/mesh.cpp index 3a1efbbcb..0c74e4d8c 100644 --- a/examples/04-mesh/mesh.cpp +++ b/examples/04-mesh/mesh.cpp @@ -10,6 +10,7 @@ #include "../common/entry.h" #include "../common/dbg.h" #include "../common/math.h" +#include "../common/processevents.h" #include #include @@ -275,17 +276,15 @@ struct Mesh int _main_(int _argc, char** _argv) { + uint32_t width = 1280; + uint32_t height = 720; + uint32_t debug = BGFX_DEBUG_TEXT; + bgfx::init(); - bgfx::reset(1280, 720); + bgfx::reset(width, height); // Enable debug text. - bgfx::setDebug(BGFX_DEBUG_TEXT); - - // Set view 0 default viewport. - bgfx::setViewRect(0, 0, 0, 1280, 720); - - // Set view 1 default viewport. - bgfx::setViewRect(1, 0, 0, 1280, 720); + bgfx::setDebug(debug); // Set view 0 clear state. bgfx::setViewClear(0 @@ -327,8 +326,11 @@ int _main_(int _argc, char** _argv) Mesh mesh; mesh.load("meshes/bunny.bin"); - while (entry::Event::Exit != entry::poll() ) + while (!processEvents(width, height, debug) ) { + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, width, 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::submit(0); diff --git a/examples/05-instancing/instancing.cpp b/examples/05-instancing/instancing.cpp index b19259362..8af0db7fd 100644 --- a/examples/05-instancing/instancing.cpp +++ b/examples/05-instancing/instancing.cpp @@ -9,6 +9,7 @@ #include "../common/entry.h" #include "../common/dbg.h" #include "../common/math.h" +#include "../common/processevents.h" #include #include @@ -95,15 +96,16 @@ static const bgfx::Memory* loadShader(const char* _name) int _main_(int _argc, char** _argv) { - bgfx::init(); - bgfx::reset(1280, 720); - - // Enable debug text. - bgfx::setDebug(BGFX_DEBUG_TEXT); - - // Set view 0 default viewport. - bgfx::setViewRect(0, 0, 0, 1280, 720); - + uint32_t width = 1280; + uint32_t height = 720; + uint32_t debug = BGFX_DEBUG_TEXT; + + bgfx::init(); + bgfx::reset(width, height); + + // Enable debug text. + bgfx::setDebug(debug); + // Set view 0 clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT @@ -169,8 +171,11 @@ int _main_(int _argc, char** _argv) bgfx::destroyVertexShader(vsh); bgfx::destroyFragmentShader(fsh); - while (entry::Event::Exit != entry::poll() ) - { + while (!processEvents(width, height, debug) ) + { + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, width, 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::submit(0); diff --git a/examples/06-bump/bump.cpp b/examples/06-bump/bump.cpp index d6a25d2ea..b83d7d4b6 100644 --- a/examples/06-bump/bump.cpp +++ b/examples/06-bump/bump.cpp @@ -10,6 +10,7 @@ #include "../common/entry.h" #include "../common/dbg.h" #include "../common/math.h" +#include "../common/processevents.h" #include #include @@ -251,15 +252,16 @@ void calcTangents(void* _vertices, uint16_t _numVertices, bgfx::VertexDecl _decl int _main_(int _argc, char** _argv) { - bgfx::init(); - bgfx::reset(1280, 720); - - // Enable debug text. - bgfx::setDebug(BGFX_DEBUG_TEXT); - - // Set view 0 default viewport. - bgfx::setViewRect(0, 0, 0, 1280, 720); - + uint32_t width = 1280; + uint32_t height = 720; + uint32_t debug = BGFX_DEBUG_TEXT; + + bgfx::init(); + bgfx::reset(width, height); + + // Enable debug text. + bgfx::setDebug(debug); + // Set view 0 clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT @@ -345,8 +347,11 @@ int _main_(int _argc, char** _argv) mem = loadTexture("fieldstone-n.dds"); bgfx::TextureHandle textureNormal = bgfx::createTexture(mem); - while (entry::Event::Exit != entry::poll() ) - { + while (!processEvents(width, height, debug) ) + { + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, width, 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::submit(0); diff --git a/examples/08-update/update.cpp b/examples/08-update/update.cpp index 258bd31de..6a8d662b0 100644 --- a/examples/08-update/update.cpp +++ b/examples/08-update/update.cpp @@ -10,6 +10,7 @@ #include "../common/entry.h" #include "../common/dbg.h" #include "../common/math.h" +#include "../common/processevents.h" #include #include @@ -124,15 +125,16 @@ static const bgfx::Memory* loadShader(const char* _name) int _main_(int _argc, char** _argv) { - bgfx::init(); - bgfx::reset(1280, 720); - - // Enable debug text. - bgfx::setDebug(BGFX_DEBUG_TEXT); - - // Set view 0 default viewport. - bgfx::setViewRect(0, 0, 0, 1280, 720); - + uint32_t width = 1280; + uint32_t height = 720; + uint32_t debug = BGFX_DEBUG_TEXT; + + bgfx::init(); + bgfx::reset(width, height); + + // Enable debug text. + bgfx::setDebug(debug); + // Set view 0 clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT @@ -225,8 +227,11 @@ int _main_(int _argc, char** _argv) int64_t updateTime = 0; - while (entry::Event::Exit != entry::poll() ) - { + while (!processEvents(width, height, debug) ) + { + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, width, 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::submit(0); diff --git a/examples/common/entry.h b/examples/common/entry.h index 9845e90fc..6b7db8f53 100644 --- a/examples/common/entry.h +++ b/examples/common/entry.h @@ -122,12 +122,41 @@ namespace entry { enum Enum { - Nop, Exit, + Key, + Mouse, + Size, }; + + Event::Enum m_type; }; - Event::Enum poll(); + struct KeyEvent : public Event + { + Key::Enum m_key; + uint8_t m_modifiers; + bool m_down; + }; + + struct MouseEvent : public Event + { + int32_t m_mx; + int32_t m_my; + MouseButton::Enum m_button; + bool m_down; + }; + + struct SizeEvent : public Event + { + uint32_t m_width; + uint32_t m_height; + }; + + const Event* poll(); + void release(const Event* _event); + + void setWindowSize(uint32_t _width, uint32_t _height); + void toggleWindowFrame(); } // namespace entry diff --git a/examples/common/entry_emscripten.cpp b/examples/common/entry_emscripten.cpp index 63c7fcc95..8b43bed58 100644 --- a/examples/common/entry_emscripten.cpp +++ b/examples/common/entry_emscripten.cpp @@ -15,11 +15,23 @@ namespace entry { - Event::Enum poll() + const Event* poll() + { + return NULL; + } + + void release(const Event* _event) + { + } + + void setWindowSize(uint32_t _width, uint32_t _height) { - return Event::Nop; - } - + } + + void toggleWindowFrame() + { + } + } // namespace entry extern int _main_(int _argc, char** _argv); diff --git a/examples/common/entry_linux.cpp b/examples/common/entry_linux.cpp index 63e773419..a93a85ff6 100644 --- a/examples/common/entry_linux.cpp +++ b/examples/common/entry_linux.cpp @@ -95,9 +95,21 @@ namespace entry static Context s_ctx; - Event::Enum poll() + const Event* poll() { - return Event::Nop; + return NULL; + } + + void release(const Event* _event) + { + } + + void setWindowSize(uint32_t _width, uint32_t _height) + { + } + + void toggleWindowFrame() + { } } // namespace entry diff --git a/examples/common/entry_nacl.cpp b/examples/common/entry_nacl.cpp index 6d8946681..d15e216dc 100644 --- a/examples/common/entry_nacl.cpp +++ b/examples/common/entry_nacl.cpp @@ -27,10 +27,22 @@ namespace entry { - Event::Enum poll() + const Event* poll() + { + return NULL; + } + + void release(const Event* _event) + { + } + + void setWindowSize(uint32_t _width, uint32_t _height) { - return Event::Nop; - } + } + + void toggleWindowFrame() + { + } } // namespace entry diff --git a/examples/common/entry_osx.mm b/examples/common/entry_osx.mm index 639ac5e22..06236e3a8 100755 --- a/examples/common/entry_osx.mm +++ b/examples/common/entry_osx.mm @@ -219,9 +219,21 @@ namespace entry static Context s_ctx; - Event::Enum poll() + const Event* poll() { - return s_ctx.m_exit ? Event::Exit : Event::Nop; + return NULL; + } + + void release(const Event* _event) + { + } + + void setWindowSize(uint32_t _width, uint32_t _height) + { + } + + void toggleWindowFrame() + { } } // namespace entry diff --git a/examples/common/entry_p.h b/examples/common/entry_p.h new file mode 100644 index 000000000..2d9bcfeb4 --- /dev/null +++ b/examples/common/entry_p.h @@ -0,0 +1,73 @@ +/* + * Copyright 2011-2013 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef __ENTRY_PRIVATE_H__ +#define __ENTRY_PRIVATE_H__ + +#include +#include + +#include "dbg.h" +#include "entry.h" + +namespace entry +{ + class EventQueue + { + public: + void postExitEvent() + { + Event* ev = new Event; + ev->m_type = Event::Exit; + m_queue.push(ev); + } + + void postKeyEvent(Key::Enum _key, uint8_t _modifiers, bool _down) + { + KeyEvent* ev = new KeyEvent; + ev->m_type = Event::Key; + ev->m_key = _key; + ev->m_modifiers = _modifiers; + ev->m_down = _down; + m_queue.push(ev); + } + + void postMouseEvent(int32_t _mx, int32_t _my, MouseButton::Enum _button, bool _down) + { + MouseEvent* ev = new MouseEvent; + ev->m_type = Event::Mouse; + ev->m_mx = _mx; + ev->m_my = _my; + ev->m_button = _button; + ev->m_down = _down; + m_queue.push(ev); + } + + void postSizeEvent(uint32_t _width, uint32_t _height) + { + SizeEvent* ev = new SizeEvent; + ev->m_type = Event::Size; + ev->m_width = _width; + ev->m_height = _height; + m_queue.push(ev); + } + + const Event* poll() + { + return m_queue.pop(); + } + + void release(const Event* _event) const + { + delete _event; + } + + private: + bx::SpScUnboundedQueue m_queue; + }; + +} // namespace entry + +#endif // __ENTRY_PRIVATE_H__ diff --git a/examples/common/entry_windows.cpp b/examples/common/entry_windows.cpp index d31745abb..57550f3d3 100644 --- a/examples/common/entry_windows.cpp +++ b/examples/common/entry_windows.cpp @@ -7,38 +7,149 @@ #if BX_PLATFORM_WINDOWS -#include +#include "entry_p.h" + +#include #include #include -#include "entry.h" -#include "dbg.h" +#include #define DEFAULT_WIDTH 1280 #define DEFAULT_HEIGHT 720 +#define WM_USER_SET_WINDOW_SIZE (WM_USER+0) +#define WM_USER_TOGGLE_WINDOW_FRAME (WM_USER+1) + extern int _main_(int _argc, char** _argv); namespace entry { + struct TranslateKeyModifiers + { + int m_vk; + Modifier::Enum m_modifier; + }; + + static const TranslateKeyModifiers s_translateKeyModifiers[8] = + { + { VK_LMENU, Modifier::LeftAlt }, + { VK_RMENU, Modifier::RightAlt }, + { VK_LCONTROL, Modifier::LeftCtrl }, + { VK_RCONTROL, Modifier::RightCtrl }, + { VK_LSHIFT, Modifier::LeftShift }, + { VK_RSHIFT, Modifier::RightShift }, + { VK_LWIN, Modifier::LeftMeta }, + { VK_RWIN, Modifier::RightMeta }, + }; + + static uint8_t translateKeyModifiers() + { + uint8_t modifiers = 0; + for (uint32_t ii = 0; ii < countof(s_translateKeyModifiers); ++ii) + { + const TranslateKeyModifiers& tkm = s_translateKeyModifiers[ii]; + modifiers |= 0 > GetKeyState(tkm.m_vk) ? tkm.m_modifier : Modifier::None; + } + return modifiers; + } + + static uint8_t s_translateKey[256]; + + static Key::Enum translateKey(WPARAM _wparam) + { + return (Key::Enum)s_translateKey[_wparam&0xff]; + } + struct MainThreadEntry { int m_argc; char** m_argv; - static int32_t threadFunc(void* _userData) - { - MainThreadEntry* self = (MainThreadEntry*)_userData; - return _main_(self->m_argc, self->m_argv); - } + static int32_t threadFunc(void* _userData); }; struct Context { Context() : m_frame(true) + , m_init(false) , m_exit(false) { + memset(s_translateKey, 0, sizeof(s_translateKey) ); + s_translateKey[VK_ESCAPE] = Key::Esc; + s_translateKey[VK_RETURN] = Key::Return; + s_translateKey[VK_TAB] = Key::Tab; + s_translateKey[VK_BACK] = Key::Backspace; + s_translateKey[VK_SPACE] = Key::Space; + s_translateKey[VK_UP] = Key::Up; + s_translateKey[VK_DOWN] = Key::Down; + s_translateKey[VK_LEFT] = Key::Left; + s_translateKey[VK_RIGHT] = Key::Right; + s_translateKey[VK_PRIOR] = Key::PageUp; + s_translateKey[VK_NEXT] = Key::PageUp; + s_translateKey[VK_HOME] = Key::Home; + s_translateKey[VK_END] = Key::End; + s_translateKey[VK_SNAPSHOT] = Key::Print; + s_translateKey[VK_OEM_PLUS] = Key::Plus; + s_translateKey[VK_OEM_MINUS] = Key::Minus; + s_translateKey[VK_F1] = Key::F1; + s_translateKey[VK_F2] = Key::F2; + s_translateKey[VK_F3] = Key::F3; + s_translateKey[VK_F4] = Key::F4; + s_translateKey[VK_F5] = Key::F5; + s_translateKey[VK_F6] = Key::F6; + s_translateKey[VK_F7] = Key::F7; + s_translateKey[VK_F8] = Key::F8; + s_translateKey[VK_F9] = Key::F9; + s_translateKey[VK_F10] = Key::F10; + s_translateKey[VK_F11] = Key::F11; + s_translateKey[VK_F12] = Key::F12; + s_translateKey[VK_NUMPAD0] = Key::NumPad0; + s_translateKey[VK_NUMPAD1] = Key::NumPad1; + s_translateKey[VK_NUMPAD2] = Key::NumPad2; + s_translateKey[VK_NUMPAD3] = Key::NumPad3; + s_translateKey[VK_NUMPAD4] = Key::NumPad4; + s_translateKey[VK_NUMPAD5] = Key::NumPad5; + s_translateKey[VK_NUMPAD6] = Key::NumPad6; + s_translateKey[VK_NUMPAD7] = Key::NumPad7; + s_translateKey[VK_NUMPAD8] = Key::NumPad8; + s_translateKey[VK_NUMPAD9] = Key::NumPad9; + s_translateKey['0'] = Key::Key0; + s_translateKey['1'] = Key::Key1; + s_translateKey['2'] = Key::Key2; + s_translateKey['3'] = Key::Key3; + s_translateKey['4'] = Key::Key4; + s_translateKey['5'] = Key::Key5; + s_translateKey['6'] = Key::Key6; + s_translateKey['7'] = Key::Key7; + s_translateKey['8'] = Key::Key8; + s_translateKey['9'] = Key::Key9; + s_translateKey['A'] = Key::KeyA; + s_translateKey['B'] = Key::KeyB; + s_translateKey['C'] = Key::KeyC; + s_translateKey['D'] = Key::KeyD; + s_translateKey['E'] = Key::KeyE; + s_translateKey['F'] = Key::KeyF; + s_translateKey['G'] = Key::KeyG; + s_translateKey['H'] = Key::KeyH; + s_translateKey['I'] = Key::KeyI; + s_translateKey['J'] = Key::KeyJ; + s_translateKey['K'] = Key::KeyK; + s_translateKey['L'] = Key::KeyL; + s_translateKey['M'] = Key::KeyM; + s_translateKey['O'] = Key::KeyO; + s_translateKey['P'] = Key::KeyP; + s_translateKey['Q'] = Key::KeyQ; + s_translateKey['R'] = Key::KeyR; + s_translateKey['S'] = Key::KeyS; + s_translateKey['T'] = Key::KeyT; + s_translateKey['U'] = Key::KeyU; + s_translateKey['V'] = Key::KeyV; + s_translateKey['W'] = Key::KeyW; + s_translateKey['X'] = Key::KeyX; + s_translateKey['Y'] = Key::KeyY; + s_translateKey['Z'] = Key::KeyZ; } int32_t main(int _argc, char** _argv) @@ -97,6 +208,8 @@ namespace entry bgfx::winSetHwnd(m_hwnd); adjust(DEFAULT_WIDTH, DEFAULT_HEIGHT, true); + m_oldWidth = DEFAULT_WIDTH; + m_oldHeight = DEFAULT_HEIGHT; MainThreadEntry mte; mte.m_argc = _argc; @@ -104,6 +217,7 @@ namespace entry bx::Thread thread; thread.init(mte.threadFunc, &mte); + m_init = true; MSG msg; msg.message = WM_NULL; @@ -121,88 +235,158 @@ namespace entry thread.shutdown(); + DestroyWindow(m_hwnd); + DestroyWindow(hwnd); + return 0; } LRESULT process(HWND _hwnd, UINT _id, WPARAM _wparam, LPARAM _lparam) { - switch (_id) + if (m_init) { - case WM_CLOSE: - TerminateProcess(GetCurrentProcess(), 0); - break; - - case WM_SIZING: + switch (_id) { - RECT clientRect; - GetClientRect(_hwnd, &clientRect); - uint32_t width = clientRect.right-clientRect.left; - uint32_t height = clientRect.bottom-clientRect.top; + case WM_USER_SET_WINDOW_SIZE: + { + uint32_t width = GET_X_LPARAM(_lparam); + uint32_t height = GET_Y_LPARAM(_lparam); + adjust(width, height, true); + } + break; - RECT& rect = *(RECT*)_lparam; - uint32_t frameWidth = rect.right-rect.left - width; - uint32_t frameHeight = rect.bottom-rect.top - height; + case WM_USER_TOGGLE_WINDOW_FRAME: + { + if (m_frame) + { + m_oldWidth = m_width; + m_oldHeight = m_height; + } + adjust(m_oldWidth, m_oldHeight, !m_frame); + } + break; + case WM_DESTROY: + break; + + case WM_QUIT: + case WM_CLOSE: + m_exit = true; + m_eventQueue.postExitEvent(); + break; + + case WM_SIZING: + { + RECT clientRect; + GetClientRect(_hwnd, &clientRect); + uint32_t width = clientRect.right-clientRect.left; + uint32_t height = clientRect.bottom-clientRect.top; + + RECT& rect = *(RECT*)_lparam; + uint32_t frameWidth = rect.right-rect.left - width; + uint32_t frameHeight = rect.bottom-rect.top - height; + + switch (_wparam) + { + case WMSZ_LEFT: + case WMSZ_RIGHT: + { + float aspectRatio = 1.0f/m_aspectRatio; + width = bx::uint32_max(DEFAULT_WIDTH/4, width); + height = uint32_t(float(width)*aspectRatio); + } + break; + + default: + { + float aspectRatio = m_aspectRatio; + height = bx::uint32_max(DEFAULT_HEIGHT/4, height); + width = uint32_t(float(height)*aspectRatio); + } + break; + } + + rect.right = rect.left + width + frameWidth; + rect.bottom = rect.top + height + frameHeight; + + SetWindowPos(_hwnd + , HWND_TOP + , rect.left + , rect.top + , (rect.right-rect.left) + , (rect.bottom-rect.top) + , SWP_SHOWWINDOW + ); + } + return 0; + + case WM_SIZE: + { + m_width = GET_X_LPARAM(_lparam); + m_height = GET_Y_LPARAM(_lparam); + m_eventQueue.postSizeEvent(m_width, m_height); + } + break; + + case WM_SYSCOMMAND: switch (_wparam) { - case WMSZ_LEFT: - case WMSZ_RIGHT: + case SC_MINIMIZE: + case SC_RESTORE: { - float aspectRatio = 1.0f/m_aspectRatio; - width = bx::uint32_max(DEFAULT_WIDTH/4, width); - height = uint32_t(float(width)*aspectRatio); + HWND parent = GetWindow(_hwnd, GW_OWNER); + if (NULL != parent) + { + PostMessage(parent, _id, _wparam, _lparam); + } } - break; - - default: - { - float aspectRatio = m_aspectRatio; - height = bx::uint32_max(DEFAULT_HEIGHT/4, height); - width = uint32_t(float(height)*aspectRatio); - } - break; } + break; - rect.right = rect.left + width + frameWidth; - rect.bottom = rect.top + height + frameHeight; - - SetWindowPos(_hwnd - , HWND_TOP - , rect.left - , rect.top - , (rect.right-rect.left) - , (rect.bottom-rect.top) - , SWP_SHOWWINDOW - ); - } - return 0; - - case WM_SYSCOMMAND: - switch (_wparam) - { - case SC_MINIMIZE: - case SC_RESTORE: + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_LBUTTONDBLCLK: { - HWND parent = GetWindow(_hwnd, GW_OWNER); - if (NULL != parent) - { - PostMessage(parent, _id, _wparam, _lparam); - } + int32_t mx = GET_X_LPARAM(_lparam); + int32_t my = GET_Y_LPARAM(_lparam); + m_eventQueue.postMouseEvent(mx, my, MouseButton::Middle, _id == WM_LBUTTONDOWN); } - } - break; + break; - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - if ((WM_KEYDOWN == _id && VK_F11 == _wparam) - || (WM_SYSKEYDOWN == _id && VK_RETURN == _wparam) ) - { - toggleWindowFrame(); - } - break; + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_MBUTTONDBLCLK: + { + int32_t mx = GET_X_LPARAM(_lparam); + int32_t my = GET_Y_LPARAM(_lparam); + m_eventQueue.postMouseEvent(mx, my, MouseButton::Middle, _id == WM_MBUTTONDOWN); + } + break; - default: - break; + case WM_RBUTTONUP: + case WM_RBUTTONDOWN: + case WM_RBUTTONDBLCLK: + { + int32_t mx = GET_X_LPARAM(_lparam); + int32_t my = GET_Y_LPARAM(_lparam); + m_eventQueue.postMouseEvent(mx, my, MouseButton::Middle, _id == WM_RBUTTONDOWN); + } + break; + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_KEYUP: + case WM_SYSKEYUP: + { + uint8_t modifiers = translateKeyModifiers(); + Key::Enum key = translateKey(_wparam); + m_eventQueue.postKeyEvent(key, modifiers, _id == WM_KEYDOWN || _id == WM_SYSKEYDOWN); + } + break; + + default: + break; + } } return DefWindowProc(_hwnd, _id, _wparam, _lparam); @@ -314,19 +498,20 @@ namespace entry static LRESULT CALLBACK wndProc(HWND _hwnd, UINT _id, WPARAM _wparam, LPARAM _lparam); - void toggleWindowFrame() - { - adjust(m_width, m_height, !m_frame); - } + EventQueue m_eventQueue; HWND m_hwnd; RECT m_rect; DWORD m_style; uint32_t m_width; uint32_t m_height; + uint32_t m_oldWidth; + uint32_t m_oldHeight; float m_aspectRatio; bool m_frame; + bool m_init; bool m_exit; + }; static Context s_ctx; @@ -336,9 +521,32 @@ namespace entry return s_ctx.process(_hwnd, _id, _wparam, _lparam); } - Event::Enum poll() + const Event* poll() { - return Event::Nop; + return s_ctx.m_eventQueue.poll(); + } + + void release(const Event* _event) + { + s_ctx.m_eventQueue.release(_event); + } + + void setWindowSize(uint32_t _width, uint32_t _height) + { + PostMessage(s_ctx.m_hwnd, WM_USER_SET_WINDOW_SIZE, 0, (_height<<16) | (_width&0xffff) ); + } + + void toggleWindowFrame() + { + PostMessage(s_ctx.m_hwnd, WM_USER_TOGGLE_WINDOW_FRAME, 0, 0); + } + + int32_t MainThreadEntry::threadFunc(void* _userData) + { + MainThreadEntry* self = (MainThreadEntry*)_userData; + int32_t result = _main_(self->m_argc, self->m_argv); + PostMessage(s_ctx.m_hwnd, WM_QUIT, 0, 0); + return result; } } // namespace entry diff --git a/examples/common/processevents.h b/examples/common/processevents.h new file mode 100644 index 000000000..481a4244e --- /dev/null +++ b/examples/common/processevents.h @@ -0,0 +1,71 @@ +/* + * Copyright 2011-2013 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#ifndef __PROCESS_EVENTS_H__ +#define __PROCESS_EVENTS_H__ + +inline bool processEvents(uint32_t& _width, uint32_t& _height, uint32_t& _debug) +{ + using namespace entry; + + const Event* ev; + do + { + struct SE { const Event* m_ev; SE() : m_ev(poll() ) {} ~SE() { if (NULL != m_ev) { release(m_ev); } } } scopeEvent; + ev = scopeEvent.m_ev; + + if (NULL != ev) + { + switch (ev->m_type) + { + case Event::Exit: + return true; + + case Event::Key: + { + const KeyEvent* key = static_cast(ev); + if ( (key->m_key == Key::KeyQ && (key->m_modifiers & (Modifier::LeftCtrl|Modifier::RightCtrl) ) ) + || ( (key->m_key == Key::Esc) ) ) + { + return true; + } + else if (key->m_key == Key::F1 && key->m_down) + { + _debug ^= BGFX_DEBUG_STATS; + bgfx::setDebug(_debug); + return false; + } + else if (key->m_key == Key::F10 && key->m_down) + { + setWindowSize(1280, 720); + _width = 1280; + _height = 720; + } + else if (key->m_key == Key::F11 && key->m_down) + { + toggleWindowFrame(); + } + } + break; + + case Event::Size: + { + const SizeEvent* size = static_cast(ev); + bgfx::reset(size->m_width, size->m_height); + _width = size->m_width; + _height = size->m_height; + } + break; + + default: + break; + } + } + } while (NULL != ev); + + return false; +} + +#endif // __PROCESS_EVENTS_H__ diff --git a/include/bgfx.h b/include/bgfx.h index 73b0fd5ea..7fce1e4d8 100644 --- a/include/bgfx.h +++ b/include/bgfx.h @@ -210,9 +210,8 @@ /// #define BGFX_RESET_NONE UINT32_C(0x00000000) #define BGFX_RESET_FULLSCREEN UINT32_C(0x00000001) -#define BGFX_RESET_FULLSCREEN_FAKE UINT32_C(0x00000002) #define BGFX_RESET_FULLSCREEN_SHIFT 0 -#define BGFX_RESET_FULLSCREEN_MASK UINT32_C(0x00000003) +#define BGFX_RESET_FULLSCREEN_MASK UINT32_C(0x00000001) #define BGFX_RESET_MSAA_X2 UINT32_C(0x00000010) #define BGFX_RESET_MSAA_X4 UINT32_C(0x00000020) #define BGFX_RESET_MSAA_X8 UINT32_C(0x00000030) diff --git a/src/bgfx_p.h b/src/bgfx_p.h index c073334a0..1ddaeaec5 100755 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -1473,14 +1473,9 @@ namespace bgfx { m_resolution.m_width = _width; m_resolution.m_height = _height; - m_resolution.m_flags = _flags&(~BGFX_RESET_FULLSCREEN_FAKE); + m_resolution.m_flags = _flags; memset(m_rt, 0xff, sizeof(m_rt) ); - -#if BX_PLATFORM_WINDOWS - uint32_t fullscreen = (_flags&BGFX_RESET_FULLSCREEN_MASK)>>BGFX_RESET_FULLSCREEN_SHIFT; - m_window.adjust(_width, _height, BGFX_RESET_FULLSCREEN_FAKE != fullscreen); -#endif // BX_PLATFORM_WINDOWS } void dbgTextClear(uint8_t _attr, bool _small) @@ -2842,131 +2837,6 @@ namespace bgfx TextVideoMemBlitter m_textVideoMemBlitter; ClearQuad m_clearQuad; -#if BX_PLATFORM_WINDOWS - struct Window - { - Window() - : m_frame(true) - { - } - - void adjust(uint32_t _width, uint32_t _height, bool _windowFrame) - { - m_width = _width; - m_height = _height; - m_aspectRatio = float(_width)/float(_height); - - 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(g_bgfxHwnd, &m_rect); - m_style = GetWindowLong(g_bgfxHwnd, GWL_STYLE); - } - - if (_windowFrame) - { - rect = m_rect; - style = m_style; - } - else - { -#if defined(__MINGW32__) - rect = m_rect; - style = m_style; -#else - HMONITOR monitor = MonitorFromWindow(g_bgfxHwnd, MONITOR_DEFAULTTONEAREST); - MONITORINFO mi; - mi.cbSize = sizeof(mi); - GetMonitorInfo(monitor, &mi); - newrect = mi.rcMonitor; - rect = mi.rcMonitor; -#endif // !defined(__MINGW__) - } - - SetWindowLong(g_bgfxHwnd, GWL_STYLE, style); - AdjustWindowRect(&newrect, style, FALSE); - UpdateWindow(g_bgfxHwnd); - - if (rect.left == -32000 - || rect.top == -32000) - { - rect.left = 0; - rect.top = 0; - } - - int32_t left = rect.left; - int32_t top = rect.top; - int32_t width = (newrect.right-newrect.left); - int32_t height = (newrect.bottom-newrect.top); - - if (!_windowFrame) - { - float aspectRatio = 1.0f/m_aspectRatio; - width = bx::uint32_max(BGFX_DEFAULT_WIDTH/4, width); - height = uint32_t(float(width)*aspectRatio); - - left = newrect.left+(newrect.right-newrect.left-width)/2; - top = newrect.top+(newrect.bottom-newrect.top-height)/2; - } - - HWND parent = GetWindow(g_bgfxHwnd, GW_OWNER); - if (NULL != parent) - { - if (_windowFrame) - { - SetWindowPos(parent - , HWND_TOP - , -32000 - , -32000 - , 0 - , 0 - , SWP_SHOWWINDOW - ); - } - else - { - SetWindowPos(parent - , HWND_TOP - , newrect.left - , newrect.top - , newrect.right-newrect.left - , newrect.bottom-newrect.top - , SWP_SHOWWINDOW - ); - } - } - - SetWindowPos(g_bgfxHwnd - , HWND_TOP - , left - , top - , width - , height - , SWP_SHOWWINDOW - ); - - ShowWindow(g_bgfxHwnd, SW_RESTORE); - - m_frame = _windowFrame; - } - - private: - RECT m_rect; - DWORD m_style; - uint32_t m_width; - uint32_t m_height; - float m_aspectRatio; - bool m_frame; - bool m_update; - }; - - Window m_window; -#endif // BX_PLATFORM_WINDOWS - bool m_rendererInitialized; bool m_exit; }; diff --git a/src/glcontext_egl.cpp b/src/glcontext_egl.cpp index d59d76eb4..ee5414c59 100644 --- a/src/glcontext_egl.cpp +++ b/src/glcontext_egl.cpp @@ -88,37 +88,6 @@ namespace bgfx void GlContext::resize(uint32_t _width, uint32_t _height) { - eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - - eglDestroySurface(m_display, m_surface); - - EGLint attrs[] = - { - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - -# if BX_PLATFORM_ANDROID - EGL_DEPTH_SIZE, 16, -# else - EGL_DEPTH_SIZE, 24, -# endif // BX_PLATFORM_ - - EGL_NONE - }; - - EGLint numConfig = 0; - EGLConfig config; - EGLBoolean success = eglChooseConfig(m_display, attrs, &config, 1, &numConfig); - BGFX_FATAL(success, Fatal::UnableToInitialize, "eglChooseConfig"); - - EGLNativeWindowType nwt = (EGLNativeWindowType)NULL; -# if BX_PLATFORM_WINDOWS - nwt = g_bgfxHwnd; -# endif // BX_PLATFORM_ - - m_surface = eglCreateWindowSurface(m_display, config, nwt, NULL); - BGFX_FATAL(m_surface != EGL_NO_SURFACE, Fatal::UnableToInitialize, "Failed to create surface."); - - eglMakeCurrent(m_display, m_surface, m_surface, m_context); } void GlContext::swap()