diff options
Diffstat (limited to 'Samples/CommonSrc')
31 files changed, 996 insertions, 3431 deletions
diff --git a/Samples/CommonSrc/Platform/Gamepad.h b/Samples/CommonSrc/Platform/Gamepad.h index 95cff10..d078bdb 100644 --- a/Samples/CommonSrc/Platform/Gamepad.h +++ b/Samples/CommonSrc/Platform/Gamepad.h @@ -24,9 +24,9 @@ limitations under the License. #ifndef OVR_Gamepad_h #define OVR_Gamepad_h -#include <OVR.h> +#include <OVR_Kernel.h> -namespace OVR { namespace Platform { +namespace OVR { namespace OvrPlatform { // Buttons on a typical gamepad controller. enum GamepadButtons @@ -57,7 +57,7 @@ enum GamepadButtons // Describes the state of the controller buttons and analog inputs. struct GamepadState { - UInt32 Buttons; // Bitfield representing button state. + uint32_t Buttons; // Bitfield representing button state. float LX; // Left stick X axis [-1,1] float LY; // Left stick Y axis [-1,1] float RX; // Right stick X axis [-1,1] @@ -91,12 +91,12 @@ class GamepadManager : public RefCountBase<GamepadManager> public: // Get the number of connected gamepads. - virtual UInt32 GetGamepadCount() = 0; + virtual uint32_t GetGamepadCount() = 0; // Get the state of the gamepad with a given index. - virtual bool GetGamepadState(UInt32 index, GamepadState* pState) = 0; + virtual bool GetGamepadState(uint32_t index, GamepadState* pState) = 0; }; -}} // OVR::Platform +}} // OVR::OvrPlatform #endif // OVR_Gamepad_h diff --git a/Samples/CommonSrc/Platform/Linux_Gamepad.cpp b/Samples/CommonSrc/Platform/Linux_Gamepad.cpp deleted file mode 100644 index 1546768..0000000 --- a/Samples/CommonSrc/Platform/Linux_Gamepad.cpp +++ /dev/null @@ -1,453 +0,0 @@ -/************************************************************************************ - -Filename : Linux_Gamepad.cpp -Content : Linux implementation of Platform app infrastructure -Created : May 6, 2013 -Authors : Lee Cooper, Simon Hallam - -Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <glob.h> -#include <linux/joystick.h> -#include "Linux_Gamepad.h" - - -namespace OVR { namespace Platform { namespace Linux { - -const char* pNameXbox360Wireless = "Xbox 360"; -const char* pNameXbox360Wired = "Microsoft X-Box 360"; - - -GamepadManager::GamepadManager() : - pDevice(NULL) -{ -} - -GamepadManager::~GamepadManager() -{ - // if we have an open device, close it - if (pDevice) - { - pDevice->Close(); - pDevice = NULL; - } -} - -UInt32 GamepadManager::GetGamepadCount() -{ - return 1; -} - -bool GamepadManager::GetGamepadState(UInt32 index, GamepadState *pState) -{ - if (!pDevice) - { - // get a list of paths to all the connected joystick devices - glob_t joystickGlobBuffer; - glob("/dev/input/js*", 0, NULL, &joystickGlobBuffer); - - // open each joystick device, until we find one that will work for our needs - for (UInt32 i = 0; i < joystickGlobBuffer.gl_pathc; i++) - { - pDevice = new Gamepad(); - if (pDevice->Open(joystickGlobBuffer.gl_pathv[i])) - { - - if (pDevice->IsSupportedType()) - { - break; - } - } - - // we don't know why the device was not useable, make sure it gets closed cleanly - pDevice->Close(); - pDevice = NULL; - } - - } - - if (pDevice) - { - // we have a device, so update it - pDevice->UpdateState(); - - // copy the device state into the struct param - memcpy(pState, pDevice->GetState(), sizeof(GamepadState)); - - // TODO: is the device still active/connected? if not, we should close it - // and clear pDevice, so that another device can take over - - return true; - } - else - { - return false; - } -} - -Gamepad::Gamepad() : - IsInitialized(false), - Name(String("Undefined")), - Type(UNDEFINED) -{ -} - -Gamepad::~Gamepad() -{ - this->Close(); -} - -bool Gamepad::Open(const String& devicePathName) -{ - Name = "Undefined"; - Type = UNDEFINED; - - FileDescriptor = ::open(devicePathName.ToCStr(), O_RDONLY | O_NONBLOCK); - if (FileDescriptor == -1) - { - return false; - } - - // get the device name - char name[128]; - if (ioctl(FileDescriptor, JSIOCGNAME(sizeof(name)), name) < 0) - { - return false; - } - - Name = name; - - // see if device name matches one of our supported devices - static const UInt32 Wireless360Len = String(pNameXbox360Wireless).GetLength(); - static const UInt32 Wired360Len = String(pNameXbox360Wired).GetLength(); - if (Name.Substring(0, Wireless360Len) == pNameXbox360Wireless) - { - Type = XBOX360GAMEPADWIRELESS; - return true; - } - else if(Name.Substring(0, Wired360Len) == pNameXbox360Wired) - { - Type = XBOX360GAMEPADWIRED; - return true; - } - - return false; -} - -bool Gamepad::Close() -{ - IsInitialized = false; - Name = "Undefined"; - Type = UNDEFINED; - return !::close(FileDescriptor); -} - -void Gamepad::UpdateState() -{ - GamepadState *pState = &State; - js_event gamepadEvent; - - // read the latest batch of events - while (read(FileDescriptor, &gamepadEvent, sizeof(struct js_event)) != -1) - { - switch (gamepadEvent.type) - { - case JS_EVENT_BUTTON: - IsInitialized = true; - SetStateButton(pState, gamepadEvent.number, gamepadEvent.value); - break; - - case JS_EVENT_AXIS: - IsInitialized = true; - SetStateAxis(pState, gamepadEvent.number, gamepadEvent.value); - break; - - case JS_EVENT_BUTTON | JS_EVENT_INIT: - if (IsInitialized) // skip the fake values during device event initialization - { - SetStateButton(pState, gamepadEvent.number, gamepadEvent.value); - } - break; - - case JS_EVENT_AXIS | JS_EVENT_INIT: - if (IsInitialized) // skip the fake values during device event initialization - { - SetStateAxis(pState, gamepadEvent.number, gamepadEvent.value); - } - break; - - default: - LogText("OVR::Linux::UpdateState unknown event type\n"); - } - } -} - -const GamepadState* Gamepad::GetState() -{ - return &State; -} - - -bool Gamepad::IsSupportedType() -{ - return Type != UNDEFINED; -} - -const String& Gamepad::GetIdentifier() -{ - return Name; -} - -static inline float NormalizeGamepadStickXbox360(SInt32 in) -{ - float v; - if (abs(in) < 9000) return 0; - else if (in > 9000) v = (float)in - 9000; - else v = (float)in + 9000; - return v / (32767 - 9000); -} - -static inline float NormalizeGamepadTriggerXbox360(SInt32 in, - SInt32 offset, - SInt32 deadBand, - float divisor) -{ - in += offset; - - if (in < deadBand) - { - return 0; - } - else - { - return float(in - deadBand) / divisor; - } -} - -static inline void UpdateButtonMaskAndBitfield(GamepadState *pState, - SInt32 value, - UInt32 buttonBitfield) -{ - if (value) - { - pState->Buttons |= buttonBitfield; - } - else - { - pState->Buttons = pState->Buttons & (0xFFFFFFFF ^ buttonBitfield); - } -} - -void Gamepad::SetStateAxis(GamepadState *pState, UInt32 axis, SInt32 value) -{ - // some pads/sticks have lots in common with one another, - // handle those shared cases first - switch (Type) - { - case XBOX360GAMEPADWIRELESS: - case XBOX360GAMEPADWIRED: - switch (axis) - { - case 0: - pState->LX = NormalizeGamepadStickXbox360(value); - break; - - case 1: - pState->LY = -NormalizeGamepadStickXbox360(value); - break; - - case 3: - pState->RX = NormalizeGamepadStickXbox360(value); - break; - - case 4: - pState->RY = -NormalizeGamepadStickXbox360(value); - break; - } - break; - - case UNDEFINED: - default: - break; - } - - // handle the special cases, or pads/sticks which are unique - switch (Type) - { - case XBOX360GAMEPADWIRELESS: - switch (axis) - { - case 2: - pState->LT = NormalizeGamepadTriggerXbox360(value, 0, 500, 32267); - break; - - case 5: - pState->RT = NormalizeGamepadTriggerXbox360(value, 0, 500, 32267); - break; - } - break; - - case XBOX360GAMEPADWIRED: - switch (axis) - { - case 2: - pState->LT = NormalizeGamepadTriggerXbox360(value, 32767, 1000, 64535); - break; - - case 5: - pState->RT = NormalizeGamepadTriggerXbox360(value, 32767, 1000, 64535); - break; - - case 6: - if (value == 0) - { - UpdateButtonMaskAndBitfield(pState, 0, Gamepad_Left); - UpdateButtonMaskAndBitfield(pState, 0, Gamepad_Right); - } - else if (value < 0) - { - UpdateButtonMaskAndBitfield(pState, 1, Gamepad_Left); - } - else if (value > 0) - { - UpdateButtonMaskAndBitfield(pState, 1, Gamepad_Right); - } - break; - - case 7: - if (value == 0) - { - UpdateButtonMaskAndBitfield(pState, 0, Gamepad_Up); - UpdateButtonMaskAndBitfield(pState, 0, Gamepad_Down); - } - else if (value < 0) - { - UpdateButtonMaskAndBitfield(pState, 1, Gamepad_Up); - } - else if (value > 0) - { - UpdateButtonMaskAndBitfield(pState, 1, Gamepad_Down); - } - break; - } - break; - - case UNDEFINED: - default: - break; - } -} - -void Gamepad::SetStateButton(GamepadState *pState, UInt32 button, SInt32 value) -{ - // some pads/sticks have lots in common with one another, - // handle those shared cases first - switch (Type) - { - case XBOX360GAMEPADWIRELESS: - case XBOX360GAMEPADWIRED: - switch (button) - { - case 0: - UpdateButtonMaskAndBitfield(pState, value, Gamepad_A); - break; - - case 1: - UpdateButtonMaskAndBitfield(pState, value, Gamepad_B); - break; - - case 2: - UpdateButtonMaskAndBitfield(pState, value, Gamepad_X); - break; - - case 3: - UpdateButtonMaskAndBitfield(pState, value, Gamepad_Y); - break; - - case 4: - UpdateButtonMaskAndBitfield(pState, value, Gamepad_L1); - break; - - case 5: - UpdateButtonMaskAndBitfield(pState, value, Gamepad_R1); - break; - - case 6: - UpdateButtonMaskAndBitfield(pState, value, Gamepad_Back); - break; - - case 7: - UpdateButtonMaskAndBitfield(pState, value, Gamepad_Start); - break; - - case 8: - // we have no value defined for the Xbox/power button - break; - - case 9: - UpdateButtonMaskAndBitfield(pState, value, Gamepad_LStick); - break; - - case 10: - UpdateButtonMaskAndBitfield(pState, value, Gamepad_RStick); - break; - } - break; - - case UNDEFINED: - default: - break; - } - - // handle the special cases, or pads/sticks which are unique - switch (Type) - { - case XBOX360GAMEPADWIRELESS: - switch (button) - { - case 11: - UpdateButtonMaskAndBitfield(pState, value, Gamepad_Left); - break; - - case 12: - UpdateButtonMaskAndBitfield(pState, value, Gamepad_Right); - break; - - case 13: - UpdateButtonMaskAndBitfield(pState, value, Gamepad_Up); - break; - - case 14: - UpdateButtonMaskAndBitfield(pState, value, Gamepad_Down); - break; - } - - case XBOX360GAMEPADWIRED: - break; - - case UNDEFINED: - default: - break; - } -} - -}}} // OVR::Platform::Linux - diff --git a/Samples/CommonSrc/Platform/Linux_Gamepad.h b/Samples/CommonSrc/Platform/Linux_Gamepad.h deleted file mode 100644 index 762d7a9..0000000 --- a/Samples/CommonSrc/Platform/Linux_Gamepad.h +++ /dev/null @@ -1,83 +0,0 @@ -/************************************************************************************ - -Filename : Linux_Gamepad.h -Content : Linux implementation of Gamepad functionality. -Created : May 6, 2013 -Authors : Lee Cooper, Simon Hallam - -Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Linux_Gamepad_h -#define OVR_Linux_Gamepad_h - -#include "Gamepad.h" - -namespace OVR { namespace Platform { namespace Linux { - -class Gamepad; // forward declaration for readability - -class GamepadManager : public Platform::GamepadManager -{ -public: - - GamepadManager(); - ~GamepadManager(); - - virtual UInt32 GetGamepadCount(); - virtual bool GetGamepadState(UInt32 index, GamepadState *pState); - -private: - - Gamepad *pDevice; -}; - -class Gamepad -{ -public: - - Gamepad(); - virtual ~Gamepad(); - - bool Open(const String& devicePathName); - bool Close(); - bool IsSupportedType(); - const String& GetIdentifier(); - void UpdateState(); - const GamepadState* GetState(); - -private: - - void SetStateAxis(GamepadState *pState, UInt32 axis, SInt32 value); - void SetStateButton(GamepadState *pState, UInt32 button, SInt32 value); - - enum GamepadType - { - UNDEFINED, - XBOX360GAMEPADWIRELESS, - XBOX360GAMEPADWIRED - }; - - UInt32 FileDescriptor; - bool IsInitialized; - String Name; - GamepadType Type; - GamepadState State; -}; - -}}} - -#endif // OVR_Linux_Gamepad_h diff --git a/Samples/CommonSrc/Platform/Linux_Platform.cpp b/Samples/CommonSrc/Platform/Linux_Platform.cpp deleted file mode 100644 index bf84270..0000000 --- a/Samples/CommonSrc/Platform/Linux_Platform.cpp +++ /dev/null @@ -1,784 +0,0 @@ -/************************************************************************************ - -Filename : Platform_Linux.cpp -Content : Linux (X11) implementation of Platform app infrastructure -Created : September 6, 2012 -Authors : Andrew Reisse - -Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "Kernel/OVR_System.h" -#include "Kernel/OVR_Array.h" -#include "Kernel/OVR_String.h" -#include "Kernel/OVR_Timer.h" -#include "OVR_CAPI_GL.h" - -#include "Linux_Platform.h" -#include "Linux_Gamepad.h" - -// Renderers -#include "../Render/Render_GL_Device.h" - -#include "../../3rdParty/EDID/edid.h" -#include <X11/extensions/Xinerama.h> -#include <X11/extensions/Xrandr.h> - - -namespace OVR { namespace Platform { namespace Linux { - -static const char *AtomNames[] = {"WM_PROTOCOLS", "WM_DELETE_WINDOW"}; - -PlatformCore::PlatformCore(Application* app) - : Platform::PlatformCore(app), Disp(NULL), Win(0), Vis(NULL), Quit(0), MMode(Mouse_Normal) - , StartVP(0, 0, 0, 0) -{ - pGamepadManager = *new Linux::GamepadManager(); -} -PlatformCore::~PlatformCore() -{ - XFreeCursor(Disp, InvisibleCursor); - - if (Disp) - XCloseDisplay(Disp); -} - -// Setup an X11 window in windowed mode. -bool PlatformCore::SetupWindow(int w, int h) -{ - - if (!Disp) - { - XInitThreads(); - - Disp = XOpenDisplay(NULL); - if (!Disp) - { - OVR_DEBUG_LOG(("XOpenDisplay failed.")); - return false; - } - - XInternAtoms(Disp, const_cast<char**>(AtomNames), NumAtoms, false, Atoms); - } - - XSetWindowAttributes winattr; - unsigned attrmask = CWEventMask | CWBorderPixel; - - winattr.event_mask = ButtonPressMask|ButtonReleaseMask|KeyPressMask|KeyReleaseMask|ButtonMotionMask|PointerMotionMask| - /*PointerMotionHintMask|*/StructureNotifyMask;//|ExposureMask; - winattr.border_pixel = 0; - - int screenNumber = DefaultScreen(Disp); - - if (!Vis) - { - int attr[16]; - int nattr = 2; - - attr[0] = GLX_RGBA; - attr[1] = GLX_DOUBLEBUFFER; - attr[nattr++] = GLX_DEPTH_SIZE; - attr[nattr++] = 24; - attr[nattr] = 0; - - Vis = glXChooseVisual(Disp, screenNumber, attr); - - if (!Vis) - { - OVR_DEBUG_LOG(("glXChooseVisual failed.")); - return false; - } - } - - Window rootWindow = XRootWindow(Disp, Vis->screen); - - winattr.colormap = XCreateColormap(Disp, rootWindow, Vis->visual, AllocNone); - attrmask |= CWColormap; - - - Win = XCreateWindow(Disp, rootWindow, 0, 0, w, h, 0, Vis->depth, - InputOutput, Vis->visual, attrmask, &winattr); - - if (!Win) - { - OVR_DEBUG_LOG(("XCreateWindow failed.")); - return false; - } - - - XStoreName(Disp, Win, "OVR App"); - XSetWMProtocols(Disp, Win, &Atoms[WM_DELETE_WINDOW], 1); - - // Intialize empty cursor for show/hide. - XColor black; - static char noData[] = { 0,0,0,0,0,0,0,0 }; - black.red = black.green = black.blue = 0; - - Pixmap bitmapNoData = XCreateBitmapFromData(Disp, Win, noData, 8, 8); - InvisibleCursor = XCreatePixmapCursor(Disp, bitmapNoData, bitmapNoData, - &black, &black, 0, 0); - XDefineCursor(Disp, Win, InvisibleCursor); - - Width = w; - Height = h; - - return true; -} - -void PlatformCore::SetMouseMode(MouseMode mm) -{ - if (mm == MMode) - return; - - if (Win) - { - if (mm == Mouse_Relative) - { - XWarpPointer(Disp, Win, Win, 0,0,Width,Height, Width/2, Height/2); - } - else - { - //if (MMode == Mouse_Relative) - // ShowCursor(TRUE); - } - } - MMode = mm; -} - -void PlatformCore::GetWindowSize(int* w, int* h) const -{ - *w = Width; - *h = Height; -} - -void PlatformCore::SetWindowTitle(const char* title) -{ - XStoreName(Disp, Win, title); -} - -void PlatformCore::ShowWindow(bool show) -{ - if (show) - XRaiseWindow(Disp, Win); - else - XIconifyWindow(Disp, Win, 0); -} - -void PlatformCore::DestroyWindow() -{ - if (Win) - XDestroyWindow(Disp, Win); - Win = 0; -} - - -static int KeyMap[][2] = -{ - { XK_BackSpace, Key_Backspace }, - { XK_Tab, Key_Tab }, - { XK_Clear, Key_Clear }, - { XK_Return, Key_Return }, - { XK_Shift_L, Key_Shift }, - { XK_Control_L, Key_Control }, - { XK_Alt_L, Key_Alt }, - { XK_Shift_R, Key_Shift }, - { XK_Control_R, Key_Control }, - { XK_Alt_R, Key_Alt }, - { XK_Pause, Key_Pause }, - { XK_Caps_Lock, Key_CapsLock }, - { XK_Escape, Key_Escape }, - { XK_space, Key_Space }, - { XK_Page_Up, Key_PageUp }, - { XK_Page_Down, Key_PageDown }, - { XK_Prior, Key_PageUp }, - { XK_Next, Key_PageDown }, - { XK_End, Key_End }, - { XK_Home, Key_Home }, - { XK_Left, Key_Left }, - { XK_Up, Key_Up }, - { XK_Right, Key_Right }, - { XK_Down, Key_Down }, - { XK_Insert, Key_Insert }, - { XK_Delete, Key_Delete }, - { XK_Help, Key_Help }, - { XK_Num_Lock, Key_NumLock }, - { XK_Scroll_Lock, Key_ScrollLock }, -}; - - -static KeyCode MapXKToKeyCode(unsigned vk) -{ - unsigned key = Key_None; - - if ((vk >= 'a') && (vk <= 'z')) - { - key = vk - 'a' + Key_A; - } - else if ((vk >= ' ') && (vk <= '~')) - { - key = vk; - } - else if ((vk >= XK_KP_0) && (vk <= XK_KP_9)) - { - key = vk - XK_KP_0 + Key_KP_0; - } - else if ((vk >= XK_F1) && (vk <= XK_F15)) - { - key = vk - XK_F1 + Key_F1; - } - else - { - for (unsigned i = 0; i< (sizeof(KeyMap) / sizeof(KeyMap[1])); i++) - { - if (vk == KeyMap[i][0]) - { - key = KeyMap[i][1]; - break; - } - } - } - - return (KeyCode)key; -} - -static int MapModifiers(int xmod) -{ - int mod = 0; - if (xmod & ShiftMask) - mod |= Mod_Shift; - if (xmod & ControlMask) - mod |= Mod_Control; - if (xmod & Mod1Mask) - mod |= Mod_Alt; - if (xmod & Mod4Mask) - mod |= Mod_Meta; - return mod; -} - -void PlatformCore::processEvent(XEvent& event) -{ - switch (event.xany.type) - { - case ConfigureNotify: - if (event.xconfigure.width != Width || event.xconfigure.height != Height) - { - Width = event.xconfigure.width; - Height = event.xconfigure.height; - pApp->OnResize(Width, Height); - - if (pRender) - pRender->SetWindowSize(Width, Height); - } - break; - - case KeyPress: - case KeyRelease: - { - char chars[8] = {0}; - KeySym xk; - XComposeStatus comp; - XLookupString(&event.xkey, chars, sizeof(chars), &xk, &comp); - if (xk != XK_VoidSymbol) - pApp->OnKey(MapXKToKeyCode((unsigned)xk), chars[0], event.xany.type == KeyPress, MapModifiers(event.xkey.state)); - if (xk == XK_Escape && MMode == Mouse_Relative) - { - //ungrab - MMode = Mouse_RelativeEscaped; - showCursor(true); - } - } - break; - - case MotionNotify: - if (MMode == Mouse_Relative) - { - int dx = event.xmotion.x - Width/2; - int dy = event.xmotion.y - Height/2; - - // do not remove this check, WarpPointer generates events too. - if (dx == 0 && dy == 0) - break; - - XWarpPointer(Disp, Win, Win, 0,0,Width,Height, Width/2, Height/2); - pApp->OnMouseMove(dx, dy, Mod_MouseRelative|MapModifiers(event.xmotion.state)); - } - else - { - pApp->OnMouseMove(event.xmotion.x, event.xmotion.y, MapModifiers(event.xmotion.state)); - } - break; - - case MapNotify: - if (MMode == Mouse_Relative) - { - XWarpPointer(Disp, Win, Win, 0,0,Width,Height, Width/2, Height/2); - showCursor(false); - } - break; - - case ButtonPress: - if (event.xbutton.button == 1) - { - //grab - - if (MMode == Mouse_RelativeEscaped) - { - XWarpPointer(Disp, Win, Win, 0,0,Width,Height, Width/2, Height/2); - showCursor(false); - MMode = Mouse_Relative; - } - } - break; - - case FocusOut: - if (MMode == Mouse_Relative) - { - MMode = Mouse_RelativeEscaped; - showCursor(true); - } - break; - - case ClientMessage: - if (event.xclient.message_type == Atoms[WM_PROTOCOLS] && - Atom(event.xclient.data.l[0]) == Atoms[WM_DELETE_WINDOW]) - pApp->OnQuitRequest(); - break; - } -} - -int PlatformCore::Run() -{ - while (!Quit) - { - if (XPending(Disp)) - { - XEvent event; - XNextEvent(Disp, &event); - - if (pApp && event.xany.window == Win) - processEvent(event); - } - else - { - pApp->OnIdle(); - } - } - - return ExitCode; -} - -bool PlatformCore::determineScreenOffset(int screenId, int* screenOffsetX, int* screenOffsetY) -{ - Display* display = XOpenDisplay(NULL); - - bool foundScreen = false; - - if (display) - { - int numberOfScreens; - XineramaScreenInfo* screens = XineramaQueryScreens(display, &numberOfScreens); - - if (screenId < numberOfScreens) - { - XineramaScreenInfo screenInfo = screens[screenId]; - *screenOffsetX = screenInfo.x_org; - *screenOffsetY = screenInfo.y_org; - - foundScreen = true; - } - - XFree(screens); - } - - return foundScreen; -} - -void PlatformCore::showWindowDecorations(bool show) -{ - // Declaration of 'MOTIF_WM_HINTS' struct and flags can be found at: - // https://people.gnome.org/~tthurman/docs/metacity/xprops_8h-source.html - typedef struct WMHints - { - unsigned long flags; - unsigned long functions; - unsigned long decorations; - long inputMode; - unsigned long status; - } Hints; - - #define MWM_DECOR_ALL (1L << 0) - #define MWM_DECOR_BORDER (1L << 1) - #define MWM_DECOR_RESIZEH (1L << 2) - #define MWM_DECOR_TITLE (1L << 3) - #define MWM_DECOR_MENU (1L << 4) - #define MWM_DECOR_MINIMIZE (1L << 5) - #define MWM_DECOR_MAXIMIZE (1L << 6) - - Atom property = XInternAtom(Disp, "_MOTIF_WM_HINTS", true); - - Hints hints; - hints.flags = 2; // We only want to specify decoration. - - if (show) - { - hints.decorations = MWM_DECOR_BORDER | MWM_DECOR_TITLE | MWM_DECOR_MENU | MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE; - } - else - { - // Remove all window border items. - hints.decorations = 0; - } - - XChangeProperty(Disp,Win,property,property,32,PropModeReplace,(unsigned char *)&hints,5); -} - -int PlatformCore::IndexOf(Render::DisplayId id) -{ - RROutput primaryOutput = XRRGetOutputPrimary(Disp, DefaultRootWindow(Disp)); - if (id.CgDisplayId == 0 && primaryOutput != 0) - return 0; - - int index = (primaryOutput != 0) ? 0 : -1; - XRRScreenResources *screen = XRRGetScreenResources(Disp, Win); - for (int i = 0; i < screen->noutput && i <= id.CgDisplayId; ++i) - { - RROutput output = screen->outputs[i]; - MonitorInfo * mi = read_edid_data(Disp, output); - if (mi != NULL && (primaryOutput == 0 || output != primaryOutput)) - ++index; - - delete mi; - } - XRRFreeScreenResources(screen); - - return index; -} - -bool PlatformCore::SetFullscreen(const Render::RendererParams& rp, int fullscreen) -{ - if (fullscreen == pRender->GetParams().Fullscreen) - return false; - - int displayIndex = IndexOf(rp.Display); - OVR_DEBUG_LOG(("Display %d has index %d", rp.Display.CgDisplayId, displayIndex)); - - if (pRender->GetParams().Fullscreen == Render::Display_Window) - { - // Save the original window size and position so we can restore later. - - XWindowAttributes xwa; - XGetWindowAttributes(Disp, Win, &xwa); - int x, y; - Window unused; - XTranslateCoordinates(Disp, Win, DefaultRootWindow(Disp), xwa.x, xwa.y, &x, &y, &unused); - - StartVP.w = Width; - StartVP.h = Height; - StartVP.x = x; - StartVP.y = y; - } - else if (pRender->GetParams().Fullscreen == Render::Display_Fullscreen) - { -// if (StartMode == NULL) -// return true; - -// XF86VidModeSwitchToMode(Disp, 0, StartMode); -// XF86VidModeSetViewPort(Disp, Win, 0, 0); - { - XEvent xev; - memset(&xev, 0, sizeof(xev)); - - xev.type = ClientMessage; - xev.xclient.window = Win; - xev.xclient.message_type = XInternAtom( Disp, "_NET_WM_STATE", False); - xev.xclient.format = 32; - xev.xclient.data.l[0] = 0; - xev.xclient.data.l[1] = XInternAtom( Disp, "_NET_WM_STATE_FULLSCREEN", False); - xev.xclient.data.l[2] = 0; - - XSendEvent( Disp, DefaultRootWindow( Disp ), False, SubstructureNotifyMask, &xev); - } - -// XWindowAttributes windowattr; -// XGetWindowAttributes(Disp, Win, &windowattr); -// Width = windowattr.width; -// Height = windowattr.height; -// pApp->OnResize(Width, Height); - -// if (pRender) -// pRender->SetWindowSize(Width, Height); - - XWindowChanges wc; - wc.width = StartVP.w; - wc.height = StartVP.h; - wc.x = StartVP.x; - wc.y = StartVP.y; - - XConfigureWindow(Disp, Win, CWWidth | CWHeight | CWX | CWY, &wc); - - showWindowDecorations(false); - } - - if (fullscreen == Render::Display_FakeFullscreen) - { - // Transitioning from windowed to fake fullscreen. - int xOffset; - int yOffset; - - if (!determineScreenOffset(displayIndex, &xOffset, &yOffset)) - { - return false; - } - - showWindowDecorations(false); - - XMoveWindow(Disp, Win, xOffset, yOffset); - XMapRaised(Disp, Win); - } - else if (fullscreen == Render::Display_Window) - { - // Transitioning from fake fullscreen to windowed. - showWindowDecorations(true); - - XMoveWindow(Disp, Win, StartVP.x, StartVP.y); - XMapRaised(Disp, Win); - } - else if (fullscreen == Render::Display_Fullscreen) - { - // Move, size, and decorate the window for fullscreen. - - int xOffset; - int yOffset; - - if (!determineScreenOffset(displayIndex, &xOffset, &yOffset)) - return false; - - showWindowDecorations(false); - - XWindowChanges wc; - wc.x = xOffset; - wc.y = yOffset; - wc.stack_mode = 0; - - XConfigureWindow(Disp, Win, CWX | CWY | CWStackMode, &wc); - - // Change the display mode. - -// XF86VidModeModeInfo **modes = NULL; -// int modeNum = 0; -// if (!XF86VidModeGetAllModeLines(Disp, 0, &modeNum, &modes)) -// return false; - -// OVR_ASSERT(modeNum > 0); -// StartMode = modes[0]; - -// int bestMode = -1; -// for (int i = 0; i < modeNum; i++) -// { -// if ((modes[i]->hdisplay == Width) && (modes[i]->vdisplay == Height)) -// bestMode = i; -// } - -// if (bestMode == -1) -// return false; - -// XF86VidModeSwitchToMode(Disp, 0, modes[bestMode]); - //XF86VidModeSetViewPort(Disp, Win, 0, 0); - - // Make the window fullscreen in the window manager. - - { - XEvent xev; - memset(&xev, 0, sizeof(xev)); - - xev.type = ClientMessage; - xev.xclient.window = Win; - xev.xclient.message_type = XInternAtom( Disp, "_NET_WM_STATE", False); - xev.xclient.format = 32; - xev.xclient.data.l[0] = 1; - xev.xclient.data.l[1] = XInternAtom( Disp, "_NET_WM_STATE_FULLSCREEN", False); - xev.xclient.data.l[2] = 0; - - XSendEvent( Disp, DefaultRootWindow( Disp ), False, SubstructureNotifyMask, &xev); - } - } - - XMapRaised(Disp, Win); - - Platform::PlatformCore::SetFullscreen(rp, fullscreen); - return true; -} - -int PlatformCore::GetDisplayCount() -{ - int numberOfScreens = 0; - XineramaScreenInfo* screens = XineramaQueryScreens(Disp, &numberOfScreens); - XFree(screens); - return numberOfScreens; -} - -Render::DisplayId PlatformCore::GetDisplay(int screenId) -{ - char device_id[32] = ""; - int displayId = 0; - - int screensPassed = 0; - - RROutput primaryOutput = XRRGetOutputPrimary(Disp, DefaultRootWindow(Disp)); - - XRRScreenResources *screen = XRRGetScreenResources(Disp, Win); - for (int i = 0; i < screen->noutput; ++i) - { - RROutput output = screen->outputs[i]; - MonitorInfo * mi = read_edid_data(Disp, output); - if (mi == NULL) - continue; - - bool isMyScreen = - (primaryOutput == 0) ? screensPassed++ > screenId : - (output == primaryOutput) ? screenId == 0 : - ++screensPassed >= screenId; - if (isMyScreen) - { - OVR_sprintf(device_id, 32, "%s%04d", mi->manufacturer_code, mi->product_code); - displayId = (screenId == 0 && primaryOutput != 0) ? 0 : i; // Require 0 to return the primary display - delete mi; - break; - } - - delete mi; - } - XRRFreeScreenResources(screen); - - return Render::DisplayId(device_id, displayId); -} - -RenderDevice* PlatformCore::SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc, - const char* type, const Render::RendererParams& rp) -{ - const SetupGraphicsDeviceSet* setupDesc = setupGraphicsDesc.PickSetupDevice(type); - OVR_ASSERT(setupDesc); - - pRender = *setupDesc->pCreateDevice(rp, this); - if (pRender) - pRender->SetWindowSize(Width, Height); - - return pRender.GetPtr(); -} - -void PlatformCore::showCursor(bool show) -{ - if (show) - { - XUndefineCursor(Disp, Win); - } - else - { - XDefineCursor(Disp, Win, InvisibleCursor); - } -} - -}} - -// GL -namespace Render { namespace GL { namespace Linux { - -ovrRenderAPIConfig RenderDevice::Get_ovrRenderAPIConfig() const -{ - static ovrGLConfig cfg; - cfg.OGL.Header.API = ovrRenderAPI_OpenGL; - cfg.OGL.Header.RTSize = Sizei(WindowWidth, WindowHeight); - cfg.OGL.Header.Multisample = Params.Multisample; - cfg.OGL.Win = Win; - cfg.OGL.Disp = Disp; - return cfg.Config; -} - -Render::RenderDevice* RenderDevice::CreateDevice(const RendererParams& rp, void* oswnd) -{ - Platform::Linux::PlatformCore* PC = (Platform::Linux::PlatformCore*)oswnd; - - GLXContext context = glXCreateContext(PC->Disp, PC->Vis, 0, GL_TRUE); - - if (!context) - return NULL; - - if (!glXMakeCurrent(PC->Disp, PC->Win, context)) - { - glXDestroyContext(PC->Disp, context); - return NULL; - } - - XMapRaised(PC->Disp, PC->Win); - - InitGLExtensions(); - - XSync(PC->Disp, 0); - - for (XWindowAttributes attribute; attribute.map_state != IsViewable; ) - XGetWindowAttributes(PC->Disp,PC->Win,&attribute); - - XSetInputFocus(PC->Disp, PC->Win, RevertToParent, CurrentTime); - - return new Render::GL::Linux::RenderDevice(rp, PC->Disp, PC->Win, context); -} - -void RenderDevice::Present(bool withVsync) -{ - unsigned swapInterval = (withVsync) ? 1 : 0; - GLuint currentSwapInterval = 0; - glXQueryDrawable(Disp, Win, GLX_SWAP_INTERVAL_EXT, ¤tSwapInterval); - if (currentSwapInterval != swapInterval) - glXSwapIntervalEXT(Disp, Win, swapInterval); - - glXSwapBuffers(Disp, Win); -} - -void RenderDevice::Shutdown() -{ - if (Context) - { - glXMakeCurrent(Disp, 0, NULL); - glXDestroyContext(Disp, Context); - Context = NULL; - Win = 0; - } -} - -}}}} - - -int main(int argc, const char* argv[]) -{ - using namespace OVR; - using namespace OVR::Platform; - - // CreateApplication must be the first call since it does OVR::System::Initialize. - Application* app = Application::CreateApplication(); - Linux::PlatformCore* platform = new Linux::PlatformCore(app); - // The platform attached to an app will be deleted by DestroyApplication. - app->SetPlatformCore(platform); - - int exitCode = app->OnStartup(argc, argv); - if (!exitCode) - exitCode = platform->Run(); - - // No OVR functions involving memory are allowed after this. - Application::DestroyApplication(app); - app = 0; - - return exitCode; -} diff --git a/Samples/CommonSrc/Platform/Linux_Platform.h b/Samples/CommonSrc/Platform/Linux_Platform.h deleted file mode 100644 index f2e438e..0000000 --- a/Samples/CommonSrc/Platform/Linux_Platform.h +++ /dev/null @@ -1,147 +0,0 @@ -/************************************************************************************ - -Filename : Platform_Linux.h -Content : Linux (X11) implementation of Platform app infrastructure -Created : September 6, 2012 -Authors : Andrew Reisse - -Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Platform_Linux_h -#define OVR_Platform_Linux_h - -#include "Platform.h" -#include "../Render/Render_GL_Device.h" - -#include <GL/glx.h> -#include <X11/extensions/xf86vmode.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> - -namespace OVR { namespace Render { - class RenderDevice; -}} - -namespace OVR { namespace Platform { namespace Linux { - -class PlatformCore : public Platform::PlatformCore -{ - XF86VidModeModeInfo* StartMode; - Recti StartVP; - - int IndexOf(Render::DisplayId id); - -public: - Display* Disp; - XVisualInfo* Vis; - Window Win; - - bool Quit; - int ExitCode; - int Width, Height; - - MouseMode MMode; - Cursor InvisibleCursor; - - enum - { - WM_PROTOCOLS, - WM_DELETE_WINDOW, - NumAtoms - }; - Atom Atoms[NumAtoms]; - - void processEvent(XEvent& event); - - Render::RenderDevice* SetupGraphics_GL(const Render::RendererParams& rp); - - void showCursor(bool show); - bool determineScreenOffset(int screenId, int* screenOffsetX, int* screenOffsetY); - void showWindowDecorations(bool show); - -public: - PlatformCore(Application* app); - ~PlatformCore(); - - bool SetupWindow(int w, int h); - void Exit(int exitcode) { Quit = 1; ExitCode = exitcode; } - - RenderDevice* SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc, - const char* gtype, const Render::RendererParams& rp); - - void SetMouseMode(MouseMode mm); - void GetWindowSize(int* w, int* h) const; - - void SetWindowTitle(const char*title); - - void ShowWindow(bool show); - void DestroyWindow(); - bool SetFullscreen(const Render::RendererParams& rp, int fullscreen); - int GetDisplayCount(); - Render::DisplayId GetDisplay(int screen); - - int Run(); -}; - -}} -namespace Render { namespace GL { namespace Linux { - -class RenderDevice : public Render::GL::RenderDevice -{ - Display* Disp; - Window Win; - GLXContext Context; - -public: - RenderDevice(const Render::RendererParams& p, Display* disp, Window w, GLXContext gl) - : GL::RenderDevice(p), Disp(disp), Win(w), Context(gl) {} - - virtual void Shutdown(); - virtual void Present(bool withVsync); - virtual ovrRenderAPIConfig Get_ovrRenderAPIConfig() const; - - // oswnd = Linux::PlatformCore* - static Render::RenderDevice* CreateDevice(const RendererParams& rp, void* oswnd); -}; - -}}}} - - -// OVR_PLATFORM_APP_ARGS specifies the Application class to use for startup, -// providing it with startup arguments. -#define OVR_PLATFORM_APP_ARGS(AppClass, args) \ - OVR::Platform::Application* OVR::Platform::Application::CreateApplication() \ - { OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All)); \ - return new AppClass args; } \ - void OVR::Platform::Application::DestroyApplication(OVR::Platform::Application* app) \ - { OVR::Platform::PlatformCore* platform = app->pPlatform; \ - delete app; delete platform; OVR::System::Destroy(); }; - -// OVR_PLATFORM_APP_ARGS specifies the Application startup class with no args. -#define OVR_PLATFORM_APP(AppClass) OVR_PLATFORM_APP_ARGS(AppClass, ()) - -#define OVR_PLATFORM_APP_ARGS_WITH_LOG(AppClass, LogClass, args) \ - OVR::Platform::Application* OVR::Platform::Application::CreateApplication() \ - { static LogClass log; OVR::System::Init(&log); \ - return new AppClass args; } \ - void OVR::Platform::Application::DestroyApplication(OVR::Platform::Application* app) \ - { OVR::Platform::PlatformCore* platform = app->pPlatform; \ - delete app; delete platform; OVR::System::Destroy(); }; - -#define OVR_PLATFORM_APP_WITH_LOG(AppClass,LogClass) OVR_PLATFORM_APP_ARGS_WITH_LOG(AppClass,LogClass, ()) - -#endif diff --git a/Samples/CommonSrc/Platform/OSX_Gamepad.cpp b/Samples/CommonSrc/Platform/OSX_Gamepad.cpp deleted file mode 100644 index 36f8109..0000000 --- a/Samples/CommonSrc/Platform/OSX_Gamepad.cpp +++ /dev/null @@ -1,430 +0,0 @@ -/************************************************************************************ - -Filename : OSX_Gamepad.cpp -Content : OSX implementation of Gamepad functionality. -Created : May 6, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OSX_Gamepad.h" - - -static const UInt32 Logitech_F710_VendorID = 0x046D; -//static const UInt32 Logitech_F710_ProductID = 0xC219; - -static const UInt32 Sony_DualShock3_VendorID = 0x054C; -//static const UInt32 Sony_DualShock3_ProductID = 0x0268; - - -namespace OVR { namespace Platform { namespace OSX { - - -GamepadManager::GamepadManager() - : bStateChanged(false) -{ - - HidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); - IOHIDManagerOpen(HidManager, kIOHIDOptionsTypeNone); - IOHIDManagerScheduleWithRunLoop(HidManager, - CFRunLoopGetCurrent(), - kCFRunLoopDefaultMode); - - - // Setup device matching. - CFStringRef keys[] = { CFSTR(kIOHIDDeviceUsagePageKey), - CFSTR(kIOHIDDeviceUsageKey)}; - - int value; - CFNumberRef values[2]; - CFDictionaryRef dictionaries[2]; - - // Match joysticks. - value = kHIDPage_GenericDesktop; - values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); - - value = kHIDUsage_GD_Joystick; - values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); - - dictionaries[0] = CFDictionaryCreate(kCFAllocatorDefault, - (const void **) keys, - (const void **) values, - 2, - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFRelease(values[0]); - CFRelease(values[1]); - - // Match gamepads. - value = kHIDPage_GenericDesktop; - values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); - - value = kHIDUsage_GD_GamePad; - values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); - - dictionaries[1] = CFDictionaryCreate(kCFAllocatorDefault, - (const void **) keys, - (const void **) values, - 2, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CFRelease(values[0]); - CFRelease(values[1]); - - CFArrayRef array = CFArrayCreate( kCFAllocatorDefault, - (const void **) dictionaries, - 2, - &kCFTypeArrayCallBacks); - CFRelease(dictionaries[0]); - CFRelease(dictionaries[1]); - - IOHIDManagerSetDeviceMatchingMultiple(HidManager, array); - - CFRelease(array); - - - IOHIDManagerRegisterDeviceMatchingCallback(HidManager, staticOnDeviceMatched, this); - IOHIDManagerRegisterDeviceRemovalCallback(HidManager, staticOnDeviceRemoved, this); - -} - -GamepadManager::~GamepadManager() -{ - CFRelease(HidManager); -} - -UInt32 GamepadManager::GetGamepadCount() -{ - return 1; -} - -bool GamepadManager::GetGamepadState(UInt32 index, GamepadState* pState) -{ - // For now we just support one gamepad. - OVR_UNUSED(index); - - if (!bStateChanged) - { - return false; - } - - bStateChanged = false; -// State.Debug(); - - *pState = State; - return true; -} - -int GamepadManager::getIntDeviceProperty(IOHIDDeviceRef device, CFStringRef key) -{ - CFTypeRef type = IOHIDDeviceGetProperty(device, key); - OVR_ASSERT(type != NULL && CFGetTypeID(type) == CFNumberGetTypeID()); - - int value; - CFNumberGetValue((CFNumberRef) type, kCFNumberSInt32Type, &value); - - return value; -} - -void GamepadManager::staticOnDeviceMatched(void* context, IOReturn result, void* sender, IOHIDDeviceRef device) -{ - OVR_UNUSED(result); - OVR_UNUSED(sender); - GamepadManager* pManager = (GamepadManager*) context; - pManager->onDeviceMatched(device); -} - -void GamepadManager::onDeviceMatched(IOHIDDeviceRef device) -{ - IOHIDDeviceRegisterInputValueCallback(device, staticOnDeviceValueChanged, this); -} - -void GamepadManager::staticOnDeviceRemoved(void* context, IOReturn result, void* sender, IOHIDDeviceRef device) -{ - OVR_UNUSED(result); - OVR_UNUSED(sender); - GamepadManager* pManager = (GamepadManager*) context; - pManager->onDeviceRemoved(device); -} - -void GamepadManager::onDeviceRemoved(IOHIDDeviceRef device) -{ - IOHIDDeviceRegisterInputValueCallback(device, NULL, NULL); -} - -void GamepadManager::staticOnDeviceValueChanged(void* context, IOReturn result, void* sender, IOHIDValueRef value) -{ - OVR_UNUSED(result); - OVR_UNUSED(sender); - GamepadManager* pManager = (GamepadManager*) context; - pManager->onDeviceValueChanged(value); -} - -float GamepadManager::mapAnalogAxis(IOHIDValueRef value, IOHIDElementRef element) -{ - - CFIndex val = IOHIDValueGetIntegerValue(value); - CFIndex min = IOHIDElementGetLogicalMin(element); - CFIndex max = IOHIDElementGetLogicalMax(element); - - float v = (float) (val - min) / (float) (max - min); - v = v * 2.0f - 1.0f; - - // Dead zone. - if (v < 0.1f && v > -0.1f) - { - v = 0.0f; - } - - return v; -} - -bool GamepadManager::setStateIfDifferent(float& state, float newState) -{ - if (state == newState) - return false; - - state = newState; - - return true; -} - -void GamepadManager::onDeviceValueChanged(IOHIDValueRef value) -{ - - IOHIDElementRef element = IOHIDValueGetElement(value); - IOHIDDeviceRef device = IOHIDElementGetDevice(element); - - unsigned int vendorID = (unsigned int)getIntDeviceProperty(device, CFSTR(kIOHIDVendorIDKey)); - unsigned int productID = (unsigned int)getIntDeviceProperty(device, CFSTR(kIOHIDProductIDKey)); - OVR_UNUSED(productID); - - uint32_t usagePage = IOHIDElementGetUsagePage(element); - uint32_t usage = IOHIDElementGetUsage(element); - - // The following controller mapping is based on the Logitech F710, however we use it for - // all Logitech devices on the assumption that they're likely to share the same mapping. - if (vendorID == Logitech_F710_VendorID) - { - // Logitech F710 mapping. - if (usagePage == kHIDPage_Button) - { - bool buttonState = IOHIDValueGetIntegerValue(value); - - switch(usage) - { - case kHIDUsage_Button_1: - manipulateBitField(State.Buttons, Gamepad_X, buttonState); - break; - case kHIDUsage_Button_2: - manipulateBitField(State.Buttons, Gamepad_A, buttonState); - break; - case kHIDUsage_Button_3: - manipulateBitField(State.Buttons, Gamepad_B, buttonState); - break; - case kHIDUsage_Button_4: - manipulateBitField(State.Buttons, Gamepad_Y, buttonState); - break; - case 0x05: - manipulateBitField(State.Buttons, Gamepad_L1, buttonState); - break; - case 0x06: - manipulateBitField(State.Buttons, Gamepad_R1, buttonState); - break; - case 0x07: - State.LT = buttonState ? 1.0f:0.0f; - break; - case 0x08: - State.RT = buttonState ? 1.0f:0.0f; - break; - case 0x09: - manipulateBitField(State.Buttons, Gamepad_Back, buttonState); - break; - case 0x0A: - manipulateBitField(State.Buttons, Gamepad_Start, buttonState); - break; - case 0x0B: - manipulateBitField(State.Buttons, Gamepad_LStick, buttonState); - break; - case 0x0C: - manipulateBitField(State.Buttons, Gamepad_RStick, buttonState); - break; - default: - return; - } - } - else if (usagePage == kHIDPage_GenericDesktop) - { - float v; - switch(usage) - { - case kHIDUsage_GD_X: - v = mapAnalogAxis(value, element); - if (!setStateIfDifferent(State.LX, v)) - return; - break; - case kHIDUsage_GD_Y: - v = mapAnalogAxis(value, element); - if (!setStateIfDifferent(State.LY, -v)) - return; - break; - case kHIDUsage_GD_Z: - v = mapAnalogAxis(value, element); - if (!setStateIfDifferent(State.RX, v)) - return; - break; - case kHIDUsage_GD_Rz: - v = mapAnalogAxis(value, element); - if (!setStateIfDifferent(State.RY, -v)) - return; - break; - case kHIDUsage_GD_Hatswitch: - { - CFIndex integerValue = IOHIDValueGetIntegerValue(value); - - manipulateBitField(State.Buttons, - Gamepad_Up, - integerValue == 7 || integerValue == 0 || integerValue == 1); - manipulateBitField(State.Buttons, - Gamepad_Down, - integerValue == 3 || integerValue == 4 || integerValue == 5); - manipulateBitField(State.Buttons, - Gamepad_Left, - integerValue == 5 || integerValue == 6 || integerValue == 7); - manipulateBitField(State.Buttons, - Gamepad_Right, - integerValue == 1 || integerValue == 2 || integerValue == 3); - } - break; - default: - return; - } - } - } - // The following controller mapping is based on the Sony DualShock3, however we use it for - // all Sony devices on the assumption that they're likely to share the same mapping. - else if (vendorID == Sony_DualShock3_VendorID) - { - // PS3 Controller. - if (usagePage == kHIDPage_Button) - { - bool buttonState = IOHIDValueGetIntegerValue(value); - - switch(usage) - { - case kHIDUsage_Button_1: - manipulateBitField(State.Buttons, Gamepad_Back, buttonState); - break; - case kHIDUsage_Button_2: - manipulateBitField(State.Buttons, Gamepad_LStick, buttonState); - break; - case kHIDUsage_Button_3: - manipulateBitField(State.Buttons, Gamepad_RStick, buttonState); - break; - case kHIDUsage_Button_4: - manipulateBitField(State.Buttons, Gamepad_Start, buttonState); - break; - case 0x05: - manipulateBitField(State.Buttons, Gamepad_Up, buttonState); - break; - case 0x06: - manipulateBitField(State.Buttons, Gamepad_Right, buttonState); - break; - case 0x07: - manipulateBitField(State.Buttons, Gamepad_Down, buttonState); - break; - case 0x08: - manipulateBitField(State.Buttons, Gamepad_Left, buttonState); - break; - case 0x09: - State.LT = buttonState ? 1.0f:0.0f; - break; - case 0x0A: - State.RT = buttonState ? 1.0f:0.0f; - break; - case 0x0B: - manipulateBitField(State.Buttons, Gamepad_L1, buttonState); - break; - case 0x0C: - manipulateBitField(State.Buttons, Gamepad_R1, buttonState); - break; - case 0x0D: - // PS3 Triangle. - manipulateBitField(State.Buttons, Gamepad_TRIANGLE, buttonState); - break; - case 0x0E: - // PS3 Circle - manipulateBitField(State.Buttons, Gamepad_CIRCLE, buttonState); - break; - case 0x0F: - // PS3 Cross - manipulateBitField(State.Buttons, Gamepad_CROSS, buttonState); - break; - case 0x10: - // PS3 Square - manipulateBitField(State.Buttons, Gamepad_SQUARE, buttonState); - break; - default: - return; - } - } - else if (usagePage == kHIDPage_GenericDesktop) - { - float v; - switch(usage) - { - case kHIDUsage_GD_X: - v = mapAnalogAxis(value, element); - if (!setStateIfDifferent(State.LX, v)) - return; - break; - case kHIDUsage_GD_Y: - v = mapAnalogAxis(value, element); - if (!setStateIfDifferent(State.LY, -v)) - return; - break; - case kHIDUsage_GD_Z: - v = mapAnalogAxis(value, element); - if (!setStateIfDifferent(State.RX, v)) - return; - break; - case kHIDUsage_GD_Rz: - v = mapAnalogAxis(value, element); - if (!setStateIfDifferent(State.RY, -v)) - return; - break; - default: - return; - } - } - } - - bStateChanged = true; -} - -void GamepadManager::manipulateBitField(unsigned int& bitfield, unsigned int mask, bool val) -{ - if (val) - { - bitfield |= mask; - } - else - { - bitfield &= ~mask; - } -} - -}}} // OVR::Platform::OSX diff --git a/Samples/CommonSrc/Platform/OSX_Gamepad.h b/Samples/CommonSrc/Platform/OSX_Gamepad.h deleted file mode 100644 index 27a0948..0000000 --- a/Samples/CommonSrc/Platform/OSX_Gamepad.h +++ /dev/null @@ -1,66 +0,0 @@ -/************************************************************************************ - -Filename : OSX_Gamepad.h -Content : OSX implementation of Gamepad functionality. -Created : May 6, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_OSX_Gamepad_h -#define OVR_OSX_Gamepad_h - -#include <IOKit/IOKitLib.h> -#include <IOKit/hid/IOHIDManager.h> - -#include "Gamepad.h" - -namespace OVR { namespace Platform { namespace OSX { - - -class GamepadManager : public Platform::GamepadManager -{ -public: - GamepadManager(); - ~GamepadManager(); - - virtual UInt32 GetGamepadCount(); - virtual bool GetGamepadState(UInt32 index, GamepadState* pState); - -private: - static void staticOnDeviceMatched(void* context, IOReturn result, void* sender, IOHIDDeviceRef device); - void onDeviceMatched(IOHIDDeviceRef device); - - static void staticOnDeviceRemoved(void* context, IOReturn result, void* sender, IOHIDDeviceRef device); - void onDeviceRemoved(IOHIDDeviceRef device); - - static void staticOnDeviceValueChanged(void* context, IOReturn result, void* sender, IOHIDValueRef value); - void onDeviceValueChanged(IOHIDValueRef value); - - int getIntDeviceProperty(IOHIDDeviceRef device, CFStringRef key); - float mapAnalogAxis(IOHIDValueRef value, IOHIDElementRef element); - void manipulateBitField(unsigned int& bitfield, unsigned int mask, bool val); - bool setStateIfDifferent(float& state, float newState); - - IOHIDManagerRef HidManager; - GamepadState State; - bool bStateChanged; -}; - -}}} - -#endif // OVR_OSX_Gamepad_h diff --git a/Samples/CommonSrc/Platform/OSX_Platform.h b/Samples/CommonSrc/Platform/OSX_Platform.h deleted file mode 100644 index 5aa8ee1..0000000 --- a/Samples/CommonSrc/Platform/OSX_Platform.h +++ /dev/null @@ -1,113 +0,0 @@ -/************************************************************************************ - -Filename : OSX_Platform.h -Content : -Created : -Authors : - -Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "../Platform/Platform.h" -#include "../Render/Render_GL_Device.h" - -namespace OVR { namespace Platform { namespace OSX { - -class PlatformCore : public Platform::PlatformCore -{ -public: - void* Win; - void* View; - void* NsApp; - bool Quit; - int ExitCode; - int Width, Height; - MouseMode MMode; - - void RunIdle(); - -public: - PlatformCore(Application* app, void* nsapp); - ~PlatformCore(); - - bool SetupWindow(int w, int h); - void Exit(int exitcode); - - RenderDevice* SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc, - const char* gtype, const Render::RendererParams& rp); - - void SetMouseMode(MouseMode mm); - void GetWindowSize(int* w, int* h) const; - - void SetWindowTitle(const char*title); - - void ShowWindow(bool show); - void DestroyWindow(); - bool SetFullscreen(const Render::RendererParams& rp, int fullscreen); - int GetDisplayCount(); - Render::DisplayId GetDisplay(int screen); - - String GetContentDirectory() const; -}; - -}} -namespace Render { namespace GL { namespace OSX { - -class RenderDevice : public Render::GL::RenderDevice -{ -public: - void* Context; - - RenderDevice(const Render::RendererParams& p, void* context) - : GL::RenderDevice(p), Context(context) {} - - virtual void Shutdown(); - virtual void Present(bool useVsync); - - virtual bool SetFullscreen(DisplayMode fullscreen); - - virtual ovrRenderAPIConfig Get_ovrRenderAPIConfig() const; - - // oswnd = X11::PlatformCore* - static Render::RenderDevice* CreateDevice(const RendererParams& rp, void* oswnd); -}; - -}}}} - - -// OVR_PLATFORM_APP_ARGS specifies the Application class to use for startup, -// providing it with startup arguments. -#define OVR_PLATFORM_APP_ARGS_WITH_LOG(AppClass, LogClass, args) \ -OVR::Platform::Application* OVR::Platform::Application::CreateApplication() \ -{ static LogClass log; OVR::System::Init(&log); \ -return new AppClass args; } \ -void OVR::Platform::Application::DestroyApplication(OVR::Platform::Application* app) \ -{ OVR::Platform::PlatformCore* platform = app->pPlatform; \ -delete app; delete platform; OVR::System::Destroy(); }; - -#define OVR_PLATFORM_APP_ARGS(AppClass, args) \ - OVR::Platform::Application* OVR::Platform::Application::CreateApplication() \ -{ OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All)); \ - return new AppClass args; } \ - void OVR::Platform::Application::DestroyApplication(OVR::Platform::Application* app) \ -{ OVR::Platform::PlatformCore* platform = app->pPlatform; \ - delete app; delete platform; OVR::System::Destroy(); }; - -// OVR_PLATFORM_APP_ARGS specifies the Application startup class with no args. -#define OVR_PLATFORM_APP(AppClass) OVR_PLATFORM_APP_ARGS(AppClass, ()) - -#define OVR_PLATFORM_APP_WITH_LOG(AppClass,LogClass) OVR_PLATFORM_APP_ARGS_WITH_LOG(AppClass,LogClass, ()) - diff --git a/Samples/CommonSrc/Platform/OSX_Platform.mm b/Samples/CommonSrc/Platform/OSX_Platform.mm deleted file mode 100644 index 1f9ea68..0000000 --- a/Samples/CommonSrc/Platform/OSX_Platform.mm +++ /dev/null @@ -1,553 +0,0 @@ -/************************************************************************************ - -Filename : OSX_Platform.mm -Content : -Created : -Authors : - -Copyright : Copyright 2012 Oculus, Inc. All Rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#import "../Platform/OSX_PlatformObjc.h" - -using namespace OVR; -using namespace OVR::Platform; - -@implementation OVRApp - -- (void)dealloc -{ - [super dealloc]; -} - -- (void)run -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - _running = YES; - OVR::Platform::Application* app; - { - using namespace OVR; - using namespace OVR::Platform; - - // CreateApplication must be the first call since it does OVR::System::Initialize. - app = Application::CreateApplication(); - OSX::PlatformCore* platform = new OSX::PlatformCore(app, self); - // The platform attached to an app will be deleted by DestroyApplication. - app->SetPlatformCore(platform); - - [self setApp:app]; - [self setPlatform:platform]; - - const char* argv[] = {"OVRApp"}; - int exitCode = app->OnStartup(1, argv); - if (exitCode) - { - Application::DestroyApplication(app); - exit(exitCode); - } - } - [self finishLaunching]; - [pool drain]; - - while ([self isRunning]) - { - pool = [[NSAutoreleasePool alloc] init]; - NSEvent* event = [self nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES]; - if (event) - { - [self sendEvent:event]; - } - _App->OnIdle(); - [pool drain]; - } - OVR::Platform::Application::DestroyApplication(app); -} - -@end - -static int KeyMap[][2] = -{ - { NSDeleteFunctionKey, OVR::Key_Delete }, - { '\t', OVR::Key_Tab }, - { '\n', OVR::Key_Return }, - { NSPauseFunctionKey, OVR::Key_Pause }, - { 27, OVR::Key_Escape }, - { 127, OVR::Key_Backspace }, - { ' ', OVR::Key_Space }, - { NSPageUpFunctionKey, OVR::Key_PageUp }, - { NSPageDownFunctionKey, OVR::Key_PageDown }, - { NSNextFunctionKey, OVR::Key_PageDown }, - { NSEndFunctionKey, OVR::Key_End }, - { NSHomeFunctionKey, OVR::Key_Home }, - { NSLeftArrowFunctionKey, OVR::Key_Left }, - { NSUpArrowFunctionKey, OVR::Key_Up }, - { NSRightArrowFunctionKey, OVR::Key_Right }, - { NSDownArrowFunctionKey, OVR::Key_Down }, - { NSInsertFunctionKey, OVR::Key_Insert }, - { NSDeleteFunctionKey, OVR::Key_Delete }, - { NSHelpFunctionKey, OVR::Key_Insert }, -}; - - -static KeyCode MapToKeyCode(wchar_t vk) -{ - unsigned key = Key_None; - - if ((vk >= 'a') && (vk <= 'z')) - { - key = vk - 'a' + Key_A; - } - else if ((vk >= ' ') && (vk <= '~')) - { - key = vk; - } - else if ((vk >= '0') && (vk <= '9')) - { - key = vk - '0' + Key_Num0; - } - else if ((vk >= NSF1FunctionKey) && (vk <= NSF15FunctionKey)) - { - key = vk - NSF1FunctionKey + Key_F1; - } - else - { - for (unsigned i = 0; i< (sizeof(KeyMap) / sizeof(KeyMap[1])); i++) - { - if (vk == KeyMap[i][0]) - { - key = KeyMap[i][1]; - break; - } - } - } - - return (KeyCode)key; -} - -static int MapModifiers(unsigned long xmod) -{ - int mod = 0; - if (xmod & NSShiftKeyMask) - mod |= OVR::Platform::Mod_Shift; - if (xmod & NSCommandKeyMask) - mod |= OVR::Platform::Mod_Control; - if (xmod & NSAlternateKeyMask) - mod |= OVR::Platform::Mod_Alt; - if (xmod & NSControlKeyMask) - mod |= OVR::Platform::Mod_Meta; - return mod; -} - -@implementation OVRView - --(BOOL) acceptsFirstResponder -{ - return YES; -} --(BOOL) acceptsFirstMouse:(NSEvent *)ev -{ - return YES; -} - -+(CGDirectDisplayID) displayFromScreen:(NSScreen *)s -{ - NSNumber* didref = (NSNumber*)[[s deviceDescription] objectForKey:@"NSScreenNumber"]; - CGDirectDisplayID disp = (CGDirectDisplayID)[didref longValue]; - return disp; -} - --(void) warpMouseToCenter -{ - NSPoint w; - w.x = _Platform->Width/2.0f; - w.y = _Platform->Height/2.0f; - w = [[self window] convertBaseToScreen:w]; - CGDirectDisplayID disp = [OVRView displayFromScreen:[[self window] screen]]; - CGPoint p = {w.x, CGDisplayPixelsHigh(disp)-w.y}; - CGDisplayMoveCursorToPoint(disp, p); -} - -static bool LookupKey(NSEvent* ev, wchar_t& ch, OVR::KeyCode& key, unsigned& mods) -{ - NSString* chars = [ev charactersIgnoringModifiers]; - if ([chars length] == 0) - return false; - ch = [chars characterAtIndex:0]; - mods = MapModifiers([ev modifierFlags]); - - // check for Cmd+Latin Letter - NSString* modchars = [ev characters]; - if ([modchars length]) - { - wchar_t modch = [modchars characterAtIndex:0]; - if (modch >= 'a' && modch <= 'z') - ch = modch; - } - key = MapToKeyCode(ch); - return true; -} - --(void) keyDown:(NSEvent*)ev -{ - OVR::KeyCode key; - unsigned mods; - wchar_t ch; - if (!LookupKey(ev, ch, key, mods)) - return; - if (key == Key_Escape && _Platform->MMode == Mouse_Relative) - { - [self warpMouseToCenter]; - CGAssociateMouseAndMouseCursorPosition(true); - [NSCursor unhide]; - _Platform->MMode = Mouse_RelativeEscaped; - } - _App->OnKey(key, ch, true, mods); -} --(void) keyUp:(NSEvent*)ev -{ - OVR::KeyCode key; - unsigned mods; - wchar_t ch; - if (LookupKey(ev, ch, key, mods)) - _App->OnKey(key, ch, false, mods); -} - -static const OVR::KeyCode ModifierKeys[] = {OVR::Key_None, OVR::Key_Shift, OVR::Key_Control, OVR::Key_Alt, OVR::Key_Meta}; - --(void)flagsChanged:(NSEvent *)ev -{ - unsigned long cmods = [ev modifierFlags]; - if ((cmods & 0xffff0000) != _Modifiers) - { - uint32_t mods = MapModifiers(cmods); - for (int i = 1; i <= 4; i++) - { - unsigned long m = (1 << (16+i)); - if ((cmods & m) != (_Modifiers & m)) - { - if (cmods & m) - _App->OnKey(ModifierKeys[i], 0, true, mods); - else - _App->OnKey(ModifierKeys[i], 0, false, mods); - } - } - _Modifiers = cmods & 0xffff0000; - } -} - --(void)ProcessMouse:(NSEvent*)ev -{ - switch ([ev type]) - { - case NSLeftMouseDragged: - case NSRightMouseDragged: - case NSOtherMouseDragged: - case NSMouseMoved: - { - if (_Platform->MMode == OVR::Platform::Mouse_Relative) - { - int dx = [ev deltaX]; - int dy = [ev deltaY]; - - if (dx != 0 || dy != 0) - { - _App->OnMouseMove(dx, dy, Mod_MouseRelative|MapModifiers([ev modifierFlags])); - [self warpMouseToCenter]; - } - } - else - { - NSPoint p = [ev locationInWindow]; - _App->OnMouseMove(p.x, p.y, MapModifiers([ev modifierFlags])); - } - } - break; - case NSLeftMouseDown: - case NSRightMouseDown: - case NSOtherMouseDown: - break; - } -} - --(void) mouseMoved:(NSEvent*)ev -{ - [self ProcessMouse:ev]; -} --(void) mouseDragged:(NSEvent*)ev -{ - [self ProcessMouse:ev]; -} --(void) mouseDown:(NSEvent*)ev -{ - if (_Platform->MMode == Mouse_RelativeEscaped) - { - [self warpMouseToCenter]; - CGAssociateMouseAndMouseCursorPosition(false); - [NSCursor hide]; - _Platform->MMode = Mouse_Relative; - } -} - -//-(void) - --(id) initWithFrame:(NSRect)frameRect -{ - NSOpenGLPixelFormatAttribute attr[] = - { -// NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, -// NSOpenGLPFAWindow, - NSOpenGLPFADoubleBuffer, - NSOpenGLPFADepthSize, 24, - nil - }; - - NSOpenGLPixelFormat *pf = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attr] autorelease]; - - self = [super initWithFrame:frameRect pixelFormat:pf]; - GLint swap = 0; - [[self openGLContext] setValues:&swap forParameter:NSOpenGLCPSwapInterval]; - //[self setWantsBestResolutionOpenGLSurface:YES]; - return self; -} - --(void) reshape -{ - NSRect bounds = [self bounds]; - _App->OnResize(bounds.size.width, bounds.size.height); - - _Platform->Width = bounds.size.width; - _Platform->Height = bounds.size.height; - - if (_Platform->GetRenderer()) - _Platform->GetRenderer()->SetWindowSize(bounds.size.width, bounds.size.height); -} - --(BOOL)windowShouldClose:(id)sender -{ - if (_Platform) - _Platform->Exit(0); - else - exit(0); - return 1; -} - -@end - -namespace OVR { namespace Platform { namespace OSX { - -PlatformCore::PlatformCore(Application* app, void* nsapp) - : Platform::PlatformCore(app), NsApp(nsapp), Win(NULL), View(NULL), Quit(0), MMode(Mouse_Normal) -{ - pGamepadManager = *new OSX::GamepadManager(); -} -PlatformCore::~PlatformCore() -{ -} - -void PlatformCore::Exit(int exitcode) -{ - OVRApp* nsApp = (OVRApp*)NsApp; - [nsApp stop:nil]; -} - -String PlatformCore::GetContentDirectory() const -{ - NSBundle* bundle = [NSBundle mainBundle]; - if (bundle) - return String([[bundle bundlePath] UTF8String]) + "/Contents/Resources"; - else - return "."; -} - - -void PlatformCore::SetMouseMode(MouseMode mm) -{ - if (mm == MMode) - return; - - if (Win) - { - if (mm == Mouse_Relative) - { - [NSCursor hide]; - [(OVRView*)View warpMouseToCenter]; - CGAssociateMouseAndMouseCursorPosition(false); - } - else - { - if (MMode == Mouse_Relative) - { - CGAssociateMouseAndMouseCursorPosition(true); - [NSCursor unhide]; - [(OVRView*)View warpMouseToCenter]; - } - } - } - MMode = mm; -} - - -void PlatformCore::GetWindowSize(int* w, int* h) const -{ - *w = Width; - *h = Height; -} - -bool PlatformCore::SetupWindow(int w, int h) -{ - NSRect winrect; - winrect.origin.x = 0; - winrect.origin.y = 1000; - winrect.size.width = w; - winrect.size.height = h; - NSWindow* win = [[NSWindow alloc] initWithContentRect:winrect styleMask:NSTitledWindowMask|NSClosableWindowMask backing:NSBackingStoreBuffered defer:NO]; - - OVRView* view = [[OVRView alloc] initWithFrame:winrect]; - [view setPlatform:this]; - [win setContentView:view]; - [win setAcceptsMouseMovedEvents:YES]; - [win setDelegate:view]; - [view setApp:pApp]; - Win = win; - View = view; - return 1; -} - -void PlatformCore::SetWindowTitle(const char* title) -{ - [((NSWindow*)Win) setTitle:[[NSString alloc] initWithBytes:title length:strlen(title) encoding:NSUTF8StringEncoding]]; -} - -void PlatformCore::ShowWindow(bool show) -{ - if (show) - [((NSWindow*)Win) makeKeyAndOrderFront:nil]; - else - [((NSWindow*)Win) orderOut:nil]; -} - -void PlatformCore::DestroyWindow() -{ - [((NSWindow*)Win) close]; - Win = NULL; -} - -RenderDevice* PlatformCore::SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc, - const char* type, const Render::RendererParams& rp) -{ - const SetupGraphicsDeviceSet* setupDesc = setupGraphicsDesc.PickSetupDevice(type); - OVR_ASSERT(setupDesc); - - pRender = *setupDesc->pCreateDevice(rp, this); - if (pRender) - pRender->SetWindowSize(Width, Height); - - return pRender.GetPtr(); -} - -int PlatformCore::GetDisplayCount() -{ - return (int)[[NSScreen screens] count]; -} - -Render::DisplayId PlatformCore::GetDisplay(int i) -{ - NSScreen* s = (NSScreen*)[[NSScreen screens] objectAtIndex:i]; - return Render::DisplayId([OVRView displayFromScreen:s]); -} - -bool PlatformCore::SetFullscreen(const Render::RendererParams& rp, int fullscreen) -{ - if (fullscreen == Render::Display_Window) - [(OVRView*)View exitFullScreenModeWithOptions:nil]; - else - { - NSScreen* usescreen = [NSScreen mainScreen]; - NSArray* screens = [NSScreen screens]; - for (int i = 0; i < [screens count]; i++) - { - NSScreen* s = (NSScreen*)[screens objectAtIndex:i]; - CGDirectDisplayID disp = [OVRView displayFromScreen:s]; - - if (disp == rp.Display.CgDisplayId) - usescreen = s; - } - - [(OVRView*)View enterFullScreenMode:usescreen withOptions:nil]; - [(NSWindow*)Win setInitialFirstResponder:(OVRView*)View]; - [(NSWindow*)Win makeFirstResponder:(OVRView*)View]; - } - - if (pRender) - pRender->SetFullscreen((Render::DisplayMode)fullscreen); - return 1; -} - -}} -// GL -namespace Render { namespace GL { namespace OSX { - -ovrRenderAPIConfig RenderDevice::Get_ovrRenderAPIConfig() const -{ - ovrRenderAPIConfig result = ovrRenderAPIConfig(); - result.Header.API = ovrRenderAPI_OpenGL; - result.Header.RTSize = Sizei(WindowWidth, WindowHeight); - result.Header.Multisample = Params.Multisample; - return result; -} - -Render::RenderDevice* RenderDevice::CreateDevice(const RendererParams& rp, void* oswnd) -{ - Platform::OSX::PlatformCore* PC = (Platform::OSX::PlatformCore*)oswnd; - - OVRView* view = (OVRView*)PC->View; - NSOpenGLContext *context = [view openGLContext]; - if (!context) - return NULL; - - [context makeCurrentContext]; - [((NSWindow*)PC->Win) makeKeyAndOrderFront:nil]; - - return new Render::GL::OSX::RenderDevice(rp, context); -} - -void RenderDevice::Present(bool useVsync) -{ - NSOpenGLContext *context = (NSOpenGLContext*)Context; - [context flushBuffer]; -} - -void RenderDevice::Shutdown() -{ - Context = NULL; -} - -bool RenderDevice::SetFullscreen(DisplayMode fullscreen) -{ - Params.Fullscreen = fullscreen; - return 1; -} - -}}}} - - -int main(int argc, char *argv[]) -{ - NSApplication* nsapp = [OVRApp sharedApplication]; - [nsapp run]; - return 0; -} - diff --git a/Samples/CommonSrc/Platform/OSX_PlatformObjc.h b/Samples/CommonSrc/Platform/OSX_PlatformObjc.h deleted file mode 100644 index 8ef1ba2..0000000 --- a/Samples/CommonSrc/Platform/OSX_PlatformObjc.h +++ /dev/null @@ -1,53 +0,0 @@ -/*********************************************************************** - -Filename : OSX_PlatformObjc.h -Content : -Created : -Authors : - -Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************/ - -#import <Cocoa/Cocoa.h> -#import "OSX_Platform.h" -#import "OSX_Gamepad.h" - -#import <CoreGraphics/CoreGraphics.h> -#import <CoreGraphics/CGDirectDisplay.h> - -@interface OVRApp : NSApplication - -@property (assign) IBOutlet NSWindow* win; -@property (assign) OVR::Platform::OSX::PlatformCore* Platform; -@property (assign) OVR::Platform::Application* App; - --(void) run; - -@end - -@interface OVRView : NSOpenGLView <NSWindowDelegate> - -@property (assign) OVR::Platform::OSX::PlatformCore* Platform; -@property (assign) OVR::Platform::Application* App; -@property unsigned long Modifiers; - --(void)ProcessMouse:(NSEvent*)event; --(void)warpMouseToCenter; - -+(CGDirectDisplayID) displayFromScreen:(NSScreen*)s; - -@end - diff --git a/Samples/CommonSrc/Platform/OSX_WavPlayer.cpp b/Samples/CommonSrc/Platform/OSX_WavPlayer.cpp deleted file mode 100644 index f85d4c4..0000000 --- a/Samples/CommonSrc/Platform/OSX_WavPlayer.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/************************************************************************************ - -Filename : WavPlayer_OSX.cpp -Content : An Apple OSX audio handler. -Created : March 5, 2013 -Authors : Robotic Arm Software - Peter Hoff, Dan Goodman, Bryan Croteau - -Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OSX_WavPlayer.h" - -namespace OVR { namespace Platform { namespace OSX { - -WavPlayer::WavPlayer(const char* fileName) -{ - FileName = fileName; -} - -bool WavPlayer::isDataChunk(unsigned char* buffer, int index) -{ - unsigned char a = buffer[index]; - unsigned char b = buffer[index + 1]; - unsigned char c = buffer[index + 2]; - unsigned char d = buffer[index + 3]; - return (a == 'D' || a == 'd') && (b == 'A' || b == 'a') && - (c == 'T' || c == 't') && (d == 'A' || d == 'a'); -} - -int WavPlayer::getWord(unsigned char* buffer, int index) -{ - unsigned char a = buffer[index]; - unsigned char b = buffer[index + 1]; - unsigned char c = buffer[index + 2]; - unsigned char d = buffer[index + 3]; - int result = 0; - result |= a; - result |= b << 8; - result |= c << 16; - result |= d << 24; - return result; -} - -short WavPlayer::getHalf(unsigned char* buffer, int index) -{ - unsigned char a = buffer[index]; - unsigned char b = buffer[index + 1]; - short result = 0; - result |= a; - result |= b << 8; - return result; -} - -void *WavPlayer::LoadPCM(const char *filename, unsigned long *len) -{ - FILE *file; - struct stat s; - void *pcm; - - if(stat(filename, &s)) - { - return NULL; - } - *len = s.st_size; - pcm = (void *) malloc(s.st_size); - if(!pcm) - { - return NULL; - } - file = fopen(filename, "rb"); - if(!file) - { - free(pcm); - return NULL; - } - fread(pcm, s.st_size, 1, file); - fclose(file); - return pcm; -} - -int WavPlayer::PlayBuffer(void *pcmbuffer, unsigned long len) -{ - AQCallbackStruct aqc; - UInt32 err, bufferSize; - int i; - - aqc.DataFormat.mSampleRate = SampleRate; - aqc.DataFormat.mFormatID = kAudioFormatLinearPCM; - if(BitsPerSample == 16) - { - aqc.DataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger - | kAudioFormatFlagIsPacked; - } - aqc.DataFormat.mBytesPerPacket = NumChannels * (BitsPerSample / 8); - aqc.DataFormat.mFramesPerPacket = 1; - aqc.DataFormat.mBytesPerFrame = NumChannels * (BitsPerSample / 8); - aqc.DataFormat.mChannelsPerFrame = NumChannels; - aqc.DataFormat.mBitsPerChannel = BitsPerSample; - aqc.FrameCount = SampleRate / 60; - aqc.SampleLen = (UInt32)(len); - aqc.PlayPtr = 0; - aqc.PCMBuffer = static_cast<unsigned char*>(pcmbuffer); - - err = AudioQueueNewOutput(&aqc.DataFormat, - aqBufferCallback, - &aqc, - NULL, - kCFRunLoopCommonModes, - 0, - &aqc.Queue); - if(err) - { - return err; - } - - aqc.FrameCount = SampleRate / 60; - bufferSize = aqc.FrameCount * aqc.DataFormat.mBytesPerPacket; - - for(i = 0; i < AUDIO_BUFFERS; i++) - { - err = AudioQueueAllocateBuffer(aqc.Queue, bufferSize, - &aqc.Buffers[i]); - if(err) - { - return err; - } - aqBufferCallback(&aqc, aqc.Queue, aqc.Buffers[i]); - } - - err = AudioQueueStart(aqc.Queue, NULL); - if(err) - { - return err; - } - - while(true) - { - } - sleep(1); - return 0; -} - -void WavPlayer::aqBufferCallback(void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB) -{ - AQCallbackStruct *aqc; - unsigned char *coreAudioBuffer; - - aqc = (AQCallbackStruct *) in; - coreAudioBuffer = (unsigned char*) outQB->mAudioData; - - printf("Sync: %u / %u\n", aqc->PlayPtr, aqc->SampleLen); - - if(aqc->FrameCount > 0) - { - outQB->mAudioDataByteSize = aqc->DataFormat.mBytesPerFrame * aqc->FrameCount; - for(int i = 0; i < aqc->FrameCount * aqc->DataFormat.mBytesPerFrame; i++) - { - if(aqc->PlayPtr > aqc->SampleLen) - { - aqc->PlayPtr = 0; - i = 0; - } - coreAudioBuffer[i] = aqc->PCMBuffer[aqc->PlayPtr]; - aqc->PlayPtr++; - } - AudioQueueEnqueueBuffer(inQ, outQB, 0, NULL); - } -} - -int WavPlayer::PlayAudio() -{ - unsigned long len; - void *pcmbuffer; - int ret; - - pcmbuffer = LoadPCM(FileName, &len); - if(!pcmbuffer) - { - fprintf(stderr, "%s: %s\n", FileName, strerror(errno)); - exit(EXIT_FAILURE); - } - - unsigned char* bytes = (unsigned char*)pcmbuffer; - int index = 0; - - // 'RIFF' - getWord(bytes, index); - index += 4; - // int Length - getWord(bytes, index); - index += 4; - // 'WAVE' - getWord(bytes, index); - index += 4; - // 'fmt ' - getWord(bytes, index); - index += 4; - - // int Format Length - int fmtLen = getWord(bytes, index); - index += 4; - AudioFormat = getHalf(bytes, index); - index += 2; - NumChannels = getHalf(bytes, index); - index += 2; - SampleRate = getWord(bytes, index); - index += 4; - ByteRate = getWord(bytes, index); - index += 4; - BlockAlign = getHalf(bytes, index); - index += 2; - BitsPerSample = getHalf(bytes, index); - index += 2; - index += fmtLen - 16; - while(!isDataChunk(bytes, index)) - { - // Any Chunk - getWord(bytes, index); - index += 4; - // Any Chunk Length - int anyChunkLen = getWord(bytes, index); - index += 4 + anyChunkLen; - } - // 'data' - getWord(bytes, index); - index += 4; - // int Data Length - unsigned long dataLen = getWord(bytes, index); - index += 4; - unsigned char* target = &bytes[index]; - - ret = PlayBuffer((void *)target, dataLen); - free(pcmbuffer); - return ret; -} - -}}} diff --git a/Samples/CommonSrc/Platform/OSX_WavPlayer.h b/Samples/CommonSrc/Platform/OSX_WavPlayer.h deleted file mode 100644 index 8d4610f..0000000 --- a/Samples/CommonSrc/Platform/OSX_WavPlayer.h +++ /dev/null @@ -1,72 +0,0 @@ -/************************************************************************************ - -Filename : WavPlayer_OSX.h -Content : An Apple OSX audio handler. -Created : March 5, 2013 -Authors : Robotic Arm Software - Peter Hoff, Dan Goodman, Bryan Croteau - -Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_WavPlayer_h -#define OVR_WavPlayer_h - -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <sys/stat.h> -#include <AudioToolbox/AudioQueue.h> - -#define AUDIO_BUFFERS 4 - -namespace OVR { namespace Platform { namespace OSX { - -typedef struct AQCallbackStruct -{ - AudioQueueRef Queue; - UInt32 FrameCount; - AudioQueueBufferRef Buffers[AUDIO_BUFFERS]; - AudioStreamBasicDescription DataFormat; - UInt32 PlayPtr; - UInt32 SampleLen; - unsigned char* PCMBuffer; -} AQCallbackStruct; - -class WavPlayer -{ -public: - WavPlayer(const char* fileName); - int PlayAudio(); -private: - bool isDataChunk(unsigned char* buffer, int index); - int getWord(unsigned char* buffer, int index); - short getHalf(unsigned char* buffer, int index); - void *LoadPCM(const char *filename, unsigned long *len); - int PlayBuffer(void *pcm, unsigned long len); - static void aqBufferCallback(void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB); - - short AudioFormat; - short NumChannels; - int SampleRate; - int ByteRate; - short BlockAlign; - short BitsPerSample; - const char* FileName; -}; - -}}} - -#endif diff --git a/Samples/CommonSrc/Platform/Platform.cpp b/Samples/CommonSrc/Platform/Platform.cpp index 108c7f5..40d7842 100644 --- a/Samples/CommonSrc/Platform/Platform.cpp +++ b/Samples/CommonSrc/Platform/Platform.cpp @@ -21,15 +21,13 @@ limitations under the License. ************************************************************************************/ - - #include "Platform.h" #include <Kernel/OVR_Std.h> #include <Kernel/OVR_Timer.h> #include "../Render/Render_Device.h" #include "Gamepad.h" -namespace OVR { namespace Platform { +namespace OVR { namespace OvrPlatform { const SetupGraphicsDeviceSet* SetupGraphicsDeviceSet::PickSetupDevice(const char* typeArg) const diff --git a/Samples/CommonSrc/Platform/Platform.h b/Samples/CommonSrc/Platform/Platform.h index 47d8f67..e9325a7 100644 --- a/Samples/CommonSrc/Platform/Platform.h +++ b/Samples/CommonSrc/Platform/Platform.h @@ -24,7 +24,7 @@ limitations under the License. #ifndef OVR_Platform_h #define OVR_Platform_h -#include "OVR.h" +#include "OVR_Kernel.h" #include "Kernel/OVR_KeyCodes.h" @@ -34,7 +34,7 @@ namespace OVR { namespace Render { struct RendererParams; }} -namespace OVR { namespace Platform { +namespace OVR { namespace OvrPlatform { using Render::RenderDevice; @@ -116,37 +116,45 @@ protected: public: PlatformCore(Application *app); virtual ~PlatformCore() { } - Application* GetApp() { return pApp; } - RenderDevice* GetRenderer() const { return pRender; } - GamepadManager* GetGamepadManager() const { return pGamepadManager; } + Application* GetApp() { return pApp; } + RenderDevice* GetRenderer() const { return pRender; } + GamepadManager* GetGamepadManager() const { return pGamepadManager; } - virtual bool SetupWindow(int w, int h) = 0; + virtual void* SetupWindow(int w, int h) = 0; // Destroys window and also releases renderer. - virtual void DestroyWindow() = 0; - virtual void Exit(int exitcode) = 0; + virtual void DestroyWindow() = 0; + virtual void Exit(int exitcode) = 0; - virtual void ShowWindow(bool visible) = 0; + virtual void ShowWindow(bool visible) = 0; - virtual bool SetFullscreen(const Render::RendererParams& rp, int fullscreen); + virtual bool SetFullscreen(const Render::RendererParams& rp, int fullscreen); // Search for a matching graphics renderer based on type argument and initializes it. virtual RenderDevice* SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc, const char* gtype, const Render::RendererParams& rp) = 0; - virtual void SetMouseMode(MouseMode mm) { OVR_UNUSED(mm); } + virtual void SetMouseMode(MouseMode mm) { OVR_UNUSED(mm); } - virtual void GetWindowSize(int* w, int* h) const = 0; + virtual void GetWindowSize(int* w, int* h) const = 0; - virtual void SetWindowTitle(const char*title) = 0; - virtual void PlayMusicFile(const char *fileName) { OVR_UNUSED(fileName); } - virtual int GetDisplayCount() { return 0; } + virtual void SetWindowTitle(const char*title) = 0; + virtual void PlayMusicFile(const char *fileName) { OVR_UNUSED(fileName); } + virtual int GetDisplayCount() { return 0; } virtual Render::DisplayId GetDisplay(int screen); // Get time since start of application in seconds. - double GetAppTime() const; + double GetAppTime() const; - virtual String GetContentDirectory() const { return "."; } + virtual String GetContentDirectory() const { return "."; } + + // Creates notification overlay text box over the top of OS window. Multiple + // messages can be created with different 'index' values. Pass null string + // to remove the overlay. + // Intended to be used with Oculus display driver only; may be unsupported on some platforms. + virtual void SetNotificationOverlay(int index, int fontHeightPixels, + int yoffset, const char* text) + { OVR_UNUSED4(index, fontHeightPixels, yoffset, text); } }; //------------------------------------------------------------------------------------- diff --git a/Samples/CommonSrc/Platform/Win32_Gamepad.cpp b/Samples/CommonSrc/Platform/Win32_Gamepad.cpp index ce7af63..5186773 100644 --- a/Samples/CommonSrc/Platform/Win32_Gamepad.cpp +++ b/Samples/CommonSrc/Platform/Win32_Gamepad.cpp @@ -23,7 +23,7 @@ limitations under the License. #include "Win32_Gamepad.h" -namespace OVR { namespace Platform { namespace Win32 { +namespace OVR { namespace OvrPlatform { namespace Win32 { GamepadManager::GamepadManager() { @@ -61,12 +61,12 @@ static inline float GamepadTrigger(BYTE in) return float(in-30) / 225; } -UInt32 GamepadManager::GetGamepadCount() +uint32_t GamepadManager::GetGamepadCount() { return 1; } -bool GamepadManager::GetGamepadState(UInt32 index, GamepadState* pState) +bool GamepadManager::GetGamepadState(uint32_t index, GamepadState* pState) { // For now we just support one gamepad. OVR_UNUSED(index); @@ -98,4 +98,4 @@ bool GamepadManager::GetGamepadState(UInt32 index, GamepadState* pState) return false; } -}}} // OVR::Platform::Win32 +}}} // OVR::OvrPlatform::Win32 diff --git a/Samples/CommonSrc/Platform/Win32_Gamepad.h b/Samples/CommonSrc/Platform/Win32_Gamepad.h index e3f81af..6c80350 100644 --- a/Samples/CommonSrc/Platform/Win32_Gamepad.h +++ b/Samples/CommonSrc/Platform/Win32_Gamepad.h @@ -26,19 +26,22 @@ limitations under the License. #include "Gamepad.h" -#include <windows.h> +#include <WinSock2.h> +#include <WS2tcpip.h> +#define WIN32_LEAN_AND_MEAN +#include <Windows.h> #include <xinput.h> -namespace OVR { namespace Platform { namespace Win32 { +namespace OVR { namespace OvrPlatform { namespace Win32 { -class GamepadManager : public Platform::GamepadManager +class GamepadManager : public OvrPlatform::GamepadManager { public: GamepadManager(); ~GamepadManager(); - virtual UInt32 GetGamepadCount(); - virtual bool GetGamepadState(UInt32 index, GamepadState* pState); + virtual uint32_t GetGamepadCount(); + virtual bool GetGamepadState(uint32_t index, GamepadState* pState); private: // Dynamically ink to XInput to simplify projects. @@ -46,7 +49,7 @@ private: typedef DWORD (WINAPI *PFn_XInputGetState)(DWORD dwUserIndex, XINPUT_STATE* pState); PFn_XInputGetState pXInputGetState; - UInt32 LastPadPacketNo; + uint32_t LastPadPacketNo; }; }}} diff --git a/Samples/CommonSrc/Platform/Win32_Platform.cpp b/Samples/CommonSrc/Platform/Win32_Platform.cpp index 0614a3f..a3e491d 100644 --- a/Samples/CommonSrc/Platform/Win32_Platform.cpp +++ b/Samples/CommonSrc/Platform/Win32_Platform.cpp @@ -21,7 +21,11 @@ limitations under the License. ************************************************************************************/ +#include <WinSock2.h> +#include <WS2tcpip.h> +#define WIN32_LEAN_AND_MEAN #include <Windows.h> +//#include <playsoundapi.h> #include "Kernel/OVR_System.h" #include "Kernel/OVR_Array.h" @@ -31,11 +35,11 @@ limitations under the License. #include "Win32_Gamepad.h" #include "../Render/Render_Device.h" -namespace OVR { namespace Platform { namespace Win32 { +namespace OVR { namespace OvrPlatform { namespace Win32 { PlatformCore::PlatformCore(Application* app, HINSTANCE hinst) - : Platform::PlatformCore(app), hWnd(NULL), hInstance(hinst), Quit(0), MMode(Mouse_Normal), + : OvrPlatform::PlatformCore(app), hWnd(NULL), hInstance(hinst), Quit(0), MMode(Mouse_Normal), Cursor(0), Modifiers(0), WindowTitle("App") { pGamepadManager = *new Win32::GamepadManager(); @@ -45,7 +49,7 @@ PlatformCore::~PlatformCore() { } -bool PlatformCore::SetupWindow(int w, int h) +void* PlatformCore::SetupWindow(int w, int h) { WNDCLASS wc; memset(&wc, 0, sizeof(wc)); @@ -53,6 +57,7 @@ bool PlatformCore::SetupWindow(int w, int h) wc.style = CS_OWNDC; wc.lpfnWndProc = systemWindowProc; wc.cbWndExtra = sizeof(PlatformCore*); + wc.hbrBackground = (HBRUSH)::GetStockObject(BLACK_BRUSH); RegisterClass(&wc); @@ -63,7 +68,8 @@ bool PlatformCore::SetupWindow(int w, int h) winSize.right = Width; winSize.bottom = Height; AdjustWindowRect(&winSize, WS_OVERLAPPEDWINDOW, false); - hWnd = CreateWindowA("OVRAppWindow", WindowTitle.ToCStr(), WS_OVERLAPPEDWINDOW, + // WS_CLIPCHILDREN is needed to support NotificationOverlay. + hWnd = CreateWindowA("OVRAppWindow", WindowTitle.ToCStr(), WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, // 1950, 10, winSize.right-winSize.left, winSize.bottom-winSize.top, @@ -84,7 +90,7 @@ bool PlatformCore::SetupWindow(int w, int h) } ::SetFocus(hWnd); - return (hWnd != NULL); + return (void*)hWnd; } void PlatformCore::DestroyWindow() @@ -145,7 +151,7 @@ void PlatformCore::SetWindowTitle(const char* title) ::SetWindowTextA(hWnd, title); } -static UByte KeyMap[][2] = +static uint8_t KeyMap[][2] = { { VK_BACK, Key_Backspace }, { VK_TAB, Key_Tab }, @@ -246,7 +252,7 @@ LRESULT CALLBACK PlatformCore::systemWindowProc(HWND hwnd, UINT msg, WPARAM wp, } else { - self = (PlatformCore*)(UPInt)GetWindowLongPtr(hwnd, 0); + self = (PlatformCore*)(size_t)GetWindowLongPtr(hwnd, 0); } return self ? self->WindowProc(msg, wp, lp) : @@ -262,7 +268,7 @@ LRESULT PlatformCore::WindowProc(UINT msg, WPARAM wp, LPARAM lp) { case WM_PAINT: { - PAINTSTRUCT ps; + PAINTSTRUCT ps; BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps); } @@ -373,6 +379,13 @@ LRESULT PlatformCore::WindowProc(UINT msg, WPARAM wp, LPARAM lp) Height = HIWORD(lp); if (pRender) pRender->SetWindowSize(Width, Height); + + for (int i = 0; i< NotificationOverlays.GetSizeI(); i++) + { + if (NotificationOverlays[i]) + NotificationOverlays[i]->UpdateOnWindowSize(); + } + pApp->OnResize(Width,Height); } break; @@ -542,16 +555,92 @@ Render::DisplayId PlatformCore::GetDisplay(int screen) return screen_name; } +// Creates notification overlay text box over the top of OS window. +void PlatformCore::SetNotificationOverlay(int index, int fontHeightPixels, + int yoffset, const char* text) +{ + // Not intended for extensive text display.. or array management should be cleaned up. + OVR_ASSERT(index < 100); + // Must call SetupWindow first for now. + OVR_ASSERT(hWnd); + + // If null text, destroy overlay. + if (!text) + { + if (index < NotificationOverlays.GetSizeI()) + NotificationOverlays[index].Clear(); + return; + } + + // Otherwise create new overlay in this slot. + if (index >= NotificationOverlays.GetSizeI()) + NotificationOverlays.Resize(index+1); + NotificationOverlays[index] = *new NotificationOverlay(this, fontHeightPixels, yoffset, text); +} + + +// ----------------------------------------------------------------------------- + +NotificationOverlay::NotificationOverlay(PlatformCore* core, int fontHeightPixels, + int yoffset, const char* text) +{ + Array<wchar_t> buffer; + intptr_t textLength = UTF8Util::GetLength(text); + buffer.Resize(textLength+1); + UTF8Util::DecodeString(&buffer[0], text); + + pCore = core; + YOffest = yoffset; + + // Create a static, centered TextField of specified font size. + + hFont= CreateFont(fontHeightPixels, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, + OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, L"Arial"); + + HDC dc = ::CreateCompatibleDC(0); + ::SelectObject(dc, hFont); + TextSize.cx = TextSize.cy = 0; + ::GetTextExtentPoint32(dc, &buffer[0], (int)textLength, &TextSize); + ::DeleteDC(dc); + + int vpos = (YOffest > 0) ? YOffest : (pCore->Height + YOffest - (TextSize.cy + 7)); + + hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("STATIC"), + &buffer[0], WS_CHILD|WS_VISIBLE|SS_CENTER|WS_CLIPSIBLINGS, + (core->Width-TextSize.cx+20)/2, vpos, + TextSize.cx+20, TextSize.cy + 7, + core->hWnd, HMENU(NULL), core->hInstance, NULL); + + SendMessage(hWnd, WM_SETFONT, WPARAM (hFont), TRUE); +} + +NotificationOverlay::~NotificationOverlay() +{ + ::DestroyWindow(hWnd); + ::DeleteObject(hFont); +} + +void NotificationOverlay::UpdateOnWindowSize() +{ + // Just reposition the window for proper centering and alignment. + int vpos = (YOffest > 0) ? YOffest : (pCore->Height + YOffest - (TextSize.cy + 7)); + + ::SetWindowPos(hWnd, 0, + (pCore->Width-TextSize.cx+20)/2, vpos, + TextSize.cx+20, TextSize.cy + 7, SWP_NOSIZE|SWP_NOZORDER); +} + }}} -OVR::Platform::Application* g_app; +OVR::OvrPlatform::Application* g_app; int WINAPI WinMain(HINSTANCE hinst, HINSTANCE prevInst, LPSTR inArgs, int show) { using namespace OVR; - using namespace OVR::Platform; + using namespace OVR::OvrPlatform; OVR_UNUSED2(prevInst, show); @@ -587,7 +676,7 @@ int WINAPI WinMain(HINSTANCE hinst, HINSTANCE prevInst, LPSTR inArgs, int show) } if (p != pstart) args.PushBack(String(pstart, p - pstart)); - for (UPInt i = 0; i < args.GetSize(); i++) + for (size_t i = 0; i < args.GetSize(); i++) argv.PushBack(args[i].ToCStr()); exitCode = g_app->OnStartup((int)argv.GetSize(), &argv[0]); @@ -599,6 +688,7 @@ int WINAPI WinMain(HINSTANCE hinst, HINSTANCE prevInst, LPSTR inArgs, int show) Application::DestroyApplication(g_app); g_app = 0; - OVR_DEBUG_STATEMENT(_CrtDumpMemoryLeaks()); + // If this assert fires, then look at the debug output to see what memory is leaking + OVR_ASSERT(!_CrtDumpMemoryLeaks()); return exitCode; } diff --git a/Samples/CommonSrc/Platform/Win32_Platform.h b/Samples/CommonSrc/Platform/Win32_Platform.h index a450cb4..b21bd0d 100644 --- a/Samples/CommonSrc/Platform/Win32_Platform.h +++ b/Samples/CommonSrc/Platform/Win32_Platform.h @@ -25,17 +25,48 @@ limitations under the License. #define OVR_Win32_Platform_h #include "Platform.h" -#include <windows.h> +#include <WinSock2.h> +#include <WS2tcpip.h> +#define WIN32_LEAN_AND_MEAN +#include <Windows.h> namespace OVR { namespace Render { class RenderDevice; struct DisplayId; }} -namespace OVR { namespace Platform { namespace Win32 { +namespace OVR { namespace OvrPlatform { namespace Win32 { -class PlatformCore : public Platform::PlatformCore +class PlatformCore; + +// ----------------------------------------------------------------------------- +// ***** NotificationOverlay + +// Describes a notification overlay window that contains a message string. +// When used with Oculus Display Driver, allows the message to be shown +// in the monitor window that is not visible on the Rift. +class NotificationOverlay : public RefCountBase<NotificationOverlay> +{ +public: + NotificationOverlay(PlatformCore* core, + int fontHeightPixels, int yoffset, const char* text); + ~NotificationOverlay(); + + void UpdateOnWindowSize(); + +private: + PlatformCore* pCore; + HWND hWnd; + HFONT hFont; + SIZE TextSize; + int YOffest; // Negative if counting from the bottom +}; + + +// ----------------------------------------------------------------------------- + +class PlatformCore : public OvrPlatform::PlatformCore { HWND hWnd; HINSTANCE hInstance; @@ -49,22 +80,27 @@ class PlatformCore : public Platform::PlatformCore int Modifiers; String WindowTitle; + friend class NotificationOverlay; + // Win32 static function that delegates to WindowProc member function. static LRESULT CALLBACK systemWindowProc(HWND window, UINT msg, WPARAM wp, LPARAM lp); LRESULT WindowProc(UINT msg, WPARAM wp, LPARAM lp); + Array<Ptr<NotificationOverlay> > NotificationOverlays; + public: PlatformCore(Application* app, HINSTANCE hinst); ~PlatformCore(); - bool SetupWindow(int w, int h); + void* SetupWindow(int w, int h); void DestroyWindow(); void ShowWindow(bool visible); void Exit(int exitcode) { - for (MSG msg; PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); ) - ; + // On some AMD cards, additional events may cause crashing after exit. + //for (MSG msg; PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); ) + // ; Quit = 1; ExitCode = exitcode; } @@ -80,6 +116,10 @@ public: int GetDisplayCount(); Render::DisplayId GetDisplay(int screen); + // Creates notification overlay text box over the top of OS window. + virtual void SetNotificationOverlay(int index, int fontHeightPixels, + int yoffset, const char* text); + int Run(); }; @@ -93,22 +133,22 @@ KeyCode MapVKToKeyCode(unsigned vk); // OVR_PLATFORM_APP_ARGS specifies the Application class to use for startup, // providing it with startup arguments. #define OVR_PLATFORM_APP_ARGS(AppClass, args) \ - OVR::Platform::Application* OVR::Platform::Application::CreateApplication() \ + OVR::OvrPlatform::Application* OVR::OvrPlatform::Application::CreateApplication() \ { OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All)); \ return new AppClass args; } \ - void OVR::Platform::Application::DestroyApplication(OVR::Platform::Application* app) \ - { OVR::Platform::PlatformCore* platform = app->pPlatform; \ + void OVR::OvrPlatform::Application::DestroyApplication(OVR::OvrPlatform::Application* app) \ + { OVR::OvrPlatform::PlatformCore* platform = app->pPlatform; \ delete app; delete platform; OVR::System::Destroy(); }; // OVR_PLATFORM_APP_ARGS specifies the Application startup class with no args. #define OVR_PLATFORM_APP(AppClass) OVR_PLATFORM_APP_ARGS(AppClass, ()) #define OVR_PLATFORM_APP_ARGS_WITH_LOG(AppClass, LogClass, args) \ - OVR::Platform::Application* OVR::Platform::Application::CreateApplication() \ + OVR::OvrPlatform::Application* OVR::OvrPlatform::Application::CreateApplication() \ { static LogClass log; OVR::System::Init(&log); \ return new AppClass args; } \ - void OVR::Platform::Application::DestroyApplication(OVR::Platform::Application* app) \ - { OVR::Platform::PlatformCore* platform = app->pPlatform; \ + void OVR::OvrPlatform::Application::DestroyApplication(OVR::OvrPlatform::Application* app) \ + { OVR::OvrPlatform::PlatformCore* platform = app->pPlatform; \ delete app; delete platform; OVR::System::Destroy(); }; #define OVR_PLATFORM_APP_WITH_LOG(AppClass,LogClass) OVR_PLATFORM_APP_ARGS_WITH_LOG(AppClass,LogClass, ()) diff --git a/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp b/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp index 5476a6f..3f645ab 100644 --- a/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp +++ b/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp @@ -26,6 +26,9 @@ limitations under the License. #include "Kernel/OVR_Log.h" #include "Kernel/OVR_Std.h" +#define WIN32_LEAN_AND_MEAN +#include <comdef.h> + #include "Render_D3D1X_Device.h" #include "Util/Util_ImageWindow.h" @@ -159,7 +162,7 @@ static const char* MultiTexturePixelShaderSrc = " if (color2.a <= 0.4)\n" " discard;\n" // go to back to gamma space space colors (assume gamma 2.0 for speed) - " return float4(sqrt(color2.rgb), color2.a);\n" + " return float4(sqrt(color2.rgb) / color2.a, 1);\n" "}\n"; #define LIGHTING_COMMON \ @@ -225,6 +228,24 @@ static const char* AlphaTexturePixelShaderSrc = " finalColor.rgb *= finalColor.a;\n" " return finalColor;\n" "}\n"; + +static const char* AlphaBlendedTexturePixelShaderSrc = + "Texture2D Texture : register(t0);\n" + "SamplerState Linear : register(s0);\n" + "struct Varyings\n" + "{\n" + " float4 Position : SV_Position;\n" + " float4 Color : COLOR0;\n" + " float2 TexCoord : TEXCOORD0;\n" + "};\n" + "float4 main(in Varyings ov) : SV_Target\n" + "{\n" + " float4 finalColor = ov.Color;\n" + " finalColor *= Texture.Sample(Linear, ov.TexCoord);\n" + // blend state expects premultiplied alpha + " finalColor.rgb *= finalColor.a;\n" + " return finalColor;\n" + "}\n"; #pragma endregion #pragma region Distortion shaders @@ -662,7 +683,8 @@ static const char* FShaderSrcs[FShader_Count] = SolidPixelShaderSrc, GouraudPixelShaderSrc, TexturePixelShaderSrc, - AlphaTexturePixelShaderSrc, + AlphaTexturePixelShaderSrc, + AlphaBlendedTexturePixelShaderSrc, PostProcessPixelShaderWithChromAbSrc, LitSolidPixelShaderSrc, LitTexturePixelShaderSrc, @@ -673,32 +695,96 @@ static const char* FShaderSrcs[FShader_Count] = PostProcessHeightmapTimewarpPixelShaderSrc }; +#ifdef OVR_BUILD_DEBUG + +static void ReportCOMError(HRESULT hr, const char* file, int line) +{ + if (FAILED(hr)) + { + _com_error err(hr); + LPCTSTR errMsg = err.ErrorMessage(); + + if (sizeof(TCHAR) == sizeof(char)) + { + LogError("[D3D] Error in %s on line %d : %s", file, line, errMsg); + } + else + { + size_t len = wcslen(errMsg); + char* data = new char[len + 1]; + size_t count = len; + wcstombs_s(&count, data, len + 1, errMsg, len); + if (count < len) + { + len = count; + } + data[len] = '\0'; + LogError("[D3D] Error in %s on line %d : %s", file, line, data); + delete[] data; + } + + OVR_ASSERT(false); + } +} + +#define OVR_LOG_COM_ERROR(hr) \ + ReportCOMError(hr, __FILE__, __LINE__); + +#else + +#define OVR_LOG_COM_ERROR(hr) ; + +#endif + RenderDevice::RenderDevice(const RendererParams& p, HWND window) { - RECT rc; - GetClientRect(window, &rc); - UINT width = rc.right - rc.left; - UINT height = rc.bottom - rc.top; - ::OVR::Render::RenderDevice::SetWindowSize(width, height); + HRESULT hr; + RECT rc; + if (p.Resolution == Sizei(0)) + { + GetClientRect(window, &rc); + UINT width = rc.right - rc.left; + UINT height = rc.bottom - rc.top; + ::OVR::Render::RenderDevice::SetWindowSize(width, height); + } + else + { + // TBD: This should be renamed to not be tied to window for App mode. + ::OVR::Render::RenderDevice::SetWindowSize(p.Resolution.w, p.Resolution.h); + } + Window = window; Params = p; - HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&DXGIFactory.GetRawRef())); - if (FAILED(hr)) + DXGIFactory = NULL; + hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&DXGIFactory.GetRawRef())); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); return; + } // Find the adapter & output (monitor) to use for fullscreen, based on the reported name of the HMD's monitor. if (Params.Display.MonitorName.GetLength() > 0) { for(UINT AdapterIndex = 0; ; AdapterIndex++) { + Adapter = NULL; HRESULT hr = DXGIFactory->EnumAdapters(AdapterIndex, &Adapter.GetRawRef()); if (hr == DXGI_ERROR_NOT_FOUND) break; + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } DXGI_ADAPTER_DESC Desc; - Adapter->GetDesc(&Desc); + hr = Adapter->GetDesc(&Desc); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } UpdateMonitorOutputs(); @@ -712,25 +798,37 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window) if (!Adapter) { - DXGIFactory->EnumAdapters(0, &Adapter.GetRawRef()); + hr = DXGIFactory->EnumAdapters(0, &Adapter.GetRawRef()); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } UpdateMonitorOutputs(); } int flags = D3D10_CREATE_DEVICE_BGRA_SUPPORT; //0; #if (OVR_D3D_VERSION == 10) + Device = NULL; hr = D3D10CreateDevice1(Adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, D3D10_FEATURE_LEVEL_10_1, D3D10_1_SDK_VERSION, &Device.GetRawRef()); Context = Device; Context->AddRef(); #else //11 + Device = NULL; + Context = NULL; D3D_FEATURE_LEVEL featureLevel; // TODO: Limit certain features based on D3D feature level hr = D3D11CreateDevice(Adapter, Adapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE, NULL, flags, NULL, 0, D3D1x_(SDK_VERSION), &Device.GetRawRef(), &featureLevel, &Context.GetRawRef()); #endif - if (FAILED(hr)) - return; + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + LogError("[D3D1X] Unable to create device: %x", hr); + OVR_ASSERT(false); + return; + } if (!RecreateSwapChain()) return; @@ -769,28 +867,40 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window) } } - SPInt bufferSize = vsData->GetBufferSize(); + intptr_t bufferSize = vsData->GetBufferSize(); const void* buffer = vsData->GetBufferPointer(); + ModelVertexIL = NULL; ID3D1xInputLayout** objRef = &ModelVertexIL.GetRawRef(); - HRESULT validate = Device->CreateInputLayout(ModelVertexDesc, sizeof(ModelVertexDesc)/sizeof(ModelVertexDesc[0]), buffer, bufferSize, objRef); - OVR_UNUSED(validate); + hr = Device->CreateInputLayout(ModelVertexDesc, sizeof(ModelVertexDesc)/sizeof(ModelVertexDesc[0]), buffer, bufferSize, objRef); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } { ID3D10Blob* vsData2 = CompileShader("vs_4_1", PostProcessMeshVertexShaderSrc); - SPInt bufferSize2 = vsData2->GetBufferSize(); + intptr_t bufferSize2 = vsData2->GetBufferSize(); const void* buffer2 = vsData2->GetBufferPointer(); + DistortionVertexIL = NULL; ID3D1xInputLayout** objRef2 = &DistortionVertexIL.GetRawRef(); - HRESULT validate2 = Device->CreateInputLayout(DistortionVertexDesc, sizeof(DistortionVertexDesc)/sizeof(DistortionVertexDesc[0]), buffer2, bufferSize2, objRef2); - OVR_UNUSED(validate2); + hr = Device->CreateInputLayout(DistortionVertexDesc, sizeof(DistortionVertexDesc)/sizeof(DistortionVertexDesc[0]), buffer2, bufferSize2, objRef2); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } } { ID3D10Blob* vsData2 = CompileShader("vs_4_1", PostProcessHeightmapTimewarpVertexShaderSrc); - SPInt bufferSize2 = vsData2->GetBufferSize(); + intptr_t bufferSize2 = vsData2->GetBufferSize(); const void* buffer2 = vsData2->GetBufferPointer(); + HeightmapVertexIL = NULL; ID3D1xInputLayout** objRef2 = &HeightmapVertexIL.GetRawRef(); - HRESULT validate2 = Device->CreateInputLayout(HeightmapVertexDesc, sizeof(HeightmapVertexDesc)/sizeof(HeightmapVertexDesc[0]), buffer2, bufferSize2, objRef2); - OVR_UNUSED(validate2); + hr = Device->CreateInputLayout(HeightmapVertexDesc, sizeof(HeightmapVertexDesc)/sizeof(HeightmapVertexDesc[0]), buffer2, bufferSize2, objRef2); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } } Ptr<ShaderSet> gouraudShaders = *new ShaderSet(); @@ -806,7 +916,8 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window) bm.SrcBlend = bm.SrcBlendAlpha = D3D1x_(BLEND_ONE); //premultiplied alpha bm.DestBlend = bm.DestBlendAlpha = D3D1x_(BLEND_INV_SRC_ALPHA); bm.RenderTargetWriteMask[0] = D3D1x_(COLOR_WRITE_ENABLE_ALL); - Device->CreateBlendState(&bm, &BlendState.GetRawRef()); + BlendState = NULL; + hr = Device->CreateBlendState(&bm, &BlendState.GetRawRef()); #else D3D1x_(BLEND_DESC) bm; memset(&bm, 0, sizeof(bm)); @@ -815,8 +926,13 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window) bm.RenderTarget[0].SrcBlend = bm.RenderTarget[0].SrcBlendAlpha = D3D1x_(BLEND_ONE); //premultiplied alpha bm.RenderTarget[0].DestBlend = bm.RenderTarget[0].DestBlendAlpha = D3D1x_(BLEND_INV_SRC_ALPHA); bm.RenderTarget[0].RenderTargetWriteMask = D3D1x_(COLOR_WRITE_ENABLE_ALL); - Device->CreateBlendState(&bm, &BlendState.GetRawRef()); + BlendState = NULL; + hr = Device->CreateBlendState(&bm, &BlendState.GetRawRef()); #endif + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } D3D1x_(RASTERIZER_DESC) rs; memset(&rs, 0, sizeof(rs)); @@ -825,13 +941,21 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window) // rs.CullMode = D3D1x_(CULL_NONE); rs.DepthClipEnable = true; rs.FillMode = D3D1x_(FILL_SOLID); - Device->CreateRasterizerState(&rs, &Rasterizer.GetRawRef()); + Rasterizer = NULL; + hr = Device->CreateRasterizerState(&rs, &Rasterizer.GetRawRef()); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } QuadVertexBuffer = *CreateBuffer(); const Render::Vertex QuadVertices[] = { Vertex(Vector3f(0, 1, 0)), Vertex(Vector3f(1, 1, 0)), Vertex(Vector3f(0, 0, 0)), Vertex(Vector3f(1, 0, 0)) }; - QuadVertexBuffer->Data(Buffer_Vertex | Buffer_ReadOnly, QuadVertices, sizeof(QuadVertices)); + if (!QuadVertexBuffer->Data(Buffer_Vertex | Buffer_ReadOnly, QuadVertices, sizeof(QuadVertices))) + { + OVR_ASSERT(false); + } SetDepthMode(0, 0); } @@ -840,7 +964,11 @@ RenderDevice::~RenderDevice() { if (SwapChain && Params.Fullscreen) { - SwapChain->SetFullscreenState(false, NULL); + HRESULT hr = SwapChain->SetFullscreenState(false, NULL); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } } } @@ -848,7 +976,25 @@ RenderDevice::~RenderDevice() // Implement static initializer function to create this class. Render::RenderDevice* RenderDevice::CreateDevice(const RendererParams& rp, void* oswnd) { - return new RenderDevice(rp, (HWND)oswnd); +#if (OVR_D3D_VERSION == 10) + Render::D3D10::RenderDevice* render = new RenderDevice(rp, (HWND)oswnd); +#else + Render::D3D11::RenderDevice* render = new RenderDevice(rp, (HWND)oswnd); +#endif + // Sanity check to make sure our resources were created. + // This should stop a lot of driver related crashes we have experienced + if ((render->DXGIFactory == NULL) || (render->Device == NULL) || (render->SwapChain == NULL)) + { + OVR_ASSERT(false); + // TBD: Probabaly other things like shader creation should be verified as well + render->Shutdown(); + render->Release(); + return NULL; + } + else + { + return render; + } } @@ -861,16 +1007,16 @@ BOOL CALLBACK MonitorEnumFunc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) { RenderDevice* renderer = (RenderDevice*)dwData; - MONITORINFOEX monitor; + MONITORINFOEXA monitor; monitor.cbSize = sizeof(monitor); - if (::GetMonitorInfo(hMonitor, &monitor) && monitor.szDevice[0]) + if (::GetMonitorInfoA(hMonitor, &monitor) && monitor.szDevice[0]) { - DISPLAY_DEVICE dispDev; + DISPLAY_DEVICEA dispDev; memset(&dispDev, 0, sizeof(dispDev)); dispDev.cb = sizeof(dispDev); - if (::EnumDisplayDevices(monitor.szDevice, 0, &dispDev, 0)) + if (::EnumDisplayDevicesA(monitor.szDevice, 0, &dispDev, 0)) { if (strstr(String(dispDev.DeviceName).ToCStr(), renderer->GetParams().Display.MonitorName.ToCStr())) { @@ -895,17 +1041,27 @@ void RenderDevice::UpdateMonitorOutputs(bool needRecreate) // to get latest info about monitors. if (SwapChain) { - SwapChain->SetFullscreenState(FALSE, NULL); - SwapChain->Release(); + hr = SwapChain->SetFullscreenState(FALSE, NULL); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } SwapChain = NULL; } DXGIFactory = NULL; Adapter = NULL; hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&DXGIFactory.GetRawRef())); - if (FAILED(hr)) + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); return; - DXGIFactory->EnumAdapters(0, &Adapter.GetRawRef()); + } + hr = DXGIFactory->EnumAdapters(0, &Adapter.GetRawRef()); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } } bool deviceNameFound = false; @@ -918,19 +1074,23 @@ void RenderDevice::UpdateMonitorOutputs(bool needRecreate) { break; } + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } DXGI_OUTPUT_DESC OutDesc; Output->GetDesc(&OutDesc); - MONITORINFOEX monitor; + MONITORINFOEXA monitor; monitor.cbSize = sizeof(monitor); - if (::GetMonitorInfo(OutDesc.Monitor, &monitor) && monitor.szDevice[0]) + if (::GetMonitorInfoA(OutDesc.Monitor, &monitor) && monitor.szDevice[0]) { - DISPLAY_DEVICE dispDev; + DISPLAY_DEVICEA dispDev; memset(&dispDev, 0, sizeof(dispDev)); dispDev.cb = sizeof(dispDev); - if (::EnumDisplayDevices(monitor.szDevice, 0, &dispDev, 0)) + if (::EnumDisplayDevicesA(monitor.szDevice, 0, &dispDev, 0)) { if (strstr(String(dispDev.DeviceName).ToCStr(), Params.Display.MonitorName.ToCStr())) { @@ -946,19 +1106,23 @@ void RenderDevice::UpdateMonitorOutputs(bool needRecreate) if (!deviceNameFound && !Params.Display.MonitorName.IsEmpty()) { - EnumDisplayMonitors(0, 0, MonitorEnumFunc, (LPARAM)this); + if (!EnumDisplayMonitors(0, 0, MonitorEnumFunc, (LPARAM)this)) + { + OVR_ASSERT(false); + } } } bool RenderDevice::RecreateSwapChain() { + HRESULT hr; + DXGI_SWAP_CHAIN_DESC scDesc; memset(&scDesc, 0, sizeof(scDesc)); scDesc.BufferCount = 1; scDesc.BufferDesc.Width = WindowWidth; scDesc.BufferDesc.Height = WindowHeight; scDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - //scDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; // Use default refresh rate; switching rate on CC prototype can cause screen lockup. scDesc.BufferDesc.RefreshRate.Numerator = 0; scDesc.BufferDesc.RefreshRate.Denominator = 1; @@ -971,29 +1135,42 @@ bool RenderDevice::RecreateSwapChain() if (SwapChain) { - SwapChain->SetFullscreenState(FALSE, NULL); - SwapChain->Release(); - SwapChain = NULL; + hr = SwapChain->SetFullscreenState(FALSE, NULL); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } + SwapChain = NULL; } Ptr<IDXGISwapChain> newSC; - if (FAILED(DXGIFactory->CreateSwapChain(Device, &scDesc, &newSC.GetRawRef()))) - return false; + hr = DXGIFactory->CreateSwapChain(Device, &scDesc, &newSC.GetRawRef()); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + return false; + } SwapChain = newSC; BackBuffer = NULL; BackBufferRT = NULL; - HRESULT hr = SwapChain->GetBuffer(0, __uuidof(ID3D1xTexture2D), (void**)&BackBuffer.GetRawRef()); + hr = SwapChain->GetBuffer(0, __uuidof(ID3D1xTexture2D), (void**)&BackBuffer.GetRawRef()); if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); return false; + } hr = Device->CreateRenderTargetView(BackBuffer, NULL, &BackBufferRT.GetRawRef()); if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); return false; + } Texture* depthBuffer = GetDepthBuffer(WindowWidth, WindowHeight, Params.Multisample); CurDepthBuffer = depthBuffer; - if (CurRenderTarget == NULL) + if (CurRenderTarget == NULL && depthBuffer != NULL) { Context->OMSetRenderTargets(1, &BackBufferRT.GetRawRef(), depthBuffer->TexDsv); } @@ -1059,20 +1236,12 @@ ovrTexture Texture::Get_ovrTexture() void RenderDevice::SetWindowSize(int w, int h) { - if (w == WindowWidth && h == WindowHeight) - return; - - ::OVR::Render::RenderDevice::SetWindowSize(w, h); - - Context->OMSetRenderTargets(0, NULL, NULL); - BackBuffer = NULL; - BackBufferRT = NULL; - if (SwapChain) - { - SwapChain->ResizeBuffers(2, WindowWidth, WindowHeight, DXGI_FORMAT_R8G8B8A8_UNORM, 0); - SwapChain->GetBuffer(0, __uuidof(ID3D1xTexture2D), (void**)&BackBuffer.GetRawRef()); - } - Device->CreateRenderTargetView(BackBuffer, NULL, &BackBufferRT.GetRawRef()); + // This code is rendered a no-op + // It interferes with proper driver operation in + // application mode and doesn't add any value in + // compatibility mode + OVR_UNUSED(w); + OVR_UNUSED(h); } bool RenderDevice::SetFullscreen(DisplayMode fullscreen) @@ -1121,6 +1290,7 @@ bool RenderDevice::SetFullscreen(DisplayMode fullscreen) HRESULT hr = SwapChain->SetFullscreenState(fullscreen, fullscreen ? FullscreenOutput : NULL); if (FAILED(hr)) { + OVR_LOG_COM_ERROR(hr); return false; } } @@ -1180,7 +1350,11 @@ void RenderDevice::SetDepthMode(bool enable, bool write, CompareFunc func) OVR_ASSERT(0); } dss.DepthWriteMask = write ? D3D1x_(DEPTH_WRITE_MASK_ALL) : D3D1x_(DEPTH_WRITE_MASK_ZERO); - Device->CreateDepthStencilState(&dss, &DepthStates[index].GetRawRef()); + HRESULT hr = Device->CreateDepthStencilState(&dss, &DepthStates[index].GetRawRef()); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } Context->OMSetDepthStencilState(DepthStates[index], 0); CurDepthState = DepthStates[index]; } @@ -1258,6 +1432,7 @@ bool Buffer::Data(int use, const void *buffer, size_t size) } else { + OVR_ASSERT (!(use & Buffer_ReadOnly)); Ren->Context->UpdateSubresource(D3DBuffer, 0, NULL, buffer, 0, 0); return true; } @@ -1307,6 +1482,7 @@ bool Buffer::Data(int use, const void *buffer, size_t size) sr.SysMemPitch = 0; sr.SysMemSlicePitch = 0; + D3DBuffer = NULL; HRESULT hr = Ren->Device->CreateBuffer(&desc, buffer ? &sr : NULL, &D3DBuffer.GetRawRef()); if (SUCCEEDED(hr)) { @@ -1314,6 +1490,10 @@ bool Buffer::Data(int use, const void *buffer, size_t size) Size = desc.ByteWidth; return 1; } + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } return 0; } @@ -1360,15 +1540,30 @@ bool Buffer::Unmap(void *m) #if (OVR_D3D_VERSION == 10) template<> bool Shader<Render::Shader_Vertex, ID3D10VertexShader>::Load(void* shader, size_t size) { - return SUCCEEDED(Ren->Device->CreateVertexShader(shader, size, &D3DShader)); + HRESULT hr = Ren->Device->CreateVertexShader(shader, size, &D3DShader); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } + return SUCCEEDED(hr); } template<> bool Shader<Render::Shader_Pixel, ID3D10PixelShader>::Load(void* shader, size_t size) { - return SUCCEEDED(Ren->Device->CreatePixelShader(shader, size, &D3DShader)); + HRESULT hr = Ren->Device->CreatePixelShader(shader, size, &D3DShader); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } + return SUCCEEDED(hr); } template<> bool Shader<Render::Shader_Geometry, ID3D10GeometryShader>::Load(void* shader, size_t size) { - return SUCCEEDED(Ren->Device->CreateGeometryShader(shader, size, &D3DShader)); + HRESULT hr = Ren->Device->CreateGeometryShader(shader, size, &D3DShader); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } + return SUCCEEDED(hr); } template<> void Shader<Render::Shader_Vertex, ID3D10VertexShader>::Set(PrimitiveType) const @@ -1387,15 +1582,30 @@ template<> void Shader<Render::Shader_Geometry, ID3D10GeometryShader>::Set(Primi #else // 11 template<> bool Shader<Render::Shader_Vertex, ID3D11VertexShader>::Load(void* shader, size_t size) { - return SUCCEEDED(Ren->Device->CreateVertexShader(shader, size, NULL, &D3DShader)); + HRESULT hr = Ren->Device->CreateVertexShader(shader, size, NULL, &D3DShader); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } + return SUCCEEDED(hr); } template<> bool Shader<Render::Shader_Pixel, ID3D11PixelShader>::Load(void* shader, size_t size) { - return SUCCEEDED(Ren->Device->CreatePixelShader(shader, size, NULL, &D3DShader)); + HRESULT hr = Ren->Device->CreatePixelShader(shader, size, NULL, &D3DShader); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } + return SUCCEEDED(hr); } template<> bool Shader<Render::Shader_Geometry, ID3D11GeometryShader>::Load(void* shader, size_t size) { - return SUCCEEDED(Ren->Device->CreateGeometryShader(shader, size, NULL, &D3DShader)); + HRESULT hr = Ren->Device->CreateGeometryShader(shader, size, NULL, &D3DShader); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } + return SUCCEEDED(hr); } template<> void Shader<Render::Shader_Vertex, ID3D11VertexShader>::Set(PrimitiveType) const @@ -1436,6 +1646,7 @@ ID3D10Blob* RenderDevice::CompileShader(const char* profile, const char* src, co OVR_DEBUG_LOG(("Compiling D3D shader for %s failed\n%s\n\n%s", profile, src, errors->GetBufferPointer())); OutputDebugStringA((char*)errors->GetBufferPointer()); + OVR_LOG_COM_ERROR(hr); return NULL; } if (errors) @@ -1472,11 +1683,17 @@ bool ShaderBase::SetUniform(const char* name, int n, const float* v) void ShaderBase::InitUniforms(ID3D10Blob* s) { ID3D10ShaderReflection* ref = NULL; - D3D10ReflectShader(s->GetBufferPointer(), s->GetBufferSize(), &ref); + HRESULT hr = D3D10ReflectShader(s->GetBufferPointer(), s->GetBufferSize(), &ref); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } ID3D10ShaderReflectionConstantBuffer* buf = ref->GetConstantBufferByIndex(0); D3D10_SHADER_BUFFER_DESC bufd; - if (FAILED(buf->GetDesc(&bufd))) + hr = buf->GetDesc(&bufd); + if (FAILED(hr)) { + //OVR_LOG_COM_ERROR(hr); - Seems to happen normally UniformsSize = 0; if (UniformData) { @@ -1492,7 +1709,8 @@ void ShaderBase::InitUniforms(ID3D10Blob* s) if (var) { D3D10_SHADER_VARIABLE_DESC vd; - if (SUCCEEDED(var->GetDesc(&vd))) + hr = var->GetDesc(&vd); + if (SUCCEEDED(hr)) { Uniform u; u.Name = vd.Name; @@ -1500,6 +1718,10 @@ void ShaderBase::InitUniforms(ID3D10Blob* s) u.Size = vd.Size; UniformInfo.PushBack(u); } + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } } } @@ -1511,7 +1733,10 @@ void ShaderBase::UpdateBuffer(Buffer* buf) { if (UniformsSize) { - buf->Data(Buffer_Uniform, UniformData, UniformsSize); + if (!buf->Data(Buffer_Uniform, UniformData, UniformsSize)) + { + OVR_ASSERT(false); + } } } @@ -1650,7 +1875,11 @@ ID3D1xSamplerState* RenderDevice::GetSamplerState(int sm) ss.Filter = D3D1x_(FILTER_MIN_MAG_MIP_LINEAR); } ss.MaxLOD = 15; - Device->CreateSamplerState(&ss, &SamplerStates[sm].GetRawRef()); + HRESULT hr = Device->CreateSamplerState(&ss, &SamplerStates[sm].GetRawRef()); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } return SamplerStates[sm]; } @@ -1797,14 +2026,28 @@ void RenderDevice::GenerateSubresourceData( Texture* RenderDevice::CreateTexture(int format, int width, int height, const void* data, int mipcount) { - UPInt gpuMemorySize = 0; + OVR_ASSERT(Device != NULL); + + size_t gpuMemorySize = 0; { IDXGIDevice* pDXGIDevice; - Device->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice); + HRESULT hr = Device->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } IDXGIAdapter * pDXGIAdapter; - pDXGIDevice->GetAdapter(&pDXGIAdapter); + hr = pDXGIDevice->GetAdapter(&pDXGIAdapter); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } DXGI_ADAPTER_DESC adapterDesc; - pDXGIAdapter->GetDesc(&adapterDesc); + hr = pDXGIAdapter->GetDesc(&adapterDesc); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } gpuMemorySize = adapterDesc.DedicatedVideoMemory; pDXGIAdapter->Release(); pDXGIDevice->Release(); @@ -1858,14 +2101,10 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo { return NULL; } - int samples = (Texture_RGBA & Texture_SamplesMask); - if (samples < 1) - { - samples = 1; - } Texture* NewTex = new Texture(this, format, largestMipWidth, largestMipHeight); - NewTex->Samples = samples; + // BCn/DXTn - no AA. + NewTex->Samples = 1; D3D1x_(TEXTURE2D_DESC) desc; desc.Width = largestMipWidth; @@ -1873,16 +2112,21 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo desc.MipLevels = effectiveMipCount; desc.ArraySize = 1; desc.Format = static_cast<DXGI_FORMAT>(convertedFormat); - desc.SampleDesc.Count = samples; + desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D1x_(USAGE_DEFAULT); desc.BindFlags = D3D1x_(BIND_SHADER_RESOURCE); desc.CPUAccessFlags = 0; desc.MiscFlags = 0; + NewTex->Tex = NULL; HRESULT hr = Device->CreateTexture2D(&desc, static_cast<D3D1x_(SUBRESOURCE_DATA)*>(subresData), &NewTex->Tex.GetRawRef()); OVR_FREE(subresData); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } if (SUCCEEDED(hr) && NewTex != 0) { @@ -1892,10 +2136,12 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D; SRVDesc.Texture2D.MipLevels = desc.MipLevels; + NewTex->TexSv = NULL; hr = Device->CreateShaderResourceView(NewTex->Tex, NULL, &NewTex->TexSv.GetRawRef()); if (FAILED(hr)) { + OVR_LOG_COM_ERROR(hr); NewTex->Release(); return NULL; } @@ -1920,11 +2166,11 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo { case Texture_BGRA: bpp = 4; - d3dformat = DXGI_FORMAT_B8G8R8A8_UNORM; + d3dformat = (format & Texture_SRGB) ? DXGI_FORMAT_B8G8R8A8_UNORM_SRGB : DXGI_FORMAT_B8G8R8A8_UNORM; break; case Texture_RGBA: bpp = 4; - d3dformat = DXGI_FORMAT_R8G8B8A8_UNORM; + d3dformat = (format & Texture_SRGB) ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM; break; case Texture_R: bpp = 1; @@ -1970,9 +2216,11 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo } } + NewTex->Tex = NULL; HRESULT hr = Device->CreateTexture2D(&dsDesc, NULL, &NewTex->Tex.GetRawRef()); if (FAILED(hr)) { + OVR_LOG_COM_ERROR(hr); OVR_DEBUG_LOG_TEXT(("Failed to create 2D D3D texture.")); NewTex->Release(); return NULL; @@ -1986,11 +2234,21 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo depthSrv.ViewDimension = samples > 1 ? D3D1x_(SRV_DIMENSION_TEXTURE2DMS) : D3D1x_(SRV_DIMENSION_TEXTURE2D); depthSrv.Texture2D.MostDetailedMip = 0; depthSrv.Texture2D.MipLevels = dsDesc.MipLevels; - Device->CreateShaderResourceView(NewTex->Tex, &depthSrv, &NewTex->TexSv.GetRawRef()); + NewTex->TexSv = NULL; + hr = Device->CreateShaderResourceView(NewTex->Tex, &depthSrv, &NewTex->TexSv.GetRawRef()); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } } else { - Device->CreateShaderResourceView(NewTex->Tex, NULL, &NewTex->TexSv.GetRawRef()); + NewTex->TexSv = NULL; + hr = Device->CreateShaderResourceView(NewTex->Tex, NULL, &NewTex->TexSv.GetRawRef()); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } } } @@ -2001,7 +2259,7 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo { int srcw = width, srch = height; int level = 0; - UByte* mipmaps = NULL; + uint8_t* mipmaps = NULL; do { level++; @@ -2017,9 +2275,9 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo } if (mipmaps == NULL) { - mipmaps = (UByte*)OVR_ALLOC(mipw * miph * 4); + mipmaps = (uint8_t*)OVR_ALLOC(mipw * miph * 4); } - FilterRgba2x2(level == 1 ? (const UByte*)data : mipmaps, srcw, srch, mipmaps); + FilterRgba2x2(level == 1 ? (const uint8_t*)data : mipmaps, srcw, srch, mipmaps); Context->UpdateSubresource(NewTex->Tex, level, NULL, mipmaps, mipw * bpp, miph * bpp); srcw = mipw; srch = miph; @@ -2042,11 +2300,21 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo depthDsv.Format = DXGI_FORMAT_D32_FLOAT; depthDsv.ViewDimension = samples > 1 ? D3D1x_(DSV_DIMENSION_TEXTURE2DMS) : D3D1x_(DSV_DIMENSION_TEXTURE2D); depthDsv.Texture2D.MipSlice = 0; - Device->CreateDepthStencilView(NewTex->Tex, createDepthSrv ? &depthDsv : NULL, &NewTex->TexDsv.GetRawRef()); + NewTex->TexDsv = NULL; + hr = Device->CreateDepthStencilView(NewTex->Tex, createDepthSrv ? &depthDsv : NULL, &NewTex->TexDsv.GetRawRef()); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } } else { - Device->CreateRenderTargetView(NewTex->Tex, NULL, &NewTex->TexRtv.GetRawRef()); + NewTex->TexRtv = NULL; + hr = Device->CreateRenderTargetView(NewTex->Tex, NULL, &NewTex->TexRtv.GetRawRef()); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } } } @@ -2109,13 +2377,19 @@ void RenderDevice::Render(const Matrix4f& matrix, Model* model) if (!model->VertexBuffer) { Ptr<Buffer> vb = *CreateBuffer(); - vb->Data(Buffer_Vertex | Buffer_ReadOnly, &model->Vertices[0], model->Vertices.GetSize() * sizeof(Vertex)); + if (!vb->Data(Buffer_Vertex | Buffer_ReadOnly, &model->Vertices[0], model->Vertices.GetSize() * sizeof(Vertex))) + { + OVR_ASSERT(false); + } model->VertexBuffer = vb; } if (!model->IndexBuffer) { Ptr<Buffer> ib = *CreateBuffer(); - ib->Data(Buffer_Index | Buffer_ReadOnly, &model->Indices[0], model->Indices.GetSize() * 2); + if (!ib->Data(Buffer_Index | Buffer_ReadOnly, &model->Indices[0], model->Indices.GetSize() * 2)) + { + OVR_ASSERT(false); + } model->IndexBuffer = ib; } @@ -2176,7 +2450,10 @@ void RenderDevice::Render(const Fill* fill, Render::Buffer* vertices, Render::Bu stdUniforms->Proj = StdUniforms.Proj; } - UniformBuffers[Shader_Vertex]->Data(Buffer_Uniform, vertexData, vshader->UniformsSize); + if (!UniformBuffers[Shader_Vertex]->Data(Buffer_Uniform, vertexData, vshader->UniformsSize)) + { + OVR_ASSERT(false); + } vshader->SetUniformBuffer(UniformBuffers[Shader_Vertex]); } @@ -2223,15 +2500,27 @@ void RenderDevice::Render(const Fill* fill, Render::Buffer* vertices, Render::Bu } } -UPInt RenderDevice::QueryGPUMemorySize() +size_t RenderDevice::QueryGPUMemorySize() { IDXGIDevice* pDXGIDevice; - Device->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice); + HRESULT hr = Device->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } IDXGIAdapter * pDXGIAdapter; - pDXGIDevice->GetAdapter(&pDXGIAdapter); - DXGI_ADAPTER_DESC adapterDesc; - pDXGIAdapter->GetDesc(&adapterDesc); - return adapterDesc.DedicatedVideoMemory; + hr = pDXGIDevice->GetAdapter(&pDXGIAdapter); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } + DXGI_ADAPTER_DESC adapterDesc; + hr = pDXGIAdapter->GetDesc(&adapterDesc); + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); + } + return adapterDesc.DedicatedVideoMemory; } @@ -2245,20 +2534,25 @@ void RenderDevice::Present ( bool withVsync ) } } + HRESULT hr; if ( withVsync ) { - SwapChain->Present(1, 0); + hr = SwapChain->Present(1, 0); } else { // Immediate present - SwapChain->Present(0, 0); + hr = SwapChain->Present(0, 0); + } + if (FAILED(hr)) + { + OVR_LOG_COM_ERROR(hr); } } void RenderDevice::WaitUntilGpuIdle() { -#if 0 +#if 1 // If enabling this option and using an NVIDIA GPU, // then make sure your "max pre-rendered frames" is set to 1 under the NVIDIA GPU settings. @@ -2289,35 +2583,35 @@ void RenderDevice::WaitUntilGpuIdle() #endif } -void RenderDevice::FillRect(float left, float top, float right, float bottom, Color c) +void RenderDevice::FillRect(float left, float top, float right, float bottom, Color c, const Matrix4f* view) { Context->OMSetBlendState(BlendState, NULL, 0xffffffff); - OVR::Render::RenderDevice::FillRect(left, top, right, bottom, c); + OVR::Render::RenderDevice::FillRect(left, top, right, bottom, c, view); Context->OMSetBlendState(NULL, NULL, 0xffffffff); } -void RenderDevice::FillGradientRect(float left, float top, float right, float bottom, Color col_top, Color col_btm) +void RenderDevice::FillGradientRect(float left, float top, float right, float bottom, Color col_top, Color col_btm, const Matrix4f* view) { Context->OMSetBlendState(BlendState, NULL, 0xffffffff); - OVR::Render::RenderDevice::FillGradientRect(left, top, right, bottom, col_top, col_btm); + OVR::Render::RenderDevice::FillGradientRect(left, top, right, bottom, col_top, col_btm, view); Context->OMSetBlendState(NULL, NULL, 0xffffffff); } -void RenderDevice::RenderText(const struct Font* font, const char* str, float x, float y, float size, Color c) +void RenderDevice::RenderText(const struct Font* font, const char* str, float x, float y, float size, Color c, const Matrix4f* view) { Context->OMSetBlendState(BlendState, NULL, 0xffffffff); - OVR::Render::RenderDevice::RenderText(font, str, x, y, size, c); + OVR::Render::RenderDevice::RenderText(font, str, x, y, size, c, view); Context->OMSetBlendState(NULL, NULL, 0xffffffff); } -void RenderDevice::RenderImage(float left, float top, float right, float bottom, ShaderFill* image) +void RenderDevice::RenderImage(float left, float top, float right, float bottom, ShaderFill* image, unsigned char alpha, const Matrix4f* view) { Context->OMSetBlendState(BlendState, NULL, 0xffffffff); - OVR::Render::RenderDevice::RenderImage(left, top, right, bottom, image); + OVR::Render::RenderDevice::RenderImage(left, top, right, bottom, image, alpha, view); Context->OMSetBlendState(NULL, NULL, 0xffffffff); } -void RenderDevice::BeginGpuEvent(const char* markerText, UInt32 markerColor) +void RenderDevice::BeginGpuEvent(const char* markerText, uint32_t markerColor) { #if GPU_PROFILING WCHAR wStr[255]; diff --git a/Samples/CommonSrc/Render/Render_D3D1X_Device.h b/Samples/CommonSrc/Render/Render_D3D1X_Device.h index bd733cc..4207d8a 100644 --- a/Samples/CommonSrc/Render/Render_D3D1X_Device.h +++ b/Samples/CommonSrc/Render/Render_D3D1X_Device.h @@ -38,6 +38,9 @@ limitations under the License. #include "../Render/Render_Device.h" +#include <WinSock2.h> +#include <WS2tcpip.h> +#define WIN32_LEAN_AND_MEAN #include <Windows.h> #if (OVR_D3D_VERSION == 10) @@ -312,7 +315,7 @@ public: virtual void WaitUntilGpuIdle(); virtual bool SetFullscreen(DisplayMode fullscreen); - virtual UPInt QueryGPUMemorySize(); + virtual size_t QueryGPUMemorySize(); virtual void Clear(float r = 0, float g = 0, float b = 0, float a = 1, float depth = 1, @@ -345,10 +348,10 @@ public: } // Overrident to apply proper blend state. - virtual void FillRect(float left, float top, float right, float bottom, Color c); - virtual void FillGradientRect(float left, float top, float right, float bottom, Color col_top, Color col_btm); - virtual void RenderText(const struct Font* font, const char* str, float x, float y, float size, Color c); - virtual void RenderImage(float left, float top, float right, float bottom, ShaderFill* image); + virtual void FillRect(float left, float top, float right, float bottom, Color c, const Matrix4f* view=NULL); + virtual void FillGradientRect(float left, float top, float right, float bottom, Color col_top, Color col_btm, const Matrix4f* view); + virtual void RenderText(const struct Font* font, const char* str, float x, float y, float size, Color c, const Matrix4f* view=NULL); + virtual void RenderImage(float left, float top, float right, float bottom, ShaderFill* image, unsigned char alpha=255, const Matrix4f* view=NULL); virtual void Render(const Matrix4f& matrix, Model* model); virtual void Render(const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices, @@ -369,7 +372,7 @@ public: void SetTexture(Render::ShaderStage stage, int slot, const Texture* t); // GPU Profiling - virtual void BeginGpuEvent(const char* markerText, UInt32 markerColor); + virtual void BeginGpuEvent(const char* markerText, uint32_t markerColor); virtual void EndGpuEvent(); }; diff --git a/Samples/CommonSrc/Render/Render_Device.cpp b/Samples/CommonSrc/Render/Render_Device.cpp index 88e611a..94ff680 100644 --- a/Samples/CommonSrc/Render/Render_Device.cpp +++ b/Samples/CommonSrc/Render/Render_Device.cpp @@ -77,7 +77,7 @@ namespace OVR { namespace Render { - UInt16 CubeIndices[] = + uint16_t CubeIndices[] = { 0, 1, 3, 3, 1, 2, @@ -127,7 +127,7 @@ namespace OVR { namespace Render { Model* box = new Model(); - UInt16 startIndex = 0; + uint16_t startIndex = 0; // Cube startIndex = box->AddVertex(Vector3f(x1, y2, z1), ycolor); @@ -238,7 +238,7 @@ namespace OVR { namespace Render { }; - UInt16 startIndex = GetNextVertexIndex(); + uint16_t startIndex = GetNextVertexIndex(); enum { @@ -265,7 +265,7 @@ namespace OVR { namespace Render { { Vector3f s = size * 0.5f; Vector3f o = origin; - UInt16 i = GetNextVertexIndex(); + uint16_t i = GetNextVertexIndex(); AddVertex(-s.x + o.x, s.y + o.y, -s.z + o.z, c, 0, 1, 0, 0, -1); AddVertex(s.x + o.x, s.y + o.y, -s.z + o.z, c, 1, 1, 0, 0, -1); @@ -324,15 +324,15 @@ namespace OVR { namespace Render { { Model *cyl = new Model(); float halfht = height * 0.5f; - for(UInt16 i = 0; i < sides; i++) + for(uint16_t i = 0; i < sides; i++) { - float x = cosf(Math<float>::TwoPi * i / float(sides)); - float y = sinf(Math<float>::TwoPi * i / float(sides)); + float x = cosf(MATH_FLOAT_TWOPI * i / float(sides)); + float y = sinf(MATH_FLOAT_TWOPI * i / float(sides)); cyl->AddVertex(radius * x, radius * y, halfht, color, x + 1, y, 0, 0, 1); cyl->AddVertex(radius * x, radius * y, -1.0f*halfht, color, x, y, 0, 0, -1); - UInt16 j = 0; + uint16_t j = 0; if(i < sides - 1) { j = i + 1; @@ -340,8 +340,8 @@ namespace OVR { namespace Render { cyl->AddTriangle(1, i * 4 + 1, i * 4 + 5); } - float nx = cosf(Math<float>::Pi * (0.5f + 2.0f * i / float(sides))); - float ny = sinf(Math<float>::Pi * (0.5f + 2.0f * i / float(sides))); + float nx = cosf(MATH_FLOAT_PI * (0.5f + 2.0f * i / float(sides))); + float ny = sinf(MATH_FLOAT_PI * (0.5f + 2.0f * i / float(sides))); cyl->AddVertex(radius * x, radius * y, halfht, color, x + 1, y, nx, ny, 0); cyl->AddVertex(radius * x, radius * y, -1.0f*halfht, color, x, y, nx, ny, 0); @@ -359,21 +359,21 @@ namespace OVR { namespace Render { float halfht = height * 0.5f; cone->AddVertex(0.0f, 0.0f, -1.0f*halfht, color, 0, 0, 0, 0, -1); - for(UInt16 i = 0; i < sides; i++) + for(uint16_t i = 0; i < sides; i++) { - float x = cosf(Math<float>::TwoPi * i / float(sides)); - float y = sinf(Math<float>::TwoPi * i / float(sides)); + float x = cosf(MATH_FLOAT_TWOPI * i / float(sides)); + float y = sinf(MATH_FLOAT_TWOPI * i / float(sides)); cone->AddVertex(radius * x, radius * y, -1.0f*halfht, color, 0, 0, 0, 0, -1); - UInt16 j = 1; + uint16_t j = 1; if(i < sides - 1) { j = i + 1; } - float next_x = cosf(Math<float>::TwoPi * j / float(sides)); - float next_y = sinf(Math<float>::TwoPi * j / float(sides)); + float next_x = cosf(MATH_FLOAT_TWOPI * j / float(sides)); + float next_y = sinf(MATH_FLOAT_TWOPI * j / float(sides)); Vector3f normal = Vector3f(x, y, -halfht).Cross(Vector3f(next_x, next_y, -halfht)); @@ -391,13 +391,13 @@ namespace OVR { namespace Render { Model* Model::CreateSphere(Color color, Vector3f origin, float radius, int sides) { Model *sphere = new Model(); - UInt16 usides = (UInt16) sides; - UInt16 halfsides = usides/2; + uint16_t usides = (uint16_t) sides; + uint16_t halfsides = usides/2; - for(UInt16 k = 0; k < halfsides; k++) { + for(uint16_t k = 0; k < halfsides; k++) { - float z = cosf(Math<float>::Pi * k / float(halfsides)); - float z_r = sinf(Math<float>::Pi * k / float(halfsides)); // the radius of the cross circle with coordinate z + float z = cosf(MATH_FLOAT_PI * k / float(halfsides)); + float z_r = sinf(MATH_FLOAT_PI * k / float(halfsides)); // the radius of the cross circle with coordinate z if (k == 0) { // add north and south poles @@ -406,12 +406,12 @@ namespace OVR { namespace Render { } else { - for(UInt16 i = 0; i < sides; i++) + for(uint16_t i = 0; i < sides; i++) { - float x = cosf(Math<float>::TwoPi * i / float(sides)) * z_r; - float y = sinf(Math<float>::TwoPi * i / float(sides)) * z_r; + float x = cosf(MATH_FLOAT_TWOPI * i / float(sides)) * z_r; + float y = sinf(MATH_FLOAT_TWOPI * i / float(sides)) * z_r; - UInt16 j = 0; + uint16_t j = 0; if(i < sides - 1) { j = i + 1; @@ -419,8 +419,8 @@ namespace OVR { namespace Render { sphere->AddVertex(radius * x, radius * y, radius * z, color, 0, 1, x, y, z); - UInt16 indi = 2 + (k -1)*usides + i; - UInt16 indj = 2 + (k -1)*usides + j; + uint16_t indi = 2 + (k -1)*usides + i; + uint16_t indj = 2 + (k -1)*usides + j; if (k == 1) // NorthPole sphere->AddTriangle(0, j + 2, i + 2); else if (k == halfsides - 1) //SouthPole @@ -548,14 +548,14 @@ namespace OVR { namespace Render { } float RenderDevice::MeasureText(const Font* font, const char* str, float size, float strsize[2], - const UPInt charRange[2], Vector2f charRangeRect[2]) + const size_t charRange[2], Vector2f charRangeRect[2]) { - UPInt length = strlen(str); + size_t length = strlen(str); float w = 0; float xp = 0; float yp = 0; - for (UPInt i = 0; i < length; i++) + for (size_t i = 0; i < length; i++) { if (str[i] == '\n') { @@ -621,8 +621,13 @@ namespace OVR { namespace Render { void RenderDevice::RenderText(const Font* font, const char* str, - float x, float y, float size, Color c) + float x, float y, float size, Color c, const Matrix4f* view) { + size_t length = strlen(str); + + // Do not attempt to render if we have an empty string. + if (length == 0) { return; } + if(!pTextVertexBuffer) { pTextVertexBuffer = *CreateBuffer(); @@ -638,8 +643,6 @@ namespace OVR { namespace Render { *CreateTexture(Texture_R, font->twidth, font->theight, font->tex)), true); } - UPInt length = strlen(str); - pTextVertexBuffer->Data(Buffer_Vertex, NULL, length * 6 * sizeof(Vertex)); Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, length * 6 * sizeof(Vertex), Map_Discard); if(!vertices) @@ -652,10 +655,13 @@ namespace OVR { namespace Render { 0, 0, 0, 0, x, y, 0, 1).Transposed(); + if (view) + m = (*view) * m; + float xp = 0, yp = (float)font->ascent; int ivertex = 0; - for (UPInt i = 0; i < length; i++) + for (size_t i = 0; i < length; i++) { if(str[i] == '\n') { @@ -696,10 +702,10 @@ namespace OVR { namespace Render { pTextVertexBuffer->Unmap(vertices); - Render(font->fill, pTextVertexBuffer, NULL, m, 0, ivertex, Prim_Triangles); + Render(font->fill, pTextVertexBuffer, NULL, m, 0, ivertex, Prim_Triangles); } - void RenderDevice::FillRect(float left, float top, float right, float bottom, Color c) + void RenderDevice::FillRect(float left, float top, float right, float bottom, Color c, const Matrix4f* matrix) { if(!pTextVertexBuffer) { @@ -729,12 +735,15 @@ namespace OVR { namespace Render { pTextVertexBuffer->Unmap(vertices); - Render(fill, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles); + if (matrix == NULL) + Render(fill, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles); + else + Render(fill, pTextVertexBuffer, NULL, *matrix, 0, 6, Prim_Triangles); } - void RenderDevice::FillGradientRect(float left, float top, float right, float bottom, Color col_top, Color col_btm) + void RenderDevice::FillGradientRect(float left, float top, float right, float bottom, Color col_top, Color col_btm, const Matrix4f* matrix) { if(!pTextVertexBuffer) { @@ -764,7 +773,10 @@ namespace OVR { namespace Render { pTextVertexBuffer->Unmap(vertices); - Render(fill, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles); + if (matrix) + Render(fill, pTextVertexBuffer, NULL, *matrix, 0, 6, Prim_Triangles); + else + Render(fill, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles); } @@ -860,7 +872,8 @@ namespace OVR { namespace Render { float right, float bottom, ShaderFill* image, - unsigned char alpha) + unsigned char alpha, + const Matrix4f* view) { Color c = Color(255, 255, 255, alpha); Ptr<Model> m = *new Model(Prim_Triangles); @@ -872,7 +885,10 @@ namespace OVR { namespace Render { m->AddTriangle(0,3,2); m->Fill = image; - Render(Matrix4f(), m); + if (view) + Render(*view, m); + else + Render(Matrix4f(), m); } bool RenderDevice::initPostProcessSupport(PostProcessType pptype) @@ -970,7 +986,6 @@ namespace OVR { namespace Render { { BeginRendering(); initPostProcessSupport(pptype); - SetViewport(VP); SetWorldUniforms(Proj); SetExtraShaders(NULL); } @@ -978,7 +993,7 @@ namespace OVR { namespace Render { void RenderDevice::FinishScene() { SetExtraShaders(0); - SetDefaultRenderTarget(); + //SetDefaultRenderTarget(); } @@ -1002,7 +1017,7 @@ namespace OVR { namespace Render { int numVerts = 0; int numTris = 0; DistortionMeshVertexData *pRawVerts = NULL; - UInt16 *pIndices = NULL; + uint16_t *pIndices = NULL; DistortionMeshCreate ( &pRawVerts, &pIndices, &numVerts, &numTris, stereoParams, hmdRenderInfo ); int numIndices = numTris * 3; @@ -1018,10 +1033,10 @@ namespace OVR { namespace Render { pCurVert->TexG = pCurRawVert->TanEyeAnglesG; pCurVert->TexB = pCurRawVert->TanEyeAnglesB; // Convert [0.0f,1.0f] to [0,255] - pCurVert->Col.R = (OVR::UByte)( floorf ( pCurRawVert->Shade * 255.999f ) ); + pCurVert->Col.R = (uint8_t)( floorf ( pCurRawVert->Shade * 255.999f ) ); pCurVert->Col.G = pCurVert->Col.R; pCurVert->Col.B = pCurVert->Col.R; - pCurVert->Col.A = (OVR::UByte)( floorf ( pCurRawVert->TimewarpLerp * 255.999f ) ); + pCurVert->Col.A = (uint8_t)( floorf ( pCurRawVert->TimewarpLerp * 255.999f ) ); pCurRawVert++; pCurVert++; } @@ -1030,7 +1045,7 @@ namespace OVR { namespace Render { pDistortionMeshVertexBuffer[eyeNum] = *CreateBuffer(); pDistortionMeshVertexBuffer[eyeNum]->Data ( Buffer_Vertex | Buffer_ReadOnly, pVerts, sizeof(DistortionVertex) * numVerts ); pDistortionMeshIndexBuffer[eyeNum] = *CreateBuffer(); - pDistortionMeshIndexBuffer[eyeNum]->Data ( Buffer_Index | Buffer_ReadOnly, pIndices, ( sizeof(UInt16) * numIndices ) ); + pDistortionMeshIndexBuffer[eyeNum]->Data ( Buffer_Index | Buffer_ReadOnly, pIndices, ( sizeof(uint16_t) * numIndices ) ); DistortionMeshDestroy ( pRawVerts, pIndices ); OVR_FREE ( pVerts ); @@ -1047,7 +1062,7 @@ namespace OVR { namespace Render { int numVerts = 0; int numTris = 0; HeightmapMeshVertexData *pRawVerts = NULL; - UInt16 *pIndices = NULL; + uint16_t *pIndices = NULL; HeightmapMeshCreate ( &pRawVerts, &pIndices, &numVerts, &numTris, stereoParams, hmdRenderInfo ); int numIndices = numTris * 3; @@ -1062,7 +1077,7 @@ namespace OVR { namespace Render { Vector2f texCoord = pCurRawVert->TanEyeAngles; pCurVert->Tex.x = texCoord.x; pCurVert->Tex.y = texCoord.y; - pCurVert->Tex.z = (OVR::UByte)( floorf ( pCurRawVert->TimewarpLerp * 255.999f ) ); + pCurVert->Tex.z = (uint8_t)( floorf ( pCurRawVert->TimewarpLerp * 255.999f ) ); pCurRawVert++; pCurVert++; } @@ -1071,7 +1086,7 @@ namespace OVR { namespace Render { pHeightmapMeshVertexBuffer[eyeNum] = *CreateBuffer(); pHeightmapMeshVertexBuffer[eyeNum]->Data ( Buffer_Vertex, pVerts, sizeof(HeightmapVertex) * numVerts ); pHeightmapMeshIndexBuffer[eyeNum] = *CreateBuffer(); - pHeightmapMeshIndexBuffer[eyeNum]->Data ( Buffer_Index, pIndices, ( sizeof(UInt16) * numIndices ) ); + pHeightmapMeshIndexBuffer[eyeNum]->Data ( Buffer_Index, pIndices, ( sizeof(uint16_t) * numIndices ) ); HeightmapMeshDestroy ( pRawVerts, pIndices ); OVR_FREE ( pVerts ); @@ -1091,8 +1106,18 @@ namespace OVR { namespace Render { RenderTarget* pHmdSpaceLayerRenderTargetLeftOrBothEyes, RenderTarget* pHmdSpaceLayerRenderTargetRight, RenderTarget* pOverlayLayerRenderTargetLeftOrBothEyes, - RenderTarget* pOverlayLayerRenderTargetRight) + RenderTarget* pOverlayLayerRenderTargetRight, + RenderTarget* pOutputTarget) { + if(pOutputTarget != NULL) + { + SetRenderTarget(pOutputTarget->pColorTex, pOutputTarget->pDepthTex); + } + else + { + SetDefaultRenderTarget(); + } + SetExtraShaders(0); bool usingOverlay = pOverlayLayerRenderTargetLeftOrBothEyes != NULL; @@ -1310,7 +1335,15 @@ namespace OVR { namespace Render { // Pass 2 - do distortion { + if(pOutputTarget != NULL) + { + SetRenderTarget(pOutputTarget->pColorTex, pOutputTarget->pDepthTex); + } + else + { SetDefaultRenderTarget(); + } + SetDepthMode(false, false); Recti vp( 0, 0, WindowWidth, WindowHeight ); @@ -1540,7 +1573,7 @@ namespace OVR { namespace Render { len = 0; } float tp = Planes[crossing].TestSide(origin + norm * len); - OVR_ASSERT(fabsf(tp) < 0.05f + Mathf::Tolerance); + OVR_ASSERT(fabsf(tp) < 0.05f + MATH_FLOAT_TOLERANCE); OVR_UNUSED(tp); if(ph) @@ -1562,12 +1595,12 @@ namespace OVR { namespace Render { return n; } - void FilterRgba2x2(const UByte* src, int w, int h, UByte* dest) + void FilterRgba2x2(const uint8_t* src, int w, int h, uint8_t* dest) { for(int j = 0; j < (h & ~1); j += 2) { - const UByte* psrc = src + (w * j * 4); - UByte* pdest = dest + ((w >> 1) * (j >> 1) * 4); + const uint8_t* psrc = src + (w * j * 4); + uint8_t* pdest = dest + ((w >> 1) * (j >> 1) * 4); for(int i = 0; i < w >> 1; i++, psrc += 8, pdest += 4) { diff --git a/Samples/CommonSrc/Render/Render_Device.h b/Samples/CommonSrc/Render/Render_Device.h index eea352e..d7e4917 100644 --- a/Samples/CommonSrc/Render/Render_Device.h +++ b/Samples/CommonSrc/Render/Render_Device.h @@ -28,6 +28,7 @@ limitations under the License. #include "Kernel/OVR_RefCount.h" #include "Kernel/OVR_String.h" #include "Kernel/OVR_File.h" +#include "Kernel/OVR_Color.h" #include "OVR_CAPI.h" #include "OVR_Stereo.h" @@ -37,6 +38,7 @@ namespace OVR { namespace Render { class RenderDevice; struct Font; + //----------------------------------------------------------------------------------- enum ShaderStage @@ -90,6 +92,7 @@ enum BuiltinShaders FShader_Gouraud , FShader_Texture , FShader_AlphaTexture , + FShader_AlphaBlendedTexture , FShader_PostProcessWithChromAb , FShader_LitGouraud , FShader_LitTexture , @@ -136,6 +139,7 @@ enum TextureFormat Texture_RenderTarget = 0x10000, Texture_SampleDepth = 0x20000, Texture_GenMipmaps = 0x40000, + Texture_SRGB = 0x80000, }; enum SampleMode @@ -502,7 +506,7 @@ class Model : public Node { public: Array<Vertex> Vertices; - Array<UInt16> Indices; + Array<uint16_t> Indices; PrimitiveType Type; Ptr<class Fill> Fill; bool Visible; @@ -532,42 +536,42 @@ public: } // Returns the index next added vertex will have. - UInt16 GetNextVertexIndex() const + uint16_t GetNextVertexIndex() const { - return (UInt16)Vertices.GetSize(); + return (uint16_t)Vertices.GetSize(); } - UInt16 AddVertex(const Vertex& v) + uint16_t AddVertex(const Vertex& v) { OVR_ASSERT(!VertexBuffer && !IndexBuffer); - UPInt size = Vertices.GetSize(); + size_t size = Vertices.GetSize(); OVR_ASSERT(size <= USHRT_MAX); // We only use a short to store vert indices. - UInt16 index = (UInt16) size; + uint16_t index = (uint16_t) size; Vertices.PushBack(v); return index; } - UInt16 AddVertex(const Vector3f& v, const Color& c, float u_ = 0, float v_ = 0) + uint16_t AddVertex(const Vector3f& v, const Color& c, float u_ = 0, float v_ = 0) { return AddVertex(Vertex(v,c,u_,v_)); } - UInt16 AddVertex(float x, float y, float z, const Color& c, float u, float v) + uint16_t AddVertex(float x, float y, float z, const Color& c, float u, float v) { return AddVertex(Vertex(Vector3f(x,y,z),c, u,v)); } - void AddLine(UInt16 a, UInt16 b) + void AddLine(uint16_t a, uint16_t b) { Indices.PushBack(a); Indices.PushBack(b); } - UInt16 AddVertex(float x, float y, float z, const Color& c, + uint16_t AddVertex(float x, float y, float z, const Color& c, float u, float v, float nx, float ny, float nz) { return AddVertex(Vertex(Vector3f(x,y,z),c, u,v, Vector3f(nx,ny,nz))); } - UInt16 AddVertex(float x, float y, float z, const Color& c, + uint16_t AddVertex(float x, float y, float z, const Color& c, float u1, float v1, float u2, float v2, float nx, float ny, float nz) { return AddVertex(Vertex(Vector3f(x,y,z), c, u1, v1, u2, v2, Vector3f(nx,ny,nz))); @@ -578,7 +582,7 @@ public: AddLine(AddVertex(a), AddVertex(b)); } - void AddTriangle(UInt16 a, UInt16 b, UInt16 c) + void AddTriangle(uint16_t a, uint16_t b, uint16_t c) { Indices.PushBack(a); Indices.PushBack(b); @@ -625,7 +629,7 @@ public: void ClearRenderer() { - for (UPInt i=0; i< Nodes.GetSize(); i++) + for (size_t i=0; i< Nodes.GetSize(); i++) Nodes[i]->ClearRenderer(); } @@ -723,9 +727,9 @@ struct DisplayId // MacOS int CgDisplayId; // CGDirectDisplayID - DisplayId() : CgDisplayId(0) {} + DisplayId() : CgDisplayId(-2) {} DisplayId(int id) : CgDisplayId(id) {} - DisplayId(String m, int id=0) : MonitorName(m), CgDisplayId(id) {} + DisplayId(String m, int id = -2) : MonitorName(m), CgDisplayId(id) {} operator bool () const { @@ -734,19 +738,28 @@ struct DisplayId bool operator== (const DisplayId& b) const { - return CgDisplayId == b.CgDisplayId && - (strstr(MonitorName.ToCStr(), b.MonitorName.ToCStr()) || - strstr(b.MonitorName.ToCStr(), MonitorName.ToCStr())); + if (MonitorName.IsEmpty() || b.MonitorName.IsEmpty()) + { + return CgDisplayId == b.CgDisplayId; + } + else + { + return strstr(MonitorName.ToCStr(), b.MonitorName.ToCStr()) || + strstr(b.MonitorName.ToCStr(), MonitorName.ToCStr()); + } } }; struct RendererParams { - int Multisample; - int Fullscreen; - DisplayId Display; - - RendererParams(int ms = 1) : Multisample(ms), Fullscreen(0) {} + int Multisample; + int Fullscreen; + DisplayId Display; + // Resolution of the rendering buffer used during creation. + // Allows buffer of different size then the widow if not zero. + Sizei Resolution; + + RendererParams(int ms = 1) : Multisample(ms), Fullscreen(0), Resolution(0) {} bool IsDisplaySet() const { @@ -777,7 +790,7 @@ protected: Ptr<ShaderSet> pPostProcessHeightmapShader; Ptr<Buffer> pFullScreenVertexBuffer; Color DistortionClearColor; - UPInt TotalTextureMemoryUsage; + size_t TotalTextureMemoryUsage; float FadeOutBorderFraction; int DistortionMeshNumTris[2]; @@ -893,7 +906,8 @@ public: RenderTarget* pHmdSpaceLayerRenderTargetLeftOrBothEyes, RenderTarget* pHmdSpaceLayerRenderTargetRight, RenderTarget* pStaticLayerRenderTargetLeftOrBothEyes, - RenderTarget* pStaticLayerRenderTargetRight); + RenderTarget* pStaticLayerRenderTargetRight, + RenderTarget* pOutputTarget); // Finish scene. virtual void FinishScene(); @@ -932,14 +946,14 @@ public: // Returns width of text in same units as drawing. If strsize is not null, stores width and height. // Can optionally return char-range selection rectangle. float MeasureText(const Font* font, const char* str, float size, float strsize[2] = NULL, - const UPInt charRange[2] = 0, Vector2f charRangeRect[2] = 0); - virtual void RenderText(const Font* font, const char* str, float x, float y, float size, Color c); + const size_t charRange[2] = 0, Vector2f charRangeRect[2] = 0); + virtual void RenderText(const Font* font, const char* str, float x, float y, float size, Color c, const Matrix4f* view = NULL); - virtual void FillRect(float left, float top, float right, float bottom, Color c); + virtual void FillRect(float left, float top, float right, float bottom, Color c, const Matrix4f* view = NULL); virtual void RenderLines ( int NumLines, Color c, float *x, float *y, float *z = NULL ); virtual void FillTexturedRect(float left, float top, float right, float bottom, float ul, float vt, float ur, float vb, Color c, Ptr<Texture> tex); - virtual void FillGradientRect(float left, float top, float right, float bottom, Color col_top, Color col_btm); - virtual void RenderImage(float left, float top, float right, float bottom, ShaderFill* image, unsigned char alpha=255); + virtual void FillGradientRect(float left, float top, float right, float bottom, Color col_top, Color col_btm, const Matrix4f* view); + virtual void RenderImage(float left, float top, float right, float bottom, ShaderFill* image, unsigned char alpha=255, const Matrix4f* view = NULL); virtual Fill *CreateSimpleFill(int flags = Fill::F_Solid) = 0; Fill * CreateTextureFill(Texture* tex, bool useAlpha = false); @@ -963,7 +977,7 @@ public: VP = Recti( 0, 0, WindowWidth, WindowHeight ); } - UPInt GetTotalTextureMemoryUsage() const + size_t GetTotalTextureMemoryUsage() const { return TotalTextureMemoryUsage; } @@ -995,7 +1009,7 @@ public: // GPU Profiling // using (void) to avoid "unused param" warnings - virtual void BeginGpuEvent(const char* markerText, UInt32 markerColor) { (void)markerText; (void)markerColor; } + virtual void BeginGpuEvent(const char* markerText, uint32_t markerColor) { (void)markerText; (void)markerColor; } virtual void EndGpuEvent() { } protected: @@ -1015,7 +1029,7 @@ private: class AutoGpuProf { public: - AutoGpuProf(RenderDevice* device, const char* markerText, UInt32 color) + AutoGpuProf(RenderDevice* device, const char* markerText, uint32_t color) : mDevice(device) { device->BeginGpuEvent(markerText, color); } @@ -1023,7 +1037,7 @@ public: AutoGpuProf(RenderDevice* device, const char* markerText) : mDevice(device) { - UInt32 color = ((rand() & 0xFF) << 24) + + uint32_t color = ((rand() & 0xFF) << 24) + ((rand() & 0xFF) << 16) + ((rand() & 0xFF) << 8) + (rand() & 0xFF); @@ -1043,11 +1057,12 @@ int GetTextureSize(int format, int w, int h); // Filter an rgba image with a 2x2 box filter, for mipmaps. // Image size must be a power of 2. -void FilterRgba2x2(const UByte* src, int w, int h, UByte* dest); +void FilterRgba2x2(const uint8_t* src, int w, int h, uint8_t* dest); Texture* LoadTextureTga(RenderDevice* ren, File* f, unsigned char alpha = 255); Texture* LoadTextureDDS(RenderDevice* ren, File* f); -}} + +}} // namespace OVR::Render #endif diff --git a/Samples/CommonSrc/Render/Render_GL_Device.cpp b/Samples/CommonSrc/Render/Render_GL_Device.cpp index 774af07..f6e13ef 100644 --- a/Samples/CommonSrc/Render/Render_GL_Device.cpp +++ b/Samples/CommonSrc/Render/Render_GL_Device.cpp @@ -306,6 +306,23 @@ static const char* AlphaTextureFragShaderSrc = " gl_FragColor = oColor * vec4(1,1,1,texture2D(Texture0, oTexCoord).r);\n" "}\n"; +static const char* AlphaBlendedTextureFragShaderSrc = + "#version 110\n" + + "uniform sampler2D Texture0;\n" + + "varying vec4 oColor;\n" + "varying vec2 oTexCoord;\n" + + "void main()\n" + "{\n" + " vec4 finalColor = oColor;\n" + " finalColor *= texture2D(Texture0, oTexCoord);\n" + // Blend state expects premultiplied alpha + " finalColor.rgb *= finalColor.a;\n" + " gl_FragColor = finalColor;\n" + "}\n"; + static const char* MultiTextureFragShaderSrc = "#version 110\n" @@ -685,6 +702,7 @@ static const char* FShaderSrcs[FShader_Count] = GouraudFragShaderSrc, TextureFragShaderSrc, AlphaTextureFragShaderSrc, + AlphaBlendedTextureFragShaderSrc, PostProcessFragShaderWithChromAbSrc, LitSolidFragShaderSrc, LitTextureFragShaderSrc, @@ -700,40 +718,44 @@ RenderDevice::RenderDevice(const RendererParams&) { int GlMajorVersion = 0; int GlMinorVersion = 0; + bool isES = false; const char* glVersionString = (const char*)glGetString(GL_VERSION); - char prefix[64]; - bool foundVersion = false; - - for (int i = 10; i < 30; ++i) - { - int major = i / 10; - int minor = i % 10; - OVR_sprintf(prefix, 64, "%d.%d", major, minor); - if (strstr(glVersionString, prefix) == glVersionString) - { - GlMajorVersion = major; - GlMinorVersion = minor; - foundVersion = true; - break; - } - } - - if (!foundVersion) - { - glGetIntegerv(GL_MAJOR_VERSION, &GlMajorVersion); - glGetIntegerv(GL_MAJOR_VERSION, &GlMinorVersion); - } - - if (GlMajorVersion >= 3) + +#ifdef OVR_CC_MSVC + // Hack: This is using sscanf_s on MSVC to kill the security warning. + // Normally the two functions are not interchangeable because the string format + // is different for %s types, however we only use %d so it's fine. +#define _OVR_SSCANF sscanf_s +#else +#define _OVR_SSCANF sscanf +#endif + + isES = strstr( glVersionString, "OpenGL ES-CM" ) != NULL; + if( isES ) { - SupportsVao = true; + _OVR_SSCANF(glVersionString, "OpenGL ES-CM %d.%d", &GlMajorVersion, &GlMinorVersion); } else { - const char* extensions = (const char*)glGetString(GL_EXTENSIONS); - SupportsVao = (strstr("GL_ARB_vertex_array_object", extensions) != NULL); + isES = strstr( glVersionString, "OpenGL ES " ) != NULL; + if ( isES ) + { + _OVR_SSCANF(glVersionString, "OpenGL ES %d.%d", &GlMajorVersion, &GlMinorVersion); + } + else + { + _OVR_SSCANF(glVersionString, "%d.%d", &GlMajorVersion, &GlMinorVersion); + } } + +#undef _OVR_SSCANF + + OVR_ASSERT( isES == false ); + OVR_ASSERT(GlMajorVersion >= 2); + + const char* extensions = (const char*)glGetString(GL_EXTENSIONS); + SupportsVao = (GlMajorVersion >= 3) || (strstr("GL_ARB_vertex_array_object", extensions) != NULL); for (int i = 0; i < VShader_Count; i++) { @@ -806,7 +828,6 @@ Shader *RenderDevice::LoadBuiltinShader(ShaderStage stage, int shader) void RenderDevice::BeginRendering() { - //glEnable(GL_FRAMEBUFFER_SRGB); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glFrontFace(GL_CW); @@ -1339,7 +1360,7 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo { case Texture_RGBA: glformat = GL_RGBA; break; case Texture_R: glformat = GL_RED; break; - case Texture_Depth: glformat = GL_DEPTH_COMPONENT32F; gltype = GL_FLOAT; break; + case Texture_Depth: glformat = GL_DEPTH_COMPONENT; gltype = GL_FLOAT; break; case Texture_DXT1: glformat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break; case Texture_DXT3: glformat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break; case Texture_DXT5: glformat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break; @@ -1348,7 +1369,14 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo } Texture* NewTex = new Texture(this, width, height); glBindTexture(GL_TEXTURE_2D, NewTex->TexId); - OVR_ASSERT(!glGetError()); + GLint err = glGetError(); + + OVR_ASSERT(!err); + + if( err ) + { + printf("%d\n", err); + } if (format & Texture_Compressed) { @@ -1366,10 +1394,14 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo if (h < 1) h = 1; } } - else if (format & Texture_Depth) - glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, GL_DEPTH_COMPONENT, gltype, data); - else - glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, glformat, gltype, data); + else + { + bool isSRGB = ((format & Texture_TypeMask) == Texture_RGBA && (format & Texture_SRGB) != 0); + bool isDepth = ((format & Texture_Depth) != 0); + GLenum internalFormat = (isSRGB) ? GL_SRGB_ALPHA : (isDepth) ? GL_DEPTH_COMPONENT32F : glformat; + + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, glformat, gltype, data); + } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); @@ -1380,15 +1412,15 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo { int srcw = width, srch = height; int level = 0; - UByte* mipmaps = NULL; + uint8_t* mipmaps = NULL; do { level++; int mipw = srcw >> 1; if (mipw < 1) mipw = 1; int miph = srch >> 1; if (miph < 1) miph = 1; if (mipmaps == NULL) - mipmaps = (UByte*)OVR_ALLOC(mipw * miph * 4); - FilterRgba2x2(level == 1 ? (const UByte*)data : mipmaps, srcw, srch, mipmaps); + mipmaps = (uint8_t*)OVR_ALLOC(mipw * miph * 4); + FilterRgba2x2(level == 1 ? (const uint8_t*)data : mipmaps, srcw, srch, mipmaps); glTexImage2D(GL_TEXTURE_2D, level, glformat, mipw, miph, 0, glformat, gltype, mipmaps); srcw = mipw; srch = miph; diff --git a/Samples/CommonSrc/Render/Render_GL_Device.h b/Samples/CommonSrc/Render/Render_GL_Device.h index 563c87b..9b8ccef 100644 --- a/Samples/CommonSrc/Render/Render_GL_Device.h +++ b/Samples/CommonSrc/Render/Render_GL_Device.h @@ -27,6 +27,9 @@ limitations under the License. #include "../Render/Render_Device.h" #if defined(OVR_OS_WIN32) + #include <WinSock2.h> + #include <WS2tcpip.h> + #define WIN32_LEAN_AND_MEAN #include <Windows.h> #include <GL/gl.h> #include <GL/glext.h> diff --git a/Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp b/Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp index 9bfcec9..8b4ac73 100644 --- a/Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp +++ b/Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp @@ -28,7 +28,7 @@ limitations under the License. namespace OVR { namespace Render { namespace GL { namespace Win32 { -typedef HRESULT (__stdcall *PFNDWMENABLECOMPOSITIONPROC) (UINT); +typedef HRESULT (WINAPI *PFNDWMENABLECOMPOSITIONPROC) (UINT); #pragma warning(disable : 4995) PFNDWMENABLECOMPOSITIONPROC DwmEnableComposition; @@ -201,16 +201,16 @@ BOOL CALLBACK MonitorEnumFunc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) { RenderDevice* renderer = (RenderDevice*)dwData; - MONITORINFOEX monitor; + MONITORINFOEXA monitor; monitor.cbSize = sizeof(monitor); - if (::GetMonitorInfo(hMonitor, &monitor) && monitor.szDevice[0]) + if (::GetMonitorInfoA(hMonitor, &monitor) && monitor.szDevice[0]) { - DISPLAY_DEVICE dispDev; + DISPLAY_DEVICEA dispDev; memset(&dispDev, 0, sizeof(dispDev)); dispDev.cb = sizeof(dispDev); - if (::EnumDisplayDevices(monitor.szDevice, 0, &dispDev, 0)) + if (::EnumDisplayDevicesA(monitor.szDevice, 0, &dispDev, 0)) { if (strstr(String(dispDev.DeviceName).ToCStr(), renderer->GetParams().Display.MonitorName.ToCStr())) { diff --git a/Samples/CommonSrc/Render/Render_GL_Win32_Device.h b/Samples/CommonSrc/Render/Render_GL_Win32_Device.h index 273e997..14d0b65 100644 --- a/Samples/CommonSrc/Render/Render_GL_Win32_Device.h +++ b/Samples/CommonSrc/Render/Render_GL_Win32_Device.h @@ -26,7 +26,10 @@ limitations under the License. #include "Render_GL_Device.h" -#ifdef WIN32 +#ifdef OVR_OS_WIN32 +#include <WinSock2.h> +#include <WS2tcpip.h> +#define WIN32_LEAN_AND_MEAN #include <Windows.h> #endif diff --git a/Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp b/Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp index cf20cdd..3da1441 100644 --- a/Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp +++ b/Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp @@ -28,45 +28,45 @@ limitations under the License. namespace OVR { namespace Render { -static const UPInt OVR_DDS_PF_FOURCC = 0x4; -static const UInt32 OVR_DXT1_MAGIC_NUMBER = 0x31545844; // "DXT1" -static const UInt32 OVR_DXT2_MAGIC_NUMBER = 0x32545844; // "DXT2" -static const UInt32 OVR_DXT3_MAGIC_NUMBER = 0x33545844; // "DXT3" -static const UInt32 OVR_DXT4_MAGIC_NUMBER = 0x34545844; // "DXT4" -static const UInt32 OVR_DXT5_MAGIC_NUMBER = 0x35545844; // "DXT5" +static const size_t OVR_DDS_PF_FOURCC = 0x4; +static const uint32_t OVR_DXT1_MAGIC_NUMBER = 0x31545844; // "DXT1" +static const uint32_t OVR_DXT2_MAGIC_NUMBER = 0x32545844; // "DXT2" +static const uint32_t OVR_DXT3_MAGIC_NUMBER = 0x33545844; // "DXT3" +static const uint32_t OVR_DXT4_MAGIC_NUMBER = 0x34545844; // "DXT4" +static const uint32_t OVR_DXT5_MAGIC_NUMBER = 0x35545844; // "DXT5" struct OVR_DDS_PIXELFORMAT { - UInt32 Size; - UInt32 Flags; - UInt32 FourCC; - UInt32 RGBBitCount; - UInt32 RBitMask; - UInt32 GBitMask; - UInt32 BBitMask; - UInt32 ABitMask; + uint32_t Size; + uint32_t Flags; + uint32_t FourCC; + uint32_t RGBBitCount; + uint32_t RBitMask; + uint32_t GBitMask; + uint32_t BBitMask; + uint32_t ABitMask; }; struct OVR_DDS_HEADER { - UInt32 Size; - UInt32 Flags; - UInt32 Height; - UInt32 Width; - UInt32 PitchOrLinearSize; - UInt32 Depth; - UInt32 MipMapCount; - UInt32 Reserved1[11]; - OVR_DDS_PIXELFORMAT PixelFormat; - UInt32 Caps; - UInt32 Caps2; - UInt32 Caps3; - UInt32 Caps4; - UInt32 Reserved2; + uint32_t Size; + uint32_t Flags; + uint32_t Height; + uint32_t Width; + uint32_t PitchOrLinearSize; + uint32_t Depth; + uint32_t MipMapCount; + uint32_t Reserved1[11]; + OVR_DDS_PIXELFORMAT PixelFormat; + uint32_t Caps; + uint32_t Caps2; + uint32_t Caps3; + uint32_t Caps4; + uint32_t Reserved2; }; // Returns -1 on failure, or a valid TextureFormat value on success -static inline int InterpretPixelFormatFourCC(UInt32 fourCC) { +static inline int InterpretPixelFormatFourCC(uint32_t fourCC) { switch (fourCC) { case OVR_DXT1_MAGIC_NUMBER: return Texture_DXT1; case OVR_DXT2_MAGIC_NUMBER: return Texture_DXT3; @@ -97,7 +97,7 @@ Texture* LoadTextureDDS(RenderDevice* ren, File* f) int format = Texture_RGBA; - UInt32 mipCount = header.MipMapCount; + uint32_t mipCount = header.MipMapCount; if(mipCount <= 0) { mipCount = 1; diff --git a/Samples/CommonSrc/Render/Render_XmlSceneLoader.cpp b/Samples/CommonSrc/Render/Render_XmlSceneLoader.cpp index 5f31250..3d035e2 100644 --- a/Samples/CommonSrc/Render/Render_XmlSceneLoader.cpp +++ b/Samples/CommonSrc/Render/Render_XmlSceneLoader.cpp @@ -52,9 +52,9 @@ bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRend // Extract the relative path to our working directory for loading textures filePath[0] = 0; - SPInt pos = 0; - SPInt len = strlen(fileName); - for(SPInt i = len; i > 0; i--) + intptr_t pos = 0; + intptr_t len = strlen(fileName); + for(intptr_t i = len; i > 0; i--) { if (fileName[i-1]=='\\' || fileName[i-1]=='/') { @@ -76,7 +76,7 @@ bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRend for(int i = 0; i < textureCount; ++i) { const char* textureName = pXmlTexture->Attribute("fileName"); - SPInt dotpos = strcspn(textureName, "."); + intptr_t dotpos = strcspn(textureName, "."); char fname[300]; if (pos == len) @@ -216,8 +216,8 @@ bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRend Models[i]->Fill = shader; //add all the vertices to the model - const UPInt numVerts = vertices->GetSize(); - for(UPInt v = 0; v < numVerts; ++v) + const size_t numVerts = vertices->GetSize(); + for(size_t v = 0; v < numVerts; ++v) { if(diffuseTextureIndex > -1) { @@ -246,18 +246,18 @@ bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRend const char* indexStr = pXmlModel->FirstChildElement("indices")-> FirstChild()->ToText()->Value(); - UPInt stringLength = strlen(indexStr); + size_t stringLength = strlen(indexStr); - for(UPInt j = 0; j < stringLength; ) + for(size_t j = 0; j < stringLength; ) { - UPInt k = j + 1; + size_t k = j + 1; for(; k < stringLength; ++k) { if (indexStr[k] == ' ') break; } char text[20]; - for(UPInt l = 0; l < k - j; ++l) + for(size_t l = 0; l < k - j; ++l) { text[l] = indexStr[j + l]; } @@ -268,10 +268,10 @@ bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRend } // Reverse index order to match original expected orientation - Array<UInt16>& indices = Models[i]->Indices; - UPInt indexCount = indices.GetSize(); + Array<uint16_t>& indices = Models[i]->Indices; + size_t indexCount = indices.GetSize(); - for (UPInt revIndex = 0; revIndex < indexCount/2; revIndex++) + for (size_t revIndex = 0; revIndex < indexCount/2; revIndex++) { unsigned short itemp = indices[revIndex]; indices[revIndex] = indices[indexCount - revIndex - 1]; @@ -366,14 +366,14 @@ bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRend void XmlHandler::ParseVectorString(const char* str, OVR::Array<OVR::Vector3f> *array, bool is2element) { - UPInt stride = is2element ? 2 : 3; - UPInt stringLength = strlen(str); - UPInt element = 0; + size_t stride = is2element ? 2 : 3; + size_t stringLength = strlen(str); + size_t element = 0; float v[3]; - for(UPInt j = 0; j < stringLength;) + for(size_t j = 0; j < stringLength;) { - UPInt k = j + 1; + size_t k = j + 1; for(; k < stringLength; ++k) { if(str[k] == ' ') @@ -382,7 +382,7 @@ void XmlHandler::ParseVectorString(const char* str, OVR::Array<OVR::Vector3f> *a } } char text[20]; - for(UPInt l = 0; l < k - j; ++l) + for(size_t l = 0; l < k - j; ++l) { text[l] = str[j + l]; } diff --git a/Samples/CommonSrc/Util/OptionMenu.cpp b/Samples/CommonSrc/Util/OptionMenu.cpp index d9acc44..2d3c3d0 100644 --- a/Samples/CommonSrc/Util/OptionMenu.cpp +++ b/Samples/CommonSrc/Util/OptionMenu.cpp @@ -30,7 +30,7 @@ limitations under the License. //------------------------------------------------------------------------------------- bool OptionShortcut::MatchKey(OVR::KeyCode key, bool shift) const { - for (UInt32 i = 0; i < Keys.GetSize(); i++) + for (uint32_t i = 0; i < Keys.GetSize(); i++) { if (Keys[i].Key != key) continue; @@ -54,9 +54,9 @@ bool OptionShortcut::MatchKey(OVR::KeyCode key, bool shift) const return false; } -bool OptionShortcut::MatchGamepadButton(UInt32 gamepadButtonMask) const +bool OptionShortcut::MatchGamepadButton(uint32_t gamepadButtonMask) const { - for (UInt32 i = 0; i < GamepadButtons.GetSize(); i++) + for (uint32_t i = 0; i < GamepadButtons.GetSize(); i++) { if (GamepadButtons[i] & gamepadButtonMask) { @@ -75,7 +75,7 @@ bool OptionShortcut::MatchGamepadButton(UInt32 gamepadButtonMask) const String OptionMenuItem::PopNamespaceFrom(OptionMenuItem* menuItem) { String label = menuItem->Label; - for (UInt32 i = 0; i < label.GetLength(); i++) + for (uint32_t i = 0; i < label.GetLength(); i++) { if (label.GetCharAt(i) == '.') { @@ -91,7 +91,7 @@ String OptionMenuItem::PopNamespaceFrom(OptionMenuItem* menuItem) String OptionVar::FormatEnum(OptionVar* var) { - UInt32 index = var->GetEnumIndex(); + uint32_t index = var->GetEnumIndex(); if (index < var->EnumValues.GetSize()) return var->EnumValues[index].Name; return String("<Bad enum index>"); @@ -116,6 +116,12 @@ String OptionVar::FormatBool(OptionVar* var) return *var->AsBool() ? "On" : "Off"; } +String OptionVar::FormatTrigger(OptionVar* var) +{ + OVR_UNUSED(var); + return "[Trigger]"; +} + OptionVar::OptionVar(const char* name, void* pvar, VarType type, FormatFunction formatFunction, @@ -124,13 +130,13 @@ OptionVar::OptionVar(const char* name, void* pvar, VarType type, Label = name; Type = type; this->pVar = pvar; - fFormat = formatFunction; + fFormat = ((Type == Type_Trigger) && !formatFunction) ? FormatTrigger : formatFunction; fUpdate = updateFunction; pNotify = 0; FormatString= 0; - MaxFloat = Math<float>::MaxValue; - MinFloat = -Math<float>::MaxValue; + MaxFloat = MATH_FLOAT_MAXVALUE; + MinFloat = -MATH_FLOAT_MAXVALUE; StepFloat = 1.0f; FormatScale = 1.0f; @@ -138,12 +144,14 @@ OptionVar::OptionVar(const char* name, void* pvar, VarType type, MinInt = -(MaxInt) - 1; StepInt = 1; + SelectedIndex = 0; + ShortcutUp.pNotify = new FunctionNotifyContext<OptionVar, bool>(this, &OptionVar::NextValue); ShortcutDown.pNotify = new FunctionNotifyContext<OptionVar, bool>(this, &OptionVar::PrevValue); } -OptionVar::OptionVar(const char* name, SInt32* pvar, - SInt32 min, SInt32 max, SInt32 stepSize, +OptionVar::OptionVar(const char* name, int32_t* pvar, + int32_t min, int32_t max, int32_t stepSize, const char* formatString, FormatFunction formatFunction, UpdateFunction updateFunction) @@ -160,6 +168,8 @@ OptionVar::OptionVar(const char* name, SInt32* pvar, MaxInt = max; StepInt = stepSize; + SelectedIndex = 0; + ShortcutUp.pNotify = new FunctionNotifyContext<OptionVar, bool>(this, &OptionVar::NextValue); ShortcutDown.pNotify = new FunctionNotifyContext<OptionVar, bool>(this, &OptionVar::PrevValue); } @@ -184,6 +194,8 @@ OptionVar::OptionVar(const char* name, float* pvar, StepFloat = stepSize; FormatScale = formatScale; + SelectedIndex = 0; + ShortcutUp.pNotify = new FunctionNotifyContext<OptionVar, bool>(this, &OptionVar::NextValue); ShortcutDown.pNotify = new FunctionNotifyContext<OptionVar, bool>(this, &OptionVar::PrevValue); } @@ -204,7 +216,7 @@ void OptionVar::NextValue(bool* pFastStep) break; case Type_Int: - *AsInt() = Alg::Min<SInt32>(*AsInt() + StepInt * (fastStep ? 5 : 1), MaxInt); + *AsInt() = Alg::Min<int32_t>(*AsInt() + StepInt * (fastStep ? 5 : 1), MaxInt); break; case Type_Float: @@ -215,6 +227,11 @@ void OptionVar::NextValue(bool* pFastStep) case Type_Bool: *AsBool() = !*AsBool(); break; + + case Type_Trigger: + break; // nothing to do + + default: OVR_ASSERT(false); break; // unhandled } SignalUpdate(); @@ -226,11 +243,11 @@ void OptionVar::PrevValue(bool* pFastStep) switch (Type) { case Type_Enum: - *AsInt() = ((GetEnumIndex() + (UInt32)EnumValues.GetSize() - 1) % EnumValues.GetSize()); + *AsInt() = ((GetEnumIndex() + (uint32_t)EnumValues.GetSize() - 1) % EnumValues.GetSize()); break; case Type_Int: - *AsInt() = Alg::Max<SInt32>(*AsInt() - StepInt * (fastStep ? 5 : 1), MinInt); + *AsInt() = Alg::Max<int32_t>(*AsInt() - StepInt * (fastStep ? 5 : 1), MinInt); break; case Type_Float: @@ -241,6 +258,11 @@ void OptionVar::PrevValue(bool* pFastStep) case Type_Bool: *AsBool() = !*AsBool(); break; + + case Type_Trigger: + break; // nothing to do + + default: OVR_ASSERT(false); break; // unhandled } SignalUpdate(); @@ -248,8 +270,16 @@ void OptionVar::PrevValue(bool* pFastStep) String OptionVar::HandleShortcutUpdate() { - SignalUpdate(); - return Label + " - " + GetValue(); + if(Type != Type_Trigger) + { + SignalUpdate(); + return Label + " - " + GetValue(); + } + else + { + // Avoid double trigger (shortcut key already triggers NextValue()) + return String("Triggered: ") + Label; + } } String OptionVar::ProcessShortcutKey(OVR::KeyCode key, bool shift) @@ -262,7 +292,7 @@ String OptionVar::ProcessShortcutKey(OVR::KeyCode key, bool shift) return String(); } -String OptionVar::ProcessShortcutButton(UInt32 buttonMask) +String OptionVar::ProcessShortcutButton(uint32_t buttonMask) { if (ShortcutUp.MatchGamepadButton(buttonMask) || ShortcutDown.MatchGamepadButton(buttonMask)) { @@ -272,7 +302,7 @@ String OptionVar::ProcessShortcutButton(UInt32 buttonMask) } -OptionVar& OptionVar::AddEnumValue(const char* displayName, SInt32 value) +OptionVar& OptionVar::AddEnumValue(const char* displayName, int32_t value) { EnumEntry entry; entry.Name = displayName; @@ -283,16 +313,19 @@ OptionVar& OptionVar::AddEnumValue(const char* displayName, SInt32 value) String OptionVar::GetValue() { - return fFormat(this); + if(fFormat == NULL) + return String(); + else + return fFormat(this); } -UInt32 OptionVar::GetEnumIndex() +uint32_t OptionVar::GetEnumIndex() { OVR_ASSERT(Type == Type_Enum); OVR_ASSERT(EnumValues.GetSize() > 0); // TODO: Change this from a linear search to binary or a hash. - for (UInt32 i = 0; i < EnumValues.GetSize(); i++) + for (uint32_t i = 0; i < EnumValues.GetSize(); i++) { if (EnumValues[i].Value == *AsInt()) return i; @@ -353,7 +386,7 @@ OptionSelectionMenu::OptionSelectionMenu(OptionSelectionMenu* parentMenu) OptionSelectionMenu::~OptionSelectionMenu() { - for (UInt32 i = 0; i < Items.GetSize(); i++) + for (uint32_t i = 0; i < Items.GetSize(); i++) delete Items[i]; } @@ -400,7 +433,7 @@ bool OptionSelectionMenu::OnKey(OVR::KeyCode key, int chr, bool down, int modifi return false; } -bool OptionSelectionMenu::OnGamepad(UInt32 buttonMask) +bool OptionSelectionMenu::OnGamepad(uint32_t buttonMask) { // Check global shortcuts first. String s = ProcessShortcutButton(buttonMask); @@ -436,7 +469,7 @@ String OptionSelectionMenu::ProcessShortcutKey(OVR::KeyCode key, bool shift) { String s; - for (UPInt i = 0; (i < Items.GetSize()) && s.IsEmpty(); i++) + for (size_t i = 0; (i < Items.GetSize()) && s.IsEmpty(); i++) { s = Items[i]->ProcessShortcutKey(key, shift); } @@ -444,11 +477,11 @@ String OptionSelectionMenu::ProcessShortcutKey(OVR::KeyCode key, bool shift) return s; } -String OptionSelectionMenu::ProcessShortcutButton(UInt32 buttonMask) +String OptionSelectionMenu::ProcessShortcutButton(uint32_t buttonMask) { String s; - for (UPInt i = 0; (i < Items.GetSize()) && s.IsEmpty(); i++) + for (size_t i = 0; (i < Items.GetSize()) && s.IsEmpty(); i++) { s = Items[i]->ProcessShortcutButton(buttonMask); } @@ -457,9 +490,9 @@ String OptionSelectionMenu::ProcessShortcutButton(UInt32 buttonMask) } // Fills in inclusive character range; returns false if line not found. -bool FindLineCharRange(const char* text, int searchLine, UPInt charRange[2]) +bool FindLineCharRange(const char* text, int searchLine, size_t charRange[2]) { - UPInt i = 0; + size_t i = 0; for (int line = 0; line <= searchLine; line ++) { @@ -522,11 +555,9 @@ void OptionSelectionMenu::Render(RenderDevice* prender, String title) float valuesSize[2] = {0.0f, 0.0f}; float maxValueWidth = 0.0f; - UPInt selection[2] = { 0, 0 }; + size_t selection[2] = { 0, 0 }; Vector2f labelSelectionRect[2]; Vector2f valueSelectionRect[2]; - bool havelLabelSelection = false; - bool haveValueSelection = false; float textSize = 22.0f; prender->MeasureText(&DejaVu, " ", textSize, bufferSize); @@ -538,14 +569,14 @@ void OptionSelectionMenu::Render(RenderDevice* prender, String title) if (DisplayState == Display_Menu) { highlightIndex = SelectedIndex; - for (UInt32 i = 0; i < Items.GetSize(); i++) + for (uint32_t i = 0; i < Items.GetSize(); i++) { if (i > 0) values += "\n"; values += Items[i]->GetValue(); } - for (UInt32 i = 0; i < Items.GetSize(); i++) + for (uint32_t i = 0; i < Items.GetSize(); i++) { if (i > 0) menuItems += "\n"; @@ -560,13 +591,15 @@ void OptionSelectionMenu::Render(RenderDevice* prender, String title) // Measure labels const char* menuItemsCStr = menuItems.ToCStr(); - havelLabelSelection = FindLineCharRange(menuItemsCStr, highlightIndex, selection); + bool havelLabelSelection = FindLineCharRange(menuItemsCStr, highlightIndex, selection); + OVR_UNUSED(havelLabelSelection); prender->MeasureText(&DejaVu, menuItemsCStr, textSize, labelsSize, selection, labelSelectionRect); // Measure label-to-value gap const char* valuesCStr = values.ToCStr(); - haveValueSelection = FindLineCharRange(valuesCStr, highlightIndex, selection); + bool haveValueSelection = FindLineCharRange(valuesCStr, highlightIndex, selection); + OVR_UNUSED(haveValueSelection); prender->MeasureText(&DejaVu, valuesCStr, textSize, valuesSize, selection, valueSelectionRect); // Measure max value size (absolute size varies, so just use a reasonable max) @@ -712,7 +745,7 @@ OptionSelectionMenu* OptionSelectionMenu::GetSubmenu() OptionSelectionMenu* OptionSelectionMenu::GetOrCreateSubmenu(String submenuName) { - for (UInt32 i = 0; i < Items.GetSize(); i++) + for (uint32_t i = 0; i < Items.GetSize(); i++) { if (!Items[i]->IsMenu()) continue; diff --git a/Samples/CommonSrc/Util/OptionMenu.h b/Samples/CommonSrc/Util/OptionMenu.h index d52ba5c..5eea9bd 100644 --- a/Samples/CommonSrc/Util/OptionMenu.h +++ b/Samples/CommonSrc/Util/OptionMenu.h @@ -24,7 +24,7 @@ limitations under the License. #ifndef INC_OptionMenu_h #define INC_OptionMenu_h -#include "OVR.h" +#include "OVR_Kernel.h" #include "../Platform/Platform_Default.h" #include "../Render/Render_Device.h" @@ -37,11 +37,11 @@ using namespace OVR::Util::Render; #include <Kernel/OVR_Log.h> #include <Kernel/OVR_Timer.h> -#include "OVR_DeviceConstants.h" +#include "Sensors/OVR_DeviceConstants.h" using namespace OVR; -using namespace OVR::Platform; +using namespace OVR::OvrPlatform; using namespace OVR::Render; @@ -108,7 +108,7 @@ struct ShortcutKey struct OptionShortcut { Array<ShortcutKey> Keys; - Array<UInt32> GamepadButtons; + Array<uint32_t> GamepadButtons; FunctionNotifyBase* pNotify; OptionShortcut() : pNotify(NULL) {} @@ -116,10 +116,10 @@ struct OptionShortcut ~OptionShortcut() { if (pNotify) delete pNotify; } void AddShortcut(ShortcutKey key) { Keys.PushBack(key); } - void AddShortcut(UInt32 gamepadButton) { GamepadButtons.PushBack(gamepadButton); } + void AddShortcut(uint32_t gamepadButton) { GamepadButtons.PushBack(gamepadButton); } bool MatchKey(OVR::KeyCode key, bool shift) const; - bool MatchGamepadButton(UInt32 gamepadButtonMask) const; + bool MatchGamepadButton(uint32_t gamepadButtonMask) const; }; @@ -142,7 +142,7 @@ public: // Returns empty string if shortcut not handled virtual String ProcessShortcutKey(OVR::KeyCode key, bool shift) = 0; - virtual String ProcessShortcutButton(UInt32 buttonMask) = 0; + virtual String ProcessShortcutButton(uint32_t buttonMask) = 0; virtual bool IsMenu() const { return false; } @@ -165,7 +165,8 @@ public: Type_Enum, Type_Int, Type_Float, - Type_Bool + Type_Bool, + Type_Trigger, }; typedef String (*FormatFunction)(OptionVar*); @@ -176,14 +177,15 @@ public: static String FormatFloat(OptionVar* var); static String FormatTan(OptionVar* var); static String FormatBool(OptionVar* var); + static String FormatTrigger(OptionVar* var); OptionVar(const char* name, void* pVar, VarType type, FormatFunction formatFunction, UpdateFunction updateFunction = NULL); // Integer with range and step size. - OptionVar(const char* name, SInt32* pVar, - SInt32 min, SInt32 max, SInt32 stepSize=1, + OptionVar(const char* name, int32_t* pVar, + int32_t min, int32_t max, int32_t stepSize=1, const char* formatString = "%d", FormatFunction formatFunction = 0, // Default int formatting. UpdateFunction updateFunction = NULL); @@ -197,10 +199,12 @@ public: virtual ~OptionVar(); - SInt32* AsInt() { return reinterpret_cast<SInt32*>(pVar); } - bool* AsBool() { return reinterpret_cast<bool*>(pVar); } - float* AsFloat() { return reinterpret_cast<float*>(pVar); } - VarType GetType() { return Type; } + int32_t* AsInt() { return reinterpret_cast<int32_t*>(pVar); } + bool* AsBool() { return reinterpret_cast<bool*>(pVar); } + float* AsFloat() { return reinterpret_cast<float*>(pVar); } + VarType GetType() { return Type; } + + //virtual void Select() { if(Type == Type_Trigger) SignalUpdate(); } // Step through values (wrap for enums). virtual void NextValue(bool* pFastStep); @@ -210,9 +214,9 @@ public: // Returns empty string for no action. String HandleShortcutUpdate(); virtual String ProcessShortcutKey(OVR::KeyCode key, bool shift); - virtual String ProcessShortcutButton(UInt32 buttonMask); + virtual String ProcessShortcutButton(uint32_t buttonMask); - OptionVar& AddEnumValue(const char* displayName, SInt32 value); + OptionVar& AddEnumValue(const char* displayName, int32_t value); template<class C> OptionVar& SetNotify(C* p, void (C::*fn)(OptionVar*)) @@ -231,7 +235,7 @@ public: OptionVar& AddShortcutUpKey(OVR::KeyCode key, ShortcutKey::ShiftUsageType shiftUsage = ShortcutKey::Shift_Modify) { ShortcutUp.AddShortcut(ShortcutKey(key, shiftUsage)); return *this; } - OptionVar& AddShortcutUpButton(UInt32 gamepadButton) + OptionVar& AddShortcutUpButton(uint32_t gamepadButton) { ShortcutUp.AddShortcut(gamepadButton); return *this; } OptionVar& AddShortcutDownKey(const ShortcutKey& shortcut) @@ -239,7 +243,7 @@ public: OptionVar& AddShortcutDownKey(OVR::KeyCode key, ShortcutKey::ShiftUsageType shiftUsage = ShortcutKey::Shift_Modify) { ShortcutDown.AddShortcut(ShortcutKey(key, shiftUsage)); return *this; } - OptionVar& AddShortcutDownButton(UInt32 gamepadButton) + OptionVar& AddShortcutDownButton(uint32_t gamepadButton) { ShortcutDown.AddShortcut(gamepadButton); return *this; } OptionVar& AddShortcutKey(const ShortcutKey& shortcut) @@ -247,7 +251,7 @@ public: OptionVar& AddShortcutKey(OVR::KeyCode key, ShortcutKey::ShiftUsageType shiftUsage = ShortcutKey::Shift_RequireOff) { return AddShortcutUpKey(key, shiftUsage); } - OptionVar& AddShortcutButton(UInt32 gamepadButton) + OptionVar& AddShortcutButton(uint32_t gamepadButton) { return AddShortcutUpButton(gamepadButton); } private: @@ -262,13 +266,13 @@ private: { // Human readable name for enum. String Name; - SInt32 Value; + int32_t Value; }; // Array of possible enum values. Array<EnumEntry> EnumValues; // Gets the index of the current enum value. - UInt32 GetEnumIndex(); + uint32_t GetEnumIndex(); FormatFunction fFormat; UpdateFunction fUpdate; @@ -286,9 +290,11 @@ private: float StepFloat; float FormatScale; // Multiply float by this before rendering - SInt32 MinInt; - SInt32 MaxInt; - SInt32 StepInt; + int32_t MinInt; + int32_t MaxInt; + int32_t StepInt; + + int SelectedIndex; }; @@ -312,7 +318,7 @@ public: bool OnKey(OVR::KeyCode key, int chr, bool down, int modifiers); - bool OnGamepad(UInt32 buttonMask); + bool OnGamepad(uint32_t buttonMask); void Render(RenderDevice* prender, String title = ""); @@ -353,12 +359,20 @@ public: AddItem(p); return *p; } + + OptionVar& AddTrigger( const char* name, OptionVar::UpdateFunction updateFunction = 0 ) + { + OptionVar* p = new OptionVar(name, NULL, OptionVar::Type_Trigger, + NULL, updateFunction); + AddItem(p); + return *p; + } virtual void Select(); virtual String GetLabel() { return Label + " >"; } virtual String ProcessShortcutKey(OVR::KeyCode key, bool shift); - virtual String ProcessShortcutButton(UInt32 buttonMask); + virtual String ProcessShortcutButton(uint32_t buttonMask); // Sets a message to display with a time-out. Default time-out is 4 seconds. // This uses the same overlay approach as used for shortcut notifications. diff --git a/Samples/CommonSrc/Util/RenderProfiler.h b/Samples/CommonSrc/Util/RenderProfiler.h index 96ec50a..7494034 100644 --- a/Samples/CommonSrc/Util/RenderProfiler.h +++ b/Samples/CommonSrc/Util/RenderProfiler.h @@ -24,7 +24,7 @@ limitations under the License. #ifndef INC_RenderProfiler_h #define INC_RenderProfiler_h -#include "OVR.h" +#include "OVR_Kernel.h" // TODO: Refactor option menu so dependencies are in a separate file. #include "OptionMenu.h" |