From 4207f9c279e832e3afcb3f5fc6cd8d84cb4cfe4c Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 28 Mar 2015 01:43:35 +0100 Subject: Bump OculusVR RIFT SDK to 0.5.0.1 --- .../Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.cpp | 845 ++++++++++---------- .../Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.h | 279 ++++--- LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.cpp | 855 ++++++++++----------- LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.h | 158 ++-- LibOVR/Src/CAPI/D3D9/CAPI_D3D9_Util.cpp | 559 +++++++------- 5 files changed, 1360 insertions(+), 1336 deletions(-) (limited to 'LibOVR/Src/CAPI/D3D9') diff --git a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.cpp b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.cpp index 05508ea..d7706ae 100644 --- a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.cpp @@ -1,409 +1,436 @@ -/************************************************************************************ - -Filename : CAPI_D3D1X_DistortionRenderer.cpp -Content : Experimental distortion renderer -Created : March 7th, 2014 -Authors : Tom Heath - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -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 "CAPI_D3D9_DistortionRenderer.h" -#define OVR_D3D_VERSION 9 -#include "../../OVR_CAPI_D3D.h" - -#include -DEFINE_GUID(IID_OVRDirect3DDevice9EX, 0xe6d58f10, 0xffa1, 0x4748, 0x85, 0x9f, 0xbc, 0xd7, 0xea, 0xe8, 0xfc, 0x1); - -namespace OVR { namespace CAPI { namespace D3D9 { - - -///QUESTION : Why not just a normal constructor? -CAPI::DistortionRenderer* DistortionRenderer::Create(ovrHmd hmd, - FrameTimeManager& timeManager, - const HMDRenderState& renderState) -{ - return new DistortionRenderer(hmd, timeManager, renderState); -} - -DistortionRenderer::DistortionRenderer(ovrHmd hmd, FrameTimeManager& timeManager, - const HMDRenderState& renderState) - : CAPI::DistortionRenderer(ovrRenderAPI_D3D9, hmd, timeManager, renderState), - Device(NULL), - SwapChain(NULL), - VertexDecl(NULL), - PixelShader(NULL), - VertexShader(NULL), - VertexShaderTimewarp(NULL), - //screenSize(), - ResolutionInPixels(0,0) - //eachEye[] -{ - ScreenSize.w = 0; - ScreenSize.h = 0; - InitLatencyTester(renderState); - - for (int i = 0; i < 2; ++i) - { - eachEye[i].dxIndices = nullptr; - eachEye[i].dxVerts = nullptr; - } -} - - -/**********************************************/ -DistortionRenderer::~DistortionRenderer() -{ - //Release any memory - if (eachEye[0].dxIndices) - { - eachEye[0].dxIndices->Release(); - } - if (eachEye[0].dxVerts) - { - eachEye[0].dxVerts->Release(); - } - if (eachEye[1].dxIndices) - { - eachEye[1].dxIndices->Release(); - } - if (eachEye[1].dxVerts) - { - eachEye[1].dxVerts->Release(); - } -} - - -/******************************************************************************/ -bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig) -{ - ///QUESTION - what is returned bool for??? Are we happy with this true, if not config. - const ovrD3D9Config * config = (const ovrD3D9Config*)apiConfig; - if (!config) return true; - if (!config->D3D9.pDevice) return false; - - if (System::DirectDisplayEnabled()) - { - Ptr ovrDevice; - if (config->D3D9.pDevice->QueryInterface(IID_OVRDirect3DDevice9EX, (void**)&ovrDevice.GetRawRef()) == E_NOINTERFACE) - { - OVR_DEBUG_LOG_TEXT(("ovr_Initialize() or ovr_InitializeRenderingShim() wasn't called before the D3D9 device was created.")); - } - } - - //Glean all the required variables from the input structures - Device = config->D3D9.pDevice; - SwapChain = config->D3D9.pSwapChain; - ScreenSize = config->D3D9.Header.BackBufferSize; - - GfxState = *new GraphicsState(Device, RState.DistortionCaps); - - CreateVertexDeclaration(); - CreateDistortionShaders(); - CreateDistortionModels(); - - return true; -} - -void DistortionRenderer::InitLatencyTester(const HMDRenderState& RenderState) -{ - ResolutionInPixels = RenderState.OurHMDInfo.ResolutionInPixels; -} - - -/**************************************************************/ -void DistortionRenderer::SubmitEye(int eyeId, const ovrTexture* eyeTexture) -{ - //Doesn't do a lot in here?? - const ovrD3D9Texture* tex = (const ovrD3D9Texture*)eyeTexture; - - //Write in values - eachEye[eyeId].texture = tex->D3D9.pTexture; - - // Its only at this point we discover what the viewport of the texture is. - // because presumably we allow users to realtime adjust the resolution. - eachEye[eyeId].TextureSize = tex->D3D9.Header.TextureSize; - eachEye[eyeId].RenderViewport = tex->D3D9.Header.RenderViewport; - - const ovrEyeRenderDesc& erd = RState.EyeRenderDesc[eyeId]; - - ovrHmd_GetRenderScaleAndOffset( erd.Fov, - eachEye[eyeId].TextureSize, eachEye[eyeId].RenderViewport, - eachEye[eyeId].UVScaleOffset ); - - if (RState.DistortionCaps & ovrDistortionCap_FlipInput) - { - eachEye[eyeId].UVScaleOffset[0].y = -eachEye[eyeId].UVScaleOffset[0].y; - eachEye[eyeId].UVScaleOffset[1].y = 1.0f - eachEye[eyeId].UVScaleOffset[1].y; - } -} - -void DistortionRenderer::renderEndFrame() -{ - RenderBothDistortionMeshes(); - - if(RegisteredPostDistortionCallback) - RegisteredPostDistortionCallback(Device); - - if (LatencyTest2Active) - { - renderLatencyPixel(LatencyTest2DrawColor); - } -} - -/******************************************************************/ -void DistortionRenderer::EndFrame(bool swapBuffers) -{ - ///QUESTION : Clear the screen? - ///QUESTION : Ensure the screen is the render target - - // Don't spin if we are explicitly asked not to - if (RState.DistortionCaps & ovrDistortionCap_TimeWarp && - !(RState.DistortionCaps & ovrDistortionCap_ProfileNoTimewarpSpinWaits)) - { - if (!TimeManager.NeedDistortionTimeMeasurement()) - { - // Wait for timewarp distortion if it is time and Gpu idle - FlushGpuAndWaitTillTime(TimeManager.GetFrameTiming().TimewarpPointTime); - - renderEndFrame(); - } - else - { - // If needed, measure distortion time so that TimeManager can better estimate - // latency-reducing time-warp wait timing. - WaitUntilGpuIdle(); - double distortionStartTime = ovr_GetTimeInSeconds(); - - renderEndFrame(); - - WaitUntilGpuIdle(); - TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime); - } - } - else - { - renderEndFrame(); - } - - if (LatencyTestActive) - { - renderLatencyQuad(LatencyTestDrawColor); - } - - if (swapBuffers) - { - if (SwapChain) - { - SwapChain->Present(NULL, NULL, NULL, NULL, 0); - } - else - { - Device->Present( NULL, NULL, NULL, NULL ); - } - - // Force GPU to flush the scene, resulting in the lowest possible latency. - // It's critical that this flush is *after* present. - // Doesn't need to be done if running through the Oculus driver. - if (RState.OurHMDInfo.InCompatibilityMode && - !(RState.DistortionCaps & ovrDistortionCap_ProfileNoTimewarpSpinWaits)) - { - WaitUntilGpuIdle(); - } - } -} - - -void DistortionRenderer::WaitUntilGpuIdle() -{ - if(Device) - { - IDirect3DQuery9* pEventQuery=NULL ; - Device->CreateQuery(D3DQUERYTYPE_EVENT, &pEventQuery) ; - - if(pEventQuery!=NULL) - { - pEventQuery->Issue(D3DISSUE_END) ; - while(S_FALSE == pEventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH)){} - pEventQuery->Release(); - } - } -} - -double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime) -{ - double initialTime = ovr_GetTimeInSeconds(); - if (initialTime >= absTime) - return 0.0; - - WaitUntilGpuIdle(); - - return WaitTillTime(absTime); -} - - -//----------------------------------------------------------------------------- -// Latency Tester Quad - -static void ConvertSRGB(unsigned char c[3]) -{ - for (int i = 0; i < 3; ++i) - { - double d = (double)c[i]; - double ds = d / 255.; - - if (ds <= 0.04045) - { - d /= 12.92; - } - else - { - d = 255. * pow((ds + 0.055) / 1.055, 2.4); - } - - int color = (int)d; - if (color < 0) - { - color = 0; - } - else if (color > 255) - { - color = 255; - } - - c[i] = (unsigned char)color; - } -} - -void DistortionRenderer::renderLatencyQuad(unsigned char* color) -{ - D3DRECT rect = { ResolutionInPixels.w / 4, ResolutionInPixels.h / 4, ResolutionInPixels.w * 3 / 4, ResolutionInPixels.h * 3 / 4 }; - unsigned char c[3] = { color[0], color[1], color[2] }; - - if (RState.DistortionCaps & ovrDistortionCap_SRGB) - { - ConvertSRGB(c); - } - - Device->Clear(1, &rect, D3DCLEAR_TARGET, D3DCOLOR_RGBA(c[0], c[1], c[2], 255), 1, 0); -} - -#ifdef OVR_BUILD_DEBUG -#define OVR_LATENCY_PIXEL_SIZE 20 -#else -#define OVR_LATENCY_PIXEL_SIZE 5 -#endif - -void DistortionRenderer::renderLatencyPixel(unsigned char* color) -{ - D3DRECT rect = { ResolutionInPixels.w - OVR_LATENCY_PIXEL_SIZE, 0, ResolutionInPixels.w, OVR_LATENCY_PIXEL_SIZE }; - unsigned char c[3] = { color[0], color[1], color[2] }; - - if (RState.DistortionCaps & ovrDistortionCap_SRGB) - { - ConvertSRGB(c); - } - - Device->Clear(1, &rect, D3DCLEAR_TARGET, D3DCOLOR_RGBA(c[0], c[1], c[2], 255), 1, 0); -} - - -//----------------------------------------------------------------------------- -// GraphicsState - -DistortionRenderer::GraphicsState::GraphicsState(IDirect3DDevice9* d, unsigned distortionCaps) -: Device(d) -, NumSavedStates(0) -, DistortionCaps(distortionCaps) -{ - #if defined(OVR_BUILD_DEBUG) - memset(SavedState, 0, sizeof(SavedState)); - #endif -} - -void DistortionRenderer::GraphicsState::RecordAndSetState(int which, int type, DWORD newValue) -{ - SavedStateType * sst = &SavedState[NumSavedStates++]; - sst->which = which; - sst->type = type; - if (which == 0) - { - Device->GetSamplerState(0, (D3DSAMPLERSTATETYPE)type, &sst->valueToRevertTo); - Device->SetSamplerState(0, (D3DSAMPLERSTATETYPE)type, newValue); - } - else - { - Device->GetRenderState((D3DRENDERSTATETYPE)type, &sst->valueToRevertTo); - Device->SetRenderState((D3DRENDERSTATETYPE)type, newValue); - } -} - -void DistortionRenderer::GraphicsState::Save() -{ - //Record and set rasterizer and sampler states. - - NumSavedStates=0; - - RecordAndSetState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); - RecordAndSetState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); - RecordAndSetState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ); - RecordAndSetState(0, D3DSAMP_BORDERCOLOR, 0x000000 ); - RecordAndSetState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER ); - RecordAndSetState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER ); - RecordAndSetState(0, D3DSAMP_SRGBTEXTURE, (DistortionCaps & ovrDistortionCap_SRGB) ? TRUE : FALSE ); - - RecordAndSetState(1, D3DRS_MULTISAMPLEANTIALIAS, FALSE ); - RecordAndSetState(1, D3DRS_DITHERENABLE, FALSE ); - RecordAndSetState(1, D3DRS_ZENABLE, FALSE ); - RecordAndSetState(1, D3DRS_ZWRITEENABLE, TRUE ); - RecordAndSetState(1, D3DRS_ZFUNC, D3DCMP_LESSEQUAL ); - RecordAndSetState(1, D3DRS_CULLMODE , D3DCULL_CCW ); - RecordAndSetState(1, D3DRS_ALPHABLENDENABLE , FALSE ); - RecordAndSetState(1, D3DRS_DEPTHBIAS , 0 ); - RecordAndSetState(1, D3DRS_SRCBLEND , D3DBLEND_SRCALPHA ); - RecordAndSetState(1, D3DRS_DESTBLEND , D3DBLEND_INVSRCALPHA ); - RecordAndSetState(1, D3DRS_FILLMODE, D3DFILL_SOLID ); - RecordAndSetState(1, D3DRS_ALPHATESTENABLE, FALSE); - RecordAndSetState(1, D3DRS_DEPTHBIAS , 0 ); - RecordAndSetState(1, D3DRS_LIGHTING, FALSE ); - RecordAndSetState(1, D3DRS_FOGENABLE, FALSE ); - RecordAndSetState(1, D3DRS_SRGBWRITEENABLE, (DistortionCaps & ovrDistortionCap_SRGB) ? TRUE : FALSE ); -} - - -void DistortionRenderer::GraphicsState::Restore() -{ - for (int i = 0; i < NumSavedStates; i++) - { - SavedStateType * sst = &SavedState[i]; - if (sst->which == 0) - { - Device->SetSamplerState(0, (D3DSAMPLERSTATETYPE)sst->type, sst->valueToRevertTo); - } - else - { - Device->SetRenderState((D3DRENDERSTATETYPE)sst->type, sst->valueToRevertTo); - } - } -} - - -}}} // OVR::CAPI::D3D1X - - +/************************************************************************************ + +Filename : CAPI_D3D11_DistortionRenderer.cpp +Content : Experimental distortion renderer +Created : March 7th, 2014 +Authors : Tom Heath + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +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 "CAPI_D3D9_DistortionRenderer.h" +#include "OVR_CAPI_D3D.h" + +#include +DEFINE_GUID(IID_OVRDirect3DDevice9EX, 0xe6d58f10, 0xffa1, 0x4748, 0x85, 0x9f, 0xbc, 0xd7, 0xea, 0xe8, 0xfc, 0x1); + +OVR_DISABLE_MSVC_WARNING(4996) // Disable deprecation warning + +namespace OVR { namespace CAPI { namespace D3D9 { + + +///QUESTION : Why not just a normal constructor? +CAPI::DistortionRenderer* DistortionRenderer::Create() +{ + return new DistortionRenderer(); +} + +DistortionRenderer::DistortionRenderer() : + Device(NULL), + SwapChain(NULL), + VertexDecl(NULL), + PixelShader(NULL), + VertexShader(NULL), + VertexShaderTimewarp(NULL), + //screenSize(), + ResolutionInPixels(0,0) + //eachEye[] +{ + ScreenSize.w = 0; + ScreenSize.h = 0; + + for (int i = 0; i < 2; ++i) + { + eachEye[i].dxIndices = nullptr; + eachEye[i].dxVerts = nullptr; + } +} + + +/**********************************************/ +DistortionRenderer::~DistortionRenderer() +{ + //Release any memory + if (eachEye[0].dxIndices) + { + eachEye[0].dxIndices->Release(); + } + if (eachEye[0].dxVerts) + { + eachEye[0].dxVerts->Release(); + } + if (eachEye[1].dxIndices) + { + eachEye[1].dxIndices->Release(); + } + if (eachEye[1].dxVerts) + { + eachEye[1].dxVerts->Release(); + } +} + + +/******************************************************************************/ +bool DistortionRenderer::initializeRenderer(const ovrRenderAPIConfig* apiConfig) +{ + initLatencyTester(); + + ///QUESTION - what is returned bool for??? Are we happy with this true, if not config. + const ovrD3D9Config * config = (const ovrD3D9Config*)apiConfig; + if (!config) return true; + if (!config->D3D9.pDevice) return false; + + if (Display::GetDirectDisplayInitialized()) + { + Ptr ovrDevice; + if (config->D3D9.pDevice->QueryInterface(IID_OVRDirect3DDevice9EX, (void**)&ovrDevice.GetRawRef()) == E_NOINTERFACE) + { + OVR_DEBUG_LOG_TEXT(("ovr_Initialize() or ovr_InitializeRenderingShim() wasn't called before the D3D9 device was created.")); + } + } + + //Glean all the required variables from the input structures + Device = config->D3D9.pDevice; + SwapChain = config->D3D9.pSwapChain; + ScreenSize = config->D3D9.Header.BackBufferSize; + + GfxState = *new GraphicsState(Device, RenderState->DistortionCaps); + + CreateVertexDeclaration(); + CreateDistortionShaders(); + return CreateDistortionModels(); +} + +void DistortionRenderer::initLatencyTester() +{ + ResolutionInPixels = RenderState->OurHMDInfo.ResolutionInPixels; +} + + +/**************************************************************/ +void DistortionRenderer::SubmitEye(int eyeId, const ovrTexture* eyeTexture) +{ + if (eyeTexture) + { + //Doesn't do a lot in here?? + const ovrD3D9Texture* tex = (const ovrD3D9Texture*)eyeTexture; + + //Write in values + eachEye[eyeId].texture = tex->D3D9.pTexture; + + // Its only at this point we discover what the viewport of the texture is. + // because presumably we allow users to realtime adjust the resolution. + eachEye[eyeId].TextureSize = tex->D3D9.Header.TextureSize; + eachEye[eyeId].RenderViewport = tex->D3D9.Header.RenderViewport; + + const ovrEyeRenderDesc& erd = RenderState->EyeRenderDesc[eyeId]; + + ovrHmd_GetRenderScaleAndOffset(erd.Fov, + eachEye[eyeId].TextureSize, eachEye[eyeId].RenderViewport, + eachEye[eyeId].UVScaleOffset); + + if (RenderState->DistortionCaps & ovrDistortionCap_FlipInput) + { + eachEye[eyeId].UVScaleOffset[0].y = -eachEye[eyeId].UVScaleOffset[0].y; + eachEye[eyeId].UVScaleOffset[1].y = 1.0f - eachEye[eyeId].UVScaleOffset[1].y; + } + } +} + +void DistortionRenderer::SubmitEyeWithDepth(int eyeId, const ovrTexture* eyeColorTexture, const ovrTexture* eyeDepthTexture) +{ + SubmitEye(eyeId, eyeColorTexture); + + OVR_UNUSED(eyeDepthTexture); +} + +void DistortionRenderer::renderEndFrame() +{ + RenderBothDistortionMeshes(); + + if(RegisteredPostDistortionCallback) + RegisteredPostDistortionCallback(Device); + + if (LatencyTest2Active) + { + renderLatencyPixel(LatencyTest2DrawColor); + } +} + +/******************************************************************/ +void DistortionRenderer::EndFrame(uint32_t frameIndex, bool swapBuffers) +{ + ///QUESTION : Clear the screen? + ///QUESTION : Ensure the screen is the render target + + // D3D9 does not provide any frame timing information. + Timing->CalculateTimewarpTiming(frameIndex); + + // Don't spin if we are explicitly asked not to + if ( (RenderState->DistortionCaps & ovrDistortionCap_TimeWarp) && + (RenderState->DistortionCaps & ovrDistortionCap_TimewarpJitDelay) && + !(RenderState->DistortionCaps & ovrDistortionCap_ProfileNoSpinWaits)) + { + if (!Timing->NeedDistortionTimeMeasurement()) + { + FlushGpuAndWaitTillTime(Timing->GetTimewarpTiming()->JIT_TimewarpTime); + + renderEndFrame(); + } + else + { + // If needed, measure distortion time so that TimeManager can better estimate + // latency-reducing time-warp wait timing. + WaitUntilGpuIdle(); + double distortionStartTime = ovr_GetTimeInSeconds(); + + renderEndFrame(); + + WaitUntilGpuIdle(); + Timing->AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime); + } + } + else + { + renderEndFrame(); + } + + if (LatencyTestActive) + { + renderLatencyQuad(LatencyTestDrawColor); + } + + if (swapBuffers) + { + if (SwapChain) + { + SwapChain->Present(NULL, NULL, NULL, NULL, 0); + } + else + { + Device->Present( NULL, NULL, NULL, NULL ); + } + + // Force GPU to flush the scene, resulting in the lowest possible latency. + // It's critical that this flush is *after* present. + // Doesn't need to be done if running through the Oculus driver. + if (RenderState->OurHMDInfo.InCompatibilityMode && + !(RenderState->DistortionCaps & ovrDistortionCap_ProfileNoSpinWaits)) + { + WaitUntilGpuIdle(); + } + } +} + + +void DistortionRenderer::WaitUntilGpuIdle() +{ + if(Device) + { + IDirect3DQuery9* pEventQuery=NULL ; + Device->CreateQuery(D3DQUERYTYPE_EVENT, &pEventQuery) ; + + if(pEventQuery!=NULL) + { + pEventQuery->Issue(D3DISSUE_END) ; + while(S_FALSE == pEventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH)){} + pEventQuery->Release(); + } + } +} + +double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime) +{ + double initialTime = ovr_GetTimeInSeconds(); + if (initialTime >= absTime) + return 0.0; + + WaitUntilGpuIdle(); + + return WaitTillTime(absTime); +} + + +//----------------------------------------------------------------------------- +// Latency Tester Quad + +static void ConvertSRGB(unsigned char c[3]) +{ + for (int i = 0; i < 3; ++i) + { + double d = (double)c[i]; + double ds = d / 255.; + + if (ds <= 0.04045) + { + d /= 12.92; + } + else + { + d = 255. * pow((ds + 0.055) / 1.055, 2.4); + } + + int color = (int)d; + if (color < 0) + { + color = 0; + } + else if (color > 255) + { + color = 255; + } + + c[i] = (unsigned char)color; + } +} + +void DistortionRenderer::renderLatencyQuad(unsigned char* color) +{ + D3DRECT rect = { ResolutionInPixels.w / 4, ResolutionInPixels.h / 4, ResolutionInPixels.w * 3 / 4, ResolutionInPixels.h * 3 / 4 }; + unsigned char c[3] = { color[0], color[1], color[2] }; + + if (RenderState->DistortionCaps & ovrDistortionCap_SRGB) + { + ConvertSRGB(c); + } + + Device->Clear(1, &rect, D3DCLEAR_TARGET, D3DCOLOR_RGBA(c[0], c[1], c[2], 255), 1, 0); +} + +#ifdef OVR_BUILD_DEBUG +#define OVR_LATENCY_PIXEL_SIZE 20 +#else +#define OVR_LATENCY_PIXEL_SIZE 5 +#endif + +void DistortionRenderer::renderLatencyPixel(unsigned char* color) +{ + D3DRECT rect; + + if (RenderState->RenderInfo.OffsetLatencyTester) + { + // TBD: Is this correct? + rect.x1 = ResolutionInPixels.w / 2; + rect.y1 = 0; + } + else + { + rect.x1 = ResolutionInPixels.w - OVR_LATENCY_PIXEL_SIZE; + rect.y1 = 0; + } + + rect.x2 = rect.x1 + OVR_LATENCY_PIXEL_SIZE; + rect.y2 = rect.y1 + OVR_LATENCY_PIXEL_SIZE; + + // TBD: Does (RenderState->RenderInfo.RotateCCW90) affect this? + + unsigned char c[3] = { color[0], color[1], color[2] }; + + if (RenderState->DistortionCaps & ovrDistortionCap_SRGB) + { + ConvertSRGB(c); + } + + Device->Clear(1, &rect, D3DCLEAR_TARGET, D3DCOLOR_RGBA(c[0], c[1], c[2], 255), 1, 0); +} + + +//----------------------------------------------------------------------------- +// GraphicsState + +DistortionRenderer::GraphicsState::GraphicsState(IDirect3DDevice9* d, unsigned distortionCaps) +: Device(d) +, NumSavedStates(0) +, DistortionCaps(distortionCaps) +{ + #if defined(OVR_BUILD_DEBUG) + memset(SavedState, 0, sizeof(SavedState)); + #endif +} + +void DistortionRenderer::GraphicsState::RecordAndSetState(int which, int type, DWORD newValue) +{ + SavedStateType * sst = &SavedState[NumSavedStates++]; + sst->which = which; + sst->type = type; + if (which == 0) + { + Device->GetSamplerState(0, (D3DSAMPLERSTATETYPE)type, &sst->valueToRevertTo); + Device->SetSamplerState(0, (D3DSAMPLERSTATETYPE)type, newValue); + } + else + { + Device->GetRenderState((D3DRENDERSTATETYPE)type, &sst->valueToRevertTo); + Device->SetRenderState((D3DRENDERSTATETYPE)type, newValue); + } +} + +void DistortionRenderer::GraphicsState::Save() +{ + //Record and set rasterizer and sampler states. + + NumSavedStates=0; + + RecordAndSetState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); + RecordAndSetState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); + RecordAndSetState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ); + RecordAndSetState(0, D3DSAMP_BORDERCOLOR, 0x000000 ); + RecordAndSetState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER ); + RecordAndSetState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER ); + RecordAndSetState(0, D3DSAMP_SRGBTEXTURE, (DistortionCaps & ovrDistortionCap_SRGB) ? TRUE : FALSE ); + + RecordAndSetState(1, D3DRS_MULTISAMPLEANTIALIAS, FALSE ); + RecordAndSetState(1, D3DRS_DITHERENABLE, FALSE ); + RecordAndSetState(1, D3DRS_ZENABLE, FALSE ); + RecordAndSetState(1, D3DRS_ZWRITEENABLE, TRUE ); + RecordAndSetState(1, D3DRS_ZFUNC, D3DCMP_LESSEQUAL ); + RecordAndSetState(1, D3DRS_CULLMODE , D3DCULL_CCW ); + RecordAndSetState(1, D3DRS_ALPHABLENDENABLE , FALSE ); + RecordAndSetState(1, D3DRS_DEPTHBIAS , 0 ); + RecordAndSetState(1, D3DRS_SRCBLEND , D3DBLEND_SRCALPHA ); + RecordAndSetState(1, D3DRS_DESTBLEND , D3DBLEND_INVSRCALPHA ); + RecordAndSetState(1, D3DRS_FILLMODE, D3DFILL_SOLID ); + RecordAndSetState(1, D3DRS_ALPHATESTENABLE, FALSE); + RecordAndSetState(1, D3DRS_DEPTHBIAS , 0 ); + RecordAndSetState(1, D3DRS_LIGHTING, FALSE ); + RecordAndSetState(1, D3DRS_FOGENABLE, FALSE ); + RecordAndSetState(1, D3DRS_SRGBWRITEENABLE, (DistortionCaps & ovrDistortionCap_SRGB) ? TRUE : FALSE ); +} + + +void DistortionRenderer::GraphicsState::Restore() +{ + for (int i = 0; i < NumSavedStates; i++) + { + SavedStateType * sst = &SavedState[i]; + if (sst->which == 0) + { + Device->SetSamplerState(0, (D3DSAMPLERSTATETYPE)sst->type, sst->valueToRevertTo); + } + else + { + Device->SetRenderState((D3DRENDERSTATETYPE)sst->type, sst->valueToRevertTo); + } + } +} + + +}}} // OVR::CAPI::D3D11 + +OVR_RESTORE_MSVC_WARNING() diff --git a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.h b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.h index 55c7d29..b289c34 100644 --- a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.h @@ -1,142 +1,137 @@ -/************************************************************************************ - -Filename : CAPI_D3D1X_DistortionRenderer.h -Content : Experimental distortion renderer -Created : March 7, 2014 -Authors : Tom Heath - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "../../Kernel/OVR_Types.h" - -#if defined (OVR_OS_WIN32) -#define WIN32_LEAN_AND_MEAN -#include -#endif - -#if defined(OVR_DEFINE_NEW) -#define new OVR_DEFINE_NEW -#endif - -#include "../CAPI_DistortionRenderer.h" - - -namespace OVR { namespace CAPI { namespace D3D9 { - - -//Implementation of DistortionRenderer for D3D9. -/***************************************************/ -class DistortionRenderer : public CAPI::DistortionRenderer -{ -public: - DistortionRenderer(ovrHmd hmd, FrameTimeManager& timeManager, const HMDRenderState& renderState); - ~DistortionRenderer(); - - // Creation function for the device. - static CAPI::DistortionRenderer* Create(ovrHmd hmd, - FrameTimeManager& timeManager, - const HMDRenderState& renderState); - - // ***** Public DistortionRenderer interface - virtual bool Initialize(const ovrRenderAPIConfig* apiConfig) OVR_OVERRIDE; - - virtual void SubmitEye(int eyeId, const ovrTexture* eyeTexture); - - virtual void EndFrame(bool swapBuffers); - - // TBD: Make public? - void WaitUntilGpuIdle(); - - // Similar to ovr_WaitTillTime but it also flushes GPU. - // Note, it exits when time expires, even if GPU is not in idle state yet. - double FlushGpuAndWaitTillTime(double absTime); - -protected: - - class GraphicsState : public CAPI::DistortionRenderer::GraphicsState - { - public: - GraphicsState(IDirect3DDevice9* d, unsigned distortionCaps); - virtual void Save(); - virtual void Restore(); - - protected: - void RecordAndSetState(int which, int type, DWORD newValue); - - //Structure to store our state changes - static const int MAX_SAVED_STATES=100; - struct SavedStateType - { - int which; //0 for samplerstate, 1 for renderstate - int type; - DWORD valueToRevertTo; - } SavedState[MAX_SAVED_STATES]; - - //Keep track of how many we've done, for reverting - int NumSavedStates; - IDirect3DDevice9* Device; - unsigned DistortionCaps; - }; - -private: - - //Functions - void CreateDistortionShaders(void); - void CreateDistortionModels(void); - void CreateVertexDeclaration(void); - void RenderBothDistortionMeshes(); - void RecordAndSetState(int which, int type, DWORD newValue); - void RevertAllStates(void); - - void renderEndFrame(); - - // Latency tester - void InitLatencyTester(const HMDRenderState& renderState); - void renderLatencyQuad(unsigned char* latencyTesterDrawColor); - void renderLatencyPixel(unsigned char* latencyTesterPixelColor); - - //Data, structures and pointers - IDirect3DDevice9 * Device; - IDirect3DSwapChain9 * SwapChain; - IDirect3DVertexDeclaration9 * VertexDecl; - IDirect3DPixelShader9 * PixelShader; - IDirect3DVertexShader9 * VertexShader; - IDirect3DVertexShader9 * VertexShaderTimewarp; - ovrSizei ScreenSize; - - // Latency tester - Size ResolutionInPixels; - - struct FOR_EACH_EYE - { - FOR_EACH_EYE() : dxVerts(NULL), dxIndices(NULL), numVerts(0), numIndices(0), texture(NULL), /*UVScaleOffset[],*/ TextureSize(0, 0), RenderViewport(0, 0, 0, 0) { } - - IDirect3DVertexBuffer9 * dxVerts; - IDirect3DIndexBuffer9 * dxIndices; - int numVerts; - int numIndices; - IDirect3DTexture9 * texture; - ovrVector2f UVScaleOffset[2]; - Sizei TextureSize; - Recti RenderViewport; - } eachEye[2]; -}; - -}}} // OVR::CAPI::D3D9 +/************************************************************************************ + +Filename : CAPI_D3D11_DistortionRenderer.h +Content : Experimental distortion renderer +Created : March 7, 2014 +Authors : Tom Heath + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "Kernel/OVR_Types.h" +#include "Util/Util_Direct3D.h" + +#if defined(OVR_DEFINE_NEW) +#define new OVR_DEFINE_NEW +#endif + +#include "../CAPI_DistortionRenderer.h" + + +namespace OVR { namespace CAPI { namespace D3D9 { + + +//Implementation of DistortionRenderer for D3D9. +/***************************************************/ +class DistortionRenderer : public CAPI::DistortionRenderer +{ +public: + DistortionRenderer(); + ~DistortionRenderer(); + + // Creation function for the device. + static CAPI::DistortionRenderer* Create(); + + // ***** Public DistortionRenderer interface + virtual void SubmitEye(int eyeId, const ovrTexture* eyeTexture) OVR_OVERRIDE; + virtual void SubmitEyeWithDepth(int eyeId, const ovrTexture* eyeColorTexture, const ovrTexture* eyeDepthTexture) OVR_OVERRIDE; + + virtual void EndFrame(uint32_t frameIndex, bool swapBuffers); + + // TBD: Make public? + void WaitUntilGpuIdle(); + + // Similar to ovr_WaitTillTime but it also flushes GPU. + // Note, it exits when time expires, even if GPU is not in idle state yet. + double FlushGpuAndWaitTillTime(double absTime); + +protected: + virtual bool initializeRenderer(const ovrRenderAPIConfig* apiConfig) OVR_OVERRIDE; + + class GraphicsState : public CAPI::DistortionRenderer::GraphicsState + { + public: + GraphicsState(IDirect3DDevice9* d, unsigned distortionCaps); + virtual void Save(); + virtual void Restore(); + + protected: + void RecordAndSetState(int which, int type, DWORD newValue); + + //Structure to store our state changes + static const int MAX_SAVED_STATES=100; + struct SavedStateType + { + int which; //0 for samplerstate, 1 for renderstate + int type; + DWORD valueToRevertTo; + } SavedState[MAX_SAVED_STATES]; + + //Keep track of how many we've done, for reverting + int NumSavedStates; + IDirect3DDevice9* Device; + unsigned DistortionCaps; + }; + +private: + + //Functions + void CreateDistortionShaders(); + bool CreateDistortionModels(); + void CreateVertexDeclaration(); + void RenderBothDistortionMeshes(); + void RecordAndSetState(int which, int type, DWORD newValue); + void RevertAllStates(); + + void renderEndFrame(); + + // Latency tester + void initLatencyTester(); + void renderLatencyQuad(unsigned char* latencyTesterDrawColor); + void renderLatencyPixel(unsigned char* latencyTesterPixelColor); + + //Data, structures and pointers + IDirect3DDevice9 * Device; + IDirect3DSwapChain9 * SwapChain; + IDirect3DVertexDeclaration9 * VertexDecl; + IDirect3DPixelShader9 * PixelShader; + IDirect3DVertexShader9 * VertexShader; + IDirect3DVertexShader9 * VertexShaderTimewarp; + ovrSizei ScreenSize; + + // Latency tester + Size ResolutionInPixels; + + struct FOR_EACH_EYE + { + FOR_EACH_EYE() : dxVerts(NULL), dxIndices(NULL), numVerts(0), numIndices(0), texture(NULL), /*UVScaleOffset[],*/ TextureSize(0, 0), RenderViewport(0, 0, 0, 0) { } + + IDirect3DVertexBuffer9 * dxVerts; + IDirect3DIndexBuffer9 * dxIndices; + int numVerts; + int numIndices; + IDirect3DTexture9 * texture; + ovrVector2f UVScaleOffset[2]; + Sizei TextureSize; + Recti RenderViewport; + } eachEye[2]; +}; + + +}}} // namespace OVR::CAPI::D3D9 diff --git a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.cpp b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.cpp index 2be55c1..3795485 100644 --- a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.cpp +++ b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.cpp @@ -1,430 +1,425 @@ -/************************************************************************************ - -Filename : CAPI_D3D9_HSWDisplay.cpp -Content : Implements Health and Safety Warning system. -Created : July 7, 2014 -Authors : Paul Pedriana - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -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. - -************************************************************************************/ - -#define OVR_D3D_VERSION 9 -#include "CAPI_D3D9_HSWDisplay.h" -#include "../../OVR_CAPI_D3D.h" -#undef OVR_D3D_VERSION - -#include -#include "../../Kernel/OVR_File.h" -#include "../../Kernel/OVR_SysFile.h" -#include "../../Kernel/OVR_Math.h" -#include "../../Kernel/OVR_Allocator.h" -#include "../../Kernel/OVR_Color.h" - - -namespace OVR { namespace CAPI { - - -// To do Need to move LoadTextureTgaData to a shared location. -uint8_t* LoadTextureTgaData(OVR::File* f, uint8_t alpha, int& width, int& height); - - -namespace D3D9 { - -// This is a temporary function implementation, and it functionality needs to be implemented in a more generic way. -IDirect3DTexture9* LoadTextureTga(HSWRenderParams& rParams, OVR::File* f, uint8_t alpha) -{ - IDirect3DTexture9* pTexture = NULL; - - int width, height; - const uint8_t* pRGBA = LoadTextureTgaData(f, alpha, width, height); - - if (pRGBA) - { - // We don't have access to D3DX9 and so we currently have to do this manually instead of calling a D3DX9 utility function. - Ptr pTextureSysmem; - HRESULT hResult = rParams.Device->CreateTexture((UINT)width, (UINT)height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pTextureSysmem.GetRawRef(), NULL); - - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("CreateTexture(D3DPOOL_SYSTEMMEM) failed. %d (%x)", hResult, hResult)); } - else - { - // Lock the texture so we can write this frame's texel data - D3DLOCKED_RECT lock; - hResult = pTextureSysmem->LockRect(0, &lock, NULL, D3DLOCK_NOSYSLOCK | D3DLOCK_NO_DIRTY_UPDATE); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("LockRect failed. %d (%x)", hResult, hResult)); } - else - { - // Four bytes per pixel. Pitch bytes per row (will be >= w * 4). - uint8_t* pRow = (uint8_t*)lock.pBits; - const uint8_t* pSource = pRGBA; - - for(int y = 0; y < height; y++, pRow += lock.Pitch, pSource += (width * 4)) - { - uint8_t* pDest = pRow; - - for(int x = 0, xEnd = width * 4; x < xEnd; x += 4) - { - pDest[x + 0] = pSource[x + 2]; - pDest[x + 1] = pSource[x + 1]; - pDest[x + 2] = pSource[x + 0]; - pDest[x + 3] = pSource[x + 3]; - } - } - - pTextureSysmem->UnlockRect(0); - - hResult = rParams.Device->CreateTexture((UINT)width, (UINT)height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("CreateTexture(D3DPOOL_DEFAULT) failed. %d (%x)", hResult, hResult)); } - else - { - hResult = rParams.Device->UpdateTexture(pTextureSysmem, pTexture); - if(FAILED(hResult)) - { - HSWDISPLAY_LOG(("UpdateTexture failed. %d (%x)", hResult, hResult)); - pTexture->Release(); - pTexture = NULL; - } - } - } - } - - OVR_FREE(const_cast(pRGBA)); - } - - return pTexture; -} - - -// Loads a texture from a memory image of a TGA file. -IDirect3DTexture9* LoadTextureTga(HSWRenderParams& rParams, const uint8_t* pData, int dataSize, uint8_t alpha) -{ - MemoryFile memoryFile("", pData, dataSize); - - return LoadTextureTga(rParams, &memoryFile, alpha); -} - - -// Loads a texture from a disk TGA file. -IDirect3DTexture9* LoadTextureTga(HSWRenderParams& rParams, const char* pFilePath, uint8_t alpha) -{ - SysFile sysFile; - - if(sysFile.Open(pFilePath, FileConstants::Open_Read | FileConstants::Open_Buffered)) - return LoadTextureTga(rParams, &sysFile, alpha); - - return NULL; -} - - - -// To do: This needs to be promoted to a central version, possibly in CAPI_HSWDisplay.h -struct HASWVertex -{ - Vector3f Pos; - Color C; - float U, V; - - HASWVertex(const Vector3f& p, const Color& c = Color(64,0,0,255), float u = 0, float v = 0) - : Pos(p), C(c), U(u), V(v) - {} - - HASWVertex(float x, float y, float z, const Color& c = Color(64,0,0,255), float u = 0, float v = 0) - : Pos(x,y,z), C(c), U(u), V(v) - {} - - bool operator==(const HASWVertex& b) const - { - return (Pos == b.Pos) && (C == b.C) && (U == b.U) && (V == b.V); - } -}; - -#define HASWVertexD3D9Format (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1) - - -// The texture below may conceivably be shared between HSWDisplay instances. However, -// beware that sharing may not be possible if two HMDs are using different locales -// simultaneously. As of this writing it's not clear if that can occur in practice. - -HSWDisplay::HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState) - : OVR::CAPI::HSWDisplay(api, hmd, renderState) - , RenderParams() -{ -} - -bool HSWDisplay::Initialize(const ovrRenderAPIConfig* apiConfig) -{ - const ovrD3D9Config* config = reinterpret_cast(apiConfig); - - if(config) - { - RenderParams.Device = config->D3D9.pDevice; - RenderParams.SwapChain = config->D3D9.pSwapChain; - RenderParams.ScreenSize = config->D3D9.Header.BackBufferSize; - } - else - { - UnloadGraphics(); - } - - return true; -} - -void HSWDisplay::Shutdown() -{ - UnloadGraphics(); -} - -void HSWDisplay::DisplayInternal() -{ - HSWDISPLAY_LOG(("[HSWDisplay D3D9] DisplayInternal()")); - // We may want to call LoadGraphics here instead of within Render. -} - -void HSWDisplay::DismissInternal() -{ - HSWDISPLAY_LOG(("[HSWDisplay D3D9] DismissInternal()")); - UnloadGraphics(); -} - - -void HSWDisplay::UnloadGraphics() -{ - // RenderParams: No need to clear. - pTexture.Clear(); - pVB.Clear(); - // OrthoProjection: No need to clear. -} - - -void HSWDisplay::LoadGraphics() -{ - // As of this writing, we don't yet have an abstraction for Textures, Buffers, and Shaders like we do for D3D11, D3D11, and OpenGL. - #if defined(OVR_BUILD_DEBUG) - if(!pTexture) - pTexture = *LoadTextureTga(RenderParams, "C:\\TestPath\\TestFile.tga", 255); - #endif - - if(!pTexture) - { - D3DCAPS9 caps; - RenderParams.Device->GetDeviceCaps(&caps); - - if(caps.TextureCaps & (D3DPTEXTURECAPS_SQUAREONLY | D3DPTEXTURECAPS_POW2)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] Square textures allowed only.")); } - - size_t textureSize; - const uint8_t* TextureData = GetDefaultTexture(textureSize); - pTexture = *LoadTextureTga(RenderParams, TextureData, (int)textureSize, 255); - OVR_ASSERT(pTexture); - } - - if(!pVB) - { - HRESULT hResult = RenderParams.Device->CreateVertexBuffer(4 * sizeof(HASWVertex), NULL, HASWVertexD3D9Format, D3DPOOL_MANAGED, &pVB.GetRawRef(), NULL); - - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] CreateVertexBuffer failed. %d (%x)", hResult, hResult)); } - else - { - void* pVerticesVoid; - hResult = pVB->Lock(0, 0, (void**)&pVerticesVoid, 0); - - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] Lock failed. %d (%x)", hResult, hResult)); } - else - { - HASWVertex* pVertices = reinterpret_cast(pVerticesVoid); - - const bool flip = ((RenderState.DistortionCaps & ovrDistortionCap_FlipInput) != 0); - const float left = -1.0f; - const float top = -1.1f; - const float right = +1.0f; - const float bottom = +0.9f; - - pVertices[0] = HASWVertex(left, top, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 1.f : 0.f); // To do: Make this branchless - pVertices[1] = HASWVertex(left, bottom, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 0.f : 1.f); - pVertices[2] = HASWVertex(right, top, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 1.f : 0.f); - pVertices[3] = HASWVertex(right, bottom, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 0.f : 1.f); - - pVB->Unlock(); - } - } - } -} - - -void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) -{ - if(RenderEnabled && eyeTexture) - { - // Note: The D3D9 implementation below is entirely fixed-function and isn't yet using shaders. - // For the time being this is sufficient, but future designs will likely necessitate moving - // to a system that uses programmable shaders. - - // We need to render to the eyeTexture with the texture viewport. - // Setup rendering to the texture. - ovrD3D9Texture* eyeTextureD3D9 = const_cast(reinterpret_cast(eyeTexture)); - OVR_ASSERT(eyeTextureD3D9->Texture.Header.API == ovrRenderAPI_D3D9); - - - // Save previous state. - // To do: Merge this saved state with that done by DistortionRenderer::GraphicsState::Save(), and put them in a shared location. - DWORD fvfSaved; - RenderParams.Device->GetFVF(&fvfSaved); - - Ptr pVBDSaved; - UINT vbOffsetSaved; - UINT vbStrideSaved; - RenderParams.Device->GetStreamSource(0, &pVBDSaved.GetRawRef(), &vbOffsetSaved, &vbStrideSaved); - - Ptr pTexture0Saved; - RenderParams.Device->GetTexture(0, &pTexture0Saved.GetRawRef()); - Ptr pTexture1Saved; - RenderParams.Device->GetTexture(1, &pTexture1Saved.GetRawRef()); - - D3DMATRIX worldMatrixSaved, viewMatrixSaved, projectionMatrixSaved, texture0MatrixSaved; - RenderParams.Device->GetTransform(D3DTS_WORLD, &worldMatrixSaved); - RenderParams.Device->GetTransform(D3DTS_VIEW, &viewMatrixSaved); - RenderParams.Device->GetTransform(D3DTS_PROJECTION, &projectionMatrixSaved); - RenderParams.Device->GetTransform(D3DTS_TEXTURE0, &texture0MatrixSaved); - - Ptr pVertexShaderSaved; - RenderParams.Device->GetVertexShader(&pVertexShaderSaved.GetRawRef()); - - Ptr pPixelShaderSaved; - RenderParams.Device->GetPixelShader(&pPixelShaderSaved.GetRawRef()); - - D3DVIEWPORT9 viewportSaved; - RenderParams.Device->GetViewport(&viewportSaved); - - Ptr pRenderTargetSaved; - RenderParams.Device->GetRenderTarget(0, &pRenderTargetSaved.GetRawRef()); - - - // Load the graphics if not loaded already. - if(!pTexture) - LoadGraphics(); - - // Calculate ortho projection. - GetOrthoProjection(RenderState, OrthoProjection); - - HRESULT hResult = RenderParams.Device->BeginScene(); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] BeginScene failed. %d (%x)", hResult, hResult)); } - - Ptr pDestSurface; - hResult = eyeTextureD3D9->D3D9.pTexture->GetSurfaceLevel(0, &pDestSurface.GetRawRef()); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] GetSurfaceLevel failed. %d (%x)", hResult, hResult)); } - - hResult = RenderParams.Device->SetRenderTarget(0, pDestSurface); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetRenderTarget failed. %d (%x)", hResult, hResult)); } - - D3DVIEWPORT9 D3DViewport; - D3DViewport.X = eyeTextureD3D9->Texture.Header.RenderViewport.Pos.x; - D3DViewport.Y = eyeTextureD3D9->Texture.Header.RenderViewport.Pos.y; - D3DViewport.Width = eyeTextureD3D9->Texture.Header.RenderViewport.Size.w; - D3DViewport.Height = eyeTextureD3D9->Texture.Header.RenderViewport.Size.h; - D3DViewport.MinZ = 0; - D3DViewport.MaxZ = 1; - hResult = RenderParams.Device->SetViewport(&D3DViewport); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetViewport failed. %d (%x)", hResult, hResult)); } - - hResult = RenderParams.Device->SetTexture(0, pTexture); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetTexture failed. %d (%x)", hResult, hResult)); } - - RenderParams.Device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - RenderParams.Device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - RenderParams.Device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - - RenderParams.Device->SetVertexShader(NULL); - RenderParams.Device->SetPixelShader(NULL); - - hResult = RenderParams.Device->SetStreamSource(0, pVB, 0, sizeof(HASWVertex)); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetStreamSource failed. %d (%x)", hResult, hResult)); } - - RenderParams.Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); - RenderParams.Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); - RenderParams.Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - RenderParams.Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - RenderParams.Device->SetRenderState(D3DRS_LIGHTING, FALSE); - RenderParams.Device->SetRenderState(D3DRS_ZENABLE, FALSE); - RenderParams.Device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - RenderParams.Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - RenderParams.Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - RenderParams.Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - - const float scale = HSWDISPLAY_SCALE * ((RenderState.OurHMDInfo.HmdType == HmdType_DK1) ? 0.70f : 1.f); - Matrix4f identityMatrix = Matrix4f::Identity(); - Vector3f translation = OrthoProjection[eye].GetTranslation(); - Matrix4f orthoStereoMatrix( - scale, 0, 0, 0, - 0, scale / 2, 0, 0, - 0, 0, HSWDISPLAY_DISTANCE, 0, - translation.x, translation.y, translation.z, 1 - ); - RenderParams.Device->SetTransform(D3DTS_WORLD, reinterpret_cast(&identityMatrix)); - RenderParams.Device->SetTransform(D3DTS_VIEW, reinterpret_cast(&identityMatrix)); - RenderParams.Device->SetTransform(D3DTS_PROJECTION, reinterpret_cast(&orthoStereoMatrix)); - RenderParams.Device->SetTransform(D3DTS_TEXTURE0, reinterpret_cast(&identityMatrix)); - - hResult = RenderParams.Device->SetFVF(HASWVertexD3D9Format); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetFVF failed. %d (%x)", hResult, hResult)); } - - hResult = RenderParams.Device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] DrawPrimitive failed. %d (%x)", hResult, hResult)); } - - hResult = RenderParams.Device->EndScene(); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] EndScene failed. %d (%x)", hResult, hResult)); } - - - // Restore previous state. - RenderParams.Device->SetRenderTarget(0, pRenderTargetSaved); - RenderParams.Device->SetViewport(&viewportSaved); - RenderParams.Device->SetPixelShader(pPixelShaderSaved); - RenderParams.Device->SetVertexShader(pVertexShaderSaved); - RenderParams.Device->SetTransform(D3DTS_TEXTURE0, &texture0MatrixSaved); - RenderParams.Device->SetTransform(D3DTS_PROJECTION, &projectionMatrixSaved); - RenderParams.Device->SetTransform(D3DTS_VIEW, &viewMatrixSaved); - RenderParams.Device->SetTransform(D3DTS_WORLD, &worldMatrixSaved); - RenderParams.Device->SetTexture(0, pTexture0Saved); - RenderParams.Device->SetTexture(1, pTexture1Saved); - RenderParams.Device->SetStreamSource(0, pVBDSaved, vbOffsetSaved, vbStrideSaved); - RenderParams.Device->SetFVF(fvfSaved); - } -} - - -}}} // namespace OVR::CAPI::D3D9 - - - - - - - +/************************************************************************************ + +Filename : CAPI_D3D9_HSWDisplay.cpp +Content : Implements Health and Safety Warning system. +Created : July 7, 2014 +Authors : Paul Pedriana + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +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 "CAPI_D3D9_HSWDisplay.h" +#include "OVR_CAPI_D3D.h" +#include "Util/Util_Direct3D.h" +#include "Kernel/OVR_File.h" +#include "Kernel/OVR_SysFile.h" +#include "Kernel/OVR_Allocator.h" +#include "Kernel/OVR_Color.h" +#include "Extras/OVR_Math.h" + + +OVR_DISABLE_MSVC_WARNING(4996) // Disable deprecation warning + +namespace OVR { namespace CAPI { + + +// To do Need to move LoadTextureTgaData to a shared location. +uint8_t* LoadTextureTgaData(OVR::File* f, uint8_t alpha, int& width, int& height); + + +namespace D3D9 { + +// This is a temporary function implementation, and it functionality needs to be implemented in a more generic way. +IDirect3DTexture9* LoadTextureTga(HSWRenderParams& rParams, OVR::File* f, uint8_t alpha) +{ + IDirect3DTexture9* pTexture = NULL; + + int width, height; + const uint8_t* pRGBA = LoadTextureTgaData(f, alpha, width, height); + + if (pRGBA) + { + // We don't have access to D3DX9 and so we currently have to do this manually instead of calling a D3DX9 utility function. + Ptr pTextureSysmem; + HRESULT hResult = rParams.Device->CreateTexture((UINT)width, (UINT)height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pTextureSysmem.GetRawRef(), NULL); + + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("CreateTexture(D3DPOOL_SYSTEMMEM) failed. %d (%x)", hResult, hResult)); } + else + { + // Lock the texture so we can write this frame's texel data + D3DLOCKED_RECT lock; + hResult = pTextureSysmem->LockRect(0, &lock, NULL, D3DLOCK_NOSYSLOCK | D3DLOCK_NO_DIRTY_UPDATE); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("LockRect failed. %d (%x)", hResult, hResult)); } + else + { + // Four bytes per pixel. Pitch bytes per row (will be >= w * 4). + uint8_t* pRow = (uint8_t*)lock.pBits; + const uint8_t* pSource = pRGBA; + + for(int y = 0; y < height; y++, pRow += lock.Pitch, pSource += (width * 4)) + { + uint8_t* pDest = pRow; + + for(int x = 0, xEnd = width * 4; x < xEnd; x += 4) + { + pDest[x + 0] = pSource[x + 2]; + pDest[x + 1] = pSource[x + 1]; + pDest[x + 2] = pSource[x + 0]; + pDest[x + 3] = pSource[x + 3]; + } + } + + pTextureSysmem->UnlockRect(0); + + hResult = rParams.Device->CreateTexture((UINT)width, (UINT)height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("CreateTexture(D3DPOOL_DEFAULT) failed. %d (%x)", hResult, hResult)); } + else + { + hResult = rParams.Device->UpdateTexture(pTextureSysmem, pTexture); + if(FAILED(hResult)) + { + HSWDISPLAY_LOG(("UpdateTexture failed. %d (%x)", hResult, hResult)); + pTexture->Release(); + pTexture = NULL; + } + } + } + } + + OVR_FREE(const_cast(pRGBA)); + } + + return pTexture; +} + + +// Loads a texture from a memory image of a TGA file. +IDirect3DTexture9* LoadTextureTga(HSWRenderParams& rParams, const uint8_t* pData, int dataSize, uint8_t alpha) +{ + MemoryFile memoryFile("", pData, dataSize); + + return LoadTextureTga(rParams, &memoryFile, alpha); +} + + +// Loads a texture from a disk TGA file. +IDirect3DTexture9* LoadTextureTga(HSWRenderParams& rParams, const char* pFilePath, uint8_t alpha) +{ + SysFile sysFile; + + if(sysFile.Open(pFilePath, FileConstants::Open_Read | FileConstants::Open_Buffered)) + return LoadTextureTga(rParams, &sysFile, alpha); + + return NULL; +} + + + +// To do: This needs to be promoted to a central version, possibly in CAPI_HSWDisplay.h +struct HASWVertex +{ + Vector3f Pos; + Color C; + float U, V; + + HASWVertex(const Vector3f& p, const Color& c = Color(64,0,0,255), float u = 0, float v = 0) + : Pos(p), C(c), U(u), V(v) + {} + + HASWVertex(float x, float y, float z, const Color& c = Color(64,0,0,255), float u = 0, float v = 0) + : Pos(x,y,z), C(c), U(u), V(v) + {} + + bool operator==(const HASWVertex& b) const + { + return (Pos == b.Pos) && (C == b.C) && (U == b.U) && (V == b.V); + } +}; + +#define HASWVertexD3D9Format (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1) + + +// The texture below may conceivably be shared between HSWDisplay instances. However, +// beware that sharing may not be possible if two HMDs are using different locales +// simultaneously. As of this writing it's not clear if that can occur in practice. + +HSWDisplay::HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState) + : OVR::CAPI::HSWDisplay(api, hmd, renderState) + , RenderParams() +{ +} + +bool HSWDisplay::Initialize(const ovrRenderAPIConfig* apiConfig) +{ + const ovrD3D9Config* config = reinterpret_cast(apiConfig); + + if(config) + { + RenderParams.Device = config->D3D9.pDevice; + RenderParams.SwapChain = config->D3D9.pSwapChain; + RenderParams.ScreenSize = config->D3D9.Header.BackBufferSize; + } + else + { + UnloadGraphics(); + } + + return true; +} + +void HSWDisplay::Shutdown() +{ + UnloadGraphics(); +} + +void HSWDisplay::DisplayInternal() +{ + HSWDISPLAY_LOG(("[HSWDisplay D3D9] DisplayInternal()")); + // We may want to call LoadGraphics here instead of within Render. +} + +void HSWDisplay::DismissInternal() +{ + HSWDISPLAY_LOG(("[HSWDisplay D3D9] DismissInternal()")); + UnloadGraphics(); +} + + +void HSWDisplay::UnloadGraphics() +{ + // RenderParams: No need to clear. + pTexture.Clear(); + pVB.Clear(); + // OrthoProjection: No need to clear. +} + + +void HSWDisplay::LoadGraphics() +{ + // As of this writing, we don't yet have an abstraction for Textures, Buffers, and Shaders like we do for D3D11, D3D11, and OpenGL. + #if defined(OVR_BUILD_DEBUG) + if(!pTexture) + pTexture = *LoadTextureTga(RenderParams, "C:\\TestPath\\TestFile.tga", 255); + #endif + + if(!pTexture) + { + D3DCAPS9 caps; + RenderParams.Device->GetDeviceCaps(&caps); + + if(caps.TextureCaps & (D3DPTEXTURECAPS_SQUAREONLY | D3DPTEXTURECAPS_POW2)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] Square textures allowed only.")); } + + size_t textureSize; + const uint8_t* TextureData = GetDefaultTexture(textureSize); + pTexture = *LoadTextureTga(RenderParams, TextureData, (int)textureSize, 255); + OVR_ASSERT(pTexture); + } + + if(!pVB) + { + HRESULT hResult = RenderParams.Device->CreateVertexBuffer(4 * sizeof(HASWVertex), NULL, HASWVertexD3D9Format, D3DPOOL_MANAGED, &pVB.GetRawRef(), NULL); + + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] CreateVertexBuffer failed. %d (%x)", hResult, hResult)); } + else + { + void* pVerticesVoid; + hResult = pVB->Lock(0, 0, (void**)&pVerticesVoid, 0); + + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] Lock failed. %d (%x)", hResult, hResult)); } + else + { + HASWVertex* pVertices = reinterpret_cast(pVerticesVoid); + + const bool flip = ((RenderState.DistortionCaps & ovrDistortionCap_FlipInput) != 0); + const float left = -1.0f; + const float top = -1.1f; + const float right = +1.0f; + const float bottom = +0.9f; + + // See warning in LoadTextureTgaData() about this TGA being loaded "upside down", i.e. UV origin is at bottom-left. + pVertices[0] = HASWVertex(left, top, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 1.f : 0.f); // To do: Make this branchless + pVertices[1] = HASWVertex(left, bottom, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 0.f : 1.f); + pVertices[2] = HASWVertex(right, top, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 1.f : 0.f); + pVertices[3] = HASWVertex(right, bottom, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 0.f : 1.f); + + pVB->Unlock(); + } + } + } +} + + +void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) +{ + if(RenderEnabled && eyeTexture) + { + // Note: The D3D9 implementation below is entirely fixed-function and isn't yet using shaders. + // For the time being this is sufficient, but future designs will likely necessitate moving + // to a system that uses programmable shaders. + + // We need to render to the eyeTexture with the texture viewport. + // Setup rendering to the texture. + ovrD3D9Texture* eyeTextureD3D9 = const_cast(reinterpret_cast(eyeTexture)); + OVR_ASSERT(eyeTextureD3D9->Texture.Header.API == ovrRenderAPI_D3D9); + + + // Save previous state. + // To do: Merge this saved state with that done by DistortionRenderer::GraphicsState::Save(), and put them in a shared location. + DWORD fvfSaved; + RenderParams.Device->GetFVF(&fvfSaved); + + Ptr pVBDSaved; + UINT vbOffsetSaved; + UINT vbStrideSaved; + RenderParams.Device->GetStreamSource(0, &pVBDSaved.GetRawRef(), &vbOffsetSaved, &vbStrideSaved); + + Ptr pTexture0Saved; + RenderParams.Device->GetTexture(0, &pTexture0Saved.GetRawRef()); + Ptr pTexture1Saved; + RenderParams.Device->GetTexture(1, &pTexture1Saved.GetRawRef()); + + D3DMATRIX worldMatrixSaved, viewMatrixSaved, projectionMatrixSaved, texture0MatrixSaved; + RenderParams.Device->GetTransform(D3DTS_WORLD, &worldMatrixSaved); + RenderParams.Device->GetTransform(D3DTS_VIEW, &viewMatrixSaved); + RenderParams.Device->GetTransform(D3DTS_PROJECTION, &projectionMatrixSaved); + RenderParams.Device->GetTransform(D3DTS_TEXTURE0, &texture0MatrixSaved); + + Ptr pVertexShaderSaved; + RenderParams.Device->GetVertexShader(&pVertexShaderSaved.GetRawRef()); + + Ptr pPixelShaderSaved; + RenderParams.Device->GetPixelShader(&pPixelShaderSaved.GetRawRef()); + + D3DVIEWPORT9 viewportSaved; + RenderParams.Device->GetViewport(&viewportSaved); + + Ptr pRenderTargetSaved; + RenderParams.Device->GetRenderTarget(0, &pRenderTargetSaved.GetRawRef()); + + + // Load the graphics if not loaded already. + if(!pTexture) + LoadGraphics(); + + // Calculate ortho projection. + GetOrthoProjection(RenderState, OrthoProjection); + + HRESULT hResult = RenderParams.Device->BeginScene(); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] BeginScene failed. %d (%x)", hResult, hResult)); } + + Ptr pDestSurface; + hResult = eyeTextureD3D9->D3D9.pTexture->GetSurfaceLevel(0, &pDestSurface.GetRawRef()); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] GetSurfaceLevel failed. %d (%x)", hResult, hResult)); } + + hResult = RenderParams.Device->SetRenderTarget(0, pDestSurface); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetRenderTarget failed. %d (%x)", hResult, hResult)); } + + D3DVIEWPORT9 D3DViewport; + D3DViewport.X = eyeTextureD3D9->Texture.Header.RenderViewport.Pos.x; + D3DViewport.Y = eyeTextureD3D9->Texture.Header.RenderViewport.Pos.y; + D3DViewport.Width = eyeTextureD3D9->Texture.Header.RenderViewport.Size.w; + D3DViewport.Height = eyeTextureD3D9->Texture.Header.RenderViewport.Size.h; + D3DViewport.MinZ = 0; + D3DViewport.MaxZ = 1; + hResult = RenderParams.Device->SetViewport(&D3DViewport); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetViewport failed. %d (%x)", hResult, hResult)); } + + hResult = RenderParams.Device->SetTexture(0, pTexture); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetTexture failed. %d (%x)", hResult, hResult)); } + + RenderParams.Device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + RenderParams.Device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + RenderParams.Device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + + RenderParams.Device->SetVertexShader(NULL); + RenderParams.Device->SetPixelShader(NULL); + + hResult = RenderParams.Device->SetStreamSource(0, pVB, 0, sizeof(HASWVertex)); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetStreamSource failed. %d (%x)", hResult, hResult)); } + + RenderParams.Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + RenderParams.Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + RenderParams.Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + RenderParams.Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + RenderParams.Device->SetRenderState(D3DRS_LIGHTING, FALSE); + RenderParams.Device->SetRenderState(D3DRS_ZENABLE, FALSE); + RenderParams.Device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + RenderParams.Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + RenderParams.Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + RenderParams.Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + + const float scale = HSWDISPLAY_SCALE * ((RenderState.OurHMDInfo.HmdType == HmdType_DK1) ? 0.70f : 1.f); + Matrix4f identityMatrix = Matrix4f::Identity(); + Vector3f translation = OrthoProjection[eye].GetTranslation(); + Matrix4f orthoStereoMatrix( + scale, 0, 0, 0, + 0, scale / 2, 0, 0, + 0, 0, HSWDISPLAY_DISTANCE, 0, + translation.x, translation.y, translation.z, 1 + ); + RenderParams.Device->SetTransform(D3DTS_WORLD, reinterpret_cast(&identityMatrix)); + RenderParams.Device->SetTransform(D3DTS_VIEW, reinterpret_cast(&identityMatrix)); + RenderParams.Device->SetTransform(D3DTS_PROJECTION, reinterpret_cast(&orthoStereoMatrix)); + RenderParams.Device->SetTransform(D3DTS_TEXTURE0, reinterpret_cast(&identityMatrix)); + + hResult = RenderParams.Device->SetFVF(HASWVertexD3D9Format); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetFVF failed. %d (%x)", hResult, hResult)); } + + hResult = RenderParams.Device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] DrawPrimitive failed. %d (%x)", hResult, hResult)); } + + hResult = RenderParams.Device->EndScene(); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] EndScene failed. %d (%x)", hResult, hResult)); } + + + // Restore previous state. + RenderParams.Device->SetRenderTarget(0, pRenderTargetSaved); + RenderParams.Device->SetViewport(&viewportSaved); + RenderParams.Device->SetPixelShader(pPixelShaderSaved); + RenderParams.Device->SetVertexShader(pVertexShaderSaved); + RenderParams.Device->SetTransform(D3DTS_TEXTURE0, &texture0MatrixSaved); + RenderParams.Device->SetTransform(D3DTS_PROJECTION, &projectionMatrixSaved); + RenderParams.Device->SetTransform(D3DTS_VIEW, &viewMatrixSaved); + RenderParams.Device->SetTransform(D3DTS_WORLD, &worldMatrixSaved); + RenderParams.Device->SetTexture(0, pTexture0Saved); + RenderParams.Device->SetTexture(1, pTexture1Saved); + RenderParams.Device->SetStreamSource(0, pVBDSaved, vbOffsetSaved, vbStrideSaved); + RenderParams.Device->SetFVF(fvfSaved); + } +} + + +}}} // namespace OVR::CAPI::D3D9 + +OVR_RESTORE_MSVC_WARNING() diff --git a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.h b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.h index b1d7191..9ad682a 100644 --- a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.h +++ b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.h @@ -1,82 +1,76 @@ -/************************************************************************************ - -Filename : CAPI_D3D9_HSWDisplay.h -Content : Implements Health and Safety Warning system. -Created : July 7, 2014 -Authors : Paul Pedriana - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -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_CAPI_D3D9_HSWDisplay_h -#define OVR_CAPI_D3D9_HSWDisplay_h - -#if !defined(OVR_D3D_VERSION) || (OVR_D3D_VERSION != 9) - #error This header expects OVR_D3D_VERSION to be defined, to 9. -#endif - -#include "../CAPI_HSWDisplay.h" -#include "../D3D1X/CAPI_D3D1X_Util.h" -#include - - -namespace OVR { namespace CAPI { namespace D3D9 { - - // There currently isn't a D3D9::RenderParams, as D3D9 support is currently only very basic. - struct HSWRenderParams - { - IDirect3DDevice9* Device; - IDirect3DSwapChain9* SwapChain; - ovrSizei ScreenSize; - }; - - class HSWDisplay : public CAPI::HSWDisplay - { - public: - HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState); - - // Must be called before use. apiConfig is such that: - // const ovrD3D9Config* config = (const ovrD3D9Config*)apiConfig; or - bool Initialize(const ovrRenderAPIConfig* apiConfig); - void Shutdown(); - void DisplayInternal(); - void DismissInternal(); - - // Draws the warning to the eye texture(s). This must be done at the end of a - // frame but prior to executing the distortion rendering of the eye textures. - void RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture); - - protected: - void LoadGraphics(); - void UnloadGraphics(); - - D3D9::HSWRenderParams RenderParams; - Ptr pTexture; - Ptr pVB; - Matrix4f OrthoProjection[2]; // Projection for 2D. - - private: - OVR_NON_COPYABLE(HSWDisplay) - }; - -}}} // namespace OVR::CAPI::D3D9 - - -#endif // OVR_CAPI_D3D9_HSWDisplay_h - +/************************************************************************************ + +Filename : CAPI_D3D9_HSWDisplay.h +Content : Implements Health and Safety Warning system. +Created : July 7, 2014 +Authors : Paul Pedriana + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +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_CAPI_D3D9_HSWDisplay_h +#define OVR_CAPI_D3D9_HSWDisplay_h + +#include "../CAPI_HSWDisplay.h" +#include "Util/Util_Direct3D.h" + +namespace OVR { namespace CAPI { namespace D3D9 { + + // There currently isn't a D3D9::RenderParams, as D3D9 support is currently only very basic. + struct HSWRenderParams + { + IDirect3DDevice9* Device; + IDirect3DSwapChain9* SwapChain; + ovrSizei ScreenSize; + }; + + class HSWDisplay : public CAPI::HSWDisplay + { + public: + HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState); + + // Must be called before use. apiConfig is such that: + // const ovrD3D9Config* config = (const ovrD3D9Config*)apiConfig; or + bool Initialize(const ovrRenderAPIConfig* apiConfig); + void Shutdown(); + void DisplayInternal(); + void DismissInternal(); + + // Draws the warning to the eye texture(s). This must be done at the end of a + // frame but prior to executing the distortion rendering of the eye textures. + void RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture); + + protected: + void LoadGraphics(); + void UnloadGraphics(); + + D3D9::HSWRenderParams RenderParams; + Ptr pTexture; + Ptr pVB; + Matrix4f OrthoProjection[2]; // Projection for 2D. + + private: + OVR_NON_COPYABLE(HSWDisplay) + }; + +}}} // namespace OVR::CAPI::D3D9 + + +#endif // OVR_CAPI_D3D9_HSWDisplay_h + diff --git a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_Util.cpp b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_Util.cpp index 0c6cd45..2f90539 100644 --- a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_Util.cpp +++ b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_Util.cpp @@ -1,273 +1,286 @@ -/************************************************************************************ - -Filename : CAPI_D3D1X_Util.cpp -Content : D3D9 utility functions for rendering -Created : March 7 , 2014 -Authors : Tom Heath - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -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 "CAPI_D3D9_DistortionRenderer.h" -#define OVR_D3D_VERSION 9 -#include "../../OVR_CAPI_D3D.h" - - -namespace OVR { namespace CAPI { namespace D3D9 { - - -#define PRECOMPILE_FLAG 0 -#if !PRECOMPILE_FLAG -//To make these, you need to run it with PRECOMPILE_FLAG, which also uses them, so good for debugging. -//Then cut and paste these from the output window. -//Then turn off the flag. -DWORD precompiledVertexShaderSrc[96] = {4294836736,3080190,1111577667,28,130,4294836736,2,28,33024,123,68,131074,655361,88,0,104,2,131073,88,0,1415936325,1970230127,1432707954,1717981014,7628147,196609,131073,1,0,1415936325,1970230127,1432707954,1633899350,1979737452,1597136755,1766654000,1936683619,544499311,539578920,1280527432,1634226976,544367972,1886220099,1919249513,841890080,892939833,825437746,2868916529,83886161,2685337601,1065353216,0,1056964608,0,33554463,2147483648,2416902144,33554463,2147614720,2416902145,33554463,2147483653,2416902146,33554463,2147549189,2416902147,33554463,2147614725,2416902148,33554433,2147680256,2699296768,67108868,3758292992,2162425856,2430861314,2699296770,67108868,3758292993,2162425856,2430861315,2699296770,67108868,3758292994,2162425856,2430861316,2699296770,67108868,3222208512,2416181248,2689597441,2686779393,33554433,3758161923,2415919105,65535,}; -DWORD precompiledVertexShaderTimewarpSrc[310] = {4294836992,4587518,1111577667,28,222,4294836992,4,28,33024,215,108,1310722,5373956,124,0,140,262146,1179652,124,0,157,131074,655361,180,0,196,2,131073,180,0,1382381893,1952543855,1164865385,2868929646,196611,262148,1,0,1382381893,1952543855,1399746409,1953653108,1702446336,1867738964,1701016181,1716475477,1952805734,2880154368,196609,131073,1,0,1415936325,1970230127,1432707954,1633899350,1979737452,1597202291,1766654000,1936683619,544499311,539578920,1280527432,1634226976,544367972,1886220099,1919249513,841890080,892939833,825437746,2868916529,83886161,2685337601,1065353216,0,1056964608,0,33554463,2147483648,2416902144,33554463,2147549184,2416902145,33554463,2147614720,2416902146,33554463,2147483653,2416902147,33554463,2147549189,2416902148,33554463,2147614725,2416902149,33554463,2147483648,3759079424,33554463,2147483653,3758292993,33554463,2147549189,3758292994,33554463,2147614725,3758292995,33554463,2147680261,3758161924,33554433,2147549184,2695495684,50331650,2147549185,2164260864,2695495700,33554433,2147614720,2695495685,50331650,2147614721,2169831424,2695495701,33554433,2147745792,2695495686,50331650,2147745793,2175401984,2695495702,33554433,2148007936,2695495687,50331650,2148007937,2180972544,2695495703,67108868,2148466688,2415919105,2162425857,2162425856,67108868,2148466689,2416181251,2689597441,2684682241,50331657,2147549186,2162425856,2162425857,33554438,2147549186,2147483650,33554433,2147680259,2699296772,50331650,2147876866,2177892355,2697986068,67108868,2147549187,2415919105,2158624770,2689925124,67108868,2147549188,2415919105,2153054210,2684354564,33554433,2147680261,2699296773,50331650,2147876866,2177105925,2697199637,67108868,2147614723,2415919105,2153054210,2689925125,67108868,2147614724,2415919105,2158624770,2684354565,33554433,2147680261,2699296774,50331650,2147811333,2177171461,2697265174,67108868,2147745795,2415919105,2147483653,2689925126,67108868,2147745796,2415919105,2158624773,2684354566,33554433,2147680261,2699296775,50331650,2148073477,2166685701,2686779415,67108868,2148007939,2415919105,2147483653,2689925127,67108868,2148007940,2415919105,2164195333,2684354567,50331657,2147549189,2162425860,2162425857,50331657,2147614725,2162425859,2162425857,50331653,2147680257,2147483650,2162425861,33554433,2147680258,2699296768,67108868,3758292993,2162425858,2162425857,2699296770,67108868,2148466689,2416181252,2689597441,2684682241,50331657,2147549189,2162425860,2162425857,50331657,2147614725,2162425859,2162425857,50331657,2147549185,2162425856,2162425857,33554438,2147549185,2147483649,50331653,2147680257,2147483649,2162425861,67108868,3758292994,2162425858,2162425857,2699296770,67108868,2148466689,2416181253,2689597441,2684682241,50331657,2147549188,2162425860,2162425857,50331657,2147614724,2162425859,2162425857,50331657,2147549184,2162425856,2162425857,33554438,2147549184,2147483648,50331653,2147680256,2147483648,2162425860,67108868,3758292995,2162425858,2162425856,2699296770,67108868,3759079424,2416181248,2689597441,2686779393,33554433,3758161924,2415919106,65535,}; -DWORD precompiledPixelShaderSrc[84] = {4294902528,2228222,1111577667,28,79,4294902528,1,28,33024,72,48,3,131073,56,0,1954047316,6648437,786436,65537,1,0,861893488,1291858015,1869767529,1952870259,693250080,1397508128,1750278220,1919247457,1836008224,1701603696,775495794,959330610,858665525,3223857,83886161,2685337600,1065353216,0,0,0,33554463,2147483653,2416115712,33554463,2147549189,2416115713,33554463,2147614725,2416115714,33554463,2147680261,2415984643,33554463,2415919104,2685339648,50331714,2148466688,2430861312,2699298816,67108868,2148073472,2147483648,2690908160,2686779392,50331714,2148466689,2430861313,2699298816,33554433,2147614720,2153054209,50331714,2148466689,2430861314,2699298816,33554433,2147745792,2158624769,50331653,2148468736,2162425856,2415919107,65535,}; - -#else -#include "d3dcompiler.h" -#pragma comment(lib, "C:\\Program Files (x86)\\Microsoft DirectX SDK (June 2010)\\Lib\\x86\\D3DCompiler.lib") -/***************************************************************************/ -const char* VertexShaderSrc = - - "float2 EyeToSourceUVScale : register(c0); \n" - "float2 EyeToSourceUVOffset : register(c2); \n" - - "void main(in float2 Position : POSITION, in float TimeWarp : POSITION1, \n" - " in float Vignette : POSITION2, in float2 TexCoord0 : TEXCOORD0, \n" - " in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2, \n" - " out float4 oPosition : SV_Position, out float2 oTexCoord0 : TEXCOORD0, \n" - " out float2 oTexCoord1 : TEXCOORD1, out float2 oTexCoord2 : TEXCOORD2, \n" - " out float oVignette : TEXCOORD3) \n" - "{ \n" - " oTexCoord0 = EyeToSourceUVScale * TexCoord0 + EyeToSourceUVOffset; \n" - " oTexCoord1 = EyeToSourceUVScale * TexCoord1 + EyeToSourceUVOffset; \n" - " oTexCoord2 = EyeToSourceUVScale * TexCoord2 + EyeToSourceUVOffset; \n" - " oVignette = Vignette; \n" - " oPosition = float4(Position.xy, 0.5, 1.0); \n" - "}"; - -/***************************************************************************/ -const char* VertexShaderTimewarpSrc = - - "float2 EyeToSourceUVScale : register(c0); \n" - "float2 EyeToSourceUVOffset : register(c2); \n" - "float4x4 EyeRotationStart : register(c4); \n" - "float4x4 EyeRotationEnd : register(c20); \n" - - "float2 TimewarpTexCoord(float2 TexCoord, float4x4 rotMat) \n" - "{ \n" - " float3 transformed = float3( mul ( rotMat, float4(TexCoord.xy, 1, 1) ).xyz); \n" - " float2 flattened = (transformed.xy / transformed.z); \n" - " return(EyeToSourceUVScale * flattened + EyeToSourceUVOffset); \n" - "} \n" - "void main(in float2 Position : POSITION, in float TimeWarp : POSITION1, \n" - " in float Vignette : POSITION2, in float2 TexCoord0 : TEXCOORD0, \n" - " in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2, \n" - " out float4 oPosition : SV_Position, out float2 oTexCoord0 : TEXCOORD0, \n" - " out float2 oTexCoord1 : TEXCOORD1, out float2 oTexCoord2 : TEXCOORD2, \n" - " out float oVignette : TEXCOORD3) \n" - "{ \n" - " float4x4 lerpedEyeRot = lerp(EyeRotationStart, EyeRotationEnd, TimeWarp); \n" - " oTexCoord0 = TimewarpTexCoord(TexCoord0,lerpedEyeRot); \n" - " oTexCoord1 = TimewarpTexCoord(TexCoord1,lerpedEyeRot); \n" - " oTexCoord2 = TimewarpTexCoord(TexCoord2,lerpedEyeRot); \n" - " oVignette = Vignette; \n" - " oPosition = float4(Position.xy, 0.5, 1.0); \n" - "}"; - -/***************************************************************************/ -const char* PixelShaderSrc = - - " sampler2D Texture : register(s0); \n" - - "float4 main(in float4 oPosition : SV_Position, in float2 oTexCoord0 : TEXCOORD0, \n" - " in float2 oTexCoord1 : TEXCOORD1, in float2 oTexCoord2 : TEXCOORD2, \n" - " in float oVignette : TEXCOORD3) \n" - " : SV_Target \n" - "{ \n" - " float R = tex2D(Texture,oTexCoord0).r; \n" - " float G = tex2D(Texture,oTexCoord1).g; \n" - " float B = tex2D(Texture,oTexCoord2).b; \n" - " return (oVignette*float4(R,G,B,1)); \n" - "}"; - -/*************************************************************/ -ID3DBlob* ShaderCompile(char * shaderName, const char * shaderSrcString, const char * profile) -{ - ID3DBlob* pShaderCode = NULL; - ID3DBlob* pErrorMsg = NULL; - - if (FAILED(D3DCompile(shaderSrcString, strlen(shaderSrcString),NULL,NULL,NULL, - "main",profile,D3DCOMPILE_OPTIMIZATION_LEVEL3,0, - &pShaderCode,&pErrorMsg))) - MessageBoxA(NULL,(char *) pErrorMsg->GetBufferPointer(),"", MB_OK); - if (pErrorMsg) pErrorMsg->Release(); - - //Now write out blob - char tempString[1000]; - int numDWORDs = ((int)pShaderCode->GetBufferSize())/4; - DWORD * ptr = (DWORD *)pShaderCode->GetBufferPointer(); - sprintf_s(tempString,"DWORD %s[%d] = {",shaderName,numDWORDs); - OutputDebugStringA(tempString); - for (int i = 0;i < numDWORDs; i++) - { - sprintf_s(tempString,"%lu,",ptr[i]); - OutputDebugStringA(tempString); - } - OutputDebugStringA("};\n"); - - return(pShaderCode); -} -#endif - -/***********************************************************/ -void DistortionRenderer::CreateDistortionShaders(void) -{ -#if PRECOMPILE_FLAG - ID3DBlob * pShaderCode; - pShaderCode = ShaderCompile("precompiledVertexShaderSrc",VertexShaderSrc,"vs_2_0"); - Device->CreateVertexShader( ( DWORD* )pShaderCode->GetBufferPointer(), &VertexShader ); - pShaderCode->Release(); - - pShaderCode = ShaderCompile("precompiledVertexShaderTimewarpSrc",VertexShaderTimewarpSrc,"vs_3_0"); - Device->CreateVertexShader( ( DWORD* )pShaderCode->GetBufferPointer(), &VertexShaderTimewarp ); - pShaderCode->Release(); - - pShaderCode = ShaderCompile("precompiledPixelShaderSrc",PixelShaderSrc,"ps_3_0"); - Device->CreatePixelShader( ( DWORD* )pShaderCode->GetBufferPointer(), &PixelShader ); - pShaderCode->Release(); -#else - Device->CreateVertexShader( precompiledVertexShaderSrc, &VertexShader ); - Device->CreateVertexShader( precompiledVertexShaderTimewarpSrc, &VertexShaderTimewarp ); - Device->CreatePixelShader( precompiledPixelShaderSrc, &PixelShader ); -#endif -} - - -/***************************************************/ -void DistortionRenderer::CreateVertexDeclaration(void) -{ - static const D3DVERTEXELEMENT9 VertexElements[7] = { - { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, - { 0, 8, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1 }, - { 0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 2 }, - { 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, - { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 }, - { 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2 }, - D3DDECL_END() }; - Device->CreateVertexDeclaration( VertexElements, &VertexDecl ); -} - - -/******************************************************/ -void DistortionRenderer::CreateDistortionModels(void) -{ - //Make the distortion models - for (int eye=0;eye<2;eye++) - { - FOR_EACH_EYE * e = &eachEye[eye]; - ovrDistortionMesh meshData; - ovrHmd_CreateDistortionMesh(HMD, - RState.EyeRenderDesc[eye].Eye, - RState.EyeRenderDesc[eye].Fov, - RState.DistortionCaps, - &meshData); - - e->numVerts = meshData.VertexCount; - e->numIndices = meshData.IndexCount; - - Device->CreateVertexBuffer( (e->numVerts)*sizeof(ovrDistortionVertex),0, 0, - D3DPOOL_MANAGED, &e->dxVerts, NULL ); - ovrDistortionVertex * dxv; e->dxVerts->Lock( 0, 0, (void**)&dxv, 0 ); - for (int v=0;vnumVerts;v++) dxv[v] = meshData.pVertexData[v]; - e->dxVerts->Unlock(); - - Device->CreateIndexBuffer( (e->numIndices)*sizeof(u_short),0, D3DFMT_INDEX16, - D3DPOOL_MANAGED, &e->dxIndices, NULL ); - unsigned short* dxi; e->dxIndices->Lock( 0, 0, (void**)&dxi, 0 ); - for (int i=0;inumIndices;i++) dxi[i] = meshData.pIndexData[i]; - e->dxIndices->Unlock(); - - ovrHmd_DestroyDistortionMesh( &meshData ); - } -} - -/**********************************************************/ -void DistortionRenderer::RenderBothDistortionMeshes(void) -{ - Device->BeginScene(); - - D3DCOLOR clearColor = D3DCOLOR_RGBA( - (int)(RState.ClearColor[0] * 255.0f), - (int)(RState.ClearColor[1] * 255.0f), - (int)(RState.ClearColor[2] * 255.0f), - (int)(RState.ClearColor[3] * 255.0f)); - - Device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER, clearColor, 0, 0); - - for (int eye=0; eye<2; eye++) - { - FOR_EACH_EYE * e = &eachEye[eye]; - D3DVIEWPORT9 vp; - vp.X=0; vp.Y=0; - vp.Width=ScreenSize.w; vp.Height=ScreenSize.h; - vp.MinZ=0; vp.MaxZ = 1; - - Device->SetViewport(&vp); - Device->SetStreamSource( 0, e->dxVerts,0, sizeof(ovrDistortionVertex) ); - Device->SetVertexDeclaration( VertexDecl ); - Device->SetIndices( e->dxIndices ); - Device->SetPixelShader( PixelShader ); - Device->SetTexture( 0, e->texture); - - //Choose which vertex shader, with associated additional inputs - if (RState.DistortionCaps & ovrDistortionCap_TimeWarp) - { - Device->SetVertexShader( VertexShaderTimewarp ); - - ovrMatrix4f timeWarpMatrices[2]; - ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eye, - RState.EyeRenderPoses[eye], timeWarpMatrices); - - //Need to transpose the matrices - timeWarpMatrices[0] = Matrix4f(timeWarpMatrices[0]).Transposed(); - timeWarpMatrices[1] = Matrix4f(timeWarpMatrices[1]).Transposed(); - - // Feed identity like matrices in until we get proper timewarp calculation going on - Device->SetVertexShaderConstantF(4, (float *) &timeWarpMatrices[0],4); - Device->SetVertexShaderConstantF(20,(float *) &timeWarpMatrices[1],4); - } - else - { - Device->SetVertexShader( VertexShader ); - } - - //Set up vertex shader constants - Device->SetVertexShaderConstantF( 0, ( FLOAT* )&(e->UVScaleOffset[0]), 1 ); - Device->SetVertexShaderConstantF( 2, ( FLOAT* )&(e->UVScaleOffset[1]), 1 ); - - Device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST,0,0,e->numVerts,0,e->numIndices/3); - } - - Device->EndScene(); -} - -}}} +/************************************************************************************ + +Filename : CAPI_D3D11_Util.cpp +Content : D3D9 utility functions for rendering +Created : March 7 , 2014 +Authors : Tom Heath + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +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 "CAPI_D3D9_DistortionRenderer.h" +#include "OVR_CAPI_D3D.h" + + +namespace OVR { namespace CAPI { namespace D3D9 { + + +#define PRECOMPILE_FLAG 0 +#if !PRECOMPILE_FLAG +//To make these, you need to run it with PRECOMPILE_FLAG, which also uses them, so good for debugging. +//Then cut and paste these from the output window. +//Then turn off the flag. +DWORD precompiledVertexShaderSrc[96] = {4294836736,3080190,1111577667,28,130,4294836736,2,28,33024,123,68,131074,655361,88,0,104,2,131073,88,0,1415936325,1970230127,1432707954,1717981014,7628147,196609,131073,1,0,1415936325,1970230127,1432707954,1633899350,1979737452,1597136755,1766654000,1936683619,544499311,539578920,1280527432,1634226976,544367972,1886220099,1919249513,841890080,892939833,825437746,2868916529,83886161,2685337601,1065353216,0,1056964608,0,33554463,2147483648,2416902144,33554463,2147614720,2416902145,33554463,2147483653,2416902146,33554463,2147549189,2416902147,33554463,2147614725,2416902148,33554433,2147680256,2699296768,67108868,3758292992,2162425856,2430861314,2699296770,67108868,3758292993,2162425856,2430861315,2699296770,67108868,3758292994,2162425856,2430861316,2699296770,67108868,3222208512,2416181248,2689597441,2686779393,33554433,3758161923,2415919105,65535,}; +DWORD precompiledVertexShaderTimewarpSrc[310] = {4294836992,4587518,1111577667,28,222,4294836992,4,28,33024,215,108,1310722,5373956,124,0,140,262146,1179652,124,0,157,131074,655361,180,0,196,2,131073,180,0,1382381893,1952543855,1164865385,2868929646,196611,262148,1,0,1382381893,1952543855,1399746409,1953653108,1702446336,1867738964,1701016181,1716475477,1952805734,2880154368,196609,131073,1,0,1415936325,1970230127,1432707954,1633899350,1979737452,1597202291,1766654000,1936683619,544499311,539578920,1280527432,1634226976,544367972,1886220099,1919249513,841890080,892939833,825437746,2868916529,83886161,2685337601,1065353216,0,1056964608,0,33554463,2147483648,2416902144,33554463,2147549184,2416902145,33554463,2147614720,2416902146,33554463,2147483653,2416902147,33554463,2147549189,2416902148,33554463,2147614725,2416902149,33554463,2147483648,3759079424,33554463,2147483653,3758292993,33554463,2147549189,3758292994,33554463,2147614725,3758292995,33554463,2147680261,3758161924,33554433,2147549184,2695495684,50331650,2147549185,2164260864,2695495700,33554433,2147614720,2695495685,50331650,2147614721,2169831424,2695495701,33554433,2147745792,2695495686,50331650,2147745793,2175401984,2695495702,33554433,2148007936,2695495687,50331650,2148007937,2180972544,2695495703,67108868,2148466688,2415919105,2162425857,2162425856,67108868,2148466689,2416181251,2689597441,2684682241,50331657,2147549186,2162425856,2162425857,33554438,2147549186,2147483650,33554433,2147680259,2699296772,50331650,2147876866,2177892355,2697986068,67108868,2147549187,2415919105,2158624770,2689925124,67108868,2147549188,2415919105,2153054210,2684354564,33554433,2147680261,2699296773,50331650,2147876866,2177105925,2697199637,67108868,2147614723,2415919105,2153054210,2689925125,67108868,2147614724,2415919105,2158624770,2684354565,33554433,2147680261,2699296774,50331650,2147811333,2177171461,2697265174,67108868,2147745795,2415919105,2147483653,2689925126,67108868,2147745796,2415919105,2158624773,2684354566,33554433,2147680261,2699296775,50331650,2148073477,2166685701,2686779415,67108868,2148007939,2415919105,2147483653,2689925127,67108868,2148007940,2415919105,2164195333,2684354567,50331657,2147549189,2162425860,2162425857,50331657,2147614725,2162425859,2162425857,50331653,2147680257,2147483650,2162425861,33554433,2147680258,2699296768,67108868,3758292993,2162425858,2162425857,2699296770,67108868,2148466689,2416181252,2689597441,2684682241,50331657,2147549189,2162425860,2162425857,50331657,2147614725,2162425859,2162425857,50331657,2147549185,2162425856,2162425857,33554438,2147549185,2147483649,50331653,2147680257,2147483649,2162425861,67108868,3758292994,2162425858,2162425857,2699296770,67108868,2148466689,2416181253,2689597441,2684682241,50331657,2147549188,2162425860,2162425857,50331657,2147614724,2162425859,2162425857,50331657,2147549184,2162425856,2162425857,33554438,2147549184,2147483648,50331653,2147680256,2147483648,2162425860,67108868,3758292995,2162425858,2162425856,2699296770,67108868,3759079424,2416181248,2689597441,2686779393,33554433,3758161924,2415919106,65535,}; +DWORD precompiledPixelShaderSrc[84] = {4294902528,2228222,1111577667,28,79,4294902528,1,28,33024,72,48,3,131073,56,0,1954047316,6648437,786436,65537,1,0,861893488,1291858015,1869767529,1952870259,693250080,1397508128,1750278220,1919247457,1836008224,1701603696,775495794,959330610,858665525,3223857,83886161,2685337600,1065353216,0,0,0,33554463,2147483653,2416115712,33554463,2147549189,2416115713,33554463,2147614725,2416115714,33554463,2147680261,2415984643,33554463,2415919104,2685339648,50331714,2148466688,2430861312,2699298816,67108868,2148073472,2147483648,2690908160,2686779392,50331714,2148466689,2430861313,2699298816,33554433,2147614720,2153054209,50331714,2148466689,2430861314,2699298816,33554433,2147745792,2158624769,50331653,2148468736,2162425856,2415919107,65535,}; + +#else +#include "d3dcompiler.h" +#pragma comment(lib, "C:\\Program Files (x86)\\Microsoft DirectX SDK (June 2010)\\Lib\\x86\\D3DCompiler.lib") +/***************************************************************************/ +const char* VertexShaderSrc = + + "float2 EyeToSourceUVScale : register(c0); \n" + "float2 EyeToSourceUVOffset : register(c2); \n" + + "void main(in float2 Position : POSITION, in float TimeWarp : POSITION1, \n" + " in float Vignette : POSITION2, in float2 TexCoord0 : TEXCOORD0, \n" + " in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2, \n" + " out float4 oPosition : SV_Position, out float2 oTexCoord0 : TEXCOORD0, \n" + " out float2 oTexCoord1 : TEXCOORD1, out float2 oTexCoord2 : TEXCOORD2, \n" + " out float oVignette : TEXCOORD3) \n" + "{ \n" + " oTexCoord0 = EyeToSourceUVScale * TexCoord0 + EyeToSourceUVOffset; \n" + " oTexCoord1 = EyeToSourceUVScale * TexCoord1 + EyeToSourceUVOffset; \n" + " oTexCoord2 = EyeToSourceUVScale * TexCoord2 + EyeToSourceUVOffset; \n" + " oVignette = Vignette; \n" + " oPosition = float4(Position.xy, 0.5, 1.0); \n" + "}"; + +/***************************************************************************/ +const char* VertexShaderTimewarpSrc = + + "float2 EyeToSourceUVScale : register(c0); \n" + "float2 EyeToSourceUVOffset : register(c2); \n" + "float4x4 EyeRotationStart : register(c4); \n" + "float4x4 EyeRotationEnd : register(c20); \n" + + "float2 TimewarpTexCoord(float2 TexCoord, float4x4 rotMat) \n" + "{ \n" + " float3 transformed = float3( mul ( rotMat, float4(TexCoord.xy, 1, 1) ).xyz); \n" + " float2 flattened = (transformed.xy / transformed.z); \n" + " return(EyeToSourceUVScale * flattened + EyeToSourceUVOffset); \n" + "} \n" + "void main(in float2 Position : POSITION, in float TimeWarp : POSITION1, \n" + " in float Vignette : POSITION2, in float2 TexCoord0 : TEXCOORD0, \n" + " in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2, \n" + " out float4 oPosition : SV_Position, out float2 oTexCoord0 : TEXCOORD0, \n" + " out float2 oTexCoord1 : TEXCOORD1, out float2 oTexCoord2 : TEXCOORD2, \n" + " out float oVignette : TEXCOORD3) \n" + "{ \n" + " float4x4 lerpedEyeRot = lerp(EyeRotationStart, EyeRotationEnd, TimeWarp); \n" + " oTexCoord0 = TimewarpTexCoord(TexCoord0,lerpedEyeRot); \n" + " oTexCoord1 = TimewarpTexCoord(TexCoord1,lerpedEyeRot); \n" + " oTexCoord2 = TimewarpTexCoord(TexCoord2,lerpedEyeRot); \n" + " oVignette = Vignette; \n" + " oPosition = float4(Position.xy, 0.5, 1.0); \n" + "}"; + +/***************************************************************************/ +const char* PixelShaderSrc = + + " sampler2D Texture : register(s0); \n" + + "float4 main(in float4 oPosition : SV_Position, in float2 oTexCoord0 : TEXCOORD0, \n" + " in float2 oTexCoord1 : TEXCOORD1, in float2 oTexCoord2 : TEXCOORD2, \n" + " in float oVignette : TEXCOORD3) \n" + " : SV_Target \n" + "{ \n" + " float R = tex2D(Texture,oTexCoord0).r; \n" + " float G = tex2D(Texture,oTexCoord1).g; \n" + " float B = tex2D(Texture,oTexCoord2).b; \n" + " return (oVignette*float4(R,G,B,1)); \n" + "}"; + +/*************************************************************/ +ID3DBlob* ShaderCompile(char * shaderName, const char * shaderSrcString, const char * profile) +{ + ID3DBlob* pShaderCode = NULL; + ID3DBlob* pErrorMsg = NULL; + + if (FAILED(D3DCompile(shaderSrcString, strlen(shaderSrcString),NULL,NULL,NULL, + "main",profile,D3DCOMPILE_OPTIMIZATION_LEVEL3,0, + &pShaderCode,&pErrorMsg))) + MessageBoxA(NULL,(char *) pErrorMsg->GetBufferPointer(),"", MB_OK); + if (pErrorMsg) pErrorMsg->Release(); + + //Now write out blob + char tempString[1000]; + int numDWORDs = ((int)pShaderCode->GetBufferSize())/4; + DWORD * ptr = (DWORD *)pShaderCode->GetBufferPointer(); + sprintf_s(tempString,"DWORD %s[%d] = {",shaderName,numDWORDs); + OutputDebugStringA(tempString); + for (int i = 0;i < numDWORDs; i++) + { + sprintf_s(tempString,"%lu,",ptr[i]); + OutputDebugStringA(tempString); + } + OutputDebugStringA("};\n"); + + return(pShaderCode); +} +#endif + +/***********************************************************/ +void DistortionRenderer::CreateDistortionShaders(void) +{ +#if PRECOMPILE_FLAG + ID3DBlob * pShaderCode; + pShaderCode = ShaderCompile("precompiledVertexShaderSrc",VertexShaderSrc,"vs_2_0"); + Device->CreateVertexShader( ( DWORD* )pShaderCode->GetBufferPointer(), &VertexShader ); + pShaderCode->Release(); + + pShaderCode = ShaderCompile("precompiledVertexShaderTimewarpSrc",VertexShaderTimewarpSrc,"vs_3_0"); + Device->CreateVertexShader( ( DWORD* )pShaderCode->GetBufferPointer(), &VertexShaderTimewarp ); + pShaderCode->Release(); + + pShaderCode = ShaderCompile("precompiledPixelShaderSrc",PixelShaderSrc,"ps_3_0"); + Device->CreatePixelShader( ( DWORD* )pShaderCode->GetBufferPointer(), &PixelShader ); + pShaderCode->Release(); +#else + Device->CreateVertexShader( precompiledVertexShaderSrc, &VertexShader ); + Device->CreateVertexShader( precompiledVertexShaderTimewarpSrc, &VertexShaderTimewarp ); + Device->CreatePixelShader( precompiledPixelShaderSrc, &PixelShader ); +#endif +} + + +/***************************************************/ +void DistortionRenderer::CreateVertexDeclaration() +{ + static const D3DVERTEXELEMENT9 VertexElements[7] = { + { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, + { 0, 8, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1 }, + { 0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 2 }, + { 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, + { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 }, + { 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2 }, + D3DDECL_END() }; + Device->CreateVertexDeclaration( VertexElements, &VertexDecl ); +} + + +/******************************************************/ +bool DistortionRenderer::CreateDistortionModels() +{ + //Make the distortion models + for (int eye=0;eye<2;eye++) + { + FOR_EACH_EYE * e = &eachEye[eye]; + ovrDistortionMesh meshData; + + if (!CalculateDistortionMeshFromFOV( + RenderState->RenderInfo, + RenderState->Distortion[eye], + (RenderState->EyeRenderDesc[eye].Eye == ovrEye_Left ? StereoEye_Left : StereoEye_Right), + RenderState->EyeRenderDesc[eye].Fov, + RenderState->DistortionCaps, + &meshData)) + { + OVR_ASSERT(false); + return false; + } + + e->numVerts = meshData.VertexCount; + e->numIndices = meshData.IndexCount; + + Device->CreateVertexBuffer( (e->numVerts)*sizeof(ovrDistortionVertex),0, 0, + D3DPOOL_MANAGED, &e->dxVerts, NULL ); + ovrDistortionVertex * dxv; e->dxVerts->Lock( 0, 0, (void**)&dxv, 0 ); + for (int v=0;vnumVerts;v++) dxv[v] = meshData.pVertexData[v]; + e->dxVerts->Unlock(); + + Device->CreateIndexBuffer( (e->numIndices)*sizeof(u_short),0, D3DFMT_INDEX16, + D3DPOOL_MANAGED, &e->dxIndices, NULL ); + unsigned short* dxi; e->dxIndices->Lock( 0, 0, (void**)&dxi, 0 ); + for (int i=0;inumIndices;i++) dxi[i] = meshData.pIndexData[i]; + e->dxIndices->Unlock(); + + ovrHmd_DestroyDistortionMesh( &meshData ); + } + + return true; +} + +/**********************************************************/ +void DistortionRenderer::RenderBothDistortionMeshes() +{ + Device->BeginScene(); + + D3DCOLOR clearColor = D3DCOLOR_RGBA( + (int)(RenderState->ClearColor[0] * 255.0f), + (int)(RenderState->ClearColor[1] * 255.0f), + (int)(RenderState->ClearColor[2] * 255.0f), + (int)(RenderState->ClearColor[3] * 255.0f)); + + Device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER, clearColor, 0, 0); + + for (int eyeNum = 0; eyeNum < 2; eyeNum++) + { + FOR_EACH_EYE * e = &eachEye[eyeNum]; + D3DVIEWPORT9 vp; + vp.X=0; vp.Y=0; + vp.Width=ScreenSize.w; vp.Height=ScreenSize.h; + vp.MinZ=0; vp.MaxZ = 1; + + Device->SetViewport(&vp); + Device->SetStreamSource( 0, e->dxVerts,0, sizeof(ovrDistortionVertex) ); + Device->SetVertexDeclaration( VertexDecl ); + Device->SetIndices( e->dxIndices ); + Device->SetPixelShader( PixelShader ); + Device->SetTexture( 0, e->texture); + + //Choose which vertex shader, with associated additional inputs + if (RenderState->DistortionCaps & ovrDistortionCap_TimeWarp) + { + Device->SetVertexShader( VertexShaderTimewarp ); + + Matrix4f startEndMatrices[2]; + double timewarpIMUTime = 0.; + CalculateOrientationTimewarpFromSensors( + RenderState->EyeRenderPoses[eyeNum].Orientation, + SensorReader, Timing->GetTimewarpTiming()->EyeStartEndTimes[eyeNum], + startEndMatrices, timewarpIMUTime); + Timing->SetTimewarpIMUTime(timewarpIMUTime); + + //Need to transpose the matrices + startEndMatrices[0].Transpose(); + startEndMatrices[1].Transpose(); + + // Feed identity like matrices in until we get proper timewarp calculation going on + Device->SetVertexShaderConstantF(4, (float *)&startEndMatrices[0], 4); + Device->SetVertexShaderConstantF(20, (float *)&startEndMatrices[1], 4); + } + else + { + Device->SetVertexShader( VertexShader ); + } + + //Set up vertex shader constants + Device->SetVertexShaderConstantF( 0, ( FLOAT* )&(e->UVScaleOffset[0]), 1 ); + Device->SetVertexShaderConstantF( 2, ( FLOAT* )&(e->UVScaleOffset[1]), 1 ); + + Device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST,0,0,e->numVerts,0,e->numIndices/3); + } + + Device->EndScene(); +} + + +}}} // namespace OVR::CAPI::D3D9 -- cgit v1.2.3