aboutsummaryrefslogtreecommitdiffstats
path: root/Samples/CommonSrc
diff options
context:
space:
mode:
Diffstat (limited to 'Samples/CommonSrc')
-rw-r--r--Samples/CommonSrc/Makefile7
-rw-r--r--Samples/CommonSrc/Platform/Gamepad.h4
-rw-r--r--Samples/CommonSrc/Platform/Linux_Gamepad.cpp453
-rw-r--r--Samples/CommonSrc/Platform/Linux_Gamepad.h83
-rw-r--r--Samples/CommonSrc/Platform/Linux_Platform.cpp563
-rw-r--r--Samples/CommonSrc/Platform/Linux_Platform.h120
-rw-r--r--Samples/CommonSrc/Platform/OSX_Gamepad.cpp424
-rw-r--r--Samples/CommonSrc/Platform/OSX_Gamepad.h66
-rw-r--r--Samples/CommonSrc/Platform/OSX_Platform.h80
-rw-r--r--Samples/CommonSrc/Platform/OSX_Platform.mm514
-rw-r--r--Samples/CommonSrc/Platform/OSX_PlatformObjc.h31
-rw-r--r--Samples/CommonSrc/Platform/OSX_WavPlayer.cpp242
-rw-r--r--Samples/CommonSrc/Platform/OSX_WavPlayer.h64
-rw-r--r--Samples/CommonSrc/Platform/Platform.cpp4
-rw-r--r--Samples/CommonSrc/Platform/Platform.h2
-rw-r--r--Samples/CommonSrc/Platform/Platform_Default.h11
-rw-r--r--Samples/CommonSrc/Platform/Win32_Gamepad.cpp2
-rw-r--r--Samples/CommonSrc/Platform/Win32_Gamepad.h2
-rw-r--r--Samples/CommonSrc/Platform/Win32_Platform.cpp7
-rw-r--r--Samples/CommonSrc/Platform/Win32_Platform.h10
-rw-r--r--Samples/CommonSrc/Render/Render_D3D1X_Device.cpp710
-rw-r--r--Samples/CommonSrc/Render/Render_D3D1X_Device.h41
-rw-r--r--Samples/CommonSrc/Render/Render_Device.cpp2306
-rw-r--r--Samples/CommonSrc/Render/Render_Device.h326
-rw-r--r--Samples/CommonSrc/Render/Render_GL_Device.cpp639
-rw-r--r--Samples/CommonSrc/Render/Render_GL_Device.h113
-rw-r--r--Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp248
-rw-r--r--Samples/CommonSrc/Render/Render_GL_Win32_Device.h24
-rw-r--r--Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp6
-rw-r--r--Samples/CommonSrc/Render/Render_XmlSceneLoader.cpp13
-rw-r--r--Samples/CommonSrc/Render/Render_XmlSceneLoader.h2
31 files changed, 2978 insertions, 4139 deletions
diff --git a/Samples/CommonSrc/Makefile b/Samples/CommonSrc/Makefile
deleted file mode 100644
index 8c07a2a..0000000
--- a/Samples/CommonSrc/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-
-PLATFORM_SRCS := Samples/CommonSrc/Platform/Platform.cpp Samples/CommonSrc/Platform/X11_Platform.cpp
-
-RENDER_SRCS := Samples/CommonSrc/Render/Render_Device.cpp Samples/CommonSrc/Render/Render_Stereo.cpp \
- Samples/CommonSrc/Render/Render_GL_Device.cpp \
- Samples/CommonSrc/Render/Render_LoadTextureTGA.cpp
-
diff --git a/Samples/CommonSrc/Platform/Gamepad.h b/Samples/CommonSrc/Platform/Gamepad.h
index f32effc..95cff10 100644
--- a/Samples/CommonSrc/Platform/Gamepad.h
+++ b/Samples/CommonSrc/Platform/Gamepad.h
@@ -5,7 +5,7 @@ Content : Cross platform Gamepad interface.
Created : May 6, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+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.
@@ -75,7 +75,7 @@ struct GamepadState
{
return !(*this == b);
}
- void Debug()
+ void Debug() const
{
OVR_DEBUG_LOG(("Buttons:0x%4x LX:%.2f LY:%.2f RX:%.2f RY:%.2f LT:%.2f RT:%.2f", Buttons, LX, LY, RX, RY, LT, RT));
}
diff --git a/Samples/CommonSrc/Platform/Linux_Gamepad.cpp b/Samples/CommonSrc/Platform/Linux_Gamepad.cpp
deleted file mode 100644
index 7bca5c5..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 2013 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 ba66e70..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 2013 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 c9d3e40..0000000
--- a/Samples/CommonSrc/Platform/Linux_Platform.cpp
+++ /dev/null
@@ -1,563 +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.
-
-Use of this software is subject to the terms of the Oculus LLC license
-agreement provided at the time of installation or download, or which
-otherwise accompanies this software in either electronic or hard copy form.
-
-************************************************************************************/
-
-#include "Kernel/OVR_System.h"
-#include "Kernel/OVR_Array.h"
-#include "Kernel/OVR_String.h"
-#include "Kernel/OVR_Timer.h"
-
-#include "Linux_Platform.h"
-#include "Linux_Gamepad.h"
-
-// Renderers
-#include "../Render/Render_GL_Device.h"
-
-#include <X11/extensions/Xinerama.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)
-{
- 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);
-}
-
-bool PlatformCore::SetFullscreen(const Render::RendererParams& rp, int fullscreen)
-{
- if (rp.Fullscreen == Render::Display_Window && fullscreen == Render::Display_FakeFullscreen)
- {
- // Transitioning from windowed to fake fullscreen.
- int xOffset;
- int yOffset;
-
- if (!determineScreenOffset(rp.Display.CgDisplayId, &xOffset, &yOffset))
- {
- return false;
- }
-
- showWindowDecorations(false);
-
- XMoveWindow(Disp, Win, xOffset, yOffset);
- XMapRaised(Disp, Win);
-
- Platform::PlatformCore::SetFullscreen(rp, fullscreen);
- return true;
- }
- else if (rp.Fullscreen == Render::Display_FakeFullscreen && fullscreen == Render::Display_Window)
- {
- // Transitioning from fake fullscreen to windowed.
- showWindowDecorations(true);
-
- XMoveWindow(Disp, Win, 0, 0);
- XMapRaised(Disp, Win);
-
- Platform::PlatformCore::SetFullscreen(rp, fullscreen);
- return true;
- }
- else if (fullscreen == Render::Display_Fullscreen)
- {
- return false;
- }
-}
-
-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 {
-
-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);
-
- return new Render::GL::Linux::RenderDevice(rp, PC->Disp, PC->Win, context);
-}
-
-void RenderDevice::Present()
-{
- 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 7fbb220..0000000
--- a/Samples/CommonSrc/Platform/Linux_Platform.h
+++ /dev/null
@@ -1,120 +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.
-
-Use of this software is subject to the terms of the Oculus LLC license
-agreement provided at the time of installation or download, or which
-otherwise accompanies this software in either electronic or hard copy form.
-
-************************************************************************************/
-
-#ifndef OVR_Platform_Linux_h
-#define OVR_Platform_Linux_h
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <GL/glx.h>
-
-#include "Platform.h"
-#include "../Render/Render_GL_Device.h"
-
-namespace OVR { namespace Render {
- class RenderDevice;
-}}
-
-namespace OVR { namespace Platform { namespace Linux {
-
-class PlatformCore : public Platform::PlatformCore
-{
-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 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();
-
- // 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, ())
-
-
-#endif
diff --git a/Samples/CommonSrc/Platform/OSX_Gamepad.cpp b/Samples/CommonSrc/Platform/OSX_Gamepad.cpp
deleted file mode 100644
index 934319b..0000000
--- a/Samples/CommonSrc/Platform/OSX_Gamepad.cpp
+++ /dev/null
@@ -1,424 +0,0 @@
-/************************************************************************************
-
-Filename : OSX_Gamepad.cpp
-Content : OSX implementation of Gamepad functionality.
-Created : May 6, 2013
-Authors : Lee Cooper
-
-Copyright : Copyright 2013 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)
-{
- 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)
-{
- 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)
-{
- 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);
-
- int vendorID = getIntDeviceProperty(device, CFSTR(kIOHIDVendorIDKey));
- int productID = 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 335a512..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 2013 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 11d4279..0000000
--- a/Samples/CommonSrc/Platform/OSX_Platform.h
+++ /dev/null
@@ -1,80 +0,0 @@
-
-#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();
-
- virtual bool SetFullscreen(DisplayMode fullscreen);
-
- // 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(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, ())
-
-
diff --git a/Samples/CommonSrc/Platform/OSX_Platform.mm b/Samples/CommonSrc/Platform/OSX_Platform.mm
deleted file mode 100644
index 491ff6c..0000000
--- a/Samples/CommonSrc/Platform/OSX_Platform.mm
+++ /dev/null
@@ -1,514 +0,0 @@
-
-#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[] =
- {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];
- }
-
- if (pRender)
- pRender->SetFullscreen((Render::DisplayMode)fullscreen);
- return 1;
-}
-
-}}
-// GL
-namespace Render { namespace GL { namespace OSX {
-
-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()
-{
- 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 7d195eb..0000000
--- a/Samples/CommonSrc/Platform/OSX_PlatformObjc.h
+++ /dev/null
@@ -1,31 +0,0 @@
-
-#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 a6cb937..0000000
--- a/Samples/CommonSrc/Platform/OSX_WavPlayer.cpp
+++ /dev/null
@@ -1,242 +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 2013 Oculus VR, Inc. All Rights reserved.
-
-Use of this software is subject to the terms of the Oculus LLC license
-agreement provided at the time of installation or download, or which
-otherwise accompanies this software in either electronic or hard copy form.
-
-************************************************************************************/
-
-#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 4aaba10..0000000
--- a/Samples/CommonSrc/Platform/OSX_WavPlayer.h
+++ /dev/null
@@ -1,64 +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 2013 Oculus VR, Inc. All Rights reserved.
-
-Use of this software is subject to the terms of the Oculus LLC license
-agreement provided at the time of installation or download, or which
-otherwise accompanies this software in either electronic or hard copy form.
-
-************************************************************************************/
-
-#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 c0e4438..108c7f5 100644
--- a/Samples/CommonSrc/Platform/Platform.cpp
+++ b/Samples/CommonSrc/Platform/Platform.cpp
@@ -52,12 +52,12 @@ PlatformCore::PlatformCore(Application *app)
{
pApp = app;
pApp->SetPlatformCore(this);
- StartupTicks = OVR::Timer::GetTicks();
+ StartupSeconds = OVR::Timer::GetSeconds();
}
double PlatformCore::GetAppTime() const
{
- return (OVR::Timer::GetTicks() - StartupTicks) * (1.0 / (double)OVR::Timer::MksPerSecond);
+ return OVR::Timer::GetSeconds() - StartupSeconds;
}
bool PlatformCore::SetFullscreen(const Render::RendererParams&, int fullscreen)
diff --git a/Samples/CommonSrc/Platform/Platform.h b/Samples/CommonSrc/Platform/Platform.h
index 201aad6..47d8f67 100644
--- a/Samples/CommonSrc/Platform/Platform.h
+++ b/Samples/CommonSrc/Platform/Platform.h
@@ -111,7 +111,7 @@ protected:
Application* pApp;
Ptr<RenderDevice> pRender;
Ptr<GamepadManager> pGamepadManager;
- UInt64 StartupTicks;
+ double StartupSeconds;
public:
PlatformCore(Application *app);
diff --git a/Samples/CommonSrc/Platform/Platform_Default.h b/Samples/CommonSrc/Platform/Platform_Default.h
index e4fecf2..420b088 100644
--- a/Samples/CommonSrc/Platform/Platform_Default.h
+++ b/Samples/CommonSrc/Platform/Platform_Default.h
@@ -29,17 +29,18 @@ limitations under the License.
#if defined(OVR_OS_WIN32)
#include "Win32_Platform.h"
-
+
#include "../Render/Render_D3D11_Device.h"
#undef OVR_D3D_VERSION
#include "../Render/Render_D3D10_Device.h"
-// #include "../Render/Render_GL_Win32_Device.h"
+ #include "../Render/Render_GL_Win32_Device.h"
// Modify this list or pass a smaller set to select a specific render device,
// while avoiding linking extra classes.
- #define OVR_DEFAULT_RENDER_DEVICE_SET \
- SetupGraphicsDeviceSet("D3D11", &OVR::Render::D3D11::RenderDevice::CreateDevice, \
- SetupGraphicsDeviceSet("D3D10", &OVR::Render::D3D10::RenderDevice::CreateDevice) )
+ #define OVR_DEFAULT_RENDER_DEVICE_SET \
+ SetupGraphicsDeviceSet("D3D11", &OVR::Render::D3D11::RenderDevice::CreateDevice, \
+ SetupGraphicsDeviceSet("D3D10", &OVR::Render::D3D10::RenderDevice::CreateDevice, \
+ SetupGraphicsDeviceSet("GL", &OVR::Render::GL::Win32::RenderDevice::CreateDevice)))
#elif defined(OVR_OS_MAC) && !defined(OVR_MAC_X11)
#include "OSX_Platform.h"
diff --git a/Samples/CommonSrc/Platform/Win32_Gamepad.cpp b/Samples/CommonSrc/Platform/Win32_Gamepad.cpp
index 9b8793f..ce7af63 100644
--- a/Samples/CommonSrc/Platform/Win32_Gamepad.cpp
+++ b/Samples/CommonSrc/Platform/Win32_Gamepad.cpp
@@ -5,7 +5,7 @@ Content : Win32 implementation of Platform app infrastructure
Created : May 6, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+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.
diff --git a/Samples/CommonSrc/Platform/Win32_Gamepad.h b/Samples/CommonSrc/Platform/Win32_Gamepad.h
index 09815ae..e3f81af 100644
--- a/Samples/CommonSrc/Platform/Win32_Gamepad.h
+++ b/Samples/CommonSrc/Platform/Win32_Gamepad.h
@@ -5,7 +5,7 @@ Content : Win32 implementation of Gamepad functionality.
Created : May 6, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+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.
diff --git a/Samples/CommonSrc/Platform/Win32_Platform.cpp b/Samples/CommonSrc/Platform/Win32_Platform.cpp
index eeab429..0614a3f 100644
--- a/Samples/CommonSrc/Platform/Win32_Platform.cpp
+++ b/Samples/CommonSrc/Platform/Win32_Platform.cpp
@@ -21,6 +21,8 @@ limitations under the License.
************************************************************************************/
+#include <Windows.h>
+
#include "Kernel/OVR_System.h"
#include "Kernel/OVR_Array.h"
#include "Kernel/OVR_String.h"
@@ -177,7 +179,7 @@ static UByte KeyMap[][2] =
{ VK_OEM_MINUS, Key_Minus },
{ VK_OEM_PERIOD,Key_Period },
{ VK_OEM_2, Key_Slash },
- { VK_OEM_3, Key_Bar },
+ { VK_OEM_3, Key_Backtick },
{ VK_OEM_4, Key_BracketLeft },
{ VK_OEM_5, Key_Backslash },
{ VK_OEM_6, Key_BracketRight },
@@ -418,9 +420,9 @@ int PlatformCore::Run()
if (IsIconic(hWnd))
{
Sleep(10);
+ }
}
}
- }
return ExitCode;
}
@@ -545,6 +547,7 @@ Render::DisplayId PlatformCore::GetDisplay(int screen)
OVR::Platform::Application* g_app;
+
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE prevInst, LPSTR inArgs, int show)
{
using namespace OVR;
diff --git a/Samples/CommonSrc/Platform/Win32_Platform.h b/Samples/CommonSrc/Platform/Win32_Platform.h
index 6081968..23f0b70 100644
--- a/Samples/CommonSrc/Platform/Win32_Platform.h
+++ b/Samples/CommonSrc/Platform/Win32_Platform.h
@@ -98,4 +98,14 @@ KeyCode MapVKToKeyCode(unsigned vk);
// 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 // OVR_Win32_Platform_h
diff --git a/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp b/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp
index 6408e08..d7c606f 100644
--- a/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp
+++ b/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp
@@ -21,13 +21,20 @@ limitations under the License.
************************************************************************************/
+#define GPU_PROFILING 0
+
#include "Kernel/OVR_Log.h"
#include "Kernel/OVR_Std.h"
#include "Render_D3D1X_Device.h"
+#include "Util/Util_ImageWindow.h"
+
+#include "OVR_CAPI_D3D.h"
#include <d3dcompiler.h>
+#include <d3d9.h> // for GPU markers
+
#if (OVR_D3D_VERSION == 10)
namespace OVR { namespace Render { namespace D3D10 {
#else
@@ -43,7 +50,6 @@ static D3D1x_(INPUT_ELEMENT_DESC) ModelVertexDesc[] =
{"Normal", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(Vertex, Norm), D3D1x_(INPUT_PER_VERTEX_DATA), 0},
};
-
static const char* StdVertexShaderSrc =
"float4x4 Proj;\n"
"float4x4 View;\n"
@@ -135,13 +141,18 @@ static const char* MultiTexturePixelShaderSrc =
"{\n"
"float4 color1;\n"
"float4 color2;\n"
- " color1 = Texture[0].Sample(Linear, ov.TexCoord);\n"
+ " color1 = Texture[0].Sample(Linear, ov.TexCoord);\n"
+ // go to linear space colors (assume gamma 2.0 for speed)
+ " color1.rgb *= color1.rgb;\n"
" color2 = Texture[1].Sample(Linear, ov.TexCoord1);\n"
+ // go to linear space colors (assume gamma 2.0 for speed)
+ " color2.rgb *= color2.rgb;\n"
" color2.rgb = color2.rgb * lerp(1.2, 1.9, saturate(length(color2.rgb)));\n"
" color2 = color1 * color2;\n"
" if (color2.a <= 0.4)\n"
" discard;\n"
- " return color2;\n"
+ // go to back to gamma space space colors (assume gamma 2.0 for speed)
+ " return float4(sqrt(color2.rgb), color2.a);\n"
"}\n";
#define LIGHTING_COMMON \
@@ -201,7 +212,9 @@ static const char* AlphaTexturePixelShaderSrc =
"};\n"
"float4 main(in Varyings ov) : SV_Target\n"
"{\n"
- " return ov.Color * float4(1,1,1,Texture.Sample(Linear, ov.TexCoord).r);\n"
+ " float4 finalColor = ov.Color;\n"
+ " finalColor.a *= Texture.Sample(Linear, ov.TexCoord).r;\n"
+ " return finalColor;\n"
"}\n";
@@ -211,97 +224,294 @@ static const char* PostProcessVertexShaderSrc =
"float4x4 View : register(c4);\n"
"float4x4 Texm : register(c8);\n"
"void main(in float4 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord : TEXCOORD0, in float2 TexCoord1 : TEXCOORD1,\n"
- " out float4 oPosition : SV_Position, out float4 oColor : COLOR, out float2 oTexCoord : TEXCOORD0)\n"
+ " out float4 oPosition : SV_Position, out float2 oTexCoord : TEXCOORD0)\n"
"{\n"
" oPosition = mul(View, Position);\n"
" oTexCoord = mul(Texm, float4(TexCoord,0,1));\n"
- " oColor = Color;\n"
"}\n";
-// Shader with just lens distortion correction.
-static const char* PostProcessPixelShaderSrc =
+
+// Shader with lens distortion and chromatic aberration correction.
+static const char* PostProcessPixelShaderWithChromAbSrc =
"Texture2D Texture : register(t0);\n"
"SamplerState Linear : register(s0);\n"
- "float2 LensCenter;\n"
- "float2 ScreenCenter;\n"
- "float2 Scale;\n"
- "float2 ScaleIn;\n"
+ "float3 DistortionClearColor;\n"
+ "float EdgeFadeScale;\n"
+ "float2 EyeToSourceUVScale;\n"
+ "float2 EyeToSourceUVOffset;\n"
+ "float2 EyeToSourceNDCScale;\n"
+ "float2 EyeToSourceNDCOffset;\n"
+ "float2 TanEyeAngleScale;\n"
+ "float2 TanEyeAngleOffset;\n"
"float4 HmdWarpParam;\n"
+ "float4 ChromAbParam;\n"
"\n"
- // Scales input texture coordinates for distortion.
- // ScaleIn maps texture coordinates to Scales to ([-1, 1]), although top/bottom will be
- // larger due to aspect ratio.
- "float2 HmdWarp(float2 in01)\n"
+ "float4 main(in float4 oPosition : SV_Position,\n"
+ " in float2 oTexCoord : TEXCOORD0) : SV_Target\n"
"{\n"
- " float2 theta = (in01 - LensCenter) * ScaleIn;\n" // Scales to [-1, 1]
- " float rSq = theta.x * theta.x + theta.y * theta.y;\n"
- " float2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + "
- " HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n"
- " return LensCenter + Scale * theta1;\n"
- "}\n"
+ // Input oTexCoord is [-1,1] across the half of the screen used for a single eye.
+ " float2 TanEyeAngleDistorted = oTexCoord * TanEyeAngleScale + TanEyeAngleOffset;\n" // Scales to tan(thetaX),tan(thetaY), but still distorted (i.e. only the center is correct)
+ " float RadiusSq = TanEyeAngleDistorted.x * TanEyeAngleDistorted.x + TanEyeAngleDistorted.y * TanEyeAngleDistorted.y;\n"
+ " float Distort = rcp ( 1.0 + RadiusSq * ( HmdWarpParam.y + RadiusSq * ( HmdWarpParam.z + RadiusSq * ( HmdWarpParam.w ) ) ) );\n"
+ " float DistortR = Distort * ( ChromAbParam.x + RadiusSq * ChromAbParam.y );\n"
+ " float DistortG = Distort;\n"
+ " float DistortB = Distort * ( ChromAbParam.z + RadiusSq * ChromAbParam.w );\n"
+ " float2 TanEyeAngleR = DistortR * TanEyeAngleDistorted;\n"
+ " float2 TanEyeAngleG = DistortG * TanEyeAngleDistorted;\n"
+ " float2 TanEyeAngleB = DistortB * TanEyeAngleDistorted;\n"
+
+ // These are now in "TanEyeAngle" space.
+ // The vectors (TanEyeAngleRGB.x, TanEyeAngleRGB.y, 1.0) are real-world vectors pointing from the eye to where the components of the pixel appear to be.
+ // If you had a raytracer, you could just use them directly.
+
+ // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye)
+ " float2 SourceCoordR = TanEyeAngleR * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " float2 SourceCoordG = TanEyeAngleG * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " float2 SourceCoordB = TanEyeAngleB * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+
+ // Find the distance to the nearest edge.
+ " float2 NDCCoord = TanEyeAngleG * EyeToSourceNDCScale + EyeToSourceNDCOffset;\n"
+ " float EdgeFadeIn = EdgeFadeScale * ( 1.0 - max ( abs ( NDCCoord.x ), abs ( NDCCoord.y ) ) );\n"
+ " if ( EdgeFadeIn < 0.0 )\n"
+ " {\n"
+ " return float4(DistortionClearColor.r, DistortionClearColor.g, DistortionClearColor.b, 1.0);\n"
+ " }\n"
+ " EdgeFadeIn = saturate ( EdgeFadeIn );\n"
+
+ // Actually do the lookups.
+ " float ResultR = Texture.Sample(Linear, SourceCoordR).r;\n"
+ " float ResultG = Texture.Sample(Linear, SourceCoordG).g;\n"
+ " float ResultB = Texture.Sample(Linear, SourceCoordB).b;\n"
+
+ " return float4(ResultR * EdgeFadeIn, ResultG * EdgeFadeIn, ResultB * EdgeFadeIn, 1.0);\n"
+ "}\n";
+
+//----------------------------------------------------------------------------
+
+// A vertex format used for mesh-based distortion.
+/*
+struct DistortionVertex
+{
+ Vector2f Pos;
+ Vector2f TexR;
+ Vector2f TexG;
+ Vector2f TexB;
+ Color Col;
+};
+*/
+static D3D1x_(INPUT_ELEMENT_DESC) DistortionVertexDesc[] =
+{
+ {"Position", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D1x_(INPUT_PER_VERTEX_DATA), 0},
+ {"TexCoord", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D1x_(INPUT_PER_VERTEX_DATA), 0},
+ {"TexCoord", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 8+8, D3D1x_(INPUT_PER_VERTEX_DATA), 0},
+ {"TexCoord", 2, DXGI_FORMAT_R32G32_FLOAT, 0, 8+8+8, D3D1x_(INPUT_PER_VERTEX_DATA), 0},
+ {"Color", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 8+8+8+8, D3D1x_(INPUT_PER_VERTEX_DATA), 0},
+};
+
+
+//----------------------------------------------------------------------------
+// Simple distortion shader that does three texture reads.
+// Used for mesh-based distortion without timewarp.
+
+static const char* PostProcessMeshVertexShaderSrc =
+ "float2 EyeToSourceUVScale;\n"
+ "float2 EyeToSourceUVOffset;\n"
+ "void main(in float2 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord0 : TEXCOORD0, in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2,\n"
+ " out float4 oPosition : SV_Position, out float4 oColor : COLOR, out float2 oTexCoord0 : TEXCOORD0, out float2 oTexCoord1 : TEXCOORD1, out float2 oTexCoord2 : TEXCOORD2)\n"
+ "{\n"
+ " oPosition.x = Position.x;\n"
+ " oPosition.y = Position.y;\n"
+ " oPosition.z = 0.5;\n"
+ " oPosition.w = 1.0;\n"
+ // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion).
+ // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye)
+ " oTexCoord0 = TexCoord0 * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " oTexCoord1 = TexCoord1 * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " oTexCoord2 = TexCoord2 * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " oColor = Color;\n" // Used for vignette fade.
+ "}\n";
+
+static const char* PostProcessMeshPixelShaderSrc =
+ "Texture2D Texture : register(t0);\n"
+ "SamplerState Linear : register(s0);\n"
+ "\n"
"float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR,\n"
- " in float2 oTexCoord : TEXCOORD0) : SV_Target\n"
+ " in float2 oTexCoord0 : TEXCOORD0, in float2 oTexCoord1 : TEXCOORD1, in float2 oTexCoord2 : TEXCOORD2) : SV_Target\n"
"{\n"
- " float2 tc = HmdWarp(oTexCoord);\n"
- " if (any(clamp(tc, ScreenCenter-float2(0.25,0.5), ScreenCenter+float2(0.25, 0.5)) - tc))\n"
- " return 0;\n"
- " return Texture.Sample(Linear, tc);\n"
+ " float ResultR = Texture.Sample(Linear, oTexCoord0).r;\n"
+ " float ResultG = Texture.Sample(Linear, oTexCoord1).g;\n"
+ " float ResultB = Texture.Sample(Linear, oTexCoord2).b;\n"
+ " return float4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0);\n"
"}\n";
-// Shader with lens distortion and chromatic aberration correction.
-static const char* PostProcessPixelShaderWithChromAbSrc =
+
+//----------------------------------------------------------------------------
+// Pixel shader is very simple - does three texture reads.
+// Vertex shader does all the hard work.
+// Used for mesh-based distortion with timewarp.
+
+static const char* PostProcessMeshTimewarpVertexShaderSrc =
+ "float2 EyeToSourceUVScale;\n"
+ "float2 EyeToSourceUVOffset;\n"
+ "float3x3 EyeRotationStart;\n"
+ "float3x3 EyeRotationEnd;\n"
+ "void main(in float2 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord0 : TEXCOORD0, in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2,\n"
+ " out float4 oPosition : SV_Position, out float4 oColor : COLOR, out float2 oTexCoord0 : TEXCOORD0, out float2 oTexCoord1 : TEXCOORD1, out float2 oTexCoord2 : TEXCOORD2)\n"
+ "{\n"
+ " oPosition.x = Position.x;\n"
+ " oPosition.y = Position.y;\n"
+ " oPosition.z = 0.5;\n"
+ " oPosition.w = 1.0;\n"
+
+ // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion).
+ // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD.
+ " float3 TanEyeAngleR = float3 ( TexCoord0.x, TexCoord0.y, 1.0 );\n"
+ " float3 TanEyeAngleG = float3 ( TexCoord1.x, TexCoord1.y, 1.0 );\n"
+ " float3 TanEyeAngleB = float3 ( TexCoord2.x, TexCoord2.y, 1.0 );\n"
+
+ // Accurate time warp lerp vs. faster
+#if 1
+ // Apply the two 3x3 timewarp rotations to these vectors.
+ " float3 TransformedRStart = mul ( TanEyeAngleR, EyeRotationStart );\n"
+ " float3 TransformedGStart = mul ( TanEyeAngleG, EyeRotationStart );\n"
+ " float3 TransformedBStart = mul ( TanEyeAngleB, EyeRotationStart );\n"
+ " float3 TransformedREnd = mul ( TanEyeAngleR, EyeRotationEnd );\n"
+ " float3 TransformedGEnd = mul ( TanEyeAngleG, EyeRotationEnd );\n"
+ " float3 TransformedBEnd = mul ( TanEyeAngleB, EyeRotationEnd );\n"
+ // And blend between them.
+ " float3 TransformedR = lerp ( TransformedRStart, TransformedREnd, Color.a );\n"
+ " float3 TransformedG = lerp ( TransformedGStart, TransformedGEnd, Color.a );\n"
+ " float3 TransformedB = lerp ( TransformedBStart, TransformedBEnd, Color.a );\n"
+#else
+ " float3x3 EyeRotation = lerp ( EyeRotationStart, EyeRotationEnd, Color.a );\n"
+ " float3 TransformedR = mul ( TanEyeAngleR, EyeRotation );\n"
+ " float3 TransformedG = mul ( TanEyeAngleG, EyeRotation );\n"
+ " float3 TransformedB = mul ( TanEyeAngleB, EyeRotation );\n"
+#endif
+
+ // Project them back onto the Z=1 plane of the rendered images.
+ " float RecipZR = rcp ( TransformedR.z );\n"
+ " float RecipZG = rcp ( TransformedG.z );\n"
+ " float RecipZB = rcp ( TransformedB.z );\n"
+ " float2 FlattenedR = float2 ( TransformedR.x * RecipZR, TransformedR.y * RecipZR );\n"
+ " float2 FlattenedG = float2 ( TransformedG.x * RecipZG, TransformedG.y * RecipZG );\n"
+ " float2 FlattenedB = float2 ( TransformedB.x * RecipZB, TransformedB.y * RecipZB );\n"
+
+ // These are now still in TanEyeAngle space.
+ // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye)
+ " float2 SrcCoordR = FlattenedR * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " float2 SrcCoordG = FlattenedG * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " float2 SrcCoordB = FlattenedB * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " oTexCoord0 = SrcCoordR;\n"
+ " oTexCoord1 = SrcCoordG;\n"
+ " oTexCoord2 = SrcCoordB;\n"
+ " oColor = Color.r;\n" // Used for vignette fade.
+ "}\n";
+
+static const char* PostProcessMeshTimewarpPixelShaderSrc =
"Texture2D Texture : register(t0);\n"
"SamplerState Linear : register(s0);\n"
- "float2 LensCenter;\n"
- "float2 ScreenCenter;\n"
- "float2 Scale;\n"
- "float2 ScaleIn;\n"
- "float4 HmdWarpParam;\n"
- "float4 ChromAbParam;\n"
"\n"
+ "float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR,\n"
+ " in float2 oTexCoord0 : TEXCOORD0, in float2 oTexCoord1 : TEXCOORD1, in float2 oTexCoord2 : TEXCOORD2) : SV_Target\n"
+ "{\n"
+ " float ResultR = Texture.Sample(Linear, oTexCoord0).r;\n"
+ " float ResultG = Texture.Sample(Linear, oTexCoord1).g;\n"
+ " float ResultB = Texture.Sample(Linear, oTexCoord2).b;\n"
+ " return float4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0);\n"
+ "}\n";
- // Scales input texture coordinates for distortion.
- // ScaleIn maps texture coordinates to Scales to ([-1, 1]), although top/bottom will be
- // larger due to aspect ratio.
+//----------------------------------------------------------------------------
+// Pixel shader is very simple - does three texture reads.
+// Vertex shader does all the hard work.
+// Used for mesh-based distortion with positional timewarp.
+
+static const char* PostProcessMeshPositionalTimewarpVertexShaderSrc =
+ "Texture2DMS<float,4> DepthTexture : register(t0);\n"
+ // Padding because we are uploading "standard uniform buffer" constants
+ "float4x4 Padding1;\n"
+ "float4x4 Padding2;\n"
+ "float2 EyeToSourceUVScale;\n"
+ "float2 EyeToSourceUVOffset;\n"
+ "float2 DepthProjector;\n"
+ "float2 DepthDimSize;\n"
+ "float4x4 EyeRotationStart;\n"
+ "float4x4 EyeRotationEnd;\n"
+
+ "float4 PositionFromDepth(float2 inTexCoord)\n"
+ "{\n"
+ " float2 eyeToSourceTexCoord = inTexCoord * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " float depth = DepthTexture.Load(int2(eyeToSourceTexCoord * DepthDimSize), 0).x;\n"
+ " float linearDepth = DepthProjector.y / (depth - DepthProjector.x);\n"
+ " float4 retVal = float4(inTexCoord, 1, 1);\n"
+ " retVal.xyz *= linearDepth;\n"
+ " return retVal;\n"
+ "}\n"
+
+ "float2 TimewarpTexCoordToWarpedPos(float2 inTexCoord, float4x4 rotMat)\n"
+ "{\n"
+ // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion).
+ // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD.
+ // Apply the 4x4 timewarp rotation to these vectors.
+ " float4 inputPos = PositionFromDepth(inTexCoord);\n"
+ " float3 transformed = float3( mul ( rotMat, inputPos ).xyz);\n"
+ // Project them back onto the Z=1 plane of the rendered images.
+ " float2 flattened = transformed.xy / transformed.z;\n"
+ // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye)
+ " float2 noDepthUV = flattened * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ //" float depth = DepthTexture.SampleLevel(Linear, noDepthUV, 0).r;\n"
+ " return noDepthUV.xy;\n"
+ "}\n"
+
+ "void main( in float2 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord0 : TEXCOORD0,\n"
+ " in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2,\n"
+ " out float4 oPosition : SV_Position, out float4 oColor : COLOR,\n"
+ " out float2 oTexCoord0 : TEXCOORD0, out float2 oTexCoord1 : TEXCOORD1, out float2 oTexCoord2 : TEXCOORD2)\n"
+ "{\n"
+ " oPosition.x = Position.x;\n"
+ " oPosition.y = Position.y;\n"
+ " oPosition.z = 0.5;\n"
+ " oPosition.w = 1.0;\n"
+
+ " float timewarpLerpFactor = Color.a;\n"
+ " float4x4 lerpedEyeRot = lerp(EyeRotationStart, EyeRotationEnd, timewarpLerpFactor);\n"
+ //" float4x4 lerpedEyeRot = EyeRotationStart;\n"
+
+ // warped positions are a bit more involved, hence a separate function
+ " oTexCoord0 = TimewarpTexCoordToWarpedPos(TexCoord0, lerpedEyeRot);\n"
+ " oTexCoord1 = TimewarpTexCoordToWarpedPos(TexCoord1, lerpedEyeRot);\n"
+ " oTexCoord2 = TimewarpTexCoordToWarpedPos(TexCoord2, lerpedEyeRot);\n"
+
+ " oColor = Color.r; // Used for vignette fade.\n"
+ "}\n";
+
+static const char* PostProcessMeshPositionalTimewarpPixelShaderSrc =
+ "Texture2D Texture : register(t0);\n"
+ "SamplerState Linear : register(s0);\n"
+ "float2 DepthDimSize;\n"
+ "\n"
"float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR,\n"
- " in float2 oTexCoord : TEXCOORD0) : SV_Target\n"
+ " in float2 oTexCoord0 : TEXCOORD0, in float2 oTexCoord1 : TEXCOORD1, in float2 oTexCoord2 : TEXCOORD2) : SV_Target\n"
"{\n"
- " float2 theta = (oTexCoord - LensCenter) * ScaleIn;\n" // Scales to [-1, 1]
- " float rSq = theta.x * theta.x + theta.y * theta.y;\n"
- " float2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + "
- " HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n"
- " \n"
- " // Detect whether blue texture coordinates are out of range since these will scaled out the furthest.\n"
- " float2 thetaBlue = theta1 * (ChromAbParam.z + ChromAbParam.w * rSq);\n"
- " float2 tcBlue = LensCenter + Scale * thetaBlue;\n"
- " if (any(clamp(tcBlue, ScreenCenter-float2(0.25,0.5), ScreenCenter+float2(0.25, 0.5)) - tcBlue))\n"
- " return 0;\n"
- " \n"
- " // Now do blue texture lookup.\n"
- " float blue = Texture.Sample(Linear, tcBlue).b;\n"
- " \n"
- " // Do green lookup (no scaling).\n"
- " float2 tcGreen = LensCenter + Scale * theta1;\n"
- " float4 greenColor = Texture.Sample(Linear, tcGreen);\n"
- " float green = greenColor.g;\n"
- " float alpha = greenColor.a;\n"
- " \n"
- " // Do red scale and lookup.\n"
- " float2 thetaRed = theta1 * (ChromAbParam.x + ChromAbParam.y * rSq);\n"
- " float2 tcRed = LensCenter + Scale * thetaRed;\n"
- " float red = Texture.Sample(Linear, tcRed).r;\n"
- " \n"
- " return float4(red, green, blue, alpha);\n"
+ " float3 result;\n"
+ " result.r = Texture.Sample(Linear, oTexCoord0).r;\n"
+ " result.g = Texture.Sample(Linear, oTexCoord1).g;\n"
+ " result.b = Texture.Sample(Linear, oTexCoord2).b;\n"
+ " return float4(result * oColor, 1.0);\n"
"}\n";
+//----------------------------------------------------------------------------
static const char* VShaderSrcs[VShader_Count] =
{
DirectVertexShaderSrc,
StdVertexShaderSrc,
- PostProcessVertexShaderSrc
+ PostProcessVertexShaderSrc,
+ PostProcessMeshVertexShaderSrc,
+ PostProcessMeshTimewarpVertexShaderSrc,
+ PostProcessMeshPositionalTimewarpVertexShaderSrc
};
static const char* FShaderSrcs[FShader_Count] =
{
@@ -309,11 +519,13 @@ static const char* FShaderSrcs[FShader_Count] =
GouraudPixelShaderSrc,
TexturePixelShaderSrc,
AlphaTexturePixelShaderSrc,
- PostProcessPixelShaderSrc,
PostProcessPixelShaderWithChromAbSrc,
LitSolidPixelShaderSrc,
LitTexturePixelShaderSrc,
- MultiTexturePixelShaderSrc
+ MultiTexturePixelShaderSrc,
+ PostProcessMeshPixelShaderSrc,
+ PostProcessMeshTimewarpPixelShaderSrc,
+ PostProcessMeshPositionalTimewarpPixelShaderSrc
};
RenderDevice::RenderDevice(const RendererParams& p, HWND window)
@@ -322,8 +534,8 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window)
GetClientRect(window, &rc);
UINT width = rc.right - rc.left;
UINT height = rc.bottom - rc.top;
- WindowWidth = width;
- WindowHeight = height;
+ ::OVR::Render::RenderDevice::SetWindowSize(width, height);
+
Window = window;
Params = p;
@@ -359,17 +571,18 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window)
UpdateMonitorOutputs();
}
- int flags = 0;
+ int flags = D3D10_CREATE_DEVICE_BGRA_SUPPORT; //0;
#if (OVR_D3D_VERSION == 10)
- hr = D3D10CreateDevice(Adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, D3D1x_(SDK_VERSION),
+ 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
+ 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(), NULL, &Context.GetRawRef());
+ &Device.GetRawRef(), &featureLevel, &Context.GetRawRef());
#endif
if (FAILED(hr))
return;
@@ -387,25 +600,43 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window)
MaxTextureSet[i] = 0;
}
- ID3D10Blob* vsData = CompileShader("vs_4_0", DirectVertexShaderSrc);
+ ID3D10Blob* vsData = CompileShader("vs_4_1", DirectVertexShaderSrc);
VertexShaders[VShader_MV] = *new VertexShader(this, vsData);
for(int i = 1; i < VShader_Count; i++)
{
- VertexShaders[i] = *new VertexShader(this, CompileShader("vs_4_0", VShaderSrcs[i]));
+ OVR_ASSERT ( VShaderSrcs[i] != NULL ); // You forgot a shader!
+ ID3D10Blob *pShader = CompileShader("vs_4_1", VShaderSrcs[i]);
+ VertexShaders[i] = NULL;
+ if ( pShader != NULL )
+ {
+ VertexShaders[i] = *new VertexShader(this, pShader);
+ }
}
for(int i = 0; i < FShader_Count; i++)
{
- PixelShaders[i] = *new PixelShader(this, CompileShader("ps_4_0", FShaderSrcs[i]));
+ OVR_ASSERT ( FShaderSrcs[i] != NULL ); // You forgot a shader!
+ ID3D10Blob *pShader = CompileShader("ps_4_1", FShaderSrcs[i]);
+ PixelShaders[i] = NULL;
+ if ( pShader != NULL )
+ {
+ PixelShaders[i] = *new PixelShader(this, pShader);
+ }
}
SPInt bufferSize = vsData->GetBufferSize();
const void* buffer = vsData->GetBufferPointer();
ID3D1xInputLayout** objRef = &ModelVertexIL.GetRawRef();
-
- HRESULT validate = Device->CreateInputLayout(ModelVertexDesc, 5, buffer, bufferSize, objRef);
+ HRESULT validate = Device->CreateInputLayout(ModelVertexDesc, sizeof(ModelVertexDesc)/sizeof(ModelVertexDesc[0]), buffer, bufferSize, objRef);
OVR_UNUSED(validate);
+ ID3D10Blob* vsData2 = CompileShader("vs_4_1", PostProcessMeshVertexShaderSrc);
+ SPInt bufferSize2 = vsData2->GetBufferSize();
+ const void* buffer2 = vsData2->GetBufferPointer();
+ ID3D1xInputLayout** objRef2 = &DistortionVertexIL.GetRawRef();
+ HRESULT validate2 = Device->CreateInputLayout(DistortionVertexDesc, sizeof(DistortionVertexDesc)/sizeof(DistortionVertexDesc[0]), buffer2, bufferSize2, objRef2);
+ OVR_UNUSED(validate2);
+
Ptr<ShaderSet> gouraudShaders = *new ShaderSet();
gouraudShaders->SetShader(VertexShaders[VShader_MVP]);
gouraudShaders->SetShader(PixelShaders[FShader_Gouraud]);
@@ -433,7 +664,7 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window)
D3D1x_(RASTERIZER_DESC) rs;
memset(&rs, 0, sizeof(rs));
- rs.AntialiasedLineEnable = true;
+ rs.AntialiasedLineEnable = false; // You can't just turn this on - it needs alpha modes etc setting up and doesn't work with Z buffers.
rs.CullMode = D3D1x_(CULL_BACK);
// rs.CullMode = D3D1x_(CULL_NONE);
rs.DepthClipEnable = true;
@@ -568,10 +799,11 @@ bool RenderDevice::RecreateSwapChain()
DXGI_SWAP_CHAIN_DESC scDesc;
memset(&scDesc, 0, sizeof(scDesc));
scDesc.BufferCount = 1;
- scDesc.BufferDesc.Width = WindowWidth;
+ scDesc.BufferDesc.Width = WindowWidth;
scDesc.BufferDesc.Height = WindowHeight;
scDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- scDesc.BufferDesc.RefreshRate.Numerator = 60;
+ // Use default refresh rate; switching rate on CC prototype can cause screen lockup.
+ scDesc.BufferDesc.RefreshRate.Numerator = 0;
scDesc.BufferDesc.RefreshRate.Denominator = 1;
scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scDesc.OutputWindow = Window;
@@ -621,18 +853,60 @@ bool RenderDevice::SetParams(const RendererParams& newParams)
UpdateMonitorOutputs(true);
}
- // Cause this to be recreated with the new multisample mode.
- pSceneColorTex = NULL;
return RecreateSwapChain();
}
+
+ovrRenderAPIConfig RenderDevice::Get_ovrRenderAPIConfig() const
+{
+#if (OVR_D3D_VERSION == 10)
+ static ovrD3D10Config cfg;
+ cfg.D3D10.Header.API = ovrRenderAPI_D3D10;
+ cfg.D3D10.Header.RTSize = Sizei(WindowWidth, WindowHeight);
+ cfg.D3D10.Header.Multisample = Params.Multisample;
+ cfg.D3D10.pDevice = Device;
+ cfg.D3D10.pBackBufferRT = BackBufferRT;
+ cfg.D3D10.pSwapChain = SwapChain;
+#else
+ static ovrD3D11Config cfg;
+ cfg.D3D11.Header.API = ovrRenderAPI_D3D11;
+ cfg.D3D11.Header.RTSize = Sizei(WindowWidth, WindowHeight);
+ cfg.D3D11.Header.Multisample = Params.Multisample;
+ cfg.D3D11.pDevice = Device;
+ cfg.D3D11.pDeviceContext = Context;
+ cfg.D3D11.pBackBufferRT = BackBufferRT;
+ cfg.D3D11.pSwapChain = SwapChain;
+#endif
+ return cfg.Config;
+}
+
+ovrTexture Texture::Get_ovrTexture()
+{
+ ovrTexture tex;
+
+ OVR::Sizei newRTSize(Width, Height);
+
+#if (OVR_D3D_VERSION == 10)
+ ovrD3D10TextureData* texData = (ovrD3D10TextureData*)&tex;
+ texData->Header.API = ovrRenderAPI_D3D10;
+#else
+ ovrD3D11TextureData* texData = (ovrD3D11TextureData*)&tex;
+ texData->Header.API = ovrRenderAPI_D3D11;
+#endif
+ texData->Header.TextureSize = newRTSize;
+ texData->Header.RenderViewport = Recti(newRTSize);
+ texData->pTexture = Tex;
+ texData->pSRView = TexSv;
+
+ return tex;
+}
void RenderDevice::SetWindowSize(int w, int h)
{
if (w == WindowWidth && h == WindowHeight)
return;
- WindowWidth = w;
- WindowHeight = h;
+ ::OVR::Render::RenderDevice::SetWindowSize(w, h);
+
Context->OMSetRenderTargets(0, NULL, NULL);
BackBuffer = NULL;
BackBufferRT = NULL;
@@ -698,32 +972,24 @@ bool RenderDevice::SetFullscreen(DisplayMode fullscreen)
return true;
}
-void RenderDevice::SetMultipleViewports(int n, const Viewport* vps)
+void RenderDevice::SetViewport(const Recti& vp)
{
- if (n > 2)
- {
- n = 2;
- }
- for(int i = 0; i < n; i++)
- {
#if (OVR_D3D_VERSION == 10)
- Viewports[i].Width = vps[i].w;
- Viewports[i].Height = vps[i].h;
- Viewports[i].MinDepth = 0;
- Viewports[i].MaxDepth = 1;
- Viewports[i].TopLeftX = vps[i].x;
- Viewports[i].TopLeftY = vps[i].y;
+ D3DViewport.Width = vp.w;
+ D3DViewport.Height = vp.h;
+ D3DViewport.MinDepth = 0;
+ D3DViewport.MaxDepth = 1;
+ D3DViewport.TopLeftX = vp.x;
+ D3DViewport.TopLeftY = vp.y;
#else
- Viewports[i].Width = (float)vps[i].w;
- Viewports[i].Height = (float)vps[i].h;
- Viewports[i].MinDepth = 0;
- Viewports[i].MaxDepth = 1;
- Viewports[i].TopLeftX = (float)vps[i].x;
- Viewports[i].TopLeftY = (float)vps[i].y;
+ D3DViewport.Width = (float)vp.w;
+ D3DViewport.Height = (float)vp.h;
+ D3DViewport.MinDepth = 0;
+ D3DViewport.MaxDepth = 1;
+ D3DViewport.TopLeftX = (float)vp.x;
+ D3DViewport.TopLeftY = (float)vp.y;
#endif
- }
- NumViewports = n;
- Context->RSSetViewports(n, Viewports);
+ Context->RSSetViewports(1,&D3DViewport);
}
static int GetDepthStateIndex(bool enable, bool write, RenderDevice::CompareFunc func)
@@ -754,7 +1020,7 @@ void RenderDevice::SetDepthMode(bool enable, bool write, CompareFunc func)
case Compare_Less: dss.DepthFunc = D3D1x_(COMPARISON_LESS); break;
case Compare_Greater: dss.DepthFunc = D3D1x_(COMPARISON_GREATER); break;
default:
- assert(0);
+ OVR_ASSERT(0);
}
dss.DepthWriteMask = write ? D3D1x_(DEPTH_WRITE_MASK_ALL) : D3D1x_(DEPTH_WRITE_MASK_ZERO);
Device->CreateDepthStencilState(&dss, &DepthStates[index].GetRawRef());
@@ -782,70 +1048,27 @@ Texture* RenderDevice::GetDepthBuffer(int w, int h, int ms)
return newDepth.GetPtr();
}
-void RenderDevice::Clear(float r, float g, float b, float a, float depth)
+void RenderDevice::Clear(float r /*= 0*/, float g /*= 0*/, float b /*= 0*/, float a /*= 1*/,
+ float depth /*= 1*/,
+ bool clearColor /*= true*/, bool clearDepth /*= true*/)
{
- const float color[] = {r, g, b, a};
-
- // save state that is affected by clearing this way
- ID3D1xDepthStencilState* oldDepthState = CurDepthState;
- StandardUniformData clearUniforms;
-
- SetDepthMode(true, true, Compare_Always);
-
- Context->IASetInputLayout(ModelVertexIL);
-#if (OVR_D3D_VERSION == 10)
- Context->GSSetShader(NULL);
-#else
- Context->GSSetShader(NULL, NULL, 0);
-#endif
- //Shader<Shader_Geometry,ID3D1xGeometryShader> NullGS(this,(ID3D1xGeometryShader*)NULL);
- //NullGS.Set(Prim_TriangleStrip);
-
- ID3D1xShaderResourceView* sv[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- if (MaxTextureSet[Shader_Fragment])
- {
- Context->PSSetShaderResources(0, MaxTextureSet[Shader_Fragment], sv);
- }
-
- ID3D1xBuffer* vertexBuffer = QuadVertexBuffer->GetBuffer();
- UINT vertexStride = sizeof(Vertex);
- UINT vertexOffset = 0;
- Context->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset);
-
- clearUniforms.View = Matrix4f(2, 0, 0, 0,
- 0, 2, 0, 0,
- 0, 0, 0, 0,
- -1, -1, depth, 1);
- UniformBuffers[Shader_Vertex]->Data(Buffer_Uniform, &clearUniforms, sizeof(clearUniforms));
-
- ID3D1xBuffer* vertexConstants = UniformBuffers[Shader_Vertex]->GetBuffer();
- Context->VSSetConstantBuffers(0, 1, &vertexConstants);
- Context->IASetPrimitiveTopology(D3D1x_(PRIMITIVE_TOPOLOGY_TRIANGLESTRIP));
- VertexShaders[VShader_MV]->Set(Prim_TriangleStrip);
- PixelShaders[FShader_Solid]->Set(Prim_TriangleStrip);
-
- UniformBuffers[Shader_Pixel]->Data(Buffer_Uniform, color, sizeof(color));
- PixelShaders[FShader_Solid]->SetUniformBuffer(UniformBuffers[Shader_Pixel]);
-
- if (NumViewports > 1)
+ if ( clearColor )
{
- for(int i = 0; i < NumViewports; i++)
+ const float color[] = {r, g, b, a};
+ if ( CurRenderTarget == NULL )
+ {
+ Context->ClearRenderTargetView ( BackBufferRT.GetRawRef(), color );
+ }
+ else
{
- Context->RSSetViewports(1, &Viewports[i]);
- Context->OMSetBlendState(NULL, NULL, 0xffffffff);
- Context->Draw(4, 0);
+ Context->ClearRenderTargetView ( CurRenderTarget->TexRtv, color );
}
- Context->RSSetViewports(NumViewports, Viewports);
}
- else
+
+ if ( clearDepth )
{
- Context->OMSetBlendState(NULL, NULL, 0xffffffff);
- Context->Draw(4, 0);
+ Context->ClearDepthStencilView ( CurDepthBuffer->TexDsv, D3D10_CLEAR_DEPTH | D3D10_CLEAR_STENCIL, depth, 0 );
}
-
- // reset
- CurDepthState = oldDepthState;
- Context->OMSetDepthStencilState(CurDepthState, 0);
}
// Buffers
@@ -1280,6 +1503,11 @@ Texture::Texture(RenderDevice* ren, int fmt, int w, int h) : Ren(ren), Tex(NULL)
Sampler = Ren->GetSamplerState(0);
}
+void* Texture::GetInternalImplementation()
+{
+ return Tex;
+}
+
Texture::~Texture()
{
}
@@ -1312,6 +1540,10 @@ void RenderDevice::SetTexture(Render::ShaderStage stage, int slot, const Texture
case Shader_Vertex:
Context->VSSetShaderResources(slot, 1, &sv);
+ if (t)
+ {
+ Context->VSSetSamplers(slot, 1, &t->Sampler.GetRawRef());
+ }
break;
}
}
@@ -1501,10 +1733,22 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
}
else
{
+ int samples = (format & Texture_SamplesMask);
+ if (samples < 1)
+ {
+ samples = 1;
+ }
+
+ bool createDepthSrv = (format & Texture_SampleDepth) > 0;
+
DXGI_FORMAT d3dformat;
int bpp;
switch(format & Texture_TypeMask)
{
+ case Texture_BGRA:
+ bpp = 4;
+ d3dformat = DXGI_FORMAT_B8G8R8A8_UNORM;
+ break;
case Texture_RGBA:
bpp = 4;
d3dformat = DXGI_FORMAT_R8G8B8A8_UNORM;
@@ -1513,30 +1757,28 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
bpp = 1;
d3dformat = DXGI_FORMAT_R8_UNORM;
break;
+ case Texture_A:
+ bpp = 1;
+ d3dformat = DXGI_FORMAT_A8_UNORM;
+ break;
case Texture_Depth:
bpp = 0;
- d3dformat = DXGI_FORMAT_D32_FLOAT;
+ d3dformat = createDepthSrv ? DXGI_FORMAT_R32_TYPELESS : DXGI_FORMAT_D32_FLOAT;
break;
default:
return NULL;
}
- int samples = (format & Texture_SamplesMask);
- if (samples < 1)
- {
- samples = 1;
- }
-
Texture* NewTex = new Texture(this, format, width, height);
NewTex->Samples = samples;
D3D1x_(TEXTURE2D_DESC) dsDesc;
- dsDesc.Width = width;
- dsDesc.Height = height;
+ dsDesc.Width = width;
+ dsDesc.Height = height;
dsDesc.MipLevels = (format == (Texture_RGBA | Texture_GenMipmaps) && data) ? GetNumMipLevels(width, height) : 1;
dsDesc.ArraySize = 1;
dsDesc.Format = d3dformat;
- dsDesc.SampleDesc.Count = samples;
+ dsDesc.SampleDesc.Count = samples;
dsDesc.SampleDesc.Quality = 0;
dsDesc.Usage = D3D1x_(USAGE_DEFAULT);
dsDesc.BindFlags = D3D1x_(BIND_SHADER_RESOURCE);
@@ -1546,9 +1788,8 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
if (format & Texture_RenderTarget)
{
if ((format & Texture_TypeMask) == Texture_Depth)
- // We don't use depth textures, and creating them in d3d10 requires different options.
{
- dsDesc.BindFlags = D3D1x_(BIND_DEPTH_STENCIL);
+ dsDesc.BindFlags = createDepthSrv ? (dsDesc.BindFlags | D3D1x_(BIND_DEPTH_STENCIL)) : D3D1x_(BIND_DEPTH_STENCIL);
}
else
{
@@ -1565,7 +1806,19 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
}
if (dsDesc.BindFlags & D3D1x_(BIND_SHADER_RESOURCE))
{
- Device->CreateShaderResourceView(NewTex->Tex, NULL, &NewTex->TexSv.GetRawRef());
+ if((dsDesc.BindFlags & D3D1x_(BIND_DEPTH_STENCIL)) > 0 && createDepthSrv)
+ {
+ D3D1x_(SHADER_RESOURCE_VIEW_DESC) depthSrv;
+ depthSrv.Format = DXGI_FORMAT_R32_FLOAT;
+ 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());
+ }
+ else
+ {
+ Device->CreateShaderResourceView(NewTex->Tex, NULL, &NewTex->TexSv.GetRawRef());
+ }
}
if (data)
@@ -1611,7 +1864,12 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
{
if ((format & Texture_TypeMask) == Texture_Depth)
{
- Device->CreateDepthStencilView(NewTex->Tex, NULL, &NewTex->TexDsv.GetRawRef());
+ D3D1x_(DEPTH_STENCIL_VIEW_DESC) depthDsv;
+ ZeroMemory(&depthDsv, sizeof(depthDsv));
+ 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());
}
else
{
@@ -1703,38 +1961,54 @@ void RenderDevice::RenderWithAlpha( const Fill* fill, Render::Buffer* vertices,
}
void RenderDevice::Render(const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices,
- const Matrix4f& matrix, int offset, int count, PrimitiveType rprim)
+ const Matrix4f& matrix, int offset, int count, PrimitiveType rprim, bool useDistortionVertex/* = false*/)
{
- Context->IASetInputLayout(ModelVertexIL);
+ ID3D1xBuffer* vertexBuffer = ((Buffer*)vertices)->GetBuffer();
+ UINT vertexOffset = offset;
+ UINT vertexStride = sizeof(Vertex);
+ if ( useDistortionVertex )
+ {
+ Context->IASetInputLayout(DistortionVertexIL);
+ vertexStride = sizeof(DistortionVertex);
+ }
+ else
+ {
+ Context->IASetInputLayout(ModelVertexIL);
+ vertexStride = sizeof(Vertex);
+ }
+ Context->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset);
+
if (indices)
{
Context->IASetIndexBuffer(((Buffer*)indices)->GetBuffer(), DXGI_FORMAT_R16_UINT, 0);
}
- ID3D1xBuffer* vertexBuffer = ((Buffer*)vertices)->GetBuffer();
- UINT vertexStride = sizeof(Vertex);
- UINT vertexOffset = offset;
- Context->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset);
-
ShaderSet* shaders = ((ShaderFill*)fill)->GetShaders();
ShaderBase* vshader = ((ShaderBase*)shaders->GetShader(Shader_Vertex));
unsigned char* vertexData = vshader->UniformData;
- if (vertexData)
+ if ( vertexData != NULL )
{
- StandardUniformData* stdUniforms = (StandardUniformData*) vertexData;
- stdUniforms->View = matrix.Transposed();
- stdUniforms->Proj = StdUniforms.Proj;
+ // TODO: some VSes don't start with StandardUniformData!
+ if ( vshader->UniformsSize >= sizeof(StandardUniformData) )
+ {
+ StandardUniformData* stdUniforms = (StandardUniformData*) vertexData;
+ stdUniforms->View = matrix.Transposed();
+ stdUniforms->Proj = StdUniforms.Proj;
+ }
+
UniformBuffers[Shader_Vertex]->Data(Buffer_Uniform, vertexData, vshader->UniformsSize);
vshader->SetUniformBuffer(UniformBuffers[Shader_Vertex]);
}
for(int i = Shader_Vertex + 1; i < Shader_Count; i++)
+ {
if (shaders->GetShader(i))
{
((ShaderBase*)shaders->GetShader(i))->UpdateBuffer(UniformBuffers[i]);
((ShaderBase*)shaders->GetShader(i))->SetUniformBuffer(UniformBuffers[i]);
}
+ }
D3D1x_(PRIMITIVE_TOPOLOGY) prim;
switch(rprim)
@@ -1749,7 +2023,7 @@ void RenderDevice::Render(const Fill* fill, Render::Buffer* vertices, Render::Bu
prim = D3D1x_(PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
break;
default:
- assert(0);
+ OVR_ASSERT(0);
return;
}
Context->IASetPrimitiveTopology(prim);
@@ -1782,20 +2056,40 @@ UPInt RenderDevice::QueryGPUMemorySize()
}
-void RenderDevice::Present()
+void RenderDevice::Present ( bool withVsync )
{
- SwapChain->Present(0, 0);
+ if( OVR::Util::ImageWindow::GlobalWindow() )
+ {
+ OVR::Util::ImageWindow::GlobalWindow()->Process();
+ }
+
+ if ( withVsync )
+ {
+ SwapChain->Present(1, 0);
+ }
+ else
+ {
+ // Immediate present
+ SwapChain->Present(0, 0);
+ }
}
-void RenderDevice::ForceFlushGPU()
+void RenderDevice::WaitUntilGpuIdle()
{
+#if 0
+ // 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.
+
+ // Flush GPU data and don't stall CPU waiting for GPU to complete
+ Context->Flush();
+#else
+ // Flush and Stall CPU while waiting for GPU to complete rendering all of the queued draw calls
D3D1x_QUERY_DESC queryDesc = { D3D1x_(QUERY_EVENT), 0 };
Ptr<ID3D1xQuery> query;
BOOL done = FALSE;
if (Device->CreateQuery(&queryDesc, &query.GetRawRef()) == S_OK)
{
-
#if (OVR_D3D_VERSION == 10)
// Begin() not used for EVENT query.
query->End();
@@ -1808,10 +2102,10 @@ void RenderDevice::ForceFlushGPU()
do { }
while(!done && !FAILED(Context->GetData(query, &done, sizeof(BOOL), 0)));
#endif
-
}
-}
+#endif
+}
void RenderDevice::FillRect(float left, float top, float right, float bottom, Color c)
{
@@ -1841,5 +2135,27 @@ void RenderDevice::RenderImage(float left, float top, float right, float bottom,
Context->OMSetBlendState(NULL, NULL, 0xffffffff);
}
+void RenderDevice::BeginGpuEvent(const char* markerText, UInt32 markerColor)
+{
+#if GPU_PROFILING
+ WCHAR wStr[255];
+ size_t newStrLen = 0;
+ mbstowcs_s(&newStrLen, wStr, markerText, 255);
+ LPCWSTR pwStr = wStr;
+
+ D3DPERF_BeginEvent(markerColor, pwStr);
+#else
+ OVR_UNUSED(markerText);
+ OVR_UNUSED(markerColor);
+#endif
+}
+
+void RenderDevice::EndGpuEvent()
+{
+#if GPU_PROFILING
+ D3DPERF_EndEvent();
+#endif
+}
+
}}}
diff --git a/Samples/CommonSrc/Render/Render_D3D1X_Device.h b/Samples/CommonSrc/Render/Render_D3D1X_Device.h
index b615e2b..e06bcda 100644
--- a/Samples/CommonSrc/Render/Render_D3D1X_Device.h
+++ b/Samples/CommonSrc/Render/Render_D3D1X_Device.h
@@ -42,7 +42,7 @@ limitations under the License.
#if (OVR_D3D_VERSION == 10)
#define _OVR_RENDERER_D3D10
-#include <d3d10.h>
+#include <d3d10_1.h>
namespace OVR { namespace Render { namespace D3D10 {
@@ -64,8 +64,8 @@ class RenderDevice;
#endif
#if (OVR_D3D_VERSION == 10)
-typedef ID3D10Device ID3D1xDevice;
-typedef ID3D10Device ID3D1xDeviceContext;
+typedef ID3D10Device1 ID3D1xDevice;
+typedef ID3D10Device1 ID3D1xDeviceContext;
typedef ID3D10RenderTargetView ID3D1xRenderTargetView;
typedef ID3D10Texture2D ID3D1xTexture2D;
typedef ID3D10ShaderResourceView ID3D1xShaderResourceView;
@@ -73,6 +73,7 @@ typedef ID3D10DepthStencilView ID3D1xDepthStencilView;
typedef ID3D10DepthStencilState ID3D1xDepthStencilState;
typedef ID3D10InputLayout ID3D1xInputLayout;
typedef ID3D10Buffer ID3D1xBuffer;
+typedef ID3D10Resource ID3D1xResource;
typedef ID3D10VertexShader ID3D1xVertexShader;
typedef ID3D10PixelShader ID3D1xPixelShader;
typedef ID3D10GeometryShader ID3D1xGeometryShader;
@@ -96,6 +97,7 @@ typedef ID3D11DepthStencilView ID3D1xDepthStencilView;
typedef ID3D11DepthStencilState ID3D1xDepthStencilState;
typedef ID3D11InputLayout ID3D1xInputLayout;
typedef ID3D11Buffer ID3D1xBuffer;
+typedef ID3D11Resource ID3D1xResource;
typedef ID3D10Blob ID3D1xBlob;
typedef ID3D11VertexShader ID3D1xVertexShader;
typedef ID3D11PixelShader ID3D1xPixelShader;
@@ -201,11 +203,12 @@ public:
class Texture : public Render::Texture
{
public:
- RenderDevice* Ren;
+ RenderDevice* Ren;
Ptr<ID3D1xTexture2D> Tex;
Ptr<ID3D1xShaderResourceView> TexSv;
Ptr<ID3D1xRenderTargetView> TexRtv;
Ptr<ID3D1xDepthStencilView> TexDsv;
+ Ptr<ID3D1xTexture2D> TexStaging;
mutable Ptr<ID3D1xSamplerState> Sampler;
int Width, Height;
int Samples;
@@ -229,6 +232,11 @@ public:
virtual void SetSampleMode(int sm);
virtual void Set(int slot, Render::ShaderStage stage = Render::Shader_Fragment) const;
+
+ virtual ovrTexture Get_ovrTexture();
+
+ virtual void* GetInternalImplementation();
+
};
class RenderDevice : public Render::RenderDevice
@@ -251,12 +259,12 @@ public:
Ptr<Texture> CurDepthBuffer;
Ptr<ID3D1xRasterizerState> Rasterizer;
Ptr<ID3D1xBlendState> BlendState;
- int NumViewports;
- D3D1x_VIEWPORT Viewports[2];
+ D3D1x_VIEWPORT D3DViewport;
Ptr<ID3D1xDepthStencilState> DepthStates[1 + 2 * Compare_Count];
Ptr<ID3D1xDepthStencilState> CurDepthState;
Ptr<ID3D1xInputLayout> ModelVertexIL;
+ Ptr<ID3D1xInputLayout> DistortionVertexIL;
Ptr<ID3D1xSamplerState> SamplerStates[Sample_Count];
@@ -292,18 +300,22 @@ public:
// and it should be recreated.
void UpdateMonitorOutputs(bool needRecreate = false);
- virtual void SetMultipleViewports(int n, const Viewport* vps);
+ virtual void SetViewport(const Recti& vp);
virtual void SetWindowSize(int w, int h);
virtual bool SetParams(const RendererParams& newParams);
- //virtual void SetScissor(int x, int y, int w, int h);
- virtual void Present();
- virtual void ForceFlushGPU();
+ // Returns details needed by CAPI distortion rendering.
+ virtual ovrRenderAPIConfig Get_ovrRenderAPIConfig() const;
+
+ virtual void Present ( bool withVsync );
+ virtual void WaitUntilGpuIdle();
virtual bool SetFullscreen(DisplayMode fullscreen);
virtual UPInt QueryGPUMemorySize();
- virtual void Clear(float r = 0, float g = 0, float b = 0, float a = 1, float depth = 1);
+ virtual void Clear(float r = 0, float g = 0, float b = 0, float a = 1,
+ float depth = 1,
+ bool clearColor = true, bool clearDepth = true);
virtual void Rect(float left, float top, float right, float bottom)
{
OVR_UNUSED4(left, top, right, bottom);
@@ -331,7 +343,6 @@ public:
ExtraShaders = s;
}
-
// 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);
@@ -340,7 +351,7 @@ public:
virtual void Render(const Matrix4f& matrix, Model* model);
virtual void Render(const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices,
- const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles);
+ const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles, bool useDistortionVertex = false);
virtual void RenderWithAlpha( const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices,
const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles);
@@ -355,6 +366,10 @@ public:
ID3D1xSamplerState* GetSamplerState(int sm);
void SetTexture(Render::ShaderStage stage, int slot, const Texture* t);
+
+ // GPU Profiling
+ virtual void BeginGpuEvent(const char* markerText, UInt32 markerColor);
+ virtual void EndGpuEvent();
};
}}}
diff --git a/Samples/CommonSrc/Render/Render_Device.cpp b/Samples/CommonSrc/Render/Render_Device.cpp
index d0f3228..e917fb0 100644
--- a/Samples/CommonSrc/Render/Render_Device.cpp
+++ b/Samples/CommonSrc/Render/Render_Device.cpp
@@ -25,107 +25,112 @@ limitations under the License.
#include "../Render/Render_Font.h"
#include "Kernel/OVR_Log.h"
+#include "Util/Util_Render_Stereo.h"
+using namespace OVR::Util::Render;
namespace OVR { namespace Render {
-void Model::Render(const Matrix4f& ltw, RenderDevice* ren)
-{
- if(Visible)
- {
- Matrix4f m = ltw * GetMatrix();
- ren->Render(m, this);
- }
-}
-
-void Container::Render(const Matrix4f& ltw, RenderDevice* ren)
-{
- Matrix4f m = ltw * GetMatrix();
- for(unsigned i = 0; i < Nodes.GetSize(); i++)
- {
- Nodes[i]->Render(m, ren);
- }
-}
-
-Matrix4f SceneView::GetViewMatrix() const
-{
- Matrix4f view = Matrix4f(GetOrientation().Conj()) * Matrix4f::Translation(GetPosition());
- return view;
-}
-
-void LightingParams::Update(const Matrix4f& view, const Vector4f* SceneLightPos)
-{
- Version++;
- for (int i = 0; i < LightCount; i++)
- {
- LightPos[i] = view.Transform(SceneLightPos[i]);
- }
-}
-
-void Scene::Render(RenderDevice* ren, const Matrix4f& view)
-{
- Lighting.Update(view, LightPos);
-
- ren->SetLighting(&Lighting);
-
- World.Render(view, ren);
-}
-
-
-
-UInt16 CubeIndices[] =
-{
- 0, 1, 3,
- 3, 1, 2,
-
- 5, 4, 6,
- 6, 4, 7,
-
- 8, 9, 11,
- 11, 9, 10,
-
- 13, 12, 14,
- 14, 12, 15,
-
- 16, 17, 19,
- 19, 17, 18,
-
- 21, 20, 22,
- 22, 20, 23
-};
-
-// Colors are specified for planes perpendicular to the axis
-// For example, "xColor" is the color of the y-z plane
-Model* Model::CreateAxisFaceColorBox(float x1, float x2, Color xcolor,
- float y1, float y2, Color ycolor,
- float z1, float z2, Color zcolor)
-{
- float t;
-
- if(x1 > x2)
- {
- t = x1;
- x1 = x2;
- x2 = t;
- }
- if(y1 > y2)
- {
- t = y1;
- y1 = y2;
- y2 = t;
- }
- if(z1 > z2)
- {
- t = z1;
- z1 = z2;
- z2 = t;
- }
-
- Model* box = new Model();
-
- UInt16 startIndex = 0;
- // Cube
- startIndex =
- box->AddVertex(Vector3f(x1, y2, z1), ycolor);
+ void Model::Render(const Matrix4f& ltw, RenderDevice* ren)
+ {
+ if(Visible)
+ {
+ AutoGpuProf prof(ren, "Model_Render");
+ Matrix4f m = ltw * GetMatrix();
+ ren->Render(m, this);
+ }
+ }
+
+ void Container::Render(const Matrix4f& ltw, RenderDevice* ren)
+ {
+ Matrix4f m = ltw * GetMatrix();
+ for(unsigned i = 0; i < Nodes.GetSize(); i++)
+ {
+ Nodes[i]->Render(m, ren);
+ }
+ }
+
+ Matrix4f SceneView::GetViewMatrix() const
+ {
+ Matrix4f view = Matrix4f(GetOrientation().Conj()) * Matrix4f::Translation(GetPosition());
+ return view;
+ }
+
+ void LightingParams::Update(const Matrix4f& view, const Vector3f* SceneLightPos)
+ {
+ Version++;
+ for (int i = 0; i < LightCount; i++)
+ {
+ LightPos[i] = view.Transform(SceneLightPos[i]);
+ }
+ }
+
+ void Scene::Render(RenderDevice* ren, const Matrix4f& view)
+ {
+ AutoGpuProf prof(ren, "Scene_Render");
+
+ Lighting.Update(view, LightPos);
+
+ ren->SetLighting(&Lighting);
+
+ World.Render(view, ren);
+ }
+
+
+
+ UInt16 CubeIndices[] =
+ {
+ 0, 1, 3,
+ 3, 1, 2,
+
+ 5, 4, 6,
+ 6, 4, 7,
+
+ 8, 9, 11,
+ 11, 9, 10,
+
+ 13, 12, 14,
+ 14, 12, 15,
+
+ 16, 17, 19,
+ 19, 17, 18,
+
+ 21, 20, 22,
+ 22, 20, 23
+ };
+
+ // Colors are specified for planes perpendicular to the axis
+ // For example, "xColor" is the color of the y-z plane
+ Model* Model::CreateAxisFaceColorBox(float x1, float x2, Color xcolor,
+ float y1, float y2, Color ycolor,
+ float z1, float z2, Color zcolor)
+ {
+ float t;
+
+ if(x1 > x2)
+ {
+ t = x1;
+ x1 = x2;
+ x2 = t;
+ }
+ if(y1 > y2)
+ {
+ t = y1;
+ y1 = y2;
+ y2 = t;
+ }
+ if(z1 > z2)
+ {
+ t = z1;
+ z1 = z2;
+ z2 = t;
+ }
+
+ Model* box = new Model();
+
+ UInt16 startIndex = 0;
+ // Cube
+ startIndex =
+ box->AddVertex(Vector3f(x1, y2, z1), ycolor);
box->AddVertex(Vector3f(x2, y2, z1), ycolor);
box->AddVertex(Vector3f(x2, y2, z2), ycolor);
box->AddVertex(Vector3f(x1, y2, z2), ycolor);
@@ -156,960 +161,1233 @@ Model* Model::CreateAxisFaceColorBox(float x1, float x2, Color xcolor,
box->AddVertex(Vector3f(x1, y2, z2), zcolor);
- enum
- {
- // CubeVertexCount = sizeof(CubeVertices)/sizeof(CubeVertices[0]),
- CubeIndexCount = sizeof(CubeIndices) / sizeof(CubeIndices[0])
- };
-
- // Renumber indices
- for(int i = 0; i < CubeIndexCount / 3; i++)
- {
- box->AddTriangle(CubeIndices[i * 3] + startIndex,
- CubeIndices[i * 3 + 1] + startIndex,
- CubeIndices[i * 3 + 2] + startIndex);
- }
-
- return box;
-}
-
-void Model::AddSolidColorBox(float x1, float y1, float z1,
- float x2, float y2, float z2,
- Color c)
-{
- float t;
-
- if(x1 > x2)
- {
- t = x1;
- x1 = x2;
- x2 = t;
- }
- if(y1 > y2)
- {
- t = y1;
- y1 = y2;
- y2 = t;
- }
- if(z1 > z2)
- {
- t = z1;
- z1 = z2;
- z2 = t;
- }
-
- // Cube vertices and their normals.
- Vector3f CubeVertices[][3] =
- {
- Vector3f(x1, y2, z1), Vector3f(z1, x1), Vector3f(0.0f, 1.0f, 0.0f),
- Vector3f(x2, y2, z1), Vector3f(z1, x2), Vector3f(0.0f, 1.0f, 0.0f),
- Vector3f(x2, y2, z2), Vector3f(z2, x2), Vector3f(0.0f, 1.0f, 0.0f),
- Vector3f(x1, y2, z2), Vector3f(z2, x1), Vector3f(0.0f, 1.0f, 0.0f),
-
- Vector3f(x1, y1, z1), Vector3f(z1, x1), Vector3f(0.0f, -1.0f, 0.0f),
- Vector3f(x2, y1, z1), Vector3f(z1, x2), Vector3f(0.0f, -1.0f, 0.0f),
- Vector3f(x2, y1, z2), Vector3f(z2, x2), Vector3f(0.0f, -1.0f, 0.0f),
- Vector3f(x1, y1, z2), Vector3f(z2, x1), Vector3f(0.0f, -1.0f, 0.0f),
-
- Vector3f(x1, y1, z2), Vector3f(z2, y1), Vector3f(-1.0f, 0.0f, 0.0f),
- Vector3f(x1, y1, z1), Vector3f(z1, y1), Vector3f(-1.0f, 0.0f, 0.0f),
- Vector3f(x1, y2, z1), Vector3f(z1, y2), Vector3f(-1.0f, 0.0f, 0.0f),
- Vector3f(x1, y2, z2), Vector3f(z2, y2), Vector3f(-1.0f, 0.0f, 0.0f),
-
- Vector3f(x2, y1, z2), Vector3f(z2, y1), Vector3f(1.0f, 0.0f, 0.0f),
- Vector3f(x2, y1, z1), Vector3f(z1, y1), Vector3f(1.0f, 0.0f, 0.0f),
- Vector3f(x2, y2, z1), Vector3f(z1, y2), Vector3f(1.0f, 0.0f, 0.0f),
- Vector3f(x2, y2, z2), Vector3f(z2, y2), Vector3f(1.0f, 0.0f, 0.0f),
-
- Vector3f(x1, y1, z1), Vector3f(x1, y1), Vector3f(0.0f, 0.0f, -1.0f),
- Vector3f(x2, y1, z1), Vector3f(x2, y1), Vector3f(0.0f, 0.0f, -1.0f),
- Vector3f(x2, y2, z1), Vector3f(x2, y2), Vector3f(0.0f, 0.0f, -1.0f),
- Vector3f(x1, y2, z1), Vector3f(x1, y2), Vector3f(0.0f, 0.0f, -1.0f),
-
- Vector3f(x1, y1, z2), Vector3f(x1, y1), Vector3f(0.0f, 0.0f, 1.0f),
- Vector3f(x2, y1, z2), Vector3f(x2, y1), Vector3f(0.0f, 0.0f, 1.0f),
- Vector3f(x2, y2, z2), Vector3f(x2, y2), Vector3f(0.0f, 0.0f, 1.0f),
- Vector3f(x1, y2, z2), Vector3f(x1, y2), Vector3f(0.0f, 0.0f, 1.0f)
- };
-
-
- UInt16 startIndex = GetNextVertexIndex();
-
- enum
- {
- CubeVertexCount = sizeof(CubeVertices) / sizeof(CubeVertices[0]),
- CubeIndexCount = sizeof(CubeIndices) / sizeof(CubeIndices[0])
- };
-
- for(int v = 0; v < CubeVertexCount; v++)
- {
- AddVertex(Vertex(CubeVertices[v][0], c, CubeVertices[v][1].x, CubeVertices[v][1].y, CubeVertices[v][2]));
- }
-
- // Renumber indices
- for(int i = 0; i < CubeIndexCount / 3; i++)
- {
- AddTriangle(CubeIndices[i * 3] + startIndex,
- CubeIndices[i * 3 + 1] + startIndex,
- CubeIndices[i * 3 + 2] + startIndex);
- }
-}
-
-
-
-Model* Model::CreateBox(Color c, Vector3f origin, Vector3f size)
-{
- Model *box = new Model();
- Vector3f s = size * 0.5f;
-
- box->AddVertex(-s.x, s.y, -s.z, c, 0, 1, 0, 0, -1);
- box->AddVertex(s.x, s.y, -s.z, c, 1, 1, 0, 0, -1);
- box->AddVertex(s.x, -s.y, -s.z, c, 1, 0, 0, 0, -1);
- box->AddVertex(-s.x, -s.y, -s.z, c, 0, 0, 0, 0, -1);
- box->AddTriangle(2, 1, 0);
- box->AddTriangle(0, 3, 2);
-
- box->AddVertex(s.x, s.y, s.z, c, 1, 1, 0, 0, 1);
- box->AddVertex(-s.x, s.y, s.z, c, 0, 1, 0, 0, 1);
- box->AddVertex(-s.x, -s.y, s.z, c, 0, 0, 0, 0, 1);
- box->AddVertex(s.x, -s.y, s.z, c, 1, 0, 0, 0, 1);
- box->AddTriangle(6, 5, 4);
- box->AddTriangle(4, 7, 6);
-
- box->AddVertex(-s.x, s.y, -s.z, c, 1, 0, -1, 0, 0);
- box->AddVertex(-s.x, s.y, s.z, c, 1, 1, -1, 0, 0);
- box->AddVertex(-s.x, -s.y, s.z, c, 0, 1, -1, 0, 0);
- box->AddVertex(-s.x, -s.y, -s.z, c, 0, 0, -1, 0, 0);
- box->AddTriangle(10, 11, 8);
- box->AddTriangle(8, 9, 10);
-
- box->AddVertex(s.x, s.y, -s.z, c, 1, 0, 1, 0, 0);
- box->AddVertex(s.x, -s.y, -s.z, c, 0, 0, 1, 0, 0);
- box->AddVertex(s.x, -s.y, s.z, c, 0, 1, 1, 0, 0);
- box->AddVertex(s.x, s.y, s.z, c, 1, 1, 1, 0, 0);
- box->AddTriangle(14, 15, 12);
- box->AddTriangle(12, 13, 14);
-
- box->AddVertex(-s.x, -s.y, s.z, c, 0, 1, 0, -1, 0);
- box->AddVertex(s.x, -s.y, s.z, c, 1, 1, 0, -1, 0);
- box->AddVertex(s.x, -s.y, -s.z, c, 1, 0, 0, -1, 0);
- box->AddVertex(-s.x, -s.y, -s.z, c, 0, 0, 0, -1, 0);
- box->AddTriangle(18, 19, 16);
- box->AddTriangle(16, 17, 18);
-
- box->AddVertex(-s.x, s.y, -s.z, c, 0, 0, 0, 1, 0);
- box->AddVertex(s.x, s.y, -s.z, c, 1, 0, 0, 1, 0);
- box->AddVertex(s.x, s.y, s.z, c, 1, 1, 0, 1, 0);
- box->AddVertex(-s.x, s.y, s.z, c, 0, 1, 0, 1, 0);
- box->AddTriangle(20, 21, 22);
- box->AddTriangle(22, 23, 20);
-
- box->SetPosition(origin);
- return box;
-}
-
-// Triangulation of a cylinder centered at the origin
-Model* Model::CreateCylinder(Color color, Vector3f origin, float height, float radius, int sides)
-{
- Model *cyl = new Model();
- float halfht = height * 0.5f;
- for(UInt16 i = 0; i < sides; i++)
- {
- 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;
- if(i < sides - 1)
- {
- j = i + 1;
- cyl->AddTriangle(0, i * 4 + 4, i * 4);
- 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)));
- 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);
-
- cyl->AddTriangle(i * 4 + 2, j * 4 + 2, i * 4 + 3);
- cyl->AddTriangle(i * 4 + 3, j * 4 + 2, j * 4 + 3);
- }
- cyl->SetPosition(origin);
- return cyl;
-};
-
-//Triangulation of a cone centered at the origin
-Model* Model::CreateCone(Color color, Vector3f origin, float height, float radius, int sides)
-{
- Model *cone = new Model();
- 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++)
- {
- 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;
- 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));
-
- Vector3f normal = Vector3f(x, y, -halfht).Cross(Vector3f(next_x, next_y, -halfht));
-
- cone->AddVertex(0.0f, 0.0f, halfht, color, 1, 0, normal.x, normal.y, normal.z);
- cone->AddVertex(radius * x, radius * y, -1.0f*halfht, color, 0, 0, normal.x, normal.y, normal.z);
-
- cone->AddTriangle(0, 3*i + 1, 3*j + 1);
- cone->AddTriangle(3*i + 2, 3*j + 3, 3*i + 3);
- }
- cone->SetPosition(origin);
- return cone;
-};
-
-//Triangulation of a sphere centered at the origin
-Model* Model::CreateSphere(Color color, Vector3f origin, float radius, int sides)
-{
- Model *sphere = new Model();
- UInt16 usides = (UInt16) sides;
- UInt16 halfsides = usides/2;
-
- for(UInt16 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
-
- if (k == 0)
- { // add north and south poles
- sphere->AddVertex(0.0f, 0.0f, radius, color, 0, 0, 0, 0, 1);
- sphere->AddVertex(0.0f, 0.0f, -radius, color, 1, 1, 0, 0, -1);
- }
- else
- {
- for(UInt16 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;
-
- UInt16 j = 0;
- if(i < sides - 1)
- {
- j = i + 1;
- }
-
- 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;
- if (k == 1) // NorthPole
- sphere->AddTriangle(0, j + 2, i + 2);
- else if (k == halfsides - 1) //SouthPole
- {
- sphere->AddTriangle(1, indi, indj);
- sphere->AddTriangle(indi, indi - usides, indj);
- sphere->AddTriangle(indi - usides, indj - usides, indj);
- }
- else
- {
- sphere->AddTriangle(indi, indi - usides, indj);
- sphere->AddTriangle(indi - usides, indj - usides, indj);
- }
- }
- } // end else
- }
- sphere->SetPosition(origin);
- return sphere;
-};
-
-Model* Model::CreateGrid(Vector3f origin, Vector3f stepx, Vector3f stepy,
- int halfx, int halfy, int nmajor, Color minor, Color major)
-{
- Model* grid = new Model(Prim_Lines);
- float halfxf = (float)halfx;
- float halfyf = (float)halfy;
-
- for(int jn = 0; jn <= halfy; jn++)
- {
- float j = (float)jn;
-
- grid->AddLine(grid->AddVertex((stepx * -halfxf) + (stepy * j), (jn % nmajor) ? minor : major, 0, 0.5f),
- grid->AddVertex((stepx * halfxf) + (stepy * j), (jn % nmajor) ? minor : major, 1, 0.5f));
-
- if(j)
- grid->AddLine(grid->AddVertex((stepx * -halfxf) + (stepy * -j), (jn % nmajor) ? minor : major, 0, 0.5f),
- grid->AddVertex((stepx * halfxf) + (stepy * -j), (jn % nmajor) ? minor : major, 1, 0.5f));
- }
-
- for(int in = 0; in <= halfx; in++)
- {
- float i = (float)in;
-
- grid->AddLine(grid->AddVertex((stepx * i) + (stepy * -halfyf), (in % nmajor) ? minor : major, 0, 0.5f),
- grid->AddVertex((stepx * i) + (stepy * halfyf), (in % nmajor) ? minor : major, 1, 0.5f));
-
- if(i)
- grid->AddLine(grid->AddVertex((stepx * -i) + (stepy * -halfyf), (in % nmajor) ? minor : major, 0, 0.5f),
- grid->AddVertex((stepx * -i) + (stepy * halfyf), (in % nmajor) ? minor : major, 1, 0.5f));
- }
-
- grid->SetPosition(origin);
- return grid;
-}
-
-
-//-------------------------------------------------------------------------------------
-
-
-void ShaderFill::Set(PrimitiveType prim) const
-{
- Shaders->Set(prim);
- for(int i = 0; i < 8; i++)
- if(Textures[i])
- {
- Textures[i]->Set(i);
- }
-}
-
-
-
-//-------------------------------------------------------------------------------------
-// ***** Rendering
-
-
-RenderDevice::RenderDevice()
- : CurPostProcess(PostProcess_None),
- SceneColorTexW(0), SceneColorTexH(0),
- SceneRenderScale(1),
-
- Distortion(1.0f, 0.18f, 0.115f),
- DistortionClearColor(0, 0, 0),
- PostProcessShaderActive(PostProcessShader_DistortionAndChromAb),
- TotalTextureMemoryUsage(0)
-{
- PostProcessShaderRequested = PostProcessShaderActive;
-}
-
-Fill* RenderDevice::CreateTextureFill(Render::Texture* t, bool useAlpha)
-{
- ShaderSet* shaders = CreateShaderSet();
- shaders->SetShader(LoadBuiltinShader(Shader_Vertex, VShader_MVP));
- shaders->SetShader(LoadBuiltinShader(Shader_Fragment, useAlpha ? FShader_AlphaTexture : FShader_Texture));
- Fill* f = new ShaderFill(*shaders);
- f->SetTexture(0, t);
- return f;
-}
-
-void LightingParams::Set(ShaderSet* s) const
-{
- s->SetUniform4fv("Ambient", 1, &Ambient);
- s->SetUniform1f("LightCount", LightCount);
- s->SetUniform4fv("LightPos", (int)LightCount, LightPos);
- s->SetUniform4fv("LightColor", (int)LightCount, LightColor);
-}
-
-void RenderDevice::SetLighting(const LightingParams* lt)
-{
- if (!LightingBuffer)
- LightingBuffer = *CreateBuffer();
-
- LightingBuffer->Data(Buffer_Uniform, lt, sizeof(LightingParams));
- SetCommonUniformBuffer(1, LightingBuffer);
-}
-
-float RenderDevice::MeasureText(const Font* font, const char* str, float size, float* strsize)
-{
- UPInt length = strlen(str);
- float w = 0;
- float xp = 0;
- float yp = 0;
-
- for (UPInt i = 0; i < length; i++)
- {
- if(str[i] == '\n')
- {
- yp += font->lineheight;
- if(xp > w)
- {
- w = xp;
- }
- xp = 0;
- continue;
- }
-
- // Tab followed by a numbers sets position to specified offset.
- if(str[i] == '\t')
- {
- char *p = 0;
- float tabPixels = (float)OVR_strtoq(str + i + 1, &p, 10);
- i += p - (str + i + 1);
- xp = tabPixels;
- }
- else
- {
- const Font::Char* ch = &font->chars[str[i]];
- xp += ch->advance;
- }
- }
-
- if(xp > w)
- {
- w = xp;
- }
-
- if(strsize)
- {
- strsize[0] = (size / font->lineheight) * w;
- strsize[1] = (size / font->lineheight) * (yp + font->lineheight);
- }
- return (size / font->lineheight) * w;
-}
-
-void RenderDevice::RenderText(const Font* font, const char* str,
- float x, float y, float size, Color c)
-{
- if(!pTextVertexBuffer)
- {
- pTextVertexBuffer = *CreateBuffer();
- if(!pTextVertexBuffer)
- {
- return;
- }
- }
-
- if(!font->fill)
- {
- font->fill = CreateTextureFill(Ptr<Texture>(
- *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)
- {
- return;
- }
+ enum
+ {
+ // CubeVertexCount = sizeof(CubeVertices)/sizeof(CubeVertices[0]),
+ CubeIndexCount = sizeof(CubeIndices) / sizeof(CubeIndices[0])
+ };
+
+ // Renumber indices
+ for(int i = 0; i < CubeIndexCount / 3; i++)
+ {
+ box->AddTriangle(CubeIndices[i * 3] + startIndex,
+ CubeIndices[i * 3 + 1] + startIndex,
+ CubeIndices[i * 3 + 2] + startIndex);
+ }
+
+ return box;
+ }
+
+ void Model::AddSolidColorBox(float x1, float y1, float z1,
+ float x2, float y2, float z2,
+ Color c)
+ {
+ float t;
+
+ if(x1 > x2)
+ {
+ t = x1;
+ x1 = x2;
+ x2 = t;
+ }
+ if(y1 > y2)
+ {
+ t = y1;
+ y1 = y2;
+ y2 = t;
+ }
+ if(z1 > z2)
+ {
+ t = z1;
+ z1 = z2;
+ z2 = t;
+ }
+
+ // Cube vertices and their normals.
+ Vector3f CubeVertices[][3] =
+ {
+ Vector3f(x1, y2, z1), Vector3f(z1, x1), Vector3f(0.0f, 1.0f, 0.0f),
+ Vector3f(x2, y2, z1), Vector3f(z1, x2), Vector3f(0.0f, 1.0f, 0.0f),
+ Vector3f(x2, y2, z2), Vector3f(z2, x2), Vector3f(0.0f, 1.0f, 0.0f),
+ Vector3f(x1, y2, z2), Vector3f(z2, x1), Vector3f(0.0f, 1.0f, 0.0f),
+
+ Vector3f(x1, y1, z1), Vector3f(z1, x1), Vector3f(0.0f, -1.0f, 0.0f),
+ Vector3f(x2, y1, z1), Vector3f(z1, x2), Vector3f(0.0f, -1.0f, 0.0f),
+ Vector3f(x2, y1, z2), Vector3f(z2, x2), Vector3f(0.0f, -1.0f, 0.0f),
+ Vector3f(x1, y1, z2), Vector3f(z2, x1), Vector3f(0.0f, -1.0f, 0.0f),
+
+ Vector3f(x1, y1, z2), Vector3f(z2, y1), Vector3f(-1.0f, 0.0f, 0.0f),
+ Vector3f(x1, y1, z1), Vector3f(z1, y1), Vector3f(-1.0f, 0.0f, 0.0f),
+ Vector3f(x1, y2, z1), Vector3f(z1, y2), Vector3f(-1.0f, 0.0f, 0.0f),
+ Vector3f(x1, y2, z2), Vector3f(z2, y2), Vector3f(-1.0f, 0.0f, 0.0f),
+
+ Vector3f(x2, y1, z2), Vector3f(z2, y1), Vector3f(1.0f, 0.0f, 0.0f),
+ Vector3f(x2, y1, z1), Vector3f(z1, y1), Vector3f(1.0f, 0.0f, 0.0f),
+ Vector3f(x2, y2, z1), Vector3f(z1, y2), Vector3f(1.0f, 0.0f, 0.0f),
+ Vector3f(x2, y2, z2), Vector3f(z2, y2), Vector3f(1.0f, 0.0f, 0.0f),
+
+ Vector3f(x1, y1, z1), Vector3f(x1, y1), Vector3f(0.0f, 0.0f, -1.0f),
+ Vector3f(x2, y1, z1), Vector3f(x2, y1), Vector3f(0.0f, 0.0f, -1.0f),
+ Vector3f(x2, y2, z1), Vector3f(x2, y2), Vector3f(0.0f, 0.0f, -1.0f),
+ Vector3f(x1, y2, z1), Vector3f(x1, y2), Vector3f(0.0f, 0.0f, -1.0f),
+
+ Vector3f(x1, y1, z2), Vector3f(x1, y1), Vector3f(0.0f, 0.0f, 1.0f),
+ Vector3f(x2, y1, z2), Vector3f(x2, y1), Vector3f(0.0f, 0.0f, 1.0f),
+ Vector3f(x2, y2, z2), Vector3f(x2, y2), Vector3f(0.0f, 0.0f, 1.0f),
+ Vector3f(x1, y2, z2), Vector3f(x1, y2), Vector3f(0.0f, 0.0f, 1.0f)
+ };
+
+
+ UInt16 startIndex = GetNextVertexIndex();
+
+ enum
+ {
+ CubeVertexCount = sizeof(CubeVertices) / sizeof(CubeVertices[0]),
+ CubeIndexCount = sizeof(CubeIndices) / sizeof(CubeIndices[0])
+ };
+
+ for(int v = 0; v < CubeVertexCount; v++)
+ {
+ AddVertex(Vertex(CubeVertices[v][0], c, CubeVertices[v][1].x, CubeVertices[v][1].y, CubeVertices[v][2]));
+ }
+
+ // Renumber indices
+ for(int i = 0; i < CubeIndexCount / 3; i++)
+ {
+ AddTriangle(CubeIndices[i * 3] + startIndex,
+ CubeIndices[i * 3 + 1] + startIndex,
+ CubeIndices[i * 3 + 2] + startIndex);
+ }
+ }
+
+ // Adds box at specified location to current vertices.
+ void Model::AddBox(Color c, Vector3f origin, Vector3f size)
+ {
+ Vector3f s = size * 0.5f;
+ Vector3f o = origin;
+ UInt16 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);
+ AddVertex(s.x + o.x, -s.y + o.y, -s.z + o.z, c, 1, 0, 0, 0, -1);
+ AddVertex(-s.x + o.x, -s.y + o.y, -s.z + o.z, c, 0, 0, 0, 0, -1);
+ AddTriangle(2 + i, 1 + i, 0 + i);
+ AddTriangle(0 + i, 3 + i, 2 + i);
+
+ AddVertex(s.x + o.x, s.y + o.y, s.z + o.z, c, 1, 1, 0, 0, 1);
+ 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, 0, 0, 0, 0, 1);
+ AddVertex(s.x + o.x, -s.y + o.y, s.z + o.z, c, 1, 0, 0, 0, 1);
+ AddTriangle(6 + i, 5 + i, 4 + i);
+ AddTriangle(4 + i, 7 + i, 6 + i);
+
+ AddVertex(-s.x + o.x, s.y + o.y, -s.z + o.z, c, 1, 0, -1, 0, 0);
+ AddVertex(-s.x + o.x, s.y + o.y, s.z + o.z, c, 1, 1, -1, 0, 0);
+ AddVertex(-s.x + o.x, -s.y + o.y, s.z + o.z, c, 0, 1, -1, 0, 0);
+ AddVertex(-s.x + o.x, -s.y + o.y, -s.z + o.z, c, 0, 0, -1, 0, 0);
+ AddTriangle(10 + i, 11 + i, 8 + i);
+ AddTriangle(8 + i, 9 + i, 10 + i);
+
+ AddVertex(s.x + o.x, s.y + o.y, -s.z + o.z, c, 1, 0, 1, 0, 0);
+ AddVertex(s.x + o.x, -s.y + o.y, -s.z + o.z, c, 0, 0, 1, 0, 0);
+ AddVertex(s.x + o.x, -s.y + o.y, s.z + o.z, c, 0, 1, 1, 0, 0);
+ AddVertex(s.x + o.x, s.y + o.y, s.z + o.z, c, 1, 1, 1, 0, 0);
+ AddTriangle(14 + i, 15 + i, 12 + i);
+ AddTriangle(12 + i, 13 + i, 14 + i);
+
+ AddVertex(-s.x+ o.x, -s.y + o.y, s.z + o.z, c, 0, 1, 0, -1, 0);
+ AddVertex(s.x + o.x, -s.y + o.y, s.z + o.z, c, 1, 1, 0, -1, 0);
+ AddVertex(s.x + o.x, -s.y + o.y, -s.z + o.z, c, 1, 0, 0, -1, 0);
+ AddVertex(-s.x+ o.x, -s.y + o.y, -s.z + o.z, c, 0, 0, 0, -1, 0);
+ AddTriangle(18 + i, 19 + i, 16 + i);
+ AddTriangle(16 + i, 17 + i, 18 + i);
+
+ AddVertex(-s.x + o.x, s.y + o.y, -s.z + o.z, c, 0, 0, 0, 1, 0);
+ AddVertex(s.x + o.x, s.y + o.y, -s.z + o.z, c, 1, 0, 0, 1, 0);
+ AddVertex(s.x + o.x, s.y + o.y, s.z + o.z, c, 1, 1, 0, 1, 0);
+ AddVertex(-s.x + o.x, s.y + o.y, s.z + o.z, c, 0, 1, 0, 1, 0);
+ AddTriangle(20 + i, 21 + i, 22 + i);
+ AddTriangle(22 + i, 23 + i, 20 + i);
+ }
+
+
+ Model* Model::CreateBox(Color c, Vector3f origin, Vector3f size)
+ {
+ Model *box = new Model();
+ box->AddBox(c, Vector3f(0), size);
+ box->SetPosition(origin);
+ return box;
+ }
+
+ // Triangulation of a cylinder centered at the origin
+ Model* Model::CreateCylinder(Color color, Vector3f origin, float height, float radius, int sides)
+ {
+ Model *cyl = new Model();
+ float halfht = height * 0.5f;
+ for(UInt16 i = 0; i < sides; i++)
+ {
+ 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;
+ if(i < sides - 1)
+ {
+ j = i + 1;
+ cyl->AddTriangle(0, i * 4 + 4, i * 4);
+ 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)));
+ 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);
+
+ cyl->AddTriangle(i * 4 + 2, j * 4 + 2, i * 4 + 3);
+ cyl->AddTriangle(i * 4 + 3, j * 4 + 2, j * 4 + 3);
+ }
+ cyl->SetPosition(origin);
+ return cyl;
+ };
+
+ //Triangulation of a cone centered at the origin
+ Model* Model::CreateCone(Color color, Vector3f origin, float height, float radius, int sides)
+ {
+ Model *cone = new Model();
+ 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++)
+ {
+ 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;
+ 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));
+
+ Vector3f normal = Vector3f(x, y, -halfht).Cross(Vector3f(next_x, next_y, -halfht));
+
+ cone->AddVertex(0.0f, 0.0f, halfht, color, 1, 0, normal.x, normal.y, normal.z);
+ cone->AddVertex(radius * x, radius * y, -1.0f*halfht, color, 0, 0, normal.x, normal.y, normal.z);
+
+ cone->AddTriangle(0, 3*i + 1, 3*j + 1);
+ cone->AddTriangle(3*i + 2, 3*j + 3, 3*i + 3);
+ }
+ cone->SetPosition(origin);
+ return cone;
+ };
+
+ //Triangulation of a sphere centered at the origin
+ Model* Model::CreateSphere(Color color, Vector3f origin, float radius, int sides)
+ {
+ Model *sphere = new Model();
+ UInt16 usides = (UInt16) sides;
+ UInt16 halfsides = usides/2;
+
+ for(UInt16 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
+
+ if (k == 0)
+ { // add north and south poles
+ sphere->AddVertex(0.0f, 0.0f, radius, color, 0, 0, 0, 0, 1);
+ sphere->AddVertex(0.0f, 0.0f, -radius, color, 1, 1, 0, 0, -1);
+ }
+ else
+ {
+ for(UInt16 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;
- Matrix4f m = Matrix4f(size / font->lineheight, 0, 0, 0,
- 0, size / font->lineheight, 0, 0,
- 0, 0, 0, 0,
- x, y, 0, 1).Transposed();
+ UInt16 j = 0;
+ if(i < sides - 1)
+ {
+ j = i + 1;
+ }
- float xp = 0, yp = (float)font->ascent;
- int ivertex = 0;
+ sphere->AddVertex(radius * x, radius * y, radius * z, color, 0, 1, x, y, z);
- for (UPInt i = 0; i < length; i++)
- {
- if(str[i] == '\n')
- {
- yp += font->lineheight;
- xp = 0;
- continue;
- }
- // Tab followed by a numbers sets position to specified offset.
- if(str[i] == '\t')
- {
- char *p = 0;
- float tabPixels = (float)OVR_strtoq(str + i + 1, &p, 10);
- i += p - (str + i + 1);
- xp = tabPixels;
- continue;
- }
-
- const Font::Char* ch = &font->chars[str[i]];
- Vertex* chv = &vertices[ivertex];
- for(int j = 0; j < 6; j++)
- {
- chv[j].C = c;
- }
- float x = xp + ch->x;
- float y = yp - ch->y;
- float cx = font->twidth * (ch->u2 - ch->u1);
- float cy = font->theight * (ch->v2 - ch->v1);
- chv[0] = Vertex(Vector3f(x, y, 0), c, ch->u1, ch->v1);
- chv[1] = Vertex(Vector3f(x + cx, y, 0), c, ch->u2, ch->v1);
- chv[2] = Vertex(Vector3f(x + cx, cy + y, 0), c, ch->u2, ch->v2);
- chv[3] = Vertex(Vector3f(x, y, 0), c, ch->u1, ch->v1);
- chv[4] = Vertex(Vector3f(x + cx, cy + y, 0), c, ch->u2, ch->v2);
- chv[5] = Vertex(Vector3f(x, y + cy, 0), c, ch->u1, ch->v2);
- ivertex += 6;
-
- xp += ch->advance;
- }
-
- pTextVertexBuffer->Unmap(vertices);
+ UInt16 indi = 2 + (k -1)*usides + i;
+ UInt16 indj = 2 + (k -1)*usides + j;
+ if (k == 1) // NorthPole
+ sphere->AddTriangle(0, j + 2, i + 2);
+ else if (k == halfsides - 1) //SouthPole
+ {
+ sphere->AddTriangle(1, indi, indj);
+ sphere->AddTriangle(indi, indi - usides, indj);
+ sphere->AddTriangle(indi - usides, indj - usides, indj);
+ }
+ else
+ {
+ sphere->AddTriangle(indi, indi - usides, indj);
+ sphere->AddTriangle(indi - usides, indj - usides, indj);
+ }
+ }
+ } // end else
+ }
+ sphere->SetPosition(origin);
+ return sphere;
+ };
- Render(font->fill, pTextVertexBuffer, NULL, m, 0, ivertex, Prim_Triangles);
-}
+ Model* Model::CreateGrid(Vector3f origin, Vector3f stepx, Vector3f stepy,
+ int halfx, int halfy, int nmajor, Color minor, Color major)
+ {
+ Model* grid = new Model(Prim_Lines);
+ float halfxf = (float)halfx;
+ float halfyf = (float)halfy;
-void RenderDevice::FillRect(float left, float top, float right, float bottom, Color c)
-{
- if(!pTextVertexBuffer)
- {
- pTextVertexBuffer = *CreateBuffer();
- if(!pTextVertexBuffer)
- {
- return;
- }
- }
+ for(int jn = 0; jn <= halfy; jn++)
+ {
+ float j = (float)jn;
- // Get!!
- Fill* fill = CreateSimpleFill();
+ grid->AddLine(grid->AddVertex((stepx * -halfxf) + (stepy * j), (jn % nmajor) ? minor : major, 0, 0.5f),
+ grid->AddVertex((stepx * halfxf) + (stepy * j), (jn % nmajor) ? minor : major, 1, 0.5f));
- pTextVertexBuffer->Data(Buffer_Vertex, NULL, 6 * sizeof(Vertex));
- Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, 6 * sizeof(Vertex), Map_Discard);
- if(!vertices)
- {
- return;
- }
+ if(j)
+ grid->AddLine(grid->AddVertex((stepx * -halfxf) + (stepy * -j), (jn % nmajor) ? minor : major, 0, 0.5f),
+ grid->AddVertex((stepx * halfxf) + (stepy * -j), (jn % nmajor) ? minor : major, 1, 0.5f));
+ }
- vertices[0] = Vertex(Vector3f(left, top, 0.0f), c);
- vertices[1] = Vertex(Vector3f(right, top, 0), c);
- vertices[2] = Vertex(Vector3f(left, bottom, 0), c);
- vertices[3] = Vertex(Vector3f(left, bottom, 0), c);
- vertices[4] = Vertex(Vector3f(right, top, 0), c);
- vertices[5] = Vertex(Vector3f(right, bottom, 0), c);
+ for(int in = 0; in <= halfx; in++)
+ {
+ float i = (float)in;
- pTextVertexBuffer->Unmap(vertices);
+ grid->AddLine(grid->AddVertex((stepx * i) + (stepy * -halfyf), (in % nmajor) ? minor : major, 0, 0.5f),
+ grid->AddVertex((stepx * i) + (stepy * halfyf), (in % nmajor) ? minor : major, 1, 0.5f));
- Render(fill, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles);
-}
+ if(i)
+ grid->AddLine(grid->AddVertex((stepx * -i) + (stepy * -halfyf), (in % nmajor) ? minor : major, 0, 0.5f),
+ grid->AddVertex((stepx * -i) + (stepy * halfyf), (in % nmajor) ? minor : major, 1, 0.5f));
+ }
-void RenderDevice::FillGradientRect(float left, float top, float right, float bottom, Color col_top, Color col_btm)
-{
- if(!pTextVertexBuffer)
- {
- pTextVertexBuffer = *CreateBuffer();
- if(!pTextVertexBuffer)
- {
- return;
- }
- }
+ grid->SetPosition(origin);
+ return grid;
+ }
- // Get!!
- Fill* fill = CreateSimpleFill();
- pTextVertexBuffer->Data(Buffer_Vertex, NULL, 6 * sizeof(Vertex));
- Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, 6 * sizeof(Vertex), Map_Discard);
- if(!vertices)
- {
- return;
- }
+ //-------------------------------------------------------------------------------------
- vertices[0] = Vertex(Vector3f(left, top, 0.0f), col_top);
- vertices[1] = Vertex(Vector3f(right, top, 0), col_top);
- vertices[2] = Vertex(Vector3f(left, bottom, 0), col_btm);
- vertices[3] = Vertex(Vector3f(left, bottom, 0), col_btm);
- vertices[4] = Vertex(Vector3f(right, top, 0), col_top);
- vertices[5] = Vertex(Vector3f(right, bottom, 0), col_btm);
-
- pTextVertexBuffer->Unmap(vertices);
-
- Render(fill, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles);
-}
-
-void RenderDevice::RenderImage(float left,
- float top,
- float right,
- float bottom,
- ShaderFill* image,
- unsigned char alpha)
-{
- /*
- if(!pTextVertexBuffer)
- {
- pTextVertexBuffer = *CreateBuffer();
- if(!pTextVertexBuffer)
- {
- return;
- }
- }
- pTextVertexBuffer->Data(Buffer_Vertex, NULL, 6 * sizeof(Vertex));
- Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, 6 * sizeof(Vertex), Map_Discard);
- if(!vertices)
- {
- return;
- }
+ void ShaderFill::Set(PrimitiveType prim) const
+ {
+ Shaders->Set(prim);
- vertices[0] = Vertex(Vector3f(left, top, 0.0f), Color(255, 255, 255, 255));
- vertices[1] = Vertex(Vector3f(right, top, 0), Color(255, 255, 255, 255));
- vertices[2] = Vertex(Vector3f(left, bottom, 0), Color(255, 255, 255, 255));
- vertices[3] = Vertex(Vector3f(left, bottom, 0), Color(255, 255, 255, 255));
- vertices[4] = Vertex(Vector3f(right, top, 0), Color(255, 255, 255, 255));
- vertices[5] = Vertex(Vector3f(right, bottom, 0), Color(255, 255, 255, 255));
-
- pTextVertexBuffer->Unmap(vertices);
-
- Render(image, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles);
- */
-
- Color c = Color(255, 255, 255, alpha);
- Ptr<Model> m = *new Model(Prim_Triangles);
- m->AddVertex(left, bottom, 0.0f, c, 0.0f, 0.0f);
- m->AddVertex(right, bottom, 0.0f, c, 1.0f, 0.0f);
- m->AddVertex(right, top, 0.0f, c, 1.0f, 1.0f);
- m->AddVertex(left, top, 0.0f, c, 0.0f, 1.0f);
- m->AddTriangle(2,1,0);
- m->AddTriangle(0,3,2);
- m->Fill = image;
-
- Render(Matrix4f(), m);
-}
-
-/*
-void RenderDevice::GetStereoViewports(const Viewport& in, Viewport* out) const
-{
- out[0] = out[1] = in;
- if (StereoBufferMode == Stereo_SplitH)
- {
- out[0].w = out[1].w = in.w / 2;
- out[1].x += WindowWidth / 2;
- }
-}
-*/
+ for(int i = 0; i < 8 && VtxTextures[i] != NULL; ++i)
+ VtxTextures[i]->Set(i, Shader_Vertex);
-void RenderDevice::SetSceneRenderScale(float ss)
-{
- SceneRenderScale = ss;
- pSceneColorTex = NULL;
-}
+ for (int i = 0; i < 8 && Textures[i] != NULL; ++i)
+ Textures[i]->Set(i);
+ }
-void RenderDevice::SetViewport(const Viewport& vp)
-{
- VP = vp;
- if(CurPostProcess == PostProcess_Distortion)
- {
- Viewport svp = vp;
- svp.w = (int)ceil(SceneRenderScale * vp.w);
- svp.h = (int)ceil(SceneRenderScale * vp.h);
- svp.x = (int)ceil(SceneRenderScale * vp.x);
- svp.y = (int)ceil(SceneRenderScale * vp.y);
- SetRealViewport(svp);
- }
- else
- {
- SetRealViewport(vp);
- }
-}
+ //-------------------------------------------------------------------------------------
+ // ***** Rendering
-bool RenderDevice::initPostProcessSupport(PostProcessType pptype)
-{
- if(pptype != PostProcess_Distortion)
- {
- return true;
- }
+ RenderDevice::RenderDevice()
+ : DistortionClearColor(0, 0, 0),
+ TotalTextureMemoryUsage(0),
+ FadeOutBorderFraction(0)
+ {
+ // Ensure these are different, so that the first time it's run, things actually get initialized.
+ PostProcessShaderActive = PostProcessShader_Count;
+ PostProcessShaderRequested = PostProcessShader_DistortionAndChromAb;
+ }
- if (PostProcessShaderRequested != PostProcessShaderActive)
+ void RenderDevice::Shutdown()
{
+ // This runs before the subclass's Shutdown(), where the context, etc, may be deleted.
+ pTextVertexBuffer.Clear();
pPostProcessShader.Clear();
- PostProcessShaderActive = PostProcessShaderRequested;
- }
-
- if (!pPostProcessShader)
- {
- Shader *vs = LoadBuiltinShader(Shader_Vertex, VShader_PostProcess);
-
- Shader *ppfs = NULL;
-
- if (PostProcessShaderActive == PostProcessShader_Distortion)
- {
- ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcess);
- }
- else if (PostProcessShaderActive == PostProcessShader_DistortionAndChromAb)
- {
- ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcessWithChromAb);
- }
- else
- OVR_ASSERT(false);
-
- pPostProcessShader = *CreateShaderSet();
- pPostProcessShader->SetShader(vs);
- pPostProcessShader->SetShader(ppfs);
- }
-
-
- int texw = (int)ceil(SceneRenderScale * WindowWidth),
- texh = (int)ceil(SceneRenderScale * WindowHeight);
-
- // If pSceneColorTex is already created and is of correct size, we are done.
- // It's important to check width/height in case window size changed.
- if (pSceneColorTex && (texw == SceneColorTexW) && (texh == SceneColorTexH))
- {
- return true;
- }
-
- pSceneColorTex = *CreateTexture(Texture_RGBA | Texture_RenderTarget | Params.Multisample,
- texw, texh, NULL);
- if(!pSceneColorTex)
- {
- return false;
- }
- SceneColorTexW = texw;
- SceneColorTexH = texh;
- pSceneColorTex->SetSampleMode(Sample_ClampBorder | Sample_Linear);
-
-
- if(!pFullScreenVertexBuffer)
- {
- pFullScreenVertexBuffer = *CreateBuffer();
- const Render::Vertex QuadVertices[] =
- {
- Vertex(Vector3f(0, 1, 0), Color(1, 1, 1, 1), 0, 0),
- Vertex(Vector3f(1, 1, 0), Color(1, 1, 1, 1), 1, 0),
- Vertex(Vector3f(0, 0, 0), Color(1, 1, 1, 1), 0, 1),
- Vertex(Vector3f(1, 0, 0), Color(1, 1, 1, 1), 1, 1)
- };
- pFullScreenVertexBuffer->Data(Buffer_Vertex, QuadVertices, sizeof(QuadVertices));
+ pFullScreenVertexBuffer.Clear();
+ pDistortionMeshVertexBuffer[0].Clear();
+ pDistortionMeshVertexBuffer[1].Clear();
+ pDistortionMeshIndexBuffer[0].Clear();
+ pDistortionMeshIndexBuffer[1].Clear();
+ LightingBuffer.Clear();
}
- return true;
-}
-
-void RenderDevice::SetProjection(const Matrix4f& proj)
-{
- Proj = proj;
- SetWorldUniforms(proj);
-}
-
-void RenderDevice::BeginScene(PostProcessType pptype)
-{
- BeginRendering();
-
- if((pptype != PostProcess_None) && initPostProcessSupport(pptype))
- {
- CurPostProcess = pptype;
- }
- else
- {
- CurPostProcess = PostProcess_None;
- }
-
- if(CurPostProcess == PostProcess_Distortion)
- {
- SetRenderTarget(pSceneColorTex);
- SetViewport(VP);
- }
- else
- {
- SetRenderTarget(0);
- }
-
- SetWorldUniforms(Proj);
- SetExtraShaders(NULL);
-}
-
-void RenderDevice::FinishScene()
-{
- SetExtraShaders(0);
- if(CurPostProcess == PostProcess_None)
- {
- return;
- }
-
- SetRenderTarget(0);
- SetRealViewport(VP);
- FinishScene1();
-
- CurPostProcess = PostProcess_None;
-}
-
+ Fill* RenderDevice::CreateTextureFill(Render::Texture* t, bool useAlpha)
+ {
+ ShaderSet* shaders = CreateShaderSet();
+ shaders->SetShader(LoadBuiltinShader(Shader_Vertex, VShader_MVP));
+ shaders->SetShader(LoadBuiltinShader(Shader_Fragment, useAlpha ? FShader_AlphaTexture : FShader_Texture));
+ Fill* f = new ShaderFill(*shaders);
+ f->SetTexture(0, t);
+ return f;
+ }
+
+ void LightingParams::Set(ShaderSet* s) const
+ {
+ s->SetUniform4fvArray("Ambient", 1, &Ambient);
+ s->SetUniform1f("LightCount", LightCount);
+ s->SetUniform4fvArray("LightPos", (int)LightCount, LightPos);
+ s->SetUniform4fvArray("LightColor", (int)LightCount, LightColor);
+ }
+
+ void RenderDevice::SetLighting(const LightingParams* lt)
+ {
+ if (!LightingBuffer)
+ LightingBuffer = *CreateBuffer();
+
+ LightingBuffer->Data(Buffer_Uniform, lt, sizeof(LightingParams));
+ SetCommonUniformBuffer(1, LightingBuffer);
+ }
+
+ float RenderDevice::MeasureText(const Font* font, const char* str, float size, float strsize[2],
+ const UPInt charRange[2], Vector2f charRangeRect[2])
+ {
+ UPInt length = strlen(str);
+ float w = 0;
+ float xp = 0;
+ float yp = 0;
+
+ for (UPInt i = 0; i < length; i++)
+ {
+ if (str[i] == '\n')
+ {
+ yp += font->lineheight;
+ if(xp > w)
+ {
+ w = xp;
+ }
+ xp = 0;
+ continue;
+ }
+
+ // Record top-left charRange rectangle coordinate.
+ if (charRange && charRangeRect && (i == charRange[0]))
+ charRangeRect[0] = Vector2f(xp, yp);
+
+ // Tab followed by a numbers sets position to specified offset.
+ if (str[i] == '\t')
+ {
+ char *p = 0;
+ float tabPixels = (float)OVR_strtoq(str + i + 1, &p, 10);
+ i += p - (str + i + 1);
+ xp = tabPixels;
+ }
+ else
+ {
+ const Font::Char* ch = &font->chars[str[i]];
+ xp += ch->advance;
+ }
+
+ // End of character range.
+ // Store 'xp' after advance, yp will advance later.
+ if (charRange && charRangeRect && (i == charRange[1]))
+ charRangeRect[1] = Vector2f(xp, yp);
+ }
+
+ if (xp > w)
+ {
+ w = xp;
+ }
+
+ float scale = (size / font->lineheight);
+
+ if (strsize)
+ {
+ strsize[0] = scale * w;
+ strsize[1] = scale * (yp + font->lineheight);
+ }
+
+ if (charRange && charRangeRect)
+ {
+ // Selection rectangle ends in teh bottom.
+ charRangeRect[1].y += font->lineheight;
+ charRangeRect[0] *= scale;
+ charRangeRect[1] *= scale;
+ }
+
+ return (size / font->lineheight) * w;
+ }
+
+
+
+
+
+ void RenderDevice::RenderText(const Font* font, const char* str,
+ float x, float y, float size, Color c)
+ {
+ if(!pTextVertexBuffer)
+ {
+ pTextVertexBuffer = *CreateBuffer();
+ if(!pTextVertexBuffer)
+ {
+ return;
+ }
+ }
+
+ if(!font->fill)
+ {
+ font->fill = CreateTextureFill(Ptr<Texture>(
+ *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)
+ {
+ return;
+ }
+
+ Matrix4f m = Matrix4f(size / font->lineheight, 0, 0, 0,
+ 0, size / font->lineheight, 0, 0,
+ 0, 0, 0, 0,
+ x, y, 0, 1).Transposed();
+
+ float xp = 0, yp = (float)font->ascent;
+ int ivertex = 0;
+
+ for (UPInt i = 0; i < length; i++)
+ {
+ if(str[i] == '\n')
+ {
+ yp += font->lineheight;
+ xp = 0;
+ continue;
+ }
+ // Tab followed by a numbers sets position to specified offset.
+ if(str[i] == '\t')
+ {
+ char *p = 0;
+ float tabPixels = (float)OVR_strtoq(str + i + 1, &p, 10);
+ i += p - (str + i + 1);
+ xp = tabPixels;
+ continue;
+ }
+
+ const Font::Char* ch = &font->chars[str[i]];
+ Vertex* chv = &vertices[ivertex];
+ for(int j = 0; j < 6; j++)
+ {
+ chv[j].C = c;
+ }
+ float x = xp + ch->x;
+ float y = yp - ch->y;
+ float cx = font->twidth * (ch->u2 - ch->u1);
+ float cy = font->theight * (ch->v2 - ch->v1);
+ chv[0] = Vertex(Vector3f(x, y, 0), c, ch->u1, ch->v1);
+ chv[1] = Vertex(Vector3f(x + cx, y, 0), c, ch->u2, ch->v1);
+ chv[2] = Vertex(Vector3f(x + cx, cy + y, 0), c, ch->u2, ch->v2);
+ chv[3] = Vertex(Vector3f(x, y, 0), c, ch->u1, ch->v1);
+ chv[4] = Vertex(Vector3f(x + cx, cy + y, 0), c, ch->u2, ch->v2);
+ chv[5] = Vertex(Vector3f(x, y + cy, 0), c, ch->u1, ch->v2);
+ ivertex += 6;
+
+ xp += ch->advance;
+ }
+
+ pTextVertexBuffer->Unmap(vertices);
+
+ Render(font->fill, pTextVertexBuffer, NULL, m, 0, ivertex, Prim_Triangles);
+ }
+
+ void RenderDevice::FillRect(float left, float top, float right, float bottom, Color c)
+ {
+ if(!pTextVertexBuffer)
+ {
+ pTextVertexBuffer = *CreateBuffer();
+ if(!pTextVertexBuffer)
+ {
+ return;
+ }
+ }
+
+ // Get!!
+ Fill* fill = CreateSimpleFill();
+
+ pTextVertexBuffer->Data(Buffer_Vertex, NULL, 6 * sizeof(Vertex));
+ Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, 6 * sizeof(Vertex), Map_Discard);
+ if(!vertices)
+ {
+ return;
+ }
+
+ vertices[0] = Vertex(Vector3f(left, top, 0.0f), c);
+ vertices[1] = Vertex(Vector3f(right, top, 0.0f), c);
+ vertices[2] = Vertex(Vector3f(left, bottom, 0.0f), c);
+ vertices[3] = Vertex(Vector3f(left, bottom, 0.0f), c);
+ vertices[4] = Vertex(Vector3f(right, top, 0.0f), c);
+ vertices[5] = Vertex(Vector3f(right, bottom, 0.0f), c);
+
+ pTextVertexBuffer->Unmap(vertices);
+
+ Render(fill, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles);
+ }
+
+
+
+ void RenderDevice::FillGradientRect(float left, float top, float right, float bottom, Color col_top, Color col_btm)
+ {
+ if(!pTextVertexBuffer)
+ {
+ pTextVertexBuffer = *CreateBuffer();
+ if(!pTextVertexBuffer)
+ {
+ return;
+ }
+ }
+
+ // Get!!
+ Fill* fill = CreateSimpleFill();
+
+ pTextVertexBuffer->Data(Buffer_Vertex, NULL, 6 * sizeof(Vertex));
+ Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, 6 * sizeof(Vertex), Map_Discard);
+ if(!vertices)
+ {
+ return;
+ }
+
+ vertices[0] = Vertex(Vector3f(left, top, 0.0f), col_top);
+ vertices[1] = Vertex(Vector3f(right, top, 0.0f), col_top);
+ vertices[2] = Vertex(Vector3f(left, bottom, 0.0f), col_btm);
+ vertices[3] = Vertex(Vector3f(left, bottom, 0.0f), col_btm);
+ vertices[4] = Vertex(Vector3f(right, top, 0.0f), col_top);
+ vertices[5] = Vertex(Vector3f(right, bottom, 0.0f), col_btm);
+
+ pTextVertexBuffer->Unmap(vertices);
+
+ Render(fill, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles);
+ }
+
+
+ void RenderDevice::FillTexturedRect(float left, float top, float right, float bottom, float ul, float vt, float ur, float vb, Color c, Ptr<Texture> tex)
+ {
+ if(!pTextVertexBuffer)
+ {
+ pTextVertexBuffer = *CreateBuffer();
+ if(!pTextVertexBuffer)
+ {
+ return;
+ }
+ }
+
+ static Fill *fill = NULL;
+ if ( fill == NULL )
+ {
+ fill = CreateTextureFill(tex, false);
+ }
+ fill->SetTexture ( 0, tex );
+
+ pTextVertexBuffer->Data(Buffer_Vertex, NULL, 6 * sizeof(Vertex));
+ Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, 6 * sizeof(Vertex), Map_Discard);
+ if(!vertices)
+ {
+ return;
+ }
+
+ vertices[0] = Vertex(Vector3f(left, top, 0.0f), c, ul, vt);
+ vertices[1] = Vertex(Vector3f(right, top, 0.0f), c, ur, vt);
+ vertices[2] = Vertex(Vector3f(left, bottom, 0.0f), c, ul, vb);
+ vertices[3] = Vertex(Vector3f(left, bottom, 0.0f), c, ul, vb);
+ vertices[4] = Vertex(Vector3f(right, top, 0.0f), c, ur, vt);
+ vertices[5] = Vertex(Vector3f(right, bottom, 0.0f), c, ur, vb);
+
+ pTextVertexBuffer->Unmap(vertices);
+
+ Render(fill, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles);
+ }
+
+
+ void RenderDevice::RenderLines ( int NumLines, Color c, float *x, float *y, float *z /*= NULL*/ )
+ {
+ OVR_ASSERT ( x != NULL );
+ OVR_ASSERT ( y != NULL );
+ // z can be NULL for 2D stuff.
+
+ if(!pTextVertexBuffer)
+ {
+ pTextVertexBuffer = *CreateBuffer();
+ if(!pTextVertexBuffer)
+ {
+ return;
+ }
+ }
+
+ // Get!!
+ Fill* fill = CreateSimpleFill();
+
+ int NumVerts = NumLines * 2;
+
+ pTextVertexBuffer->Data(Buffer_Vertex, NULL, NumVerts * sizeof(Vertex));
+ Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, NumVerts * sizeof(Vertex), Map_Discard);
+ if(!vertices)
+ {
+ return;
+ }
+
+ if ( z != NULL )
+ {
+ for ( int VertNum = 0; VertNum < NumVerts; VertNum++ )
+ {
+ vertices[VertNum] = Vertex(Vector3f(x[VertNum], y[VertNum], z[VertNum]), c);
+ }
+ }
+ else
+ {
+ for ( int VertNum = 0; VertNum < NumVerts; VertNum++ )
+ {
+ vertices[VertNum] = Vertex(Vector3f(x[VertNum], y[VertNum], 1.0f), c);
+ }
+ }
+
+ pTextVertexBuffer->Unmap(vertices);
+
+ Render(fill, pTextVertexBuffer, NULL, Matrix4f(), 0, NumVerts, Prim_Lines);
+ }
+
+
+
+ void RenderDevice::RenderImage(float left,
+ float top,
+ float right,
+ float bottom,
+ ShaderFill* image,
+ unsigned char alpha)
+ {
+ Color c = Color(255, 255, 255, alpha);
+ Ptr<Model> m = *new Model(Prim_Triangles);
+ m->AddVertex(left, bottom, 0.0f, c, 0.0f, 0.0f);
+ m->AddVertex(right, bottom, 0.0f, c, 1.0f, 0.0f);
+ m->AddVertex(right, top, 0.0f, c, 1.0f, 1.0f);
+ m->AddVertex(left, top, 0.0f, c, 0.0f, 1.0f);
+ m->AddTriangle(2,1,0);
+ m->AddTriangle(0,3,2);
+ m->Fill = image;
+
+ Render(Matrix4f(), m);
+ }
+
+ bool RenderDevice::initPostProcessSupport(PostProcessType pptype)
+ {
+ if(pptype == PostProcess_None)
+ {
+ return true;
+ }
+
+
+ if (PostProcessShaderRequested != PostProcessShaderActive)
+ {
+ pPostProcessShader.Clear();
+ PostProcessShaderActive = PostProcessShaderRequested;
+ }
+
+ if (!pPostProcessShader)
+ {
+ Shader *vs = NULL;
+ Shader *ppfs = NULL;
+
+ if (PostProcessShaderActive == PostProcessShader_DistortionAndChromAb)
+ {
+ ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcessWithChromAb);
+ vs = LoadBuiltinShader(Shader_Vertex, VShader_PostProcess);
+ }
+ else if (PostProcessShaderActive == PostProcessShader_MeshDistortionAndChromAb)
+ {
+ ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcessMeshWithChromAb);
+ vs = LoadBuiltinShader(Shader_Vertex, VShader_PostProcessMesh);
+ }
+ else if (PostProcessShaderActive == PostProcessShader_MeshDistortionAndChromAbTimewarp)
+ {
+ ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcessMeshWithChromAbTimewarp);
+ vs = LoadBuiltinShader(Shader_Vertex, VShader_PostProcessMeshTimewarp);
+ }
+ else if (PostProcessShaderActive == PostProcessShader_MeshDistortionAndChromAbPositionalTimewarp)
+ {
+ ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcessMeshWithChromAbPositionalTimewarp);
+ vs = LoadBuiltinShader(Shader_Vertex, VShader_PostProcessMeshPositionalTimewarp);
+ }
+ else
+ {
+ OVR_ASSERT(false);
+ }
+ OVR_ASSERT(ppfs); // Means the shader failed to compile - look in the debug spew.
+ OVR_ASSERT(vs);
+
+ pPostProcessShader = *CreateShaderSet();
+ pPostProcessShader->SetShader(vs);
+ pPostProcessShader->SetShader(ppfs);
+ }
+
+
+ if(!pFullScreenVertexBuffer)
+ {
+ pFullScreenVertexBuffer = *CreateBuffer();
+ const Render::Vertex QuadVertices[] =
+ {
+ Vertex(Vector3f(0, 1, 0), Color(1, 1, 1, 1), 0, 0),
+ Vertex(Vector3f(1, 1, 0), Color(1, 1, 1, 1), 1, 0),
+ Vertex(Vector3f(0, 0, 0), Color(1, 1, 1, 1), 0, 1),
+ Vertex(Vector3f(1, 0, 0), Color(1, 1, 1, 1), 1, 1)
+ };
+ pFullScreenVertexBuffer->Data(Buffer_Vertex, QuadVertices, sizeof(QuadVertices));
+ }
+ return true;
+ }
+
+ void RenderDevice::SetProjection(const Matrix4f& proj)
+ {
+ Proj = proj;
+ SetWorldUniforms(proj);
+ }
+
+ void RenderDevice::BeginScene(PostProcessType pptype)
+ {
+ BeginRendering();
+ initPostProcessSupport(pptype);
+ SetViewport(VP);
+ SetWorldUniforms(Proj);
+ SetExtraShaders(NULL);
+ }
+
+ void RenderDevice::FinishScene()
+ {
+ SetExtraShaders(0);
+ SetRenderTarget(0);
+ }
+
+
+
+ void RenderDevice::PrecalculatePostProcess(PostProcessType pptype,
+ const StereoEyeParams &stereoParamsLeft, const StereoEyeParams &stereoParamsRight,
+ const HmdRenderInfo &hmdRenderInfo )
+ {
+ PostProcessingType = pptype;
+
+ if ( ( pptype == PostProcess_MeshDistortion ) ||
+ ( pptype == PostProcess_MeshDistortionTimewarp ) ||
+ ( pptype == PostProcess_MeshDistortionPositionalTimewarp ) )
+ {
+ for ( int eyeNum = 0; eyeNum < 2; eyeNum++ )
+ {
+ const StereoEyeParams &stereoParams = ( eyeNum == 0 ) ? stereoParamsLeft : stereoParamsRight;
+
+ // Get the mesh data.
+ int numVerts = 0;
+ int numTris = 0;
+ DistortionMeshVertexData *pRawVerts = NULL;
+ UInt16 *pIndices = NULL;
+ DistortionMeshCreate ( &pRawVerts, &pIndices, &numVerts, &numTris, stereoParams, hmdRenderInfo );
+ int numIndices = numTris * 3;
+
+ // Convert to final vertex data.
+ DistortionVertex *pVerts = (DistortionVertex*)OVR_ALLOC ( sizeof(DistortionVertex) * numVerts );
+ DistortionVertex *pCurVert = pVerts;
+ DistortionMeshVertexData *pCurRawVert = pRawVerts;
+ for ( int vertNum = 0; vertNum < numVerts; vertNum++ )
+ {
+ pCurVert->Pos.x = pCurRawVert->ScreenPosNDC.x;
+ pCurVert->Pos.y = pCurRawVert->ScreenPosNDC.y;
+ pCurVert->TexR = pCurRawVert->TanEyeAnglesR;
+ 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.G = pCurVert->Col.R;
+ pCurVert->Col.B = pCurVert->Col.R;
+ pCurVert->Col.A = (OVR::UByte)( floorf ( pCurRawVert->TimewarpLerp * 255.999f ) );
+ pCurRawVert++;
+ pCurVert++;
+ }
-void RenderDevice::FinishScene1()
-{
- float r, g, b, a;
- DistortionClearColor.GetRGBA(&r, &g, &b, &a);
- Clear(r, g, b, a);
-
- float w = float(VP.w) / float(WindowWidth),
- h = float(VP.h) / float(WindowHeight),
- x = float(VP.x) / float(WindowWidth),
- y = float(VP.y) / float(WindowHeight);
-
- float as = float(VP.w) / float(VP.h);
-
- // We are using 1/4 of DistortionCenter offset value here, since it is
- // relative to [-1,1] range that gets mapped to [0, 0.5].
- pPostProcessShader->SetUniform2f("LensCenter",
- x + (w + Distortion.XCenterOffset * 0.5f)*0.5f, y + h*0.5f);
- pPostProcessShader->SetUniform2f("ScreenCenter", x + w*0.5f, y + h*0.5f);
-
- // MA: This is more correct but we would need higher-res texture vertically; we should adopt this
- // once we have asymmetric input texture scale.
- float scaleFactor = 1.0f / Distortion.Scale;
-
- pPostProcessShader->SetUniform2f("Scale", (w/2) * scaleFactor, (h/2) * scaleFactor * as);
- pPostProcessShader->SetUniform2f("ScaleIn", (2/w), (2/h) / as);
-
- pPostProcessShader->SetUniform4f("HmdWarpParam",
- Distortion.K[0], Distortion.K[1], Distortion.K[2], Distortion.K[3]);
-
- if (PostProcessShaderRequested == PostProcessShader_DistortionAndChromAb)
- {
- pPostProcessShader->SetUniform4f("ChromAbParam",
- Distortion.ChromaticAberration[0],
- Distortion.ChromaticAberration[1],
- Distortion.ChromaticAberration[2],
- Distortion.ChromaticAberration[3]);
- }
+ DistortionMeshNumTris[eyeNum] = numTris;
+ pDistortionMeshVertexBuffer[eyeNum] = *CreateBuffer();
+ pDistortionMeshVertexBuffer[eyeNum]->Data ( Buffer_Vertex, pVerts, sizeof(DistortionVertex) * numVerts );
+ pDistortionMeshIndexBuffer[eyeNum] = *CreateBuffer();
+ pDistortionMeshIndexBuffer[eyeNum]->Data ( Buffer_Index, pIndices, ( sizeof(UInt16) * numIndices ) );
+
+ DistortionMeshDestroy ( pRawVerts, pIndices );
+ OVR_FREE ( pVerts );
+ }
+ }
+ else
+ {
+ // ...no setup needed for other distortion types.
+ }
+ }
+
+
+ void RenderDevice::ApplyPostProcess(Matrix4f const &matNowFromWorldStart, Matrix4f const &matNowFromWorldEnd,
+ Matrix4f const &matRenderFromWorldLeft, Matrix4f const &matRenderFromWorldRight,
+ StereoEyeParams const &stereoParamsLeft, StereoEyeParams const &stereoParamsRight,
+ Ptr<Texture> pSourceTextureLeftOrOnly,
+ Ptr<Texture> pSourceTextureRight,
+ Ptr<Texture> pSourceTextureLeftOrOnlyDepth,
+ Ptr<Texture> pSourceTextureRightDepth)
+ {
+ SetExtraShaders(0);
+
+ if ( PostProcessingType == PostProcess_MeshDistortion )
+ {
+ Recti vp ( 0, 0, WindowWidth, WindowHeight );
+ SetViewport(vp);
+ float r, g, b, a;
+ DistortionClearColor.GetRGBA(&r, &g, &b, &a);
+ Clear(r, g, b, a);
+
+ Matrix4f dummy;
+ ShaderFill fill(pPostProcessShader);
+
+ fill.SetTexture ( 0, pSourceTextureLeftOrOnly );
+ pPostProcessShader->SetUniform2f("EyeToSourceUVScale", stereoParamsLeft.EyeToSourceUV.Scale.x, stereoParamsLeft.EyeToSourceUV.Scale.y );
+ pPostProcessShader->SetUniform2f("EyeToSourceUVOffset", stereoParamsLeft.EyeToSourceUV.Offset.x, stereoParamsLeft.EyeToSourceUV.Offset.y );
+ Render(&fill, pDistortionMeshVertexBuffer[0], pDistortionMeshIndexBuffer[0], dummy, 0, DistortionMeshNumTris[0] * 3, Prim_Triangles, true);
+
+ if ( pSourceTextureRight != NULL )
+ {
+ fill.SetTexture ( 0, pSourceTextureRight );
+ }
+ pPostProcessShader->SetUniform2f("EyeToSourceUVScale", stereoParamsRight.EyeToSourceUV.Scale.x, stereoParamsRight.EyeToSourceUV.Scale.y );
+ pPostProcessShader->SetUniform2f("EyeToSourceUVOffset", stereoParamsRight.EyeToSourceUV.Offset.x, stereoParamsRight.EyeToSourceUV.Offset.y );
+ Render(&fill, pDistortionMeshVertexBuffer[1], pDistortionMeshIndexBuffer[1], dummy, 0, DistortionMeshNumTris[1] * 3, Prim_Triangles, true);
+ }
+ else if ( PostProcessingType == PostProcess_MeshDistortionTimewarp )
+ {
+ Recti vp ( 0, 0, WindowWidth, WindowHeight );
+ SetViewport(vp);
+ float r, g, b, a;
+ DistortionClearColor.GetRGBA(&r, &g, &b, &a);
+ Clear(r, g, b, a);
+
+ ShaderFill fill(pPostProcessShader);
+ fill.SetTexture ( 0, pSourceTextureLeftOrOnly );
+
+ for ( int eyeNum = 0; eyeNum < 2; eyeNum++ )
+ {
+ Matrix4f const &matRenderFromWorld = ( eyeNum == 0 ) ? matRenderFromWorldLeft : matRenderFromWorldRight;
+ const StereoEyeParams &stereoParams = ( eyeNum == 0 ) ? stereoParamsLeft : stereoParamsRight;
+
+ Matrix4f matRenderFromNowStart = TimewarpComputePoseDelta ( matRenderFromWorld, matNowFromWorldStart );
+ Matrix4f matRenderFromNowEnd = TimewarpComputePoseDelta ( matRenderFromWorld, matNowFromWorldEnd );
+
+ pPostProcessShader->SetUniform2f("EyeToSourceUVScale", stereoParams.EyeToSourceUV.Scale.x, stereoParams.EyeToSourceUV.Scale.y );
+ pPostProcessShader->SetUniform2f("EyeToSourceUVOffset", stereoParams.EyeToSourceUV.Offset.x, stereoParams.EyeToSourceUV.Offset.y );
+ pPostProcessShader->SetUniform3x3f("EyeRotationStart", matRenderFromNowStart);
+ pPostProcessShader->SetUniform3x3f("EyeRotationEnd", matRenderFromNowEnd);
+
+ Matrix4f dummy;
+ if ( ( pSourceTextureRight != NULL ) && ( eyeNum == 1 ) )
+ {
+ fill.SetTexture ( 0, pSourceTextureRight );
+ }
+ Render(&fill, pDistortionMeshVertexBuffer[eyeNum], pDistortionMeshIndexBuffer[eyeNum], dummy, 0, DistortionMeshNumTris[eyeNum] * 3, Prim_Triangles, true);
+ }
+ }
+ else if ( PostProcessingType == PostProcess_MeshDistortionPositionalTimewarp )
+ {
+ Recti vp( 0, 0, WindowWidth, WindowHeight );
+ SetViewport(vp);
+ float r, g, b, a;
+ DistortionClearColor.GetRGBA(&r, &g, &b, &a);
+ Clear(r, g, b, a);
+
+ ShaderFill fill(pPostProcessShader);
+ fill.SetTexture ( 0, pSourceTextureLeftOrOnly );
+ fill.SetTexture ( 0, pSourceTextureLeftOrOnlyDepth, Shader_Vertex );
+
+ for ( int eyeNum = 0; eyeNum < 2; eyeNum++ )
+ {
+ Matrix4f const &matRenderFromWorld = ( eyeNum == 0 ) ? matRenderFromWorldLeft : matRenderFromWorldRight;
+ const StereoEyeParams &stereoParams = ( eyeNum == 0 ) ? stereoParamsLeft : stereoParamsRight;
+
+ Matrix4f matRenderFromNowStart = TimewarpComputePoseDelta ( matRenderFromWorld, matNowFromWorldStart );
+ Matrix4f matRenderFromNowEnd = TimewarpComputePoseDelta ( matRenderFromWorld, matNowFromWorldEnd );
+
+ pPostProcessShader->SetUniform2f("EyeToSourceUVScale", stereoParams.EyeToSourceUV.Scale.x, stereoParams.EyeToSourceUV.Scale.y );
+ pPostProcessShader->SetUniform2f("EyeToSourceUVOffset", stereoParams.EyeToSourceUV.Offset.x, stereoParams.EyeToSourceUV.Offset.y );
+
+ // DepthProjector values can also be calculated as:
+ // float DepthProjectorX = FarClip / (FarClip - NearClip);
+ // float DepthProjectorY = (-FarClip * NearClip) / (FarClip - NearClip);
+ pPostProcessShader->SetUniform2f("DepthProjector", -stereoParams.RenderedProjection.M[2][2], stereoParams.RenderedProjection.M[2][3]);
+ pPostProcessShader->SetUniform2f("DepthDimSize", (float)pSourceTextureLeftOrOnlyDepth->GetWidth(), (float)pSourceTextureLeftOrOnlyDepth->GetHeight());
+ pPostProcessShader->SetUniform4x4f("EyeRotationStart", matRenderFromNowStart);
+ pPostProcessShader->SetUniform4x4f("EyeRotationEnd", matRenderFromNowEnd);
+
+
+ Matrix4f dummy;
+ if ( ( pSourceTextureRight != NULL ) && ( eyeNum == 1 ) )
+ {
+ OVR_ASSERT(pSourceTextureRightDepth != NULL);
+ fill.SetTexture ( 0, pSourceTextureRight );
+ fill.SetTexture ( 0, pSourceTextureRightDepth, Shader_Vertex );
+ }
- Matrix4f texm(w, 0, 0, x,
- 0, h, 0, y,
- 0, 0, 0, 0,
- 0, 0, 0, 1);
- pPostProcessShader->SetUniform4x4f("Texm", texm);
-
- Matrix4f view(2, 0, 0, -1,
- 0, 2, 0, -1,
- 0, 0, 0, 0,
- 0, 0, 0, 1);
-
- ShaderFill fill(pPostProcessShader);
- fill.SetTexture(0, pSceneColorTex);
- RenderWithAlpha(&fill, pFullScreenVertexBuffer, NULL, view, 0, 4, Prim_TriangleStrip);
-}
-
-bool CollisionModel::TestPoint(const Vector3f& p) const
-{
- for(unsigned i = 0; i < Planes.GetSize(); i++)
- if(Planes[i].TestSide(p) > 0)
- {
- return 0;
- }
-
- return 1;
-}
-
-bool CollisionModel::TestRay(const Vector3f& origin, const Vector3f& norm, float& len, Planef* ph) const
-{
- if(TestPoint(origin))
- {
- len = 0;
- *ph = Planes[0];
- return true;
- }
- Vector3f fullMove = origin + norm * len;
+ Render(&fill, pDistortionMeshVertexBuffer[eyeNum], pDistortionMeshIndexBuffer[eyeNum], dummy, 0, DistortionMeshNumTris[eyeNum] * 3, Prim_Triangles, true);
+ }
+ }
+ else
+ {
+ if ( PostProcessingType == PostProcess_PixelDistortion )
+ {
+ float r, g, b, a;
+ DistortionClearColor.GetRGBA(&r, &g, &b, &a);
+ Clear(r, g, b, a);
+
+ for ( int eyeNum = 0; eyeNum < 2; eyeNum++ )
+ {
+ const StereoEyeParams &stereoParams = ( eyeNum == 0 ) ? stereoParamsLeft : stereoParamsRight;
+
+ // Always use the half-FB viewport, not the "current scene" VP which may be totally different.
+ SetViewport(stereoParams.DistortionViewport);
+
+ // TODO: precalc a bunch of things to make the shader faster.
+ // Note that the shader currently doesn't use Distortion.K[0], it hardwires it to 1.0.
+ pPostProcessShader->SetUniform4f("HmdWarpParam",
+ 1.0f,
+ stereoParams.Distortion.Lens.K[1],
+ stereoParams.Distortion.Lens.K[2],
+ stereoParams.Distortion.Lens.K[3]);
+ // We now only support one distortion type for shaders.
+ OVR_ASSERT ( stereoParams.Distortion.Lens.Eqn == Distortion_RecipPoly4 );
+
+ pPostProcessShader->SetUniform3f("DistortionClearColor",
+ DistortionClearColor.R,
+ DistortionClearColor.G,
+ DistortionClearColor.B );
+
+ // These are stored as deltas off the "main" distortion coefficients, but
+ // in the shader we use them as absolute values.
+ pPostProcessShader->SetUniform4f("ChromAbParam",
+ stereoParams.Distortion.Lens.ChromaticAberration[0] + 1.0f,
+ stereoParams.Distortion.Lens.ChromaticAberration[1],
+ stereoParams.Distortion.Lens.ChromaticAberration[2] + 1.0f,
+ stereoParams.Distortion.Lens.ChromaticAberration[3]);
+
+ // From [-1,1] space (for a single eye), offset by LensCenter, scaled to TanEyeAngle space.
+ // Done this way so that the shader can do a multiply-add, rather than a subtract-then-multiply.
+ Vector2f localTanEyeAngleOffset = -stereoParams.Distortion.LensCenter.EntrywiseMultiply(stereoParams.Distortion.TanEyeAngleScale);
+ pPostProcessShader->SetUniform2f("TanEyeAngleScale", stereoParams.Distortion.TanEyeAngleScale.x,
+ stereoParams.Distortion.TanEyeAngleScale.y);
+ pPostProcessShader->SetUniform2f("TanEyeAngleOffset", localTanEyeAngleOffset.x, localTanEyeAngleOffset.y);
+
+ // From TanEyeAngle space to the source the app rendered the standard projective scene to.
+ pPostProcessShader->SetUniform2f("EyeToSourceUVScale", stereoParams.EyeToSourceUV.Scale.x, stereoParams.EyeToSourceUV.Scale.y );
+ pPostProcessShader->SetUniform2f("EyeToSourceUVOffset", stereoParams.EyeToSourceUV.Offset.x, stereoParams.EyeToSourceUV.Offset.y );
+ pPostProcessShader->SetUniform2f("EyeToSourceNDCScale", stereoParams.EyeToSourceNDC.Scale.x, stereoParams.EyeToSourceNDC.Scale.y );
+ pPostProcessShader->SetUniform2f("EyeToSourceNDCOffset", stereoParams.EyeToSourceNDC.Offset.x, stereoParams.EyeToSourceNDC.Offset.y );
+
+ // Fade out towards the last bit of the edge, rather than having a sharp edge that attracts the eye.
+ pPostProcessShader->SetUniform1f("EdgeFadeScale", 1.0f / FadeOutBorderFraction );
+
+ // Vertex texture coordinates are (0,0) to (1,1). This moves them to (-1,-1),(1,1)
+ Matrix4f texm(2, 0, 0, -1,
+ 0, 2, 0, -1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 1);
+ pPostProcessShader->SetUniform4x4f("Texm", texm);
+
+ // Input vertices are (0,0) to (1,1). This moves them to (-1,-1),(1,1), i.e. filling the viewport (which will be set to the correct half of the screen).
+ Matrix4f view(2, 0, 0, -1,
+ 0, 2, 0, -1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 1);
+ ShaderFill fill(pPostProcessShader);
+
+ if ( ( pSourceTextureRight != NULL ) && ( eyeNum == 1 ) )
+ {
+ fill.SetTexture ( 0, pSourceTextureRight );
+ }
+ else
+ {
+ fill.SetTexture ( 0, pSourceTextureLeftOrOnly );
+ }
+ Render(&fill, pFullScreenVertexBuffer, NULL, view, 0, 4, Prim_TriangleStrip);
+ }
+ }
+ else if ( PostProcessingType == PostProcess_NoDistortion )
+ {
+ // Just splat the thing on the framebuffer with no distortion.
+ Clear ( 0.0f, 0.4f, 0.0f, 1.0f, 1.0f );
+ // 1:1 mapping to screen pixels.
+ Matrix4f ortho;
+ ortho.SetIdentity();
+ ortho.M[0][0] = 1.0f;
+ ortho.M[0][3] = 0.0f;
+ ortho.M[1][1] = -1.0f;
+ ortho.M[1][3] = 0.0f;
+ ortho.M[2][2] = 0;
+ SetProjection(ortho);
+ int rtWidth = pSourceTextureLeftOrOnly->GetWidth();
+ int rtHeight = pSourceTextureLeftOrOnly->GetHeight();
+
+ for ( int eyeNum = 0; eyeNum < 2; eyeNum++ )
+ {
+ const StereoEyeParams &stereoParams = ( eyeNum == 0 ) ? stereoParamsLeft : stereoParamsRight;
+ SetViewport ( stereoParams.DistortionViewport );
- int crossing = -1;
- float cdot1 = 0, cdot2 = 0;
+ Ptr<Texture> pTex;
+ if ( ( pSourceTextureRight != NULL ) && ( eyeNum == 1 ) )
+ {
+ pTex = pSourceTextureRight;
+ }
+ else
+ {
+ pTex = pSourceTextureLeftOrOnly;
+ }
- for(unsigned i = 0; i < Planes.GetSize(); ++i)
- {
- float dot2 = Planes[i].TestSide(fullMove);
- if(dot2 > 0)
- {
- return false;
- }
- float dot1 = Planes[i].TestSide(origin);
- if(dot1 > 0)
- {
- if(dot2 <= 0)
- {
- //assert(crossing==-1);
- if(crossing == -1)
- {
- crossing = i;
- cdot2 = dot2;
- cdot1 = dot1;
+ float ul = (float)( stereoParams.RenderedViewport.x ) / (float)rtWidth;
+ float ur = (float)( stereoParams.RenderedViewport.x + stereoParams.RenderedViewport.w ) / (float)rtWidth;
+ float vt = (float)( stereoParams.RenderedViewport.y ) / (float)rtHeight;
+ float vb = (float)( stereoParams.RenderedViewport.y + stereoParams.RenderedViewport.h ) / (float)rtHeight;
+ FillTexturedRect (
+ -1.0f, -1.0f, 1.0f, 1.0f,
+ ul, vt, ur, vb,
+ Color(255,255,255,255), pTex );
}
- else
+ }
+ else
+ {
+ OVR_ASSERT ( !"Unknown distortion type" );
+ }
+ }
+ }
+
+ bool CollisionModel::TestPoint(const Vector3f& p) const
+ {
+ for(unsigned i = 0; i < Planes.GetSize(); i++)
+ if(Planes[i].TestSide(p) > 0)
+ {
+ return 0;
+ }
+
+ return 1;
+ }
+
+ bool CollisionModel::TestRay(const Vector3f& origin, const Vector3f& norm, float& len, Planef* ph) const
+ {
+ if(TestPoint(origin))
+ {
+ len = 0;
+ *ph = Planes[0];
+ return true;
+ }
+ Vector3f fullMove = origin + norm * len;
+
+ int crossing = -1;
+ float cdot1 = 0, cdot2 = 0;
+
+ for(unsigned i = 0; i < Planes.GetSize(); ++i)
+ {
+ float dot2 = Planes[i].TestSide(fullMove);
+ if(dot2 > 0)
+ {
+ return false;
+ }
+ float dot1 = Planes[i].TestSide(origin);
+ if(dot1 > 0)
+ {
+ if(dot2 <= 0)
{
- if(dot2 > cdot2)
+ //OVR_ASSERT(crossing==-1);
+ if(crossing == -1)
{
crossing = i;
cdot2 = dot2;
cdot1 = dot1;
}
+ else
+ {
+ if(dot2 > cdot2)
+ {
+ crossing = i;
+ cdot2 = dot2;
+ cdot1 = dot1;
+ }
+ }
}
- }
- }
- }
-
- if(crossing < 0)
- {
- return false;
- }
-
- assert(TestPoint(origin + norm * len));
-
- len = len * cdot1 / (cdot1 - cdot2) - 0.05f;
- if(len < 0)
- {
- len = 0;
- }
- float tp = Planes[crossing].TestSide(origin + norm * len);
- OVR_ASSERT(fabsf(tp) < 0.05f + Mathf::Tolerance);
- OVR_UNUSED(tp);
-
- if(ph)
- {
- *ph = Planes[crossing];
- }
- return true;
-}
-
-int GetNumMipLevels(int w, int h)
-{
- int n = 1;
- while(w > 1 || h > 1)
- {
- w >>= 1;
- h >>= 1;
- n++;
- }
- return n;
-}
-
-void FilterRgba2x2(const UByte* src, int w, int h, UByte* 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);
-
- for(int i = 0; i < w >> 1; i++, psrc += 8, pdest += 4)
- {
- pdest[0] = (((int)psrc[0]) + psrc[4] + psrc[w * 4 + 0] + psrc[w * 4 + 4]) >> 2;
- pdest[1] = (((int)psrc[1]) + psrc[5] + psrc[w * 4 + 1] + psrc[w * 4 + 5]) >> 2;
- pdest[2] = (((int)psrc[2]) + psrc[6] + psrc[w * 4 + 2] + psrc[w * 4 + 6]) >> 2;
- pdest[3] = (((int)psrc[3]) + psrc[7] + psrc[w * 4 + 3] + psrc[w * 4 + 7]) >> 2;
- }
- }
-}
-
-int GetTextureSize(int format, int w, int h)
-{
- switch (format & Texture_TypeMask)
- {
- case Texture_R: return w*h;
- case Texture_RGBA: return w*h*4;
- case Texture_DXT1: {
- int bw = (w+3)/4, bh = (h+3)/4;
- return bw * bh * 8;
- }
- case Texture_DXT3:
- case Texture_DXT5: {
- int bw = (w+3)/4, bh = (h+3)/4;
- return bw * bh * 16;
- }
-
- default:
- OVR_ASSERT(0);
- }
- return 0;
-}
+ }
+ }
+
+ if(crossing < 0)
+ {
+ return false;
+ }
+
+ OVR_ASSERT(TestPoint(origin + norm * len));
+
+ len = len * cdot1 / (cdot1 - cdot2) - 0.05f;
+ if(len < 0)
+ {
+ len = 0;
+ }
+ float tp = Planes[crossing].TestSide(origin + norm * len);
+ OVR_ASSERT(fabsf(tp) < 0.05f + Mathf::Tolerance);
+ OVR_UNUSED(tp);
+
+ if(ph)
+ {
+ *ph = Planes[crossing];
+ }
+ return true;
+ }
+
+ int GetNumMipLevels(int w, int h)
+ {
+ int n = 1;
+ while(w > 1 || h > 1)
+ {
+ w >>= 1;
+ h >>= 1;
+ n++;
+ }
+ return n;
+ }
+
+ void FilterRgba2x2(const UByte* src, int w, int h, UByte* 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);
+
+ for(int i = 0; i < w >> 1; i++, psrc += 8, pdest += 4)
+ {
+ pdest[0] = (((int)psrc[0]) + psrc[4] + psrc[w * 4 + 0] + psrc[w * 4 + 4]) >> 2;
+ pdest[1] = (((int)psrc[1]) + psrc[5] + psrc[w * 4 + 1] + psrc[w * 4 + 5]) >> 2;
+ pdest[2] = (((int)psrc[2]) + psrc[6] + psrc[w * 4 + 2] + psrc[w * 4 + 6]) >> 2;
+ pdest[3] = (((int)psrc[3]) + psrc[7] + psrc[w * 4 + 3] + psrc[w * 4 + 7]) >> 2;
+ }
+ }
+ }
+
+ int GetTextureSize(int format, int w, int h)
+ {
+ switch (format & Texture_TypeMask)
+ {
+ case Texture_R: return w*h;
+ case Texture_RGBA: return w*h*4;
+ case Texture_DXT1: {
+ int bw = (w+3)/4, bh = (h+3)/4;
+ return bw * bh * 8;
+ }
+ case Texture_DXT3:
+ case Texture_DXT5: {
+ int bw = (w+3)/4, bh = (h+3)/4;
+ return bw * bh * 16;
+ }
+
+ default:
+ OVR_ASSERT(0);
+ }
+ return 0;
+ }
}}
diff --git a/Samples/CommonSrc/Render/Render_Device.h b/Samples/CommonSrc/Render/Render_Device.h
index 028f282..f8a6dff 100644
--- a/Samples/CommonSrc/Render/Render_Device.h
+++ b/Samples/CommonSrc/Render/Render_Device.h
@@ -28,24 +28,31 @@ limitations under the License.
#include "Kernel/OVR_RefCount.h"
#include "Kernel/OVR_String.h"
#include "Kernel/OVR_File.h"
+#include "OVR_CAPI.h"
-#include "Util/Util_Render_Stereo.h"
+#include "OVR_Stereo.h"
namespace OVR { namespace Render {
-using namespace OVR::Util::Render;
-
class RenderDevice;
struct Font;
//-----------------------------------------------------------------------------------
+enum ShaderStage
+{
+ Shader_Vertex = 0,
+ Shader_Geometry = 1,
+ Shader_Fragment = 2,
+ Shader_Pixel = 2,
+ Shader_Count = 3,
+};
+
enum PrimitiveType
{
Prim_Triangles,
Prim_Lines,
Prim_TriangleStrip,
- Prim_Points,
Prim_Unknown,
Prim_Count
};
@@ -64,36 +71,32 @@ public:
virtual void Set(PrimitiveType prim = Prim_Unknown) const = 0;
virtual void Unset() const {}
- virtual void SetTexture(int i, class Texture* tex) { OVR_UNUSED2(i,tex); }
- virtual Texture* GetTexture(int i) { OVR_UNUSED(i); return 0; }
-};
-
-enum ShaderStage
-{
- Shader_Vertex = 0,
- Shader_Geometry = 1,
- Shader_Fragment = 2,
- Shader_Pixel = 2,
- Shader_Count = 3,
+ virtual void SetTexture(int i, class Texture* tex, ShaderStage stage = Shader_Pixel) { OVR_UNUSED3(i,tex,stage); }
+ virtual Texture* GetTexture(int i, ShaderStage stage = Shader_Pixel) { OVR_UNUSED2(i,stage); return 0; }
};
enum BuiltinShaders
{
- VShader_MV = 0,
- VShader_MVP = 1,
- VShader_PostProcess = 2,
- VShader_Count = 3,
-
- FShader_Solid = 0,
- FShader_Gouraud = 1,
- FShader_Texture = 2,
- FShader_AlphaTexture = 3,
- FShader_PostProcess = 4,
- FShader_PostProcessWithChromAb = 5,
- FShader_LitGouraud = 6,
- FShader_LitTexture = 7,
- FShader_MultiTexture = 8,
- FShader_Count = 9,
+ VShader_MV = 0,
+ VShader_MVP ,
+ VShader_PostProcess ,
+ VShader_PostProcessMesh ,
+ VShader_PostProcessMeshTimewarp ,
+ VShader_PostProcessMeshPositionalTimewarp ,
+ VShader_Count ,
+
+ FShader_Solid = 0,
+ FShader_Gouraud ,
+ FShader_Texture ,
+ FShader_AlphaTexture ,
+ FShader_PostProcessWithChromAb ,
+ FShader_LitGouraud ,
+ FShader_LitTexture ,
+ FShader_MultiTexture ,
+ FShader_PostProcessMeshWithChromAb ,
+ FShader_PostProcessMeshWithChromAbTimewarp ,
+ FShader_PostProcessMeshWithChromAbPositionalTimewarp ,
+ FShader_Count ,
};
@@ -119,6 +122,8 @@ enum TextureFormat
{
Texture_RGBA = 0x100,
Texture_R = 0x200,
+ Texture_A = 0x400,
+ Texture_BGRA = 0x800,
Texture_DXT1 = 0x1100,
Texture_DXT3 = 0x1200,
Texture_DXT5 = 0x1300,
@@ -126,8 +131,9 @@ enum TextureFormat
Texture_TypeMask = 0xff00,
Texture_Compressed = 0x1000,
Texture_SamplesMask = 0x00ff,
- Texture_RenderTarget = 0x10000,
- Texture_GenMipmaps = 0x20000,
+ Texture_RenderTarget = 0x10000,
+ Texture_SampleDepth = 0x20000,
+ Texture_GenMipmaps = 0x40000,
};
enum SampleMode
@@ -145,16 +151,14 @@ enum SampleMode
Sample_Count =13,
};
-// A vector with a dummy w component for alignment in uniform buffers (and for float colors).
-// The w component is not used in any calculations.
-struct Vector4f : public Vector3f
+struct Color4f
{
- float w;
+ float r, g, b, a;
- Vector4f() : w(1) {}
- Vector4f(const Vector3f& v) : Vector3f(v), w(1) {}
- Vector4f(float r, float g, float b, float a) : Vector3f(r,g,b), w(a) {}
+ Color4f() : r(0), g(0), b(0), a(1) {}
+ Color4f(const Vector3f& v) : r(v.x), g(v.y), b(v.z), a(1) {}
+ Color4f(float ir, float ig, float ib, float ia) : r(ir), g(ig), b(ib), a(ia) {}
};
@@ -231,24 +235,34 @@ public:
const float v[] = {x,y};
return SetUniform(name, 2, v);
}
+ bool SetUniform3f(const char* name, float x, float y, float z)
+ {
+ const float v[] = {x,y,z};
+ return SetUniform(name, 3, v);
+ }
bool SetUniform4f(const char* name, float x, float y, float z, float w = 1)
{
const float v[] = {x,y,z,w};
return SetUniform(name, 4, v);
}
- bool SetUniformv(const char* name, const Vector3f& v)
+ bool SetUniform4fv(const char* name, const Vector3f& v)
{
const float a[] = {v.x,v.y,v.z,1};
return SetUniform(name, 4, a);
}
- bool SetUniform4fv(const char* name, int n, const Vector4f* v)
+ bool SetUniform4fvArray(const char* name, int n, const Color4f* v)
{
- return SetUniform(name, 4*n, &v[0].x);
+ return SetUniform(name, 4*n, &v[0].r);
}
virtual bool SetUniform4x4f(const char* name, const Matrix4f& m)
{
return SetUniform(name, 16, &m.M[0][0]);
}
+ virtual bool SetUniform3x3f(const char* name, const Matrix4f& m)
+ {
+ // float3x3 is actually stored the same way as float4x3, with the last items ignored by the code.
+ return SetUniform(name, 12, &m.M[0][0]);
+ }
};
class ShaderSetMatrixTranspose : public ShaderSet
@@ -265,6 +279,7 @@ class ShaderFill : public Fill
{
Ptr<ShaderSet> Shaders;
Ptr<Texture> Textures[8];
+ Ptr<Texture> VtxTextures[8];
public:
ShaderFill(ShaderSet* sh) : Shaders(sh) { }
@@ -272,8 +287,28 @@ public:
void Set(PrimitiveType prim) const;
ShaderSet* GetShaders() { return Shaders; }
- virtual void SetTexture(int i, class Texture* tex) { if (i < 8) Textures[i] = tex; }
- virtual Texture* GetTexture(int i) { if (i < 8) return Textures[i]; else return 0; }
+ virtual void SetTexture(int i, class Texture* tex, ShaderStage stage = Shader_Pixel)
+ {
+ if (i < 8)
+ {
+ if(stage == Shader_Pixel) Textures[i] = tex;
+ else if(stage == Shader_Vertex) VtxTextures[i] = tex;
+ else OVR_ASSERT(false);
+ }
+ }
+ virtual Texture* GetTexture(int i, ShaderStage stage = Shader_Pixel)
+ {
+ if (i < 8)
+ {
+ if(stage == Shader_Pixel) return Textures[i];
+ else if(stage == Shader_Vertex) return VtxTextures[i];
+ else OVR_ASSERT(false); return 0;
+ }
+ else
+ {
+ return 0;
+ }
+ }
};
/* Buffer for vertex or index data. Some renderers require separate buffers, so that
@@ -313,6 +348,10 @@ public:
virtual void SetSampleMode(int sm) = 0;
virtual void Set(int slot, ShaderStage stage = Shader_Fragment) const = 0;
+
+ virtual ovrTexture Get_ovrTexture() = 0;
+
+ virtual void* GetInternalImplementation() { return NULL; };
};
@@ -379,7 +418,7 @@ public:
{
if (!MatCurrent)
{
- Mat = Rot;
+ Mat = Matrix4f(Rot);
Mat = Matrix4f::Translation(Pos) * Mat;
MatCurrent = 1;
}
@@ -413,18 +452,27 @@ struct Vertex
}
};
+struct DistortionVertex
+{
+ Vector2f Pos;
+ Vector2f TexR;
+ Vector2f TexG;
+ Vector2f TexB;
+ Color Col;
+};
+
// this is stored in a uniform buffer, don't change it without fixing all renderers
struct LightingParams
{
- Vector4f Ambient;
- Vector4f LightPos[8];
- Vector4f LightColor[8];
+ Color4f Ambient;
+ Color4f LightPos[8]; // Not actually colours, but we need the extra element of padding.
+ Color4f LightColor[8];
float LightCount;
int Version;
LightingParams() : LightCount(0), Version(0) {}
- void Update(const Matrix4f& view, const Vector4f* SceneLightPos);
+ void Update(const Matrix4f& view, const Vector3f* SceneLightPos);
void Set(ShaderSet* s) const;
};
@@ -472,10 +520,12 @@ public:
UInt16 AddVertex(const Vertex& v)
{
- assert(!VertexBuffer && !IndexBuffer);
- UInt16 index = (UInt16)Vertices.GetSize();
- Vertices.PushBack(v);
- return index;
+ OVR_ASSERT(!VertexBuffer && !IndexBuffer);
+ UPInt size = Vertices.GetSize();
+ OVR_ASSERT(size <= USHRT_MAX); // We only use a short to store vert indices.
+ UInt16 index = (UInt16) size;
+ Vertices.PushBack(v);
+ return index;
}
UInt16 AddVertex(const Vector3f& v, const Color& c, float u_ = 0, float v_ = 0)
{
@@ -528,6 +578,9 @@ public:
float z1, float z2, Color zcolor);
+ // Adds box at specified location to current vertices.
+ void AddBox(Color c, Vector3f origin, Vector3f size);
+
// Uses texture coordinates for exactly covering each surface once.
static Model* CreateBox(Color c, Vector3f origin, Vector3f size);
@@ -575,18 +628,18 @@ class Scene
{
public:
Container World;
- Vector4f LightPos[8];
+ Vector3f LightPos[8];
LightingParams Lighting;
Array<Ptr<Model> > Models;
public:
void Render(RenderDevice* ren, const Matrix4f& view);
- void SetAmbient(Vector4f color)
+ void SetAmbient(Color4f color)
{
Lighting.Ambient = color;
}
- void AddLight(Vector3f pos, Vector4f color)
+ void AddLight(Vector3f pos, Color4f color)
{
int n = (int)Lighting.LightCount;
OVR_ASSERT(n < 8);
@@ -599,7 +652,7 @@ public:
{
World.Clear();
Models.Clear();
- Lighting.Ambient = Vector4f(0.0f, 0.0f, 0.0f, 0.0f);
+ Lighting.Ambient = Color4f(0.0f, 0.0f, 0.0f, 0.0f);
Lighting.LightCount = 0;
}
@@ -624,11 +677,15 @@ enum RenderCaps
};
// Post-processing type to apply to scene after rendering. PostProcess_Distortion
-// applied distortion as described by DistortionConfig.
+// applied distortion as described by DistortionRenderDesc.
enum PostProcessType
{
PostProcess_None,
- PostProcess_Distortion
+ PostProcess_PixelDistortion,
+ PostProcess_MeshDistortion,
+ PostProcess_MeshDistortionTimewarp,
+ PostProcess_MeshDistortionPositionalTimewarp,
+ PostProcess_NoDistortion,
};
enum DisplayMode
@@ -688,29 +745,27 @@ class RenderDevice : public RefCountBase<RenderDevice>
protected:
int WindowWidth, WindowHeight;
RendererParams Params;
- Viewport VP;
+ Recti VP;
Matrix4f Proj;
Ptr<Buffer> pTextVertexBuffer;
-
// For rendering with lens warping
- PostProcessType CurPostProcess;
- Ptr<Texture> pSceneColorTex;
- int SceneColorTexW;
- int SceneColorTexH;
+ PostProcessType PostProcessingType;
+
Ptr<ShaderSet> pPostProcessShader;
Ptr<Buffer> pFullScreenVertexBuffer;
- float SceneRenderScale;
- DistortionConfig Distortion;
Color DistortionClearColor;
- UPInt TotalTextureMemoryUsage;
+ UPInt TotalTextureMemoryUsage;
+ float FadeOutBorderFraction;
+
+ int DistortionMeshNumTris[2];
+ Ptr<Buffer> pDistortionMeshVertexBuffer[2];
+ Ptr<Buffer> pDistortionMeshIndexBuffer[2];
// For lighting on platforms with uniform buffers
Ptr<Buffer> LightingBuffer;
- void FinishScene1();
-
public:
enum CompareFunc
{
@@ -728,41 +783,43 @@ public:
virtual void Init() {}
- virtual void Shutdown() {}
+ virtual void Shutdown();
virtual bool SetParams(const RendererParams&) { return 0; }
const RendererParams& GetParams() const { return Params; }
-
+ // Returns details needed by CAPI distortion rendering.
+ virtual ovrRenderAPIConfig Get_ovrRenderAPIConfig() const = 0;
+
// StereoParams apply Viewport, Projection and Distortion simultaneously,
// doing full configuration for one eye.
void ApplyStereoParams(const StereoEyeParams& params)
{
- SetViewport(params.VP);
- SetProjection(params.Projection);
- if (params.pDistortion)
- SetDistortionConfig(*params.pDistortion, params.Eye);
+ SetViewport(params.RenderedViewport);
+ SetProjection(params.RenderedProjection);
}
+ void ApplyStereoParams(const Recti& vp, const Matrix4f& projection)
+ {
+ SetViewport(vp);
+ SetProjection(projection);
+ }
// Apply "orthographic" stereo parameters used for rendering 2D HUD overlays.
- void ApplyStereoParams2D(const StereoEyeParams& params)
+ void ApplyStereoParams2D(StereoEyeParams const &params, Matrix4f const &ortho)
{
- SetViewport(params.VP);
- SetProjection(params.OrthoProjection);
- if (params.pDistortion)
- SetDistortionConfig(*params.pDistortion, params.Eye);
+ SetViewport(params.RenderedViewport);
+ SetProjection(ortho);
}
+
- virtual void SetViewport(const Viewport& vp);
- void SetViewport(int x, int y, int w, int h) { SetViewport(Viewport(x,y,w,h)); }
- //virtual void SetScissor(int x, int y, int w, int h) = 0;
- // Set viewport ignoring any adjustments used for the stereo mode.
- virtual void SetRealViewport(const Viewport& vp) { SetMultipleViewports(1, &vp); }
- virtual void SetMultipleViewports(int n, const Viewport* vps) { OVR_UNUSED2(n, vps); }
+ virtual void SetViewport(const Recti& vp) = 0;
+ void SetViewport(int x, int y, int w, int h) { SetViewport(Recti(x,y,w,h)); }
- virtual void Clear(float r = 0, float g = 0, float b = 0, float a = 1, float depth = 1) = 0;
+ virtual void Clear(float r = 0, float g = 0, float b = 0, float a = 1,
+ float depth = 1,
+ bool clearColor = true, bool clearDepth = true) = 0;
virtual void Rect(float left, float top, float right, float bottom) = 0;
inline void Clear(const Color &c, float depth = 1)
@@ -773,9 +830,9 @@ public:
}
virtual bool IsFullscreen() const { return Params.Fullscreen != Display_Window; }
- virtual void Present() = 0;
+ virtual void Present ( bool withVsync ) = 0;
// Waits for rendering to complete; important for reducing latency.
- virtual void ForceFlushGPU() { }
+ virtual void WaitUntilGpuIdle() { }
// Resources
virtual Buffer* CreateBuffer() { return NULL; }
@@ -789,12 +846,24 @@ public:
// Rendering
+
// Begin drawing directly to the currently selected render target, no post-processing.
virtual void BeginRendering() {}
- // Begin drawing the primary scene. This will have post-processing applied (if enabled)
- // during FinishScene.
- virtual void BeginScene(PostProcessType pp = PostProcess_None); //StereoDisplay disp = Stereo_Center);
- // Postprocess the scene and return to the screen render target.
+ // Begin drawing the primary scene, starting up whatever post-processing may be needed.
+ virtual void BeginScene(PostProcessType pp = PostProcess_None);
+ // Call when any of the stereo options change, so precalculation can happen.
+ virtual void PrecalculatePostProcess(PostProcessType pptype,
+ const StereoEyeParams &stereoParamsLeft, const StereoEyeParams &stereoParamsRight,
+ const HmdRenderInfo &hmdRenderInfo );
+ // Perform postprocessing
+ virtual void ApplyPostProcess(Matrix4f const &matNowFromWorldStart, Matrix4f const &matNowFromWorldEnd,
+ Matrix4f const &matRenderFromWorldLeft, Matrix4f const &matRenderFromWorldRight,
+ StereoEyeParams const &stereoParamsLeft, StereoEyeParams const &stereoParamsRight,
+ Ptr<Texture> pSourceTextureLeftOrOnly,
+ Ptr<Texture> pSourceTextureRight,
+ Ptr<Texture> pSourceTextureLeftOrOnlyDepth,
+ Ptr<Texture> pSourceTextureRightDepth);
+ // Finish scene.
virtual void FinishScene();
// Texture must have been created with Texture_RenderTarget. Use NULL for the default render target.
@@ -818,31 +887,25 @@ public:
virtual void Render(const Matrix4f& matrix, Model* model) = 0;
// offset is in bytes; indices can be null.
virtual void Render(const Fill* fill, Buffer* vertices, Buffer* indices,
- const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles) = 0;
+ const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles, bool useDistortionVertex = false) = 0;
virtual void RenderWithAlpha(const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices,
const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles) = 0;
// Returns width of text in same units as drawing. If strsize is not null, stores width and height.
- float MeasureText(const Font* font, const char* str, float size, float* strsize = NULL);
+ // 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);
virtual void FillRect(float left, float top, float right, float bottom, Color c);
+ 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 Fill *CreateSimpleFill(int flags = Fill::F_Solid) = 0;
Fill * CreateTextureFill(Texture* tex, bool useAlpha = false);
- // PostProcess distortion
- void SetSceneRenderScale(float ss);
-
- void SetDistortionConfig(const DistortionConfig& config, StereoEye eye = StereoEye_Left)
- {
- Distortion = config;
- if (eye == StereoEye_Right)
- Distortion.XCenterOffset = -Distortion.XCenterOffset;
- }
-
// Sets the color that is applied around distortion.
void SetDistortionClearColor(Color clearColor)
{
@@ -851,7 +914,12 @@ public:
// Don't call these directly, use App/Platform instead
virtual bool SetFullscreen(DisplayMode fullscreen) { OVR_UNUSED(fullscreen); return false; }
- virtual void SetWindowSize(int w, int h) { WindowWidth = w; WindowHeight = h; }
+ virtual void SetWindowSize(int w, int h)
+ {
+ WindowWidth = w;
+ WindowHeight = h;
+ VP = Recti( 0, 0, WindowWidth, WindowHeight );
+ }
UPInt GetTotalTextureMemoryUsage() const
{
@@ -860,8 +928,10 @@ public:
enum PostProcessShader
{
- PostProcessShader_Distortion = 0,
- PostProcessShader_DistortionAndChromAb = 1,
+ PostProcessShader_DistortionAndChromAb = 0,
+ PostProcessShader_MeshDistortionAndChromAb,
+ PostProcessShader_MeshDistortionAndChromAbTimewarp,
+ PostProcessShader_MeshDistortionAndChromAbPositionalTimewarp,
PostProcessShader_Count
};
@@ -875,6 +945,16 @@ public:
PostProcessShaderRequested = newShader;
}
+ void SetFadeOutBorderFraction ( float newVal )
+ {
+ FadeOutBorderFraction = newVal;
+ }
+
+ // GPU Profiling
+ // using (void) to avoid "unused param" warnings
+ virtual void BeginGpuEvent(const char* markerText, UInt32 markerColor) { (void)markerText; (void)markerColor; }
+ virtual void EndGpuEvent() { }
+
protected:
// Stereo & post-processing
virtual bool initPostProcessSupport(PostProcessType pptype);
@@ -887,6 +967,34 @@ private:
PostProcessShader PostProcessShaderActive;
};
+//-----------------------------------------------------------------------------------
+// GPU profile marker helper to encapsulate a given scope block
+class AutoGpuProf
+{
+public:
+ AutoGpuProf(RenderDevice* device, const char* markerText, UInt32 color)
+ : mDevice(device)
+ { device->BeginGpuEvent(markerText, color); }
+
+ // Generates random color if one is not provided
+ AutoGpuProf(RenderDevice* device, const char* markerText)
+ : mDevice(device)
+ {
+ UInt32 color = ((rand() & 0xFF) << 24) +
+ ((rand() & 0xFF) << 16) +
+ ((rand() & 0xFF) << 8) +
+ (rand() & 0xFF);
+ device->BeginGpuEvent(markerText, color);
+ }
+
+ ~AutoGpuProf() { mDevice->EndGpuEvent(); }
+
+private:
+ RenderDevice* mDevice;
+ AutoGpuProf() { };
+};
+//-----------------------------------------------------------------------------------
+
int GetNumMipLevels(int w, int h);
int GetTextureSize(int format, int w, int h);
diff --git a/Samples/CommonSrc/Render/Render_GL_Device.cpp b/Samples/CommonSrc/Render/Render_GL_Device.cpp
index aaf1f0e..4b3ddec 100644
--- a/Samples/CommonSrc/Render/Render_GL_Device.cpp
+++ b/Samples/CommonSrc/Render/Render_GL_Device.cpp
@@ -23,9 +23,122 @@ limitations under the License.
#include "../Render/Render_GL_Device.h"
#include "Kernel/OVR_Log.h"
+#include "OVR_CAPI_GL.h"
namespace OVR { namespace Render { namespace GL {
+// GL Hooks for PC.
+#if defined(OVR_OS_WIN32)
+
+PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT;
+PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
+PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
+PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
+PFNGLDELETESHADERPROC glDeleteShader;
+PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
+PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
+PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
+PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
+PFNGLACTIVETEXTUREPROC glActiveTexture;
+PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
+PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
+PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
+PFNGLBINDBUFFERPROC glBindBuffer;
+PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv;
+PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
+PFNGLDELETEBUFFERSPROC glDeleteBuffers;
+PFNGLBUFFERDATAPROC glBufferData;
+PFNGLGENBUFFERSPROC glGenBuffers;
+PFNGLMAPBUFFERPROC glMapBuffer;
+PFNGLUNMAPBUFFERPROC glUnmapBuffer;
+PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
+PFNGLGETSHADERIVPROC glGetShaderiv;
+PFNGLCOMPILESHADERPROC glCompileShader;
+PFNGLSHADERSOURCEPROC glShaderSource;
+PFNGLCREATESHADERPROC glCreateShader;
+PFNGLCREATEPROGRAMPROC glCreateProgram;
+PFNGLATTACHSHADERPROC glAttachShader;
+PFNGLDETACHSHADERPROC glDetachShader;
+PFNGLDELETEPROGRAMPROC glDeleteProgram;
+PFNGLUNIFORM1IPROC glUniform1i;
+PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
+PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform;
+PFNGLUSEPROGRAMPROC glUseProgram;
+PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
+PFNGLGETPROGRAMIVPROC glGetProgramiv;
+PFNGLLINKPROGRAMPROC glLinkProgram;
+PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
+PFNGLUNIFORM4FVPROC glUniform4fv;
+PFNGLUNIFORM3FVPROC glUniform3fv;
+PFNGLUNIFORM2FVPROC glUniform2fv;
+PFNGLUNIFORM1FVPROC glUniform1fv;
+PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
+PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT;
+PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
+PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT;
+PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;
+
+PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
+
+void InitGLExtensions()
+{
+ if (glGenFramebuffersEXT)
+ return;
+
+
+ wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC) wglGetProcAddress("wglGetSwapIntervalEXT");
+ wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress("wglSwapIntervalEXT");
+ glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) wglGetProcAddress("glGenFramebuffersEXT");
+ glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) wglGetProcAddress("glDeleteFramebuffersEXT");
+ glDeleteShader = (PFNGLDELETESHADERPROC) wglGetProcAddress("glDeleteShader");
+ glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) wglGetProcAddress("glCheckFramebufferStatusEXT");
+ glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) wglGetProcAddress("glFramebufferRenderbufferEXT");
+ glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) wglGetProcAddress("glFramebufferTexture2DEXT");
+ glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) wglGetProcAddress("glBindFramebufferEXT");
+ glActiveTexture = (PFNGLACTIVETEXTUREPROC) wglGetProcAddress("glActiveTexture");
+ glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) wglGetProcAddress("glDisableVertexAttribArray");
+ glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) wglGetProcAddress("glVertexAttribPointer");
+ glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) wglGetProcAddress("glEnableVertexAttribArray");
+ glBindBuffer = (PFNGLBINDBUFFERPROC) wglGetProcAddress("glBindBuffer");
+ glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) wglGetProcAddress("glUniformMatrix3fv");
+ glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) wglGetProcAddress("glUniformMatrix4fv");
+ glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) wglGetProcAddress("glDeleteBuffers");
+ glBufferData = (PFNGLBUFFERDATAPROC) wglGetProcAddress("glBufferData");
+ glGenBuffers = (PFNGLGENBUFFERSPROC) wglGetProcAddress("glGenBuffers");
+ glMapBuffer = (PFNGLMAPBUFFERPROC) wglGetProcAddress("glMapBuffer");
+ glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) wglGetProcAddress("glUnmapBuffer");
+ glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) wglGetProcAddress("glGetShaderInfoLog");
+ glGetShaderiv = (PFNGLGETSHADERIVPROC) wglGetProcAddress("glGetShaderiv");
+ glCompileShader = (PFNGLCOMPILESHADERPROC) wglGetProcAddress("glCompileShader");
+ glShaderSource = (PFNGLSHADERSOURCEPROC) wglGetProcAddress("glShaderSource");
+ glCreateShader = (PFNGLCREATESHADERPROC) wglGetProcAddress("glCreateShader");
+ glCreateProgram = (PFNGLCREATEPROGRAMPROC) wglGetProcAddress("glCreateProgram");
+ glAttachShader = (PFNGLATTACHSHADERPROC) wglGetProcAddress("glAttachShader");
+ glDetachShader = (PFNGLDETACHSHADERPROC) wglGetProcAddress("glDetachShader");
+ glDeleteProgram = (PFNGLDELETEPROGRAMPROC) wglGetProcAddress("glDeleteProgram");
+ glUniform1i = (PFNGLUNIFORM1IPROC) wglGetProcAddress("glUniform1i");
+ glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) wglGetProcAddress("glGetUniformLocation");
+ glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) wglGetProcAddress("glGetActiveUniform");
+ glUseProgram = (PFNGLUSEPROGRAMPROC) wglGetProcAddress("glUseProgram");
+ glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) wglGetProcAddress("glGetProgramInfoLog");
+ glGetProgramiv = (PFNGLGETPROGRAMIVPROC) wglGetProcAddress("glGetProgramiv");
+ glLinkProgram = (PFNGLLINKPROGRAMPROC) wglGetProcAddress("glLinkProgram");
+ glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) wglGetProcAddress("glBindAttribLocation");
+ glUniform4fv = (PFNGLUNIFORM4FVPROC) wglGetProcAddress("glUniform4fv");
+ glUniform3fv = (PFNGLUNIFORM3FVPROC) wglGetProcAddress("glUniform3fv");
+ glUniform2fv = (PFNGLUNIFORM2FVPROC) wglGetProcAddress("glUniform2fv");
+ glUniform1fv = (PFNGLUNIFORM1FVPROC) wglGetProcAddress("glUniform1fv");
+ glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) wglGetProcAddress("glCompressedTexImage2D");
+ glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC) wglGetProcAddress("glRenderbufferStorageEXT");
+ glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC) wglGetProcAddress("glBindRenderbufferEXT");
+ glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC) wglGetProcAddress("glGenRenderbuffersEXT");
+ glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC) wglGetProcAddress("glDeleteRenderbuffersEXT");
+
+
+ glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) wglGetProcAddress("glGenVertexArrays");
+}
+
+#endif
static const char* StdVertexShaderSrc =
@@ -157,6 +270,53 @@ static const char* MultiTextureFragShaderSrc =
" gl_FragColor = color2;\n"
"}\n";
+static const char* PostProcessMeshFragShaderSrc =
+ "uniform sampler2D Texture;\n"
+ "varying vec4 oColor;\n"
+ "varying vec2 oTexCoord0;\n"
+ "varying vec2 oTexCoord1;\n"
+ "varying vec2 oTexCoord2;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " float ResultR = texture2D(Texture, oTexCoord0).r;\n"
+ " float ResultG = texture2D(Texture, oTexCoord1).g;\n"
+ " float ResultB = texture2D(Texture, oTexCoord2).b;\n"
+ " gl_FragColor = vec4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0);\n"
+ "}\n";
+
+static const char* PostProcessMeshTimewarpFragShaderSrc =
+ "uniform sampler2D Texture;\n"
+ "varying vec4 oColor;\n"
+ "varying vec2 oTexCoord0;\n"
+ "varying vec2 oTexCoord1;\n"
+ "varying vec2 oTexCoord2;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " float ResultR = texture2D(Texture, oTexCoord0).r;\n"
+ " float ResultG = texture2D(Texture, oTexCoord1).g;\n"
+ " float ResultB = texture2D(Texture, oTexCoord2).b;\n"
+ " gl_FragColor = vec4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0);\n"
+ "}\n";
+
+static const char* PostProcessMeshPositionalTimewarpFragShaderSrc =
+ "uniform sampler2D Texture0;\n"
+ "uniform sampler2D Texture1;\n"
+ "varying vec4 oColor;\n"
+ "varying vec2 oTexCoord0;\n"
+ "varying vec2 oTexCoord1;\n"
+ "varying vec2 oTexCoord2;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor.r = oColor.r * texture2D(Texture1, oTexCoord0).r;\n"
+ " gl_FragColor.g = oColor.g * texture2D(Texture1, oTexCoord1).g;\n"
+ " gl_FragColor.b = oColor.b * texture2D(Texture1, oTexCoord2).b;\n"
+ " gl_FragColor.a = 1.0;\n"
+ "}\n";
+
+
static const char* PostProcessVertexShaderSrc =
"uniform mat4 View;\n"
"uniform mat4 Texm;\n"
@@ -167,85 +327,275 @@ static const char* PostProcessVertexShaderSrc =
"{\n"
" gl_Position = View * Position;\n"
" oTexCoord = vec2(Texm * vec4(TexCoord,0,1));\n"
- " oTexCoord.y = 1.0-oTexCoord.y;\n"
+ "}\n";
+
+static const char* PostProcessMeshVertexShaderSrc =
+ "uniform vec2 EyeToSourceUVScale;\n"
+ "uniform vec2 EyeToSourceUVOffset;\n"
+
+ "attribute vec2 Position;\n"
+ "attribute vec4 Color;\n"
+ "attribute vec2 TexCoord0;\n"
+ "attribute vec2 TexCoord1;\n"
+ "attribute vec2 TexCoord2;\n"
+
+ "varying vec4 oColor;\n"
+ "varying vec2 oTexCoord0;\n"
+ "varying vec2 oTexCoord1;\n"
+ "varying vec2 oTexCoord2;\n"
+
+ "void main()\n"
+ "{\n"
+ " gl_Position.x = Position.x;\n"
+ " gl_Position.y = Position.y;\n"
+ " gl_Position.z = 0.5;\n"
+ " gl_Position.w = 1.0;\n"
+ // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion).
+ // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye)
+ " oTexCoord0 = TexCoord0 * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " oTexCoord0.y = 1-oTexCoord0.y;\n"
+ " oTexCoord1 = TexCoord1 * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " oTexCoord1.y = 1-oTexCoord1.y;\n"
+ " oTexCoord2 = TexCoord2 * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " oTexCoord2.y = 1-oTexCoord2.y;\n"
+ " oColor = Color;\n" // Used for vignette fade.
+ "}\n";
+
+static const char* PostProcessMeshTimewarpVertexShaderSrc =
+ "uniform vec2 EyeToSourceUVScale;\n"
+ "uniform vec2 EyeToSourceUVOffset;\n"
+ "uniform mat4 EyeRotationStart;\n"
+ "uniform mat4 EyeRotationEnd;\n"
+
+ "attribute vec2 Position;\n"
+ "attribute vec4 Color;\n"
+ "attribute vec2 TexCoord0;\n"
+ "attribute vec2 TexCoord1;\n"
+ "attribute vec2 TexCoord2;\n"
+
+ "varying vec4 oColor;\n"
+ "varying vec2 oTexCoord0;\n"
+ "varying vec2 oTexCoord1;\n"
+ "varying vec2 oTexCoord2;\n"
+
+ "void main()\n"
+ "{\n"
+ " gl_Position.x = Position.x;\n"
+ " gl_Position.y = Position.y;\n"
+ " gl_Position.z = 0.0;\n"
+ " gl_Position.w = 1.0;\n"
+
+ // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion).
+ // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD.
+ " vec3 TanEyeAngleR = vec3 ( TexCoord0.x, TexCoord0.y, 1.0 );\n"
+ " vec3 TanEyeAngleG = vec3 ( TexCoord1.x, TexCoord1.y, 1.0 );\n"
+ " vec3 TanEyeAngleB = vec3 ( TexCoord2.x, TexCoord2.y, 1.0 );\n"
+
+ // Accurate time warp lerp vs. faster
+#if 1
+ // Apply the two 3x3 timewarp rotations to these vectors.
+ " vec3 TransformedRStart = (EyeRotationStart * vec4(TanEyeAngleR, 0)).xyz;\n"
+ " vec3 TransformedGStart = (EyeRotationStart * vec4(TanEyeAngleG, 0)).xyz;\n"
+ " vec3 TransformedBStart = (EyeRotationStart * vec4(TanEyeAngleB, 0)).xyz;\n"
+ " vec3 TransformedREnd = (EyeRotationEnd * vec4(TanEyeAngleR, 0)).xyz;\n"
+ " vec3 TransformedGEnd = (EyeRotationEnd * vec4(TanEyeAngleG, 0)).xyz;\n"
+ " vec3 TransformedBEnd = (EyeRotationEnd * vec4(TanEyeAngleB, 0)).xyz;\n"
+ // And blend between them.
+ " vec3 TransformedR = mix ( TransformedRStart, TransformedREnd, Color.a );\n"
+ " vec3 TransformedG = mix ( TransformedGStart, TransformedGEnd, Color.a );\n"
+ " vec3 TransformedB = mix ( TransformedBStart, TransformedBEnd, Color.a );\n"
+#else
+ " mat3 EyeRotation = mix ( EyeRotationStart, EyeRotationEnd, Color.a );\n"
+ " vec3 TransformedR = EyeRotation * TanEyeAngleR;\n"
+ " vec3 TransformedG = EyeRotation * TanEyeAngleG;\n"
+ " vec3 TransformedB = EyeRotation * TanEyeAngleB;\n"
+#endif
+
+ // Project them back onto the Z=1 plane of the rendered images.
+ " float RecipZR = 1.0 / TransformedR.z;\n"
+ " float RecipZG = 1.0 / TransformedG.z;\n"
+ " float RecipZB = 1.0 / TransformedB.z;\n"
+ " vec2 FlattenedR = vec2 ( TransformedR.x * RecipZR, TransformedR.y * RecipZR );\n"
+ " vec2 FlattenedG = vec2 ( TransformedG.x * RecipZG, TransformedG.y * RecipZG );\n"
+ " vec2 FlattenedB = vec2 ( TransformedB.x * RecipZB, TransformedB.y * RecipZB );\n"
+
+ // These are now still in TanEyeAngle space.
+ // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye)
+ " vec2 SrcCoordR = FlattenedR * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " vec2 SrcCoordG = FlattenedG * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " vec2 SrcCoordB = FlattenedB * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " oTexCoord0 = SrcCoordR;\n"
+ " oTexCoord0.y = 1-oTexCoord0.y;\n"
+ " oTexCoord1 = SrcCoordG;\n"
+ " oTexCoord1.y = 1-oTexCoord1.y;\n"
+ " oTexCoord2 = SrcCoordB;\n"
+ " oTexCoord2.y = 1-oTexCoord2.y;\n"
+ " oColor = Color.r;\n" // Used for vignette fade.
+ "}\n";
+
+static const char* PostProcessMeshPositionalTimewarpVertexShaderSrc =
+ "#version 150\n"
+ "uniform sampler2D Texture0;\n"
+ "uniform vec2 EyeToSourceUVScale;\n"
+ "uniform vec2 EyeToSourceUVOffset;\n"
+ "uniform vec2 DepthProjector;\n"
+ "uniform vec2 DepthDimSize;\n"
+ "uniform mat4 EyeRotationStart;\n"
+ "uniform mat4 EyeRotationEnd;\n"
+
+ "in vec2 Position;\n"
+ "in vec4 Color;\n"
+ "in vec2 TexCoord0;\n"
+ "in vec2 TexCoord1;\n"
+ "in vec2 TexCoord2;\n"
+
+ "out vec4 oColor;\n"
+ "out vec2 oTexCoord0;\n"
+ "out vec2 oTexCoord1;\n"
+ "out vec2 oTexCoord2;\n"
+
+ "vec4 PositionFromDepth(vec2 inTexCoord)\n"
+ "{\n"
+ " vec2 eyeToSourceTexCoord = inTexCoord * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " eyeToSourceTexCoord.y = 1 - eyeToSourceTexCoord.y;\n"
+ " float depth = texelFetch(Texture0, ivec2(eyeToSourceTexCoord * DepthDimSize), 0).x;\n"
+ " float linearDepth = DepthProjector.y / (depth - DepthProjector.x);\n"
+ " vec4 retVal = vec4(inTexCoord, 1, 1);\n"
+ " retVal.xyz *= linearDepth;\n"
+ " return retVal;\n"
+ "}\n"
+
+ "vec2 TimewarpTexCoordToWarpedPos(vec2 inTexCoord, float a)\n"
+ "{\n"
+ // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion).
+ // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD.
+ // Apply the 4x4 timewarp rotation to these vectors.
+ " vec4 inputPos = PositionFromDepth(inTexCoord);\n"
+ " vec3 transformed = mix ( EyeRotationStart * inputPos, EyeRotationEnd * inputPos, a ).xyz;\n"
+ // Project them back onto the Z=1 plane of the rendered images.
+ " vec2 flattened = transformed.xy / transformed.z;\n"
+ // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye)
+ " vec2 noDepthUV = flattened * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ //" float depth = texture2DLod(Texture0, noDepthUV, 0).r;\n"
+ " return noDepthUV.xy;\n"
+ "}\n"
+
+ "void main()\n"
+ "{\n"
+ " gl_Position.x = Position.x;\n"
+ " gl_Position.y = Position.y;\n"
+ " gl_Position.z = 0.0;\n"
+ " gl_Position.w = 1.0;\n"
+
+ // warped positions are a bit more involved, hence a separate function
+ " oTexCoord0 = TimewarpTexCoordToWarpedPos(TexCoord0, Color.a);\n"
+ " oTexCoord0.y = 1-oTexCoord0.y;\n"
+ " oTexCoord1 = TimewarpTexCoordToWarpedPos(TexCoord1, Color.a);\n"
+ " oTexCoord1.y = 1-oTexCoord1.y;\n"
+ " oTexCoord2 = TimewarpTexCoordToWarpedPos(TexCoord2, Color.a);\n"
+ " oTexCoord2.y = 1-oTexCoord2.y;\n"
+
+ " oColor = vec4(Color.r); // Used for vignette fade.\n"
"}\n";
static const char* PostProcessFragShaderSrc =
"uniform vec2 LensCenter;\n"
"uniform vec2 ScreenCenter;\n"
- "uniform vec2 Scale;\n"
- "uniform vec2 ScaleIn;\n"
+ "uniform vec2 EyeToSourceUVScale;\n"
+ "uniform vec2 EyeToSourceNDCScale;\n"
"uniform vec4 HmdWarpParam;\n"
- "uniform sampler2D Texture0;\n"
+ "uniform sampler2D Texture1;\n"
+
"varying vec2 oTexCoord;\n"
- "\n"
+
"vec2 HmdWarp(vec2 in01)\n"
"{\n"
- " vec2 theta = (in01 - LensCenter) * ScaleIn;\n" // Scales to [-1, 1]
+ " vec2 theta = (in01 - LensCenter) * EyeToSourceNDCScale;\n" // Scales to [-1, 1]
" float rSq = theta.x * theta.x + theta.y * theta.y;\n"
" vec2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + "
" HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n"
- " return LensCenter + Scale * theta1;\n"
+ " return LensCenter + EyeToSourceUVScale * theta1;\n"
"}\n"
+
"void main()\n"
"{\n"
" vec2 tc = HmdWarp(oTexCoord);\n"
" if (!all(equal(clamp(tc, ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)), tc)))\n"
" gl_FragColor = vec4(0);\n"
" else\n"
- " gl_FragColor = texture2D(Texture0, tc);\n"
+ " gl_FragColor = texture2D(Texture1, tc);\n"
"}\n";
// Shader with lens distortion and chromatic aberration correction.
-static const char* PostProcessFullFragShaderSrc =
- "uniform vec2 LensCenter;\n"
- "uniform vec2 ScreenCenter;\n"
- "uniform vec2 Scale;\n"
- "uniform vec2 ScaleIn;\n"
+static const char* PostProcessFragShaderWithChromAbSrc =
+ "uniform sampler2D Texture;\n"
+ "uniform vec3 DistortionClearColor;\n"
+ "uniform float EdgeFadeScale;\n"
+ "uniform vec2 EyeToSourceUVScale;\n"
+ "uniform vec2 EyeToSourceUVOffset;\n"
+ "uniform vec2 EyeToSourceNDCScale;\n"
+ "uniform vec2 EyeToSourceNDCOffset;\n"
+ "uniform vec2 TanEyeAngleScale;\n"
+ "uniform vec2 TanEyeAngleOffset;\n"
"uniform vec4 HmdWarpParam;\n"
"uniform vec4 ChromAbParam;\n"
- "uniform sampler2D Texture0;\n"
+
+ "varying vec4 oPosition;\n"
"varying vec2 oTexCoord;\n"
- "\n"
- // Scales input texture coordinates for distortion.
- // ScaleIn maps texture coordinates to Scales to ([-1, 1]), although top/bottom will be
- // larger due to aspect ratio.
- "void main()\n"
+
+ "void main()\n"
"{\n"
- " vec2 theta = (oTexCoord - LensCenter) * ScaleIn;\n" // Scales to [-1, 1]
- " float rSq= theta.x * theta.x + theta.y * theta.y;\n"
- " vec2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + "
- " HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n"
- " \n"
- " // Detect whether blue texture coordinates are out of range since these will scaled out the furthest.\n"
- " vec2 thetaBlue = theta1 * (ChromAbParam.z + ChromAbParam.w * rSq);\n"
- " vec2 tcBlue = LensCenter + Scale * thetaBlue;\n"
- " if (!all(equal(clamp(tcBlue, ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)), tcBlue)))\n"
+ // Input oTexCoord is [-1,1] across the half of the screen used for a single eye.
+ " vec2 TanEyeAngleDistorted = oTexCoord * TanEyeAngleScale + TanEyeAngleOffset;\n" // Scales to tan(thetaX),tan(thetaY), but still distorted (i.e. only the center is correct)
+ " float RadiusSq = TanEyeAngleDistorted.x * TanEyeAngleDistorted.x + TanEyeAngleDistorted.y * TanEyeAngleDistorted.y;\n"
+ " float Distort = 1.0 / ( 1.0 + RadiusSq * ( HmdWarpParam.y + RadiusSq * ( HmdWarpParam.z + RadiusSq * ( HmdWarpParam.w ) ) ) );\n"
+ " float DistortR = Distort * ( ChromAbParam.x + RadiusSq * ChromAbParam.y );\n"
+ " float DistortG = Distort;\n"
+ " float DistortB = Distort * ( ChromAbParam.z + RadiusSq * ChromAbParam.w );\n"
+ " vec2 TanEyeAngleR = DistortR * TanEyeAngleDistorted;\n"
+ " vec2 TanEyeAngleG = DistortG * TanEyeAngleDistorted;\n"
+ " vec2 TanEyeAngleB = DistortB * TanEyeAngleDistorted;\n"
+
+ // These are now in "TanEyeAngle" space.
+ // The vectors (TanEyeAngleRGB.x, TanEyeAngleRGB.y, 1.0) are real-world vectors pointing from the eye to where the components of the pixel appear to be.
+ // If you had a raytracer, you could just use them directly.
+
+ // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye)
+ " vec2 SourceCoordR = TanEyeAngleR * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " SourceCoordR.y = 1 - SourceCoordR.y;\n"
+ " vec2 SourceCoordG = TanEyeAngleG * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " SourceCoordG.y = 1 - SourceCoordG.y;\n"
+ " vec2 SourceCoordB = TanEyeAngleB * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " SourceCoordB.y = 1 - SourceCoordB.y;\n"
+
+ // Find the distance to the nearest edge.
+ " vec2 NDCCoord = TanEyeAngleG * EyeToSourceNDCScale + EyeToSourceNDCOffset;\n"
+ " float EdgeFadeIn = clamp ( EdgeFadeScale, 0, 1e5 ) * ( 1.0 - max ( abs ( NDCCoord.x ), abs ( NDCCoord.y ) ) );\n"
+ " if ( EdgeFadeIn < 0.0 )\n"
" {\n"
- " gl_FragColor = vec4(0);\n"
- " return;\n"
+ " gl_FragColor = vec4(DistortionClearColor.r, DistortionClearColor.g, DistortionClearColor.b, 1.0);\n"
+ " return;\n"
" }\n"
- " \n"
- " // Now do blue texture lookup.\n"
- " float blue = texture2D(Texture0, tcBlue).b;\n"
- " \n"
- " // Do green lookup (no scaling).\n"
- " vec2 tcGreen = LensCenter + Scale * theta1;\n"
- " vec4 center = texture2D(Texture0, tcGreen);\n"
- " \n"
- " // Do red scale and lookup.\n"
- " vec2 thetaRed = theta1 * (ChromAbParam.x + ChromAbParam.y * rSq);\n"
- " vec2 tcRed = LensCenter + Scale * thetaRed;\n"
- " float red = texture2D(Texture0, tcRed).r;\n"
- " \n"
- " gl_FragColor = vec4(red, center.g, blue, center.a);\n"
+ " EdgeFadeIn = clamp ( EdgeFadeIn, 0.0, 1.0 );\n"
+
+ // Actually do the lookups.
+ " float ResultR = texture2D(Texture, SourceCoordR).r;\n"
+ " float ResultG = texture2D(Texture, SourceCoordG).g;\n"
+ " float ResultB = texture2D(Texture, SourceCoordB).b;\n"
+
+ " gl_FragColor = vec4(ResultR * EdgeFadeIn, ResultG * EdgeFadeIn, ResultB * EdgeFadeIn, 1.0);\n"
"}\n";
+
+
static const char* VShaderSrcs[VShader_Count] =
{
DirectVertexShaderSrc,
StdVertexShaderSrc,
- PostProcessVertexShaderSrc
+ PostProcessVertexShaderSrc,
+ PostProcessMeshVertexShaderSrc,
+ PostProcessMeshTimewarpVertexShaderSrc,
+ PostProcessMeshPositionalTimewarpVertexShaderSrc
};
static const char* FShaderSrcs[FShader_Count] =
{
@@ -253,16 +603,17 @@ static const char* FShaderSrcs[FShader_Count] =
GouraudFragShaderSrc,
TextureFragShaderSrc,
AlphaTextureFragShaderSrc,
- PostProcessFragShaderSrc,
- PostProcessFullFragShaderSrc,
+ PostProcessFragShaderWithChromAbSrc,
LitSolidFragShaderSrc,
LitTextureFragShaderSrc,
- MultiTextureFragShaderSrc
+ MultiTextureFragShaderSrc,
+ PostProcessMeshFragShaderSrc,
+ PostProcessMeshTimewarpFragShaderSrc,
+ PostProcessMeshPositionalTimewarpFragShaderSrc
};
-
-RenderDevice::RenderDevice(const RendererParams& p)
+RenderDevice::RenderDevice(const RendererParams&)
{
for (int i = 0; i < VShader_Count; i++)
VertexShaders[i] = *new Shader(this, Shader_Vertex, VShaderSrcs[i]);
@@ -278,6 +629,37 @@ RenderDevice::RenderDevice(const RendererParams& p)
glGenFramebuffersEXT(1, &CurrentFbo);
}
+RenderDevice::~RenderDevice()
+{
+ Shutdown();
+}
+
+void RenderDevice::Shutdown()
+{
+ // Release any other resources first.
+ OVR::Render::RenderDevice::Shutdown();
+
+ // This runs before the subclass's Shutdown(), where the context, etc, may be deleted.
+
+ glDeleteFramebuffersEXT(1, &CurrentFbo);
+
+ for (int i = 0; i < VShader_Count; ++i)
+ VertexShaders[i].Clear();
+
+ for (int i = 0; i < FShader_Count; ++i)
+ FragShaders[i].Clear();
+
+ DefaultFill.Clear();
+ DepthBuffers.Clear();
+}
+
+
+void RenderDevice::FillTexturedRect(float left, float top, float right, float bottom, float ul, float vt, float ur, float vb, Color c, Ptr<OVR::Render::Texture> tex)
+{
+ Render::RenderDevice::FillTexturedRect(left, top, right, bottom, ul, vb, ur, vt, c, tex);
+}
+
+
Shader *RenderDevice::LoadBuiltinShader(ShaderStage stage, int shader)
{
switch (stage)
@@ -323,7 +705,7 @@ void RenderDevice::SetDepthMode(bool enable, bool write, CompareFunc func)
glDisable(GL_DEPTH_TEST);
}
-void RenderDevice::SetRealViewport(const Viewport& vp)
+void RenderDevice::SetViewport(const Recti& vp)
{
int wh;
if (CurRenderTarget)
@@ -332,30 +714,38 @@ void RenderDevice::SetRealViewport(const Viewport& vp)
wh = WindowHeight;
glViewport(vp.x, wh-vp.y-vp.h, vp.w, vp.h);
- glEnable(GL_SCISSOR_TEST);
- glScissor(vp.x, wh-vp.y-vp.h, vp.w, vp.h);
+ //glEnable(GL_SCISSOR_TEST);
+ //glScissor(vp.x, wh-vp.y-vp.h, vp.w, vp.h);
}
-void RenderDevice::Clear(float r, float g, float b, float a, float depth)
+void RenderDevice::WaitUntilGpuIdle()
{
- glClearColor(r,g,b,a);
- glClearDepth(depth);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glFlush();
+ glFinish();
}
-RBuffer* RenderDevice::GetDepthBuffer(int w, int h, int ms)
+void RenderDevice::Clear(float r, float g, float b, float a, float depth, bool clearColor /*= true*/, bool clearDepth /*= true*/)
+{
+ glClearColor(r,g,b,a);
+ glClearDepth(depth);
+ glClear(
+ ( clearColor ? ( GL_COLOR_BUFFER_BIT ) : 0 ) |
+ ( clearDepth ? ( GL_DEPTH_BUFFER_BIT ) : 0 )
+ );
+}
+
+Texture* RenderDevice::GetDepthBuffer(int w, int h, int ms)
{
for (unsigned i = 0; i < DepthBuffers.GetSize(); i++)
- if (w == DepthBuffers[i]->Width && h == DepthBuffers[i]->Height)// && ms == DepthBuffers[i]->Samples)
+ if (w == DepthBuffers[i]->Width && h == DepthBuffers[i]->Height && ms == DepthBuffers[i]->GetSamples())
return DepthBuffers[i];
- //Ptr<Texture> newDepth = *CreateTexture(Texture_Depth|Texture_RenderTarget|ms, w, h, NULL);
- Ptr<RBuffer> newDepth = *new RBuffer(GL_DEPTH24_STENCIL8, w, h); // combined depth stencil
+ Ptr<Texture> newDepth = *CreateTexture(Texture_Depth|Texture_RenderTarget|ms, w, h, NULL);
DepthBuffers.PushBack(newDepth);
return newDepth.GetPtr();
}
-void RenderDevice::SetRenderTarget(Render::Texture* color, Render::Texture*, Render::Texture* stencil)
+void RenderDevice::SetRenderTarget(Render::Texture* color, Render::Texture* depth, Render::Texture* stencil)
{
OVR_UNUSED(stencil);
@@ -365,14 +755,14 @@ void RenderDevice::SetRenderTarget(Render::Texture* color, Render::Texture*, Ren
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
return;
}
- //if (depth == NULL)
- RBuffer* depth = GetDepthBuffer(color->GetWidth(), color->GetHeight(), 0); //CurRenderTarget->Samples);
+
+ if (depth == NULL)
+ depth = GetDepthBuffer(color->GetWidth(), color->GetHeight(), CurRenderTarget->GetSamples());
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, CurrentFbo);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, ((Texture*)color)->TexId, 0);
if (depth)
- //glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, ((Texture*)depth)->TexId, 0);
- glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, ((RBuffer*)depth)->BufId);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, ((Texture*)depth)->TexId, 0);
else
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0);
@@ -404,8 +794,7 @@ Fill* RenderDevice::CreateSimpleFill(int flags)
OVR_UNUSED(flags);
return DefaultFill;
}
-
-
+
void RenderDevice::Render(const Matrix4f& matrix, Model* model)
{
// Store data in buffers if not already
@@ -428,7 +817,7 @@ void RenderDevice::Render(const Matrix4f& matrix, Model* model)
}
void RenderDevice::Render(const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices,
- const Matrix4f& matrix, int offset, int count, PrimitiveType rprim)
+ const Matrix4f& matrix, int offset, int count, PrimitiveType rprim, bool useDistortionVertex/* = false*/)
{
ShaderSet* shaders = (ShaderSet*) ((ShaderFill*)fill)->GetShaders();
@@ -461,15 +850,26 @@ void RenderDevice::Render(const Fill* fill, Render::Buffer* vertices, Render::Bu
Lighting->Set(shaders);
}
- glBindBuffer(GL_ARRAY_BUFFER, ((Buffer*)vertices)->GLBuffer);
- for (int i = 0; i < 5; i++)
- glEnableVertexAttribArray(i);
-
- glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(Vertex), (char*)offset + offsetof(Vertex, Pos));
- glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, true, sizeof(Vertex), (char*)offset + offsetof(Vertex, C));
- glVertexAttribPointer(2, 2, GL_FLOAT, false, sizeof(Vertex), (char*)offset + offsetof(Vertex, U));
- glVertexAttribPointer(3, 2, GL_FLOAT, false, sizeof(Vertex), (char*)offset + offsetof(Vertex, U2));
- glVertexAttribPointer(4, 3, GL_FLOAT, false, sizeof(Vertex), (char*)offset + offsetof(Vertex, Norm));
+ glBindBuffer(GL_ARRAY_BUFFER, ((Buffer*)vertices)->GLBuffer);
+ for (int i = 0; i < 5; i++)
+ glEnableVertexAttribArray(i);
+
+ if (useDistortionVertex)
+ {
+ glVertexAttribPointer(0, 2, GL_FLOAT, false, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, Pos));
+ glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, true, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, Col));
+ glVertexAttribPointer(2, 2, GL_FLOAT, false, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, TexR));
+ glVertexAttribPointer(3, 2, GL_FLOAT, false, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, TexG));
+ glVertexAttribPointer(4, 2, GL_FLOAT, false, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, TexB));
+ }
+ else
+ {
+ glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(Vertex), (char*)offset + offsetof(Vertex, Pos));
+ glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, true, sizeof(Vertex), (char*)offset + offsetof(Vertex, C));
+ glVertexAttribPointer(2, 2, GL_FLOAT, false, sizeof(Vertex), (char*)offset + offsetof(Vertex, U));
+ glVertexAttribPointer(3, 2, GL_FLOAT, false, sizeof(Vertex), (char*)offset + offsetof(Vertex, U2));
+ glVertexAttribPointer(4, 3, GL_FLOAT, false, sizeof(Vertex), (char*)offset + offsetof(Vertex, Norm));
+ }
if (indices)
{
@@ -482,8 +882,8 @@ void RenderDevice::Render(const Fill* fill, Render::Buffer* vertices, Render::Bu
glDrawArrays(prim, 0, count);
}
- for (int i = 0; i < 5; i++)
- glDisableVertexAttribArray(i);
+ for (int i = 0; i < 5; i++)
+ glDisableVertexAttribArray(i);
}
void RenderDevice::RenderWithAlpha(const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices,
@@ -526,7 +926,7 @@ bool Buffer::Data(int use, const void* buffer, size_t size)
return 1;
}
-void* Buffer::Map(size_t start, size_t size, int flags)
+void* Buffer::Map(size_t, size_t, int)
{
int mode = GL_WRITE_ONLY;
//if (flags & Map_Unsynchronized)
@@ -543,7 +943,13 @@ bool Buffer::Unmap(void*)
glBindBuffer(Use, GLBuffer);
int r = glUnmapBuffer(Use);
glBindBuffer(Use, 0);
- return r;
+ return r != 0;
+}
+
+Shader::~Shader()
+{
+ if (GLShader)
+ glDeleteShader(GLShader);
}
bool Shader::Compile(const char* src)
@@ -576,6 +982,24 @@ ShaderSet::~ShaderSet()
glDeleteProgram(Prog);
}
+void ShaderSet::SetShader(Render::Shader *s)
+{
+ Shaders[s->GetStage()] = s;
+ Shader* gls = (Shader*)s;
+ glAttachShader(Prog, gls->GLShader);
+ if (Shaders[Shader_Vertex] && Shaders[Shader_Fragment])
+ Link();
+}
+
+void ShaderSet::UnsetShader(int stage)
+{
+ Shader* gls = (Shader*)(Render::Shader*)Shaders[stage];
+ if (gls)
+ glDetachShader(Prog, gls->GLShader);
+ Shaders[stage] = NULL;
+ Link();
+}
+
bool ShaderSet::Link()
{
glBindAttribLocation(Prog, 0, "Position");
@@ -600,14 +1024,19 @@ bool ShaderSet::Link()
UniformInfo.Clear();
LightingVer = 0;
UsesLighting = 0;
- GLuint i = 0;
- for(;; i++)
+
+ GLint uniformCount = 0;
+ glGetProgramiv(Prog, GL_ACTIVE_UNIFORMS, &uniformCount);
+ OVR_ASSERT(uniformCount >= 0);
+
+ for(GLuint i = 0; i < (GLuint)uniformCount; i++)
{
GLsizei namelen;
GLint size = 0;
GLenum type;
GLchar name[32];
glGetActiveUniform(Prog, i, sizeof(name), &namelen, &size, &type, name);
+
if (size)
{
int l = glGetUniformLocation(Prog, name);
@@ -628,6 +1057,7 @@ bool ShaderSet::Link()
case GL_FLOAT_VEC2: u.Type = 2; break;
case GL_FLOAT_VEC3: u.Type = 3; break;
case GL_FLOAT_VEC4: u.Type = 4; break;
+ case GL_FLOAT_MAT3: u.Type = 12; break;
case GL_FLOAT_MAT4: u.Type = 16; break;
default:
continue;
@@ -645,7 +1075,7 @@ bool ShaderSet::Link()
for (int i = 0; i < 8; i++)
{
char texv[32];
- sprintf(texv, "Texture%d", i);
+ OVR_sprintf(texv, 10, "Texture%d", i);
TexLoc[i] = glGetUniformLocation(Prog, texv);
if (TexLoc[i] < 0)
break;
@@ -664,7 +1094,7 @@ void ShaderSet::Set(PrimitiveType) const
bool ShaderSet::SetUniform(const char* name, int n, const float* v)
{
- for (int i = 0; i < UniformInfo.GetSize(); i++)
+ for (unsigned int i = 0; i < UniformInfo.GetSize(); i++)
if (!strcmp(UniformInfo[i].Name.ToCStr(), name))
{
OVR_ASSERT(UniformInfo[i].Location >= 0);
@@ -675,6 +1105,8 @@ bool ShaderSet::SetUniform(const char* name, int n, const float* v)
case 2: glUniform2fv(UniformInfo[i].Location, n/2, v); break;
case 3: glUniform3fv(UniformInfo[i].Location, n/3, v); break;
case 4: glUniform4fv(UniformInfo[i].Location, n/4, v); break;
+ case 12: glUniformMatrix3fv(UniformInfo[i].Location, 1, 1, v); break;
+ case 16: glUniformMatrix4fv(UniformInfo[i].Location, 1, 1, v); break;
default: OVR_ASSERT(0);
}
return 1;
@@ -686,7 +1118,7 @@ bool ShaderSet::SetUniform(const char* name, int n, const float* v)
bool ShaderSet::SetUniform4x4f(const char* name, const Matrix4f& m)
{
- for (int i = 0; i < UniformInfo.GetSize(); i++)
+ for (unsigned int i = 0; i < UniformInfo.GetSize(); i++)
if (!strcmp(UniformInfo[i].Name.ToCStr(), name))
{
glUseProgram(Prog);
@@ -722,7 +1154,7 @@ void Texture::SetSampleMode(int sm)
case Sample_Linear:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
break;
case Sample_Anisotropic:
@@ -734,7 +1166,7 @@ void Texture::SetSampleMode(int sm)
case Sample_Nearest:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
break;
}
@@ -758,6 +1190,20 @@ void Texture::SetSampleMode(int sm)
glBindTexture(GL_TEXTURE_2D, 0);
}
+ovrTexture Texture::Get_ovrTexture()
+{
+ ovrTexture tex;
+ OVR::Sizei newRTSize(Width, Height);
+
+ ovrGLTextureData* texData = (ovrGLTextureData*)&tex;
+ texData->Header.API = ovrRenderAPI_OpenGL;
+ texData->Header.TextureSize = newRTSize;
+ texData->Header.RenderViewport = Recti(newRTSize);
+ texData->TexId = TexId;
+
+ return tex;
+}
+
Texture* RenderDevice::CreateTexture(int format, int width, int height, const void* data, int mipcount)
{
GLenum glformat, gltype = GL_UNSIGNED_BYTE;
@@ -765,7 +1211,7 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
{
case Texture_RGBA: glformat = GL_RGBA; break;
case Texture_R: glformat = GL_ALPHA; break;
- case Texture_Depth: glformat = GL_DEPTH; gltype = GL_DEPTH_COMPONENT; break;
+ case Texture_Depth: glformat = GL_DEPTH_COMPONENT32F; 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;
@@ -774,7 +1220,7 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
}
Texture* NewTex = new Texture(this, width, height);
glBindTexture(GL_TEXTURE_2D, NewTex->TexId);
- glGetError();
+ OVR_ASSERT(!glGetError());
if (format & Texture_Compressed)
{
@@ -792,6 +1238,8 @@ 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);
@@ -831,12 +1279,6 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
return NewTex;
}
-bool RenderDevice::SetFullscreen(DisplayMode fullscreen)
-{
- Params.Fullscreen = fullscreen;
- return true;
-}
-
RBuffer::RBuffer(GLenum format, GLint w, GLint h)
{
Width = w;
@@ -849,7 +1291,8 @@ RBuffer::RBuffer(GLenum format, GLint w, GLint h)
RBuffer::~RBuffer()
{
- glDeleteRenderbuffersEXT(1, &BufId);
+ if (BufId)
+ glDeleteRenderbuffersEXT(1, &BufId);
}
}}}
diff --git a/Samples/CommonSrc/Render/Render_GL_Device.h b/Samples/CommonSrc/Render/Render_GL_Device.h
index 88eaff4..5d97eef 100644
--- a/Samples/CommonSrc/Render/Render_GL_Device.h
+++ b/Samples/CommonSrc/Render/Render_GL_Device.h
@@ -34,13 +34,76 @@ limitations under the License.
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
#else
+#ifndef GL_GLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES
+#endif
#include <GL/gl.h>
#include <GL/glext.h>
+#if defined(OVR_OS_WIN32)
+#include <GL/wglext.h>
+#endif
#endif
namespace OVR { namespace Render { namespace GL {
+// GL extension Hooks for PC.
+#if defined(OVR_OS_WIN32)
+
+extern PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT;
+extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
+extern PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
+extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
+extern PFNGLDELETESHADERPROC glDeleteShader;
+extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
+extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
+extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
+extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
+extern PFNGLACTIVETEXTUREPROC glActiveTexture;
+extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
+extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
+extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
+extern PFNGLBINDBUFFERPROC glBindBuffer;
+extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
+extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
+extern PFNGLBUFFERDATAPROC glBufferData;
+extern PFNGLGENBUFFERSPROC glGenBuffers;
+extern PFNGLMAPBUFFERPROC glMapBuffer;
+extern PFNGLUNMAPBUFFERPROC glUnmapBuffer;
+extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
+extern PFNGLGETSHADERIVPROC glGetShaderiv;
+extern PFNGLCOMPILESHADERPROC glCompileShader;
+extern PFNGLSHADERSOURCEPROC glShaderSource;
+extern PFNGLCREATESHADERPROC glCreateShader;
+extern PFNGLCREATEPROGRAMPROC glCreateProgram;
+extern PFNGLATTACHSHADERPROC glAttachShader;
+extern PFNGLDETACHSHADERPROC glDetachShader;
+extern PFNGLDELETEPROGRAMPROC glDeleteProgram;
+extern PFNGLUNIFORM1IPROC glUniform1i;
+extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
+extern PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform;
+extern PFNGLUSEPROGRAMPROC glUseProgram;
+extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
+extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
+extern PFNGLLINKPROGRAMPROC glLinkProgram;
+extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
+extern PFNGLUNIFORM4FVPROC glUniform4fv;
+extern PFNGLUNIFORM3FVPROC glUniform3fv;
+extern PFNGLUNIFORM2FVPROC glUniform2fv;
+extern PFNGLUNIFORM1FVPROC glUniform1fv;
+extern PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
+extern PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT;
+extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
+extern PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT;
+extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;
+
+// For testing
+extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
+
+extern void InitGLExtensions();
+
+#endif
+
+
class RenderDevice;
class Buffer : public Render::Buffer
@@ -77,6 +140,7 @@ public:
virtual int GetHeight() const { return Height; }
virtual void SetSampleMode(int);
+ virtual ovrTexture Get_ovrTexture();
virtual void Set(int slot, ShaderStage stage = Shader_Fragment) const;
};
@@ -91,11 +155,8 @@ public:
{
Compile(src);
}
- ~Shader()
- {
- if (GLShader)
- glDeleteShader(GLShader);
- }
+
+ ~Shader();
bool Compile(const char* src);
GLenum GLStage() const
@@ -133,22 +194,8 @@ public:
ShaderSet();
~ShaderSet();
- virtual void SetShader(Render::Shader *s)
- {
- Shaders[s->GetStage()] = s;
- Shader* gls = (Shader*)s;
- glAttachShader(Prog, gls->GLShader);
- if (Shaders[Shader_Vertex] && Shaders[Shader_Fragment])
- Link();
- }
- virtual void UnsetShader(int stage)
- {
- Shader* gls = (Shader*)(Render::Shader*)Shaders[stage];
- if (gls)
- glDetachShader(Prog, gls->GLShader);
- Shaders[stage] = NULL;
- Link();
- }
+ virtual void SetShader(Render::Shader *s);
+ virtual void UnsetShader(int stage);
virtual void Set(PrimitiveType prim) const;
@@ -161,7 +208,7 @@ public:
bool Link();
};
- class RBuffer : public RefCountBase<RBuffer>
+class RBuffer : public RefCountBase<RBuffer>
{
public:
int Width, Height;
@@ -180,28 +227,38 @@ class RenderDevice : public Render::RenderDevice
Matrix4f Proj;
+protected:
Ptr<Texture> CurRenderTarget;
- Array<Ptr<RBuffer> > DepthBuffers;
+ Array<Ptr<Texture> > DepthBuffers;
GLuint CurrentFbo;
const LightingParams* Lighting;
public:
RenderDevice(const RendererParams& p);
+ virtual ~RenderDevice();
- virtual void SetRealViewport(const Viewport& vp);
+ virtual void Shutdown();
+
+ virtual void FillTexturedRect(float left, float top, float right, float bottom, float ul, float vt, float ur, float vb, Color c, Ptr<OVR::Render::Texture> tex);
+
+ virtual void SetViewport(const Recti& vp);
//virtual void SetScissor(int x, int y, int w, int h);
+
+ virtual void WaitUntilGpuIdle();
- virtual void Clear(float r = 0, float g = 0, float b = 0, float a = 1, float depth = 1);
+ virtual void Clear(float r = 0, float g = 0, float b = 0, float a = 1, float depth = 1,
+ bool clearColor = true, bool clearDepth = true);
virtual void Rect(float left, float top, float right, float bottom) { OVR_UNUSED4(left,top,right,bottom); }
virtual void BeginRendering();
virtual void SetDepthMode(bool enable, bool write, CompareFunc func = Compare_Less);
virtual void SetWorldUniforms(const Matrix4f& proj);
- RBuffer* GetDepthBuffer(int w, int h, int ms);
+ Texture* GetDepthBuffer(int w, int h, int ms);
+ virtual void Present (bool withVsync){OVR_UNUSED(withVsync);};
virtual void SetRenderTarget(Render::Texture* color,
Render::Texture* depth = NULL, Render::Texture* stencil = NULL);
@@ -209,7 +266,7 @@ public:
virtual void Render(const Matrix4f& matrix, Model* model);
virtual void Render(const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices,
- const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles);
+ const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles, bool useDistortionVertex = false);
virtual void RenderWithAlpha(const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices,
const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles);
@@ -222,8 +279,6 @@ public:
virtual Shader *LoadBuiltinShader(ShaderStage stage, int shader);
void SetTexture(Render::ShaderStage, int slot, const Texture* t);
-
- virtual bool SetFullscreen(DisplayMode fullscreen);
};
}}}
diff --git a/Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp b/Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp
index 4f22a50..1065c98 100644
--- a/Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp
+++ b/Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp
@@ -3,7 +3,7 @@
Filename : Render_GL_Win32 Device.cpp
Content : Win32 OpenGL Device implementation
Created : September 10, 2012
-Authors : Andrew Reisse, Michael Antonov
+Authors : Andrew Reisse, Michael Antonov, David Borel
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
@@ -22,16 +22,46 @@ limitations under the License.
************************************************************************************/
#include "Render_GL_Win32_Device.h"
+#include "OVR_CAPI_GL.h"
+
+#include <dwmapi.h>
namespace OVR { namespace Render { namespace GL { namespace Win32 {
+typedef HRESULT (__stdcall *PFNDWMENABLECOMPOSITIONPROC) (UINT);
+
+#pragma warning(disable : 4995)
+PFNDWMENABLECOMPOSITIONPROC DwmEnableComposition;
+
// ***** GL::Win32::RenderDevice
+
+RenderDevice::RenderDevice(const Render::RendererParams& p, HWND win, HDC dc, HGLRC gl)
+ : GL::RenderDevice(p)
+ , Window(win)
+ , WglContext(gl)
+ , GdiDc(dc)
+ , PreFullscreen(0, 0, 0, 0)
+ , HMonitor(0)
+ , FSDesktop(0, 0, 0, 0)
+{
+ OVR_UNUSED(p);
+}
// Implement static initializer function to create this class.
-Render::RenderDevice* RenderDevice::CreateDevice(const RendererParams&, void* oswnd)
+Render::RenderDevice* RenderDevice::CreateDevice(const RendererParams& rp, void* oswnd)
{
HWND hwnd = (HWND)oswnd;
+
+ if (!DwmEnableComposition)
+ {
+ HINSTANCE hInst = LoadLibrary( L"dwmapi.dll" );
+ OVR_ASSERT(hInst);
+ DwmEnableComposition = (PFNDWMENABLECOMPOSITIONPROC)GetProcAddress( hInst, "DwmEnableComposition" );
+ OVR_ASSERT(DwmEnableComposition);
+ }
+
+ DwmEnableComposition(DWM_EC_DISABLECOMPOSITION);
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(pfd));
@@ -63,18 +93,40 @@ Render::RenderDevice* RenderDevice::CreateDevice(const RendererParams&, void* os
return NULL;
}
- // return new RenderDevice(rp, hwnd, dc, context);
- return 0;
+ InitGLExtensions();
+
+ return new RenderDevice(rp, hwnd, dc, context);
}
+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.WglContext = WglContext;
+ cfg.OGL.Window = Window;
+ cfg.OGL.GdiDc = GdiDc;
-void RenderDevice::Present()
+ return cfg.Config;
+}
+
+void RenderDevice::Present(bool useVsync)
{
- SwapBuffers(GdiDc);
+ BOOL success;
+ int swapInterval = (useVsync) ? 1 : 0;
+ if (wglGetSwapIntervalEXT() != swapInterval)
+ wglSwapIntervalEXT(swapInterval);
+
+ success = SwapBuffers(GdiDc);
+ OVR_ASSERT(success);
}
void RenderDevice::Shutdown()
{
+ //Release any remaining GL resources.
+ GL::RenderDevice::Shutdown();
+
if (WglContext)
{
wglMakeCurrent(NULL,NULL);
@@ -86,5 +138,189 @@ void RenderDevice::Shutdown()
}
}
+bool RenderDevice::SetParams(const RendererParams& newParams)
+{
+ Params = newParams;
+ //TODO: Apply changes now.
+ return true;
+}
+
+BOOL CALLBACK MonitorEnumFunc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData)
+{
+ RenderDevice* renderer = (RenderDevice*)dwData;
+
+ MONITORINFOEX monitor;
+ monitor.cbSize = sizeof(monitor);
+
+ if (::GetMonitorInfo(hMonitor, &monitor) && monitor.szDevice[0])
+ {
+ DISPLAY_DEVICE dispDev;
+ memset(&dispDev, 0, sizeof(dispDev));
+ dispDev.cb = sizeof(dispDev);
+
+ if (::EnumDisplayDevices(monitor.szDevice, 0, &dispDev, 0))
+ {
+ if (strstr(String(dispDev.DeviceName).ToCStr(), renderer->GetParams().Display.MonitorName.ToCStr()))
+ {
+ renderer->HMonitor = hMonitor;
+ renderer->FSDesktop.x = monitor.rcMonitor.left;
+ renderer->FSDesktop.y = monitor.rcMonitor.top;
+ renderer->FSDesktop.w = monitor.rcMonitor.right - monitor.rcMonitor.left;
+ renderer->FSDesktop.h = monitor.rcMonitor.bottom - monitor.rcMonitor.top;
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+bool RenderDevice::SetFullscreen(DisplayMode fullscreen)
+{
+ if (fullscreen == Params.Fullscreen)
+ {
+ return true;
+ }
+
+ if (Params.Fullscreen == Display_FakeFullscreen)
+ {
+ SetWindowLong(Window, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS);
+ SetWindowPos(Window, HWND_NOTOPMOST, PreFullscreen.x, PreFullscreen.y,
+ PreFullscreen.w, PreFullscreen.h, SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
+ }
+ else if (Params.Fullscreen == Display_Fullscreen)
+ {
+ {
+ // Find out the name of the device this window
+ // is on (this is for multi-monitor setups)
+ HMONITOR hMonitor = MonitorFromWindow(Window, MONITOR_DEFAULTTOPRIMARY);
+ MONITORINFOEX monInfo;
+ memset(&monInfo, 0, sizeof(MONITORINFOEX));
+ monInfo.cbSize = sizeof(MONITORINFOEX);
+ GetMonitorInfo(hMonitor, &monInfo);
+
+ // Restore the display resolution
+ ChangeDisplaySettingsEx(monInfo.szDevice, NULL, NULL, 0, NULL);
+ //ChangeDisplaySettings(NULL, 0);
+ }
+ {
+ // Restore the window styles
+ DWORD style = (DWORD)GetWindowLongPtr(Window, GWL_STYLE);
+ DWORD exstyle = (DWORD)GetWindowLongPtr(Window, GWL_EXSTYLE);
+ SetWindowLongPtr(Window, GWL_STYLE, style | WS_OVERLAPPEDWINDOW);
+ SetWindowLongPtr(Window, GWL_EXSTYLE, exstyle & (~(WS_EX_APPWINDOW | WS_EX_TOPMOST)));
+
+ MONITORINFOEX monInfo;
+ memset(&monInfo, 0, sizeof(MONITORINFOEX));
+ monInfo.cbSize = sizeof(MONITORINFOEX);
+ GetMonitorInfo(HMonitor, &monInfo);
+
+ // Restore the window size/position
+ SetWindowPos(Window, NULL, PreFullscreen.x, PreFullscreen.y, PreFullscreen.w, PreFullscreen.h,
+ SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOOWNERZORDER | SWP_NOREPOSITION | SWP_NOZORDER);
+ }
+ }
+
+
+ if (!Params.Display.MonitorName.IsEmpty())
+ {
+ EnumDisplayMonitors(0, 0, MonitorEnumFunc, (LPARAM)this);
+ }
+
+ if (fullscreen == Display_FakeFullscreen)
+ {
+ // Get WINDOWPLACEMENT before changing style to get OVERLAPPED coordinates,
+ // which we will restore.
+ WINDOWPLACEMENT wp;
+ wp.length = sizeof(wp);
+ GetWindowPlacement(Window, &wp);
+ PreFullscreen.w = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
+ PreFullscreen.h = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;
+ PreFullscreen.x = wp.rcNormalPosition.left;
+ PreFullscreen.y = wp.rcNormalPosition.top;
+ // Warning: SetWindowLong sends message computed based on old size (incorrect).
+ // A proper work-around would be to mask that message out during window frame change in Platform.
+ SetWindowLong(Window, GWL_STYLE, WS_OVERLAPPED | WS_VISIBLE | WS_CLIPSIBLINGS);
+ SetWindowPos(Window, NULL, FSDesktop.x, FSDesktop.y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_FRAMECHANGED);
+
+ // Relocate cursor into the window to avoid losing focus on first click.
+ POINT oldCursor;
+ if (GetCursorPos(&oldCursor) &&
+ ((oldCursor.x < FSDesktop.x) || (oldCursor.x > (FSDesktop.x + PreFullscreen.w)) ||
+ (oldCursor.y < FSDesktop.y) || (oldCursor.x > (FSDesktop.y + PreFullscreen.h))))
+ {
+ // TBD: FullScreen window logic should really be in platform; it causes world rotation
+ // in relative mouse mode.
+ ::SetCursorPos(FSDesktop.x, FSDesktop.y);
+ }
+ }
+ else if (fullscreen == Display_Fullscreen)
+ {
+ // Find out the name of the device this window
+ // is on (this is for multi-monitor setups)
+ MONITORINFOEX monInfo;
+ memset(&monInfo, 0, sizeof(MONITORINFOEX));
+ monInfo.cbSize = sizeof(MONITORINFOEX);
+ GetMonitorInfo(HMonitor, &monInfo);
+
+ // Find the requested device mode
+ DEVMODE dmode;
+ bool foundMode = false;
+ memset(&dmode, 0, sizeof(DEVMODE));
+ dmode.dmSize = sizeof(DEVMODE);
+ Recti vp = VP;
+ for(int i=0 ; EnumDisplaySettings(monInfo.szDevice, i, &dmode); ++i)
+ {
+ foundMode = (dmode.dmPelsWidth==(DWORD)vp.w) &&
+ (dmode.dmPelsHeight==(DWORD)vp.h) &&
+ (dmode.dmBitsPerPel==(DWORD)32);
+ if (foundMode)
+ break;
+ }
+ if(!foundMode)
+ return false;
+
+ dmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
+
+ // Save the current window position/size
+ RECT rect;
+ GetWindowRect(Window, &rect);
+ PreFullscreen.x = rect.left;
+ PreFullscreen.y = rect.top;
+ PreFullscreen.w = rect.right - rect.left;
+ PreFullscreen.h = rect.bottom - rect.top;
+
+ // Save the window style and set it for fullscreen mode
+ DWORD style = (DWORD)GetWindowLongPtr(Window, GWL_STYLE);
+ DWORD exstyle = (DWORD)GetWindowLongPtr(Window, GWL_EXSTYLE);
+ SetWindowLongPtr(Window, GWL_STYLE, style & (~WS_OVERLAPPEDWINDOW));
+ SetWindowLongPtr(Window, GWL_EXSTYLE, exstyle | WS_EX_APPWINDOW | WS_EX_TOPMOST);
+
+ // Attempt to change the resolution
+ LONG ret = ChangeDisplaySettingsEx(monInfo.szDevice, &dmode, NULL, CDS_FULLSCREEN, NULL);
+ //LONG ret = ChangeDisplaySettings(&dmode, CDS_FULLSCREEN);
+
+ // If it failed, clean up and return.
+ if (ret != DISP_CHANGE_SUCCESSFUL)
+ {
+ SetWindowLongPtr(Window, GWL_STYLE, style);
+ SetWindowLongPtr(Window, GWL_EXSTYLE, exstyle);
+ return false;
+ }
+
+ // We need to call GetMonitorInfo() again becase
+ // details may have changed with the resolution
+ GetMonitorInfo(HMonitor, &monInfo);
+
+ // Set the window's size and position so
+ // that it covers the entire screen
+ SetWindowPos(Window, HWND_TOPMOST, monInfo.rcMonitor.left, monInfo.rcMonitor.top, vp.w, vp.h,
+ SWP_SHOWWINDOW | SWP_NOZORDER | SWP_FRAMECHANGED);
+ }
+
+ Params.Fullscreen = fullscreen;
+ return true;
+}
+
}}}}
diff --git a/Samples/CommonSrc/Render/Render_GL_Win32_Device.h b/Samples/CommonSrc/Render/Render_GL_Win32_Device.h
index f63b1d0..de81a80 100644
--- a/Samples/CommonSrc/Render/Render_GL_Win32_Device.h
+++ b/Samples/CommonSrc/Render/Render_GL_Win32_Device.h
@@ -3,7 +3,7 @@
Filename : Render_GL_Win32 Device.h
Content : Win32 OpenGL Device implementation header
Created : September 10, 2012
-Authors : Andrew Reisse, Michael Antonov
+Authors : Andrew Reisse, Michael Antonov, David Borel
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
@@ -38,19 +38,29 @@ namespace OVR { namespace Render { namespace GL { namespace Win32 {
// Win32-Specific GL Render Device, used to create OpenGL under Windows.
class RenderDevice : public GL::RenderDevice
{
- HWND Window;
- HGLRC WglContext;
- HDC GdiDc;
+ friend BOOL CALLBACK MonitorEnumFunc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData);
+
+ HWND Window;
+ HGLRC WglContext;
+ HDC GdiDc;
+ Recti PreFullscreen;
+ Recti FSDesktop;
+ HMONITOR HMonitor;
public:
- RenderDevice(const Render::RendererParams& p, HWND win, HDC dc, HGLRC gl)
- : GL::RenderDevice(p), Window(win), WglContext(gl), GdiDc(dc) { OVR_UNUSED(p); }
+ RenderDevice(const Render::RendererParams& p, HWND win, HDC dc, HGLRC gl);
+ virtual ~RenderDevice() { Shutdown(); }
// Implement static initializer function to create this class.
static Render::RenderDevice* CreateDevice(const RendererParams& rp, void* oswnd);
+
+ virtual ovrRenderAPIConfig Get_ovrRenderAPIConfig() const;
virtual void Shutdown();
- virtual void Present();
+ virtual void Present(bool withVsync);
+ bool SetParams(const RendererParams& newParams);
+
+ virtual bool SetFullscreen(DisplayMode fullscreen);
};
diff --git a/Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp b/Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp
index b2b4b31..5bbdb21 100644
--- a/Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp
+++ b/Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp
@@ -5,7 +5,7 @@ Content : A DDS file loader for cross-platform compressed texture support.
Created : March 5, 2013
Authors : Peter Hoff, Dan Goodman, Bryan Croteau
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+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.
@@ -75,10 +75,10 @@ Texture* LoadTextureDDS(RenderDevice* ren, File* f)
f->Read((unsigned char*)(&header), sizeof(header));
- int width = header.Width;
+ int width = header.Width;
int height = header.Height;
- int format = 0;
+ int format = Texture_RGBA;
UInt32 mipCount = header.MipMapCount;
if(mipCount <= 0)
diff --git a/Samples/CommonSrc/Render/Render_XmlSceneLoader.cpp b/Samples/CommonSrc/Render/Render_XmlSceneLoader.cpp
index b2b1ac1..5f31250 100644
--- a/Samples/CommonSrc/Render/Render_XmlSceneLoader.cpp
+++ b/Samples/CommonSrc/Render/Render_XmlSceneLoader.cpp
@@ -5,7 +5,7 @@ Content : Imports and exports XML files - implementation
Created : January 21, 2013
Authors : Robotic Arm Software - Peter Hoff, Dan Goodman, Bryan Croteau
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+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.
@@ -121,6 +121,7 @@ bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRend
OVR_DEBUG_LOG_TEXT(("%i models remaining...", modelCount - i));
}
Models.PushBack(*new Model(Prim_Triangles));
+ const char* name = pXmlModel->Attribute("name");
bool isCollisionModel = false;
pXmlModel->QueryBoolAttribute("isCollisionModel", &isCollisionModel);
Models[i]->IsCollisionModel = isCollisionModel;
@@ -129,6 +130,8 @@ bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRend
Models[i]->Visible = false;
}
+ bool tree_c = (strcmp(name, "tree_C") == 0) || (strcmp(name, "Object03") == 0);
+
//read the vertices
OVR::Array<Vector3f> *vertices = new OVR::Array<Vector3f>();
ParseVectorString(pXmlModel->FirstChildElement("vertices")->FirstChild()->
@@ -137,6 +140,11 @@ bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRend
for (unsigned int vertexIndex = 0; vertexIndex < vertices->GetSize(); ++vertexIndex)
{
vertices->At(vertexIndex).x *= -1.0f;
+
+ if (tree_c)
+ { // Move the terrace tree closer to the house
+ vertices->At(vertexIndex).z += 0.5;
+ }
}
//read the normals
@@ -237,6 +245,7 @@ bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRend
// Read the vertex indices for the triangles
const char* indexStr = pXmlModel->FirstChildElement("indices")->
FirstChild()->ToText()->Value();
+
UPInt stringLength = strlen(indexStr);
for(UPInt j = 0; j < stringLength; )
@@ -306,6 +315,8 @@ bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRend
float D;
pXmlPlane->QueryFloatAttribute("d", &D);
D -= 0.5f;
+ if (i == 26)
+ D += 0.5f; // tighten the terrace collision so player can move right up to rail
Planef p(norm.z, norm.y, norm.x * -1.0f, D);
cm->Add(p);
pXmlPlane = pXmlPlane->NextSiblingElement("plane");
diff --git a/Samples/CommonSrc/Render/Render_XmlSceneLoader.h b/Samples/CommonSrc/Render/Render_XmlSceneLoader.h
index 694fc2e..7dff174 100644
--- a/Samples/CommonSrc/Render/Render_XmlSceneLoader.h
+++ b/Samples/CommonSrc/Render/Render_XmlSceneLoader.h
@@ -5,7 +5,7 @@ Content : Imports and exports XML files
Created : January 21, 2013
Authors : Robotic Arm Software - Peter Hoff, Dan Goodman, Bryan Croteau
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+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.