2014-08-04 16:30:25 +00:00
/**
* \ file stereo_ovr . cpp
* \ brief CStereoOVR
* \ date 2014 - 08 - 04 16 : 21 GMT
* \ author Jan Boon ( Kaetemi )
* CStereoOVR
*/
/*
* Copyright ( C ) 2014 by authors
*
* This file is part of NL3D .
* NL3D is free software : you can redistribute it and / or modify it
* under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation , either version 3 of the
* License , or ( at your option ) any later version .
*
* NL3D is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE . See the GNU Affero General
* Public License for more details .
*
* You should have received a copy of the GNU Affero General Public
* License along with NL3D . If not , see
* < http : //www.gnu.org/licenses/>.
*
* Linking this library statically or dynamically with other modules
* is making a combined work based on this library . Thus , the terms
* and conditions of the GNU General Public License cover the whole
* combination .
*
* As a special exception , the copyright holders of this library give
* you permission to link this library with the Oculus SDK to produce
* an executable , regardless of the license terms of the Oculus SDK ,
* and distribute linked combinations including the two , provided that
* you also meet the terms and conditions of the license of the Oculus
* SDK . You must obey the GNU General Public License in all respects
* for all of the code used other than the Oculus SDK . If you modify
* this file , you may extend this exception to your version of the
* file , but you are not obligated to do so . If you do not wish to do
* so , delete this exception statement from your version .
*/
# ifdef HAVE_LIBOVR
# include "std3d.h"
# include <nel/3d/stereo_ovr_04.h>
// STL includes
# include <sstream>
// External includes
# define OVR_NO_STDINT
# include <OVR.h>
// NeL includes
// #include <nel/misc/debug.h>
# include <nel/3d/u_camera.h>
# include <nel/3d/u_driver.h>
# include <nel/3d/material.h>
# include <nel/3d/texture_bloom.h>
# include <nel/3d/texture_user.h>
# include <nel/3d/driver_user.h>
# include <nel/3d/u_texture.h>
// Project includes
using namespace std ;
// using namespace NLMISC;
namespace NL3D {
namespace {
2014-08-04 17:19:15 +00:00
# include "stereo_ovr_04_program.h"
class CStereoOVRSystem
2014-08-04 16:30:25 +00:00
{
public :
2014-08-04 17:19:15 +00:00
CStereoOVRSystem ( ) : m_InitOk ( false )
2014-08-04 16:30:25 +00:00
{
}
2014-08-04 17:19:15 +00:00
~ CStereoOVRSystem ( )
2014-08-04 16:30:25 +00:00
{
2014-08-04 17:19:15 +00:00
if ( m_InitOk )
2014-08-04 16:30:25 +00:00
{
2014-08-04 17:19:15 +00:00
nlwarning ( " OVR: Not all resources were released before exit " ) ;
Release ( ) ;
2014-08-04 16:30:25 +00:00
}
}
2014-08-04 17:19:15 +00:00
bool Init ( )
2014-08-04 16:30:25 +00:00
{
2014-08-04 17:19:15 +00:00
if ( ! m_InitOk )
2014-08-04 16:30:25 +00:00
{
2014-08-04 17:19:15 +00:00
nldebug ( " OVR: Initialize " ) ;
m_InitOk = ovr_Initialize ( ) ;
nlassert ( m_InitOk ) ;
2014-08-04 16:30:25 +00:00
}
2014-08-04 17:19:15 +00:00
return m_InitOk ;
2014-08-04 16:30:25 +00:00
}
void Release ( )
{
2014-08-04 17:19:15 +00:00
if ( m_InitOk )
2014-08-04 16:30:25 +00:00
{
2014-08-04 17:19:15 +00:00
nldebug ( " OVR: Release " ) ;
ovr_Shutdown ( ) ;
m_InitOk = false ;
2014-08-04 16:30:25 +00:00
}
}
2014-08-04 17:19:15 +00:00
private :
bool m_InitOk ;
2014-08-04 16:30:25 +00:00
} ;
CStereoOVRSystem s_StereoOVRSystem ;
sint s_DeviceCounter = 0 ;
2014-08-04 17:19:15 +00:00
uint s_DetectId = 0 ;
2014-08-04 16:30:25 +00:00
}
2014-08-04 17:19:15 +00:00
class CStereoOVRDeviceFactory : public IStereoDeviceFactory
2014-08-04 16:30:25 +00:00
{
public :
2014-08-04 17:19:15 +00:00
uint DeviceIndex ;
uint DetectId ;
bool DebugDevice ;
ovrHmdType DebugDeviceType ;
2014-08-04 16:30:25 +00:00
IStereoDisplay * createDevice ( ) const
{
CStereoOVR * stereo = new CStereoOVR ( this ) ;
if ( stereo - > isDeviceCreated ( ) )
return stereo ;
delete stereo ;
return NULL ;
}
} ;
2014-08-05 01:54:19 +00:00
static NLMISC : : CVector2f toTex ( NLMISC : : CVector2f texCoord , NLMISC : : CVector2f uvScaleOffset [ 2 ] )
{
// return(EyeToSourceUVScale * flattened + EyeToSourceUVOffset);
NLMISC : : CVector2f vec = NLMISC : : CVector2f ( texCoord . x * uvScaleOffset [ 0 ] . x , texCoord . y * uvScaleOffset [ 0 ] . y ) + uvScaleOffset [ 1 ] ;
// some trial and error voodoo, sorry
vec = ( vec + NLMISC : : CVector2f ( 1 , 1 ) ) * 0.5f ;
vec . y = 1.0f - vec . y ;
vec . x = 1.0f - vec . x ;
vec . x + = 0.5f ;
vec . y * = 2.0f ;
vec . x = 1.0f - vec . x ;
return vec ;
}
2014-08-05 18:14:58 +00:00
static float lerp ( float f0 , float f1 , float factor )
{
return ( f1 * factor ) + ( f0 * ( 1.0f - factor ) ) ;
}
2014-08-06 23:04:58 +00:00
CStereoOVR : : CStereoOVR ( const CStereoOVRDeviceFactory * factory ) : m_DevicePtr ( NULL ) , m_Stage ( 0 ) , m_SubStage ( 0 ) , m_OrientationCached ( false ) , m_Driver ( NULL ) , m_SceneTexture ( NULL ) , m_GUITexture ( NULL ) , m_EyePosition ( 0.0f , 0.09f , 0.15f ) , m_Scale ( 1.0f ) , m_AttachedDisplay ( false )
2014-08-04 16:30:25 +00:00
{
2014-08-04 18:32:31 +00:00
nlctassert ( NL_OVR_EYE_COUNT = = ovrEye_Count ) ;
2014-08-04 17:19:15 +00:00
2014-08-04 18:32:31 +00:00
if ( factory - > DetectId ! = s_DetectId )
{
nlwarning ( " OVR: Previous device info structures become invalid after listing devices " ) ;
return ;
}
2014-08-04 16:30:25 +00:00
2014-08-04 18:32:31 +00:00
if ( factory - > DebugDevice ) m_DevicePtr = ovrHmd_CreateDebug ( factory - > DebugDeviceType ) ;
else m_DevicePtr = ovrHmd_Create ( factory - > DeviceIndex ) ;
2014-08-04 16:30:25 +00:00
2014-08-04 18:32:31 +00:00
if ( ! m_DevicePtr )
2014-08-04 16:30:25 +00:00
{
2014-08-04 18:32:31 +00:00
nlwarning ( " OVR: Device not created " ) ;
return ;
}
+ + s_DeviceCounter ;
// nldebug("OVR: HScreenSize: %f, VScreenSize: %f", m_DevicePtr->HMDInfo.HScreenSize, m_DevicePtr->HMDInfo.VScreenSize); // No more support for physically non-square pixels?
// nldebug("OVR: VScreenCenter: %f", m_DevicePtr->HMDInfo.VScreenCenter);
// nldebug("OVR: EyeToScreenDistance: %f", m_DevicePtr->HMDInfo.EyeToScreenDistance);
// nldebug("OVR: LensSeparationDistance: %f", m_DevicePtr->HMDInfo.LensSeparationDistance);
// nldebug("OVR: InterpupillaryDistance: %f", m_DevicePtr->HMDInfo.InterpupillaryDistance);
nldebug ( " OVR: Resolution.w: %i, Resolution.h: %i " , m_DevicePtr - > Resolution . w , m_DevicePtr - > Resolution . h ) ;
// nldebug("OVR: DistortionK[0]: %f, DistortionK[1]: %f", m_DevicePtr->HMDInfo.DistortionK[0], m_DevicePtr->HMDInfo.DistortionK[1]);
// nldebug("OVR: DistortionK[2]: %f, DistortionK[3]: %f", m_DevicePtr->HMDInfo.DistortionK[2], m_DevicePtr->HMDInfo.DistortionK[3]);
if ( ! ovrHmd_ConfigureTracking ( m_DevicePtr ,
ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection , // | ovrTrackingCap_Position
ovrTrackingCap_Orientation ) )
{
nlwarning ( " OVR: Cannot configure tracking " ) ;
ovrHmd_Destroy ( m_DevicePtr ) ;
m_DevicePtr = NULL ;
- - s_DeviceCounter ;
return ;
}
float nativeWidth = m_DevicePtr - > Resolution . w ;
float nativeHeight = m_DevicePtr - > Resolution . h ;
2014-08-04 22:20:21 +00:00
// get render descriptions for default fov
2014-08-04 18:32:31 +00:00
ovrEyeRenderDesc eyeRenderDesc [ ovrEye_Count ] ;
eyeRenderDesc [ ovrEye_Left ] = ovrHmd_GetRenderDesc ( m_DevicePtr , ovrEye_Left , m_DevicePtr - > DefaultEyeFov [ ovrEye_Left ] ) ;
eyeRenderDesc [ ovrEye_Right ] = ovrHmd_GetRenderDesc ( m_DevicePtr , ovrEye_Right , m_DevicePtr - > DefaultEyeFov [ ovrEye_Right ] ) ;
nldebug ( " OVR: LEFT DistortedViewport: x: %i, y: %i, w: %i, h: %i " , eyeRenderDesc [ 0 ] . DistortedViewport . Pos . x , eyeRenderDesc [ 0 ] . DistortedViewport . Pos . y , eyeRenderDesc [ 0 ] . DistortedViewport . Size . w , eyeRenderDesc [ 0 ] . DistortedViewport . Size . h ) ;
nldebug ( " OVR: LEFT PixelsPerTanAngleAtCenter: x: %f, y: %f " , eyeRenderDesc [ 0 ] . PixelsPerTanAngleAtCenter . x , eyeRenderDesc [ 0 ] . PixelsPerTanAngleAtCenter . y ) ;
nldebug ( " OVR: LEFT ViewAdjust: x: %f, y: %f, z: %f " , eyeRenderDesc [ 0 ] . ViewAdjust . x , eyeRenderDesc [ 0 ] . ViewAdjust . y , eyeRenderDesc [ 0 ] . ViewAdjust . z ) ;
nldebug ( " OVR: RIGHT DistortedViewport: x: %i, y: %i, w: %i, h: %i " , eyeRenderDesc [ 1 ] . DistortedViewport . Pos . x , eyeRenderDesc [ 1 ] . DistortedViewport . Pos . y , eyeRenderDesc [ 1 ] . DistortedViewport . Size . w , eyeRenderDesc [ 1 ] . DistortedViewport . Size . h ) ;
nldebug ( " OVR: RIGHT PixelsPerTanAngleAtCenter: x: %f, y: %f " , eyeRenderDesc [ 1 ] . PixelsPerTanAngleAtCenter . x , eyeRenderDesc [ 1 ] . PixelsPerTanAngleAtCenter . y ) ;
nldebug ( " OVR: RIGHT ViewAdjust: x: %f, y: %f, z: %f " , eyeRenderDesc [ 1 ] . ViewAdjust . x , eyeRenderDesc [ 1 ] . ViewAdjust . y , eyeRenderDesc [ 1 ] . ViewAdjust . z ) ;
// 2014/08/04 19:54:25 DBG a60 snowballs_client.exe stereo_ovr_04.cpp 171 NL3D::CStereoOVR::CStereoOVR : OVR: Resolution.w: 1280, Resolution.h: 800
// 2014/08/04 19:54:25 DBG a60 snowballs_client.exe stereo_ovr_04.cpp 189 NL3D::CStereoOVR::CStereoOVR : OVR: LEFT DistortedViewport: x: 0, y: 0, w: 640, h: 800
// 2014/08/04 19:54:25 DBG a60 snowballs_client.exe stereo_ovr_04.cpp 190 NL3D::CStereoOVR::CStereoOVR : OVR: LEFT PixelsPerTanAngleAtCenter: x: 363.247864, y: 363.247864
// 2014/08/04 19:54:25 DBG a60 snowballs_client.exe stereo_ovr_04.cpp 191 NL3D::CStereoOVR::CStereoOVR : OVR: LEFT ViewAdjust: x: 0.031800, y: 0.000000, z: 0.000000
// 2014/08/04 19:55:46 DBG 2e18 snowballs_client.exe stereo_ovr_04.cpp 192 NL3D::CStereoOVR::CStereoOVR : OVR: RIGHT DistortedViewport: x: 640, y: 0, w: 640, h: 800
// 2014/08/04 19:55:46 DBG 2e18 snowballs_client.exe stereo_ovr_04.cpp 193 NL3D::CStereoOVR::CStereoOVR : OVR: RIGHT PixelsPerTanAngleAtCenter: x: 363.247864, y: 363.247864
// 2014/08/04 19:55:46 DBG 2e18 snowballs_client.exe stereo_ovr_04.cpp 194 NL3D::CStereoOVR::CStereoOVR : OVR: RIGHT ViewAdjust: x: -0.031868, y: 0.000000, z: 0.000000
2014-08-04 22:20:21 +00:00
// find out the recommended render target size
ovrSizei fovTextureSize [ ovrEye_Count ] ;
fovTextureSize [ ovrEye_Left ] = ovrHmd_GetFovTextureSize ( m_DevicePtr , ovrEye_Left , eyeRenderDesc [ ovrEye_Left ] . Fov , 1.0f ) ;
fovTextureSize [ ovrEye_Right ] = ovrHmd_GetFovTextureSize ( m_DevicePtr , ovrEye_Right , eyeRenderDesc [ ovrEye_Right ] . Fov , 1.0f ) ;
m_RenderTargetWidth = fovTextureSize [ ovrEye_Left ] . w + fovTextureSize [ ovrEye_Right ] . w ;
m_RenderTargetHeight = max ( fovTextureSize [ ovrEye_Left ] . h , fovTextureSize [ ovrEye_Right ] . h ) ;
2014-08-04 18:32:31 +00:00
nldebug ( " OVR: RenderTarget: w: %u, h: %u " , m_RenderTargetWidth , m_RenderTargetHeight ) ;
// 2014/08/04 20:22:03 DBG 30e4 snowballs_client.exe stereo_ovr_04.cpp 213 NL3D::CStereoOVR::CStereoOVR : OVR: RenderTarget: w: 2414, h: 1870 // That looks a bit excessive...
for ( uint eye = 0 ; eye < ovrEye_Count ; + + eye )
{
ovrFovPort & fov = eyeRenderDesc [ eye ] . Fov ;
2014-08-04 22:51:53 +00:00
// store data
m_EyeViewAdjustX [ eye ] = - eyeRenderDesc [ eye ] . ViewAdjust . x ;
2014-08-04 22:20:21 +00:00
// setup viewport
2014-08-04 18:32:31 +00:00
m_EyeViewport [ eye ] . init (
( float ) eyeRenderDesc [ eye ] . DistortedViewport . Pos . x / nativeWidth ,
( float ) eyeRenderDesc [ eye ] . DistortedViewport . Pos . y / nativeHeight ,
( float ) eyeRenderDesc [ eye ] . DistortedViewport . Size . w / nativeWidth ,
( float ) eyeRenderDesc [ eye ] . DistortedViewport . Size . h / nativeHeight ) ;
nldebug ( " OVR: EyeViewport: x: %f, y: %f, w: %f, h: %f " , m_EyeViewport [ eye ] . getX ( ) , m_EyeViewport [ eye ] . getY ( ) , m_EyeViewport [ eye ] . getWidth ( ) , m_EyeViewport [ eye ] . getHeight ( ) ) ;
2014-08-04 22:20:21 +00:00
ovrRecti eyeViewport ;
eyeViewport . Pos . x = ( eyeRenderDesc [ eye ] . DistortedViewport . Pos . x * m_RenderTargetWidth ) / m_DevicePtr - > Resolution . w ;
eyeViewport . Pos . y = ( eyeRenderDesc [ eye ] . DistortedViewport . Pos . y * m_RenderTargetHeight ) / m_DevicePtr - > Resolution . h ;
eyeViewport . Size . w = ( eyeRenderDesc [ eye ] . DistortedViewport . Size . w * m_RenderTargetWidth ) / m_DevicePtr - > Resolution . w ;
eyeViewport . Size . h = ( eyeRenderDesc [ eye ] . DistortedViewport . Size . h * m_RenderTargetHeight ) / m_DevicePtr - > Resolution . h ;
// calculate hfov and ar
2014-08-04 23:49:45 +00:00
/*float combinedTanHalfFovHorizontal = max(fov.LeftTan, fov.RightTan);
2014-08-04 18:32:31 +00:00
float combinedTanHalfFovVertical = max ( fov . UpTan , fov . DownTan ) ;
float horizontalFullFovInRadians = 2.0f * atanf ( combinedTanHalfFovHorizontal ) ;
float aspectRatio = combinedTanHalfFovHorizontal / combinedTanHalfFovVertical ;
2014-08-04 23:49:45 +00:00
float m_EyeHFov [ NL_OVR_EYE_COUNT ] ;
float m_EyeAR [ NL_OVR_EYE_COUNT ] ;
2014-08-04 18:32:31 +00:00
m_EyeHFov [ eye ] = horizontalFullFovInRadians ;
m_EyeAR [ eye ] = aspectRatio ;
2014-08-04 22:20:21 +00:00
nldebug ( " OVR: HFOV: %f, AR: %f " , horizontalFullFovInRadians , aspectRatio ) ;
2014-08-04 23:49:45 +00:00
m_EyeFrustumBase [ eye ] . initPerspective ( m_EyeHFov [ eye ] , m_EyeAR [ eye ] , 1.0f , 100.f ) ;
nldebug ( " OVR: FOV: Left: %f, Right: %f, Down: %f, Up: %f " , // DOUBLE CHECK
m_EyeFrustumBase [ eye ] . Left , m_EyeFrustumBase [ eye ] . Right , m_EyeFrustumBase [ eye ] . Bottom , m_EyeFrustumBase [ eye ] . Top ) ; */
m_EyeFrustumBase [ eye ] . init (
- fov . LeftTan , // OVR provides positive values
fov . RightTan , // DEBUG: If renders shifted left and right, swap left and right
- fov . DownTan ,
fov . UpTan , // DEBUG: If renders shifted up or down, swap down and up
1.0f , // dummy
100.f , // dummy
true ) ;
nldebug ( " OVR: FOV: Left: %f, Right: %f, Down: %f, Up: %f " ,
m_EyeFrustumBase [ eye ] . Left , m_EyeFrustumBase [ eye ] . Right , m_EyeFrustumBase [ eye ] . Bottom , m_EyeFrustumBase [ eye ] . Top ) ;
2014-08-04 22:20:21 +00:00
// get distortion mesh
ovrDistortionMesh meshData ;
ovrHmd_CreateDistortionMesh ( m_DevicePtr , ( ovrEyeType ) eye , fov ,
2014-08-04 22:46:04 +00:00
ovrDistortionCap_Chromatic /*| ovrDistortionCap_TimeWarp*/ | ovrDistortionCap_Vignette , // I believe the timewarp gimmick screws with parallax
2014-08-04 22:20:21 +00:00
& meshData ) ;
ovrVector2f uvScaleOffset [ 2 ] ;
// get parameters for programs
ovrHmd_GetRenderScaleAndOffset ( fov ,
fovTextureSize [ eye ] , eyeViewport ,
( ovrVector2f * ) uvScaleOffset ) ;
m_EyeUVScaleOffset [ eye ] [ 0 ] = NLMISC : : CVector2f ( uvScaleOffset [ 0 ] . x , uvScaleOffset [ 0 ] . y ) ;
m_EyeUVScaleOffset [ eye ] [ 1 ] = NLMISC : : CVector2f ( uvScaleOffset [ 1 ] . x , uvScaleOffset [ 1 ] . y ) ;
2014-08-05 18:14:58 +00:00
// chroma bugfix
float chromaFactor = 1.00f ;
if ( m_DevicePtr - > Type = = ovrHmd_DK2 )
chromaFactor = 0.75f ;
2014-08-04 22:20:21 +00:00
// create distortion mesh vertex buffer
2014-08-05 00:55:26 +00:00
m_VB [ eye ] . setVertexFormat ( CVertexBuffer : : PositionFlag | CVertexBuffer : : TexCoord0Flag | CVertexBuffer : : TexCoord1Flag | CVertexBuffer : : TexCoord2Flag | CVertexBuffer : : PrimaryColorFlag ) ;
m_VB [ eye ] . setPreferredMemory ( CVertexBuffer : : StaticPreferred , true ) ;
m_VB [ eye ] . setNumVertices ( meshData . VertexCount ) ;
2014-08-04 22:20:21 +00:00
{
CVertexBufferReadWrite vba ;
2014-08-05 00:55:26 +00:00
m_VB [ eye ] . lock ( vba ) ;
2014-08-04 22:20:21 +00:00
for ( uint i = 0 ; i < meshData . VertexCount ; + + i )
{
ovrDistortionVertex & ov = meshData . pVertexData [ i ] ;
vba . setVertexCoord ( i , ( ov . ScreenPosNDC . x + 1.0f ) * 0.5f , ( ov . ScreenPosNDC . y + 1.0f ) * 0.5f , 0.5f ) ;
2014-08-05 18:14:58 +00:00
NLMISC : : CVector2f texR (
lerp ( ov . TanEyeAnglesG . x , ov . TanEyeAnglesR . x , chromaFactor ) ,
lerp ( ov . TanEyeAnglesG . y , ov . TanEyeAnglesR . y , chromaFactor ) ) ;
2014-08-05 01:54:19 +00:00
NLMISC : : CVector2f texG ( ov . TanEyeAnglesG . x , ov . TanEyeAnglesG . y ) ;
2014-08-05 18:14:58 +00:00
NLMISC : : CVector2f texB (
lerp ( ov . TanEyeAnglesG . x , ov . TanEyeAnglesB . x , chromaFactor ) ,
lerp ( ov . TanEyeAnglesG . y , ov . TanEyeAnglesB . y , chromaFactor ) ) ;
2014-08-05 01:54:19 +00:00
texR = toTex ( texR , m_EyeUVScaleOffset [ eye ] ) ;
texG = toTex ( texG , m_EyeUVScaleOffset [ eye ] ) ;
texB = toTex ( texB , m_EyeUVScaleOffset [ eye ] ) ;
vba . setTexCoord ( i , 0 , texR . x , texR . y ) ;
vba . setTexCoord ( i , 1 , texG . x , texG . y ) ;
vba . setTexCoord ( i , 2 , texB . x , texB . y ) ;
2014-08-04 22:20:21 +00:00
NLMISC : : CRGBA color ;
color . R = color . G = color . B = ( uint8 ) ( ov . VignetteFactor * 255.99f ) ;
2014-08-04 22:46:04 +00:00
color . A = 255 ; // (uint8)(ov.TimeWarpFactor * 255.99f);
2014-08-04 22:20:21 +00:00
vba . setColor ( i , color ) ;
}
}
// create distortion mesh index buffer
2014-08-05 00:55:26 +00:00
m_IB [ eye ] . setFormat ( NL_DEFAULT_INDEX_BUFFER_FORMAT ) ;
m_IB [ eye ] . setPreferredMemory ( CIndexBuffer : : StaticPreferred , true ) ;
m_IB [ eye ] . setNumIndexes ( meshData . IndexCount ) ;
2014-08-04 22:20:21 +00:00
{
CIndexBufferReadWrite iba ;
2014-08-05 00:55:26 +00:00
m_IB [ eye ] . lock ( iba ) ;
2014-08-04 22:20:21 +00:00
for ( uint i = 0 ; i + 2 < meshData . IndexCount ; i + = 3 )
{
nlassert ( meshData . pIndexData [ i ] < meshData . VertexCount ) ;
nlassert ( meshData . pIndexData [ i + 1 ] < meshData . VertexCount ) ;
nlassert ( meshData . pIndexData [ i + 2 ] < meshData . VertexCount ) ;
iba . setTri ( i , meshData . pIndexData [ i ] , meshData . pIndexData [ i + 1 ] , meshData . pIndexData [ i + 2 ] ) ;
}
}
// set tri count
2014-08-05 00:55:26 +00:00
m_NbTris [ eye ] = meshData . IndexCount / 3 ;
2014-08-04 22:20:21 +00:00
// destroy ovr distortion mesh
ovrHmd_DestroyDistortionMesh ( & meshData ) ;
2014-08-04 18:32:31 +00:00
}
// 2014/08/04 20:22:03 DBG 30e4 snowballs_client.exe stereo_ovr_04.cpp 222 NL3D::CStereoOVR::CStereoOVR : OVR: EyeViewport: x: 0.000000, y: 0.000000, w: 0.500000, h: 1.000000
2014-08-04 22:20:21 +00:00
// 2014/08/04 22:28:39 DBG 3040 snowballs_client.exe stereo_ovr_04.cpp 235 NL3D::CStereoOVR::CStereoOVR : OVR: HFOV: 2.339905, AR: 0.916641
2014-08-04 18:32:31 +00:00
// 2014/08/04 20:22:03 DBG 30e4 snowballs_client.exe stereo_ovr_04.cpp 222 NL3D::CStereoOVR::CStereoOVR : OVR: EyeViewport: x: 0.500000, y: 0.000000, w: 0.500000, h: 1.000000
2014-08-04 22:20:21 +00:00
// 2014/08/04 22:28:39 DBG 3040 snowballs_client.exe stereo_ovr_04.cpp 235 NL3D::CStereoOVR::CStereoOVR : OVR: HFOV: 2.339905, AR: 0.916641
2014-08-04 18:32:31 +00:00
2014-08-05 18:14:58 +00:00
ovrHmd_RecenterPose ( m_DevicePtr ) ;
2014-08-04 18:32:31 +00:00
// DEBUG EARLY EXIT
2014-08-04 23:49:45 +00:00
/*nldebug("OVR: Early exit");
2014-08-04 18:32:31 +00:00
ovrHmd_Destroy ( m_DevicePtr ) ;
m_DevicePtr = NULL ;
2014-08-04 23:49:45 +00:00
- - s_DeviceCounter ; */
2014-08-04 16:30:25 +00:00
}
CStereoOVR : : ~ CStereoOVR ( )
{
2014-08-06 23:04:58 +00:00
if ( m_AttachedDisplay )
{
detachFromDisplay ( ) ;
}
2014-08-04 22:20:21 +00:00
if ( ! m_UnlitMat . empty ( ) )
2014-08-04 16:30:25 +00:00
{
2014-08-04 22:20:21 +00:00
m_Driver - > deleteMaterial ( m_UnlitMat ) ;
2014-08-04 16:30:25 +00:00
}
2014-08-04 22:20:21 +00:00
m_Driver = NULL ;
2014-08-04 16:30:25 +00:00
2014-08-04 18:32:31 +00:00
if ( m_DevicePtr )
{
ovrHmd_Destroy ( m_DevicePtr ) ;
m_DevicePtr = NULL ;
- - s_DeviceCounter ;
}
2014-08-04 16:30:25 +00:00
}
2014-08-04 22:20:21 +00:00
2014-08-04 16:30:25 +00:00
void CStereoOVR : : setDriver ( NL3D : : UDriver * driver )
2014-08-04 22:20:21 +00:00
{
m_Driver = driver ;
CDriverUser * dru = static_cast < CDriverUser * > ( driver ) ;
IDriver * drv = dru - > getDriver ( ) ;
m_UnlitMat = m_Driver - > createMaterial ( ) ;
m_UnlitMat . initUnlit ( ) ;
m_UnlitMat . setColor ( CRGBA : : White ) ;
m_UnlitMat . setBlend ( false ) ;
m_UnlitMat . setAlphaTest ( false ) ;
NL3D : : CMaterial * unlitMat = m_UnlitMat . getObjectPtr ( ) ;
unlitMat - > setShader ( NL3D : : CMaterial : : Normal ) ;
unlitMat - > setBlendFunc ( CMaterial : : one , CMaterial : : zero ) ;
unlitMat - > setZWrite ( false ) ;
unlitMat - > setZFunc ( CMaterial : : always ) ;
unlitMat - > setDoubleSided ( true ) ;
2014-08-05 01:54:19 +00:00
unlitMat - > texConstantColor ( 0 , NLMISC : : CRGBA ( 255 , 0 , 0 , 0 ) ) ;
unlitMat - > texConstantColor ( 1 , NLMISC : : CRGBA ( 0 , 255 , 0 , 0 ) ) ;
unlitMat - > texConstantColor ( 2 , NLMISC : : CRGBA ( 0 , 0 , 255 , 0 ) ) ;
m_UnlitMat . texEnvArg0RGB ( 0 , UMaterial : : Texture , UMaterial : : SrcColor ) ;
m_UnlitMat . texEnvArg1RGB ( 0 , UMaterial : : Constant , UMaterial : : SrcColor ) ;
m_UnlitMat . texEnvOpRGB ( 0 , UMaterial : : Modulate ) ;
m_UnlitMat . texEnvArg0RGB ( 1 , UMaterial : : Texture , UMaterial : : SrcColor ) ;
m_UnlitMat . texEnvArg1RGB ( 1 , UMaterial : : Constant , UMaterial : : SrcColor ) ;
m_UnlitMat . texEnvArg2RGB ( 1 , UMaterial : : Previous , UMaterial : : SrcColor ) ;
m_UnlitMat . texEnvOpRGB ( 1 , UMaterial : : Mad ) ;
m_UnlitMat . texEnvArg0RGB ( 2 , UMaterial : : Texture , UMaterial : : SrcColor ) ;
m_UnlitMat . texEnvArg1RGB ( 2 , UMaterial : : Constant , UMaterial : : SrcColor ) ;
m_UnlitMat . texEnvArg2RGB ( 2 , UMaterial : : Previous , UMaterial : : SrcColor ) ;
m_UnlitMat . texEnvOpRGB ( 2 , UMaterial : : Mad ) ;
m_UnlitMat . texEnvArg0RGB ( 3 , UMaterial : : Previous , UMaterial : : SrcColor ) ;
m_UnlitMat . texEnvArg1RGB ( 3 , UMaterial : : Diffuse , UMaterial : : SrcColor ) ;
m_UnlitMat . texEnvOpRGB ( 3 , UMaterial : : Modulate ) ;
2014-08-04 16:30:25 +00:00
}
bool CStereoOVR : : getScreenResolution ( uint & width , uint & height )
{
2014-08-04 22:20:21 +00:00
if ( m_DevicePtr )
{
width = m_DevicePtr - > Resolution . w ;
height = m_DevicePtr - > Resolution . h ;
return true ;
}
return false ;
2014-08-04 16:30:25 +00:00
}
2014-08-06 23:04:58 +00:00
void CStereoOVR : : attachToDisplay ( )
{
nldebug ( " OVR: Attach to display '%s' " , m_DevicePtr - > DisplayDeviceName ) ;
if ( ! m_AttachedDisplay )
{
m_Driver - > getCurrentScreenMode ( m_OriginalMode ) ;
m_Driver - > getWindowPos ( m_OriginalWinPosX , m_OriginalWinPosY ) ;
}
UDriver : : CMode mode ;
mode . DisplayDevice = m_DevicePtr - > DisplayDeviceName ;
mode . Windowed = false ;
mode . Width = m_DevicePtr - > Resolution . w ;
mode . Height = m_DevicePtr - > Resolution . h ;
m_Driver - > setMode ( mode ) ;
m_AttachedDisplay = true ;
}
void CStereoOVR : : detachFromDisplay ( )
{
if ( ! m_OriginalMode . Windowed )
{
m_OriginalMode . Windowed = true ;
m_Driver - > setMode ( m_OriginalMode ) ;
m_OriginalMode . Windowed = false ;
}
m_Driver - > setMode ( m_OriginalMode ) ;
m_Driver - > setWindowPos ( m_OriginalWinPosX , m_OriginalWinPosY ) ;
m_AttachedDisplay = false ;
}
2014-08-04 16:30:25 +00:00
void CStereoOVR : : initCamera ( uint cid , const NL3D : : UCamera * camera )
{
2014-08-04 23:49:45 +00:00
m_OriginalFrustum [ cid ] = camera - > getFrustum ( ) ;
/*m_LeftFrustum[cid] = m_OriginalFrustum[cid];
m_RightFrustum [ cid ] = m_OriginalFrustum [ cid ] ;
m_ClippingFrustum [ cid ] = m_OriginalFrustum [ cid ] ;
return ; */
m_LeftFrustum [ cid ] . init (
m_EyeFrustumBase [ ovrEye_Left ] . Left * camera - > getFrustum ( ) . Near ,
m_EyeFrustumBase [ ovrEye_Left ] . Right * camera - > getFrustum ( ) . Near ,
m_EyeFrustumBase [ ovrEye_Left ] . Bottom * camera - > getFrustum ( ) . Near ,
m_EyeFrustumBase [ ovrEye_Left ] . Top * camera - > getFrustum ( ) . Near ,
camera - > getFrustum ( ) . Near ,
camera - > getFrustum ( ) . Far ,
true ) ;
m_RightFrustum [ cid ] . init (
m_EyeFrustumBase [ ovrEye_Right ] . Left * camera - > getFrustum ( ) . Near ,
m_EyeFrustumBase [ ovrEye_Right ] . Right * camera - > getFrustum ( ) . Near ,
m_EyeFrustumBase [ ovrEye_Right ] . Bottom * camera - > getFrustum ( ) . Near ,
m_EyeFrustumBase [ ovrEye_Right ] . Top * camera - > getFrustum ( ) . Near ,
camera - > getFrustum ( ) . Near ,
camera - > getFrustum ( ) . Far ,
true ) ;
m_ClippingFrustum [ cid ] . init (
min ( m_EyeFrustumBase [ ovrEye_Left ] . Left , m_EyeFrustumBase [ ovrEye_Right ] . Left ) * camera - > getFrustum ( ) . Near ,
max ( m_EyeFrustumBase [ ovrEye_Left ] . Right , m_EyeFrustumBase [ ovrEye_Right ] . Right ) * camera - > getFrustum ( ) . Near ,
min ( m_EyeFrustumBase [ ovrEye_Left ] . Bottom , m_EyeFrustumBase [ ovrEye_Right ] . Bottom ) * camera - > getFrustum ( ) . Near ,
max ( m_EyeFrustumBase [ ovrEye_Left ] . Top , m_EyeFrustumBase [ ovrEye_Right ] . Top ) * camera - > getFrustum ( ) . Near ,
camera - > getFrustum ( ) . Near ,
camera - > getFrustum ( ) . Far ,
true ) ;
2014-08-04 16:30:25 +00:00
}
/// Get the frustum to use for clipping
void CStereoOVR : : getClippingFrustum ( uint cid , NL3D : : UCamera * camera ) const
{
camera - > setFrustum ( m_ClippingFrustum [ cid ] ) ;
}
/// Get the original frustum of the camera
void CStereoOVR : : getOriginalFrustum ( uint cid , NL3D : : UCamera * camera ) const
{
camera - > setFrustum ( m_OriginalFrustum [ cid ] ) ;
}
void CStereoOVR : : updateCamera ( uint cid , const NL3D : : UCamera * camera )
{
if ( camera - > getFrustum ( ) . Near ! = m_LeftFrustum [ cid ] . Near
| | camera - > getFrustum ( ) . Far ! = m_LeftFrustum [ cid ] . Far )
CStereoOVR : : initCamera ( cid , camera ) ;
m_CameraMatrix [ cid ] = camera - > getMatrix ( ) ;
}
bool CStereoOVR : : nextPass ( )
{
if ( m_Driver - > getPolygonMode ( ) = = UDriver : : Filled )
{
switch ( m_Stage ) // Previous stage
{
case 0 :
m_Stage + = 2 ;
m_SubStage = 0 ;
// stage 2:
// draw interface 2d (onto render target)
return true ;
case 2 :
+ + m_Stage ;
m_SubStage = 0 ;
// stage 3:
// (initBloom)
// clear buffer
// draw scene left
return true ;
case 3 :
+ + m_Stage ;
m_SubStage = 0 ;
// stage 4:
// draw scene right
return true ;
case 4 :
+ + m_Stage ;
m_SubStage = 0 ;
// stage 5:
// (endBloom)
// draw interface 3d left
return true ;
case 5 :
+ + m_Stage ;
m_SubStage = 0 ;
// stage 6:
// draw interface 3d right
return true ;
/*case 6:
+ + m_Stage ;
m_SubStage = 0 ;
// stage 7:
// (endInterfacesDisplayBloom)
// draw interface 2d left
return true ;
case 7 :
+ + m_Stage ;
m_SubStage = 0 ;
// stage 8:
// draw interface 2d right
return true ; */
case 6 :
m_Stage = 0 ;
m_SubStage = 0 ;
// present
m_OrientationCached = false ;
return false ;
}
}
else
{
switch ( m_Stage )
{
case 0 :
+ + m_Stage ;
m_SubStage = 0 ;
return true ;
case 1 :
m_Stage = 0 ;
m_SubStage = 0 ;
return false ;
}
}
nlerror ( " Invalid stage " ) ;
m_Stage = 0 ;
m_SubStage = 0 ;
m_OrientationCached = false ;
return false ;
}
const NL3D : : CViewport & CStereoOVR : : getCurrentViewport ( ) const
{
if ( m_Stage = = 2 ) return m_RegularViewport ;
2014-08-04 18:32:31 +00:00
else if ( m_Stage % 2 ) return m_EyeViewport [ ovrEye_Left ] ;
else return m_EyeViewport [ ovrEye_Right ] ;
2014-08-04 16:30:25 +00:00
}
const NL3D : : CFrustum & CStereoOVR : : getCurrentFrustum ( uint cid ) const
{
if ( m_Stage = = 2 ) return m_OriginalFrustum [ cid ] ;
else if ( m_Stage % 2 ) return m_LeftFrustum [ cid ] ;
else return m_RightFrustum [ cid ] ;
}
void CStereoOVR : : getCurrentFrustum ( uint cid , NL3D : : UCamera * camera ) const
{
if ( m_Stage = = 2 ) camera - > setFrustum ( m_OriginalFrustum [ cid ] ) ;
else if ( m_Stage % 2 ) camera - > setFrustum ( m_LeftFrustum [ cid ] ) ;
else camera - > setFrustum ( m_RightFrustum [ cid ] ) ;
}
void CStereoOVR : : getCurrentMatrix ( uint cid , NL3D : : UCamera * camera ) const
2014-08-04 22:51:53 +00:00
{
2014-08-04 16:30:25 +00:00
CMatrix translate ;
if ( m_Stage = = 2 ) { }
2014-08-04 23:49:45 +00:00
else if ( m_Stage % 2 ) translate . translate ( CVector ( m_EyeViewAdjustX [ ovrEye_Left ] * m_Scale , 0.f , 0.f ) ) ; // ok
else translate . translate ( CVector ( m_EyeViewAdjustX [ ovrEye_Right ] * m_Scale , 0.f , 0.f ) ) ; // ok
2014-08-04 16:30:25 +00:00
CMatrix mat = m_CameraMatrix [ cid ] * translate ;
if ( camera - > getTransformMode ( ) = = NL3D : : UTransformable : : RotQuat )
{
camera - > setPos ( mat . getPos ( ) ) ;
camera - > setRotQuat ( mat . getRot ( ) ) ;
}
else
{
// camera->setTransformMode(NL3D::UTransformable::DirectMatrix);
camera - > setMatrix ( mat ) ;
2014-08-04 22:51:53 +00:00
}
2014-08-04 16:30:25 +00:00
}
bool CStereoOVR : : wantClear ( )
{
switch ( m_Stage )
{
case 3 :
m_SubStage = 1 ;
return true ;
}
return m_Driver - > getPolygonMode ( ) ! = UDriver : : Filled ;
}
bool CStereoOVR : : wantScene ( )
{
switch ( m_Stage )
{
case 3 :
case 4 :
m_SubStage = 2 ;
return true ;
}
return m_Driver - > getPolygonMode ( ) ! = UDriver : : Filled ;
}
2014-08-06 12:36:09 +00:00
bool CStereoOVR : : wantSceneEffects ( )
{
switch ( m_Stage )
{
case 4 :
return true ;
}
return m_Driver - > getPolygonMode ( ) ! = UDriver : : Filled ;
}
2014-08-04 16:30:25 +00:00
bool CStereoOVR : : wantInterface3D ( )
{
switch ( m_Stage )
{
case 5 :
case 6 :
m_SubStage = 3 ;
return true ;
}
return m_Driver - > getPolygonMode ( ) ! = UDriver : : Filled ;
}
bool CStereoOVR : : wantInterface2D ( )
{
switch ( m_Stage )
{
case 2 :
m_SubStage = 4 ;
return true ;
}
return m_Driver - > getPolygonMode ( ) ! = UDriver : : Filled ;
}
2014-08-06 12:36:09 +00:00
bool CStereoOVR : : isSceneFirst ( )
{
switch ( m_Stage )
{
case 3 :
return true ;
2014-08-06 23:04:58 +00:00
case 4 :
return false ;
2014-08-06 12:36:09 +00:00
}
return m_Driver - > getPolygonMode ( ) ! = UDriver : : Filled ;
}
bool CStereoOVR : : isSceneLast ( )
{
switch ( m_Stage )
{
2014-08-06 23:04:58 +00:00
case 3 :
return false ;
2014-08-06 12:36:09 +00:00
case 4 :
return true ;
}
return m_Driver - > getPolygonMode ( ) ! = UDriver : : Filled ;
}
2014-08-04 16:30:25 +00:00
/// Returns non-NULL if a new render target was set
bool CStereoOVR : : beginRenderTarget ( )
{
// render target always set before driver clear
// nlassert(m_SubStage <= 1);
// Set GUI render target
if ( m_Driver & & m_Stage = = 2 & & ( m_Driver - > getPolygonMode ( ) = = UDriver : : Filled ) )
{
nlassert ( ! m_GUITexture ) ;
uint32 width , height ;
m_Driver - > getWindowSize ( width , height ) ;
m_GUITexture = m_Driver - > getRenderTargetManager ( ) . getRenderTarget ( width , height , true , UTexture : : RGBA8888 ) ;
static_cast < CDriverUser * > ( m_Driver ) - > setRenderTarget ( * m_GUITexture ) ;
m_Driver - > clearBuffers ( NLMISC : : CRGBA ( 0 , 0 , 0 , 0 ) ) ;
return true ;
}
// Begin 3D scene render target
2014-08-04 22:46:04 +00:00
if ( m_Driver & & m_Stage = = 3 & & ( m_Driver - > getPolygonMode ( ) = = UDriver : : Filled ) )
2014-08-04 16:30:25 +00:00
{
2014-08-05 00:55:26 +00:00
nlassert ( ! m_SceneTexture ) ;
2014-08-04 22:46:04 +00:00
m_SceneTexture = m_Driver - > getRenderTargetManager ( ) . getRenderTarget ( m_RenderTargetWidth , m_RenderTargetHeight ) ;
2014-08-04 16:30:25 +00:00
static_cast < CDriverUser * > ( m_Driver ) - > setRenderTarget ( * m_SceneTexture ) ;
2014-08-05 00:25:14 +00:00
return true ;
2014-08-05 00:55:26 +00:00
/*nldebug("OVR: Begin render target");*/
//m_Driver->beginDefaultRenderTarget(m_RenderTargetWidth, m_RenderTargetHeight); // DEBUG
//return true;
2014-08-04 22:46:04 +00:00
}
2014-08-04 16:30:25 +00:00
return false ;
}
void CStereoOVR : : setInterfaceMatrix ( const NL3D : : CMatrix & matrix )
{
m_InterfaceCameraMatrix = matrix ;
}
void CStereoOVR : : renderGUI ( )
{
m_Driver - > setModelMatrix ( m_InterfaceCameraMatrix ) ;
{
NLMISC : : CLine line ( NLMISC : : CVector ( 0 , 5 , 2 ) , NLMISC : : CVector ( 0 , 5 , 3 ) ) ;
NL3D : : UMaterial mat = m_Driver - > createMaterial ( ) ;
mat . setZWrite ( false ) ;
// mat.setZFunc(UMaterial::always); // Not nice!
mat . setDoubleSided ( true ) ;
mat . setColor ( NLMISC : : CRGBA : : Red ) ;
mat . setBlend ( false ) ;
m_Driver - > drawLine ( line , mat ) ;
m_Driver - > deleteMaterial ( mat ) ;
}
{
nlassert ( m_GUITexture ) ;
NLMISC : : CQuadUV quad ;
NL3D : : UMaterial umat = m_Driver - > createMaterial ( ) ;
umat . initUnlit ( ) ;
umat . setColor ( NLMISC : : CRGBA : : White ) ;
umat . setDoubleSided ( true ) ;
umat . setBlend ( true ) ;
umat . setAlphaTest ( false ) ;
NL3D : : CMaterial * mat = umat . getObjectPtr ( ) ;
mat - > setShader ( NL3D : : CMaterial : : Normal ) ;
mat - > setBlendFunc ( CMaterial : : one , CMaterial : : invsrcalpha ) ;
mat - > setZWrite ( false ) ;
// mat->setZFunc(CMaterial::always); // Not nice
mat - > setDoubleSided ( true ) ;
mat - > setTexture ( 0 , m_GUITexture - > getITexture ( ) ) ;
// user options
float scale = 1.0f ;
float distance = 1.5f ;
float offcenter = 0.75f ;
float height = scale * distance * 2.0f ;
uint32 winw , winh ;
m_Driver - > getWindowSize ( winw , winh ) ;
float width = height * ( float ) winw / ( float ) winh ;
float bottom = - ( height * 0.5f ) ;
float top = ( height * 0.5f ) ;
NLMISC : : CQuadUV quadUV ;
quadUV . V0 = CVector ( - ( width * 0.5f ) , distance , - ( height * 0.5f ) ) ;
quadUV . V1 = CVector ( ( width * 0.5f ) , distance , - ( height * 0.5f ) ) ;
quadUV . V2 = CVector ( ( width * 0.5f ) , distance , ( height * 0.5f ) ) ;
quadUV . V3 = CVector ( - ( width * 0.5f ) , distance , ( height * 0.5f ) ) ;
quadUV . Uv0 = CUV ( 0.f , 0.f ) ;
quadUV . Uv1 = CUV ( 1.f , 0.f ) ;
quadUV . Uv2 = CUV ( 1.f , 1.f ) ;
quadUV . Uv3 = CUV ( 0.f , 1.f ) ;
const uint nbQuads = 128 ;
static CVertexBuffer vb ;
static CIndexBuffer ib ;
vb . setVertexFormat ( CVertexBuffer : : PositionFlag | CVertexBuffer : : TexCoord0Flag ) ;
vb . setPreferredMemory ( CVertexBuffer : : RAMVolatile , false ) ;
vb . setNumVertices ( ( nbQuads + 1 ) * 2 ) ;
{
CVertexBufferReadWrite vba ;
vb . lock ( vba ) ;
float radius = distance + offcenter ;
float relWidth = width / radius ;
float quadWidth = relWidth / ( float ) nbQuads ;
for ( uint i = 0 ; i < nbQuads + 1 ; + + i )
{
uint vi0 = i * 2 ;
uint vi1 = vi0 + 1 ;
float lineH = - ( relWidth * 0.5f ) + quadWidth * ( float ) i ;
float lineUV = ( float ) i / ( float ) ( nbQuads ) ;
float left = sin ( lineH ) * radius ;
float forward = cos ( lineH ) * radius ;
vba . setVertexCoord ( vi0 , left , forward - offcenter , bottom ) ;
vba . setTexCoord ( vi0 , 0 , lineUV , 0.0f ) ;
vba . setVertexCoord ( vi1 , left , forward - offcenter , top ) ;
vba . setTexCoord ( vi1 , 0 , lineUV , 1.0f ) ;
}
}
ib . setFormat ( NL_DEFAULT_INDEX_BUFFER_FORMAT ) ;
ib . setPreferredMemory ( CIndexBuffer : : RAMVolatile , false ) ;
ib . setNumIndexes ( nbQuads * 6 ) ;
{
CIndexBufferReadWrite iba ;
ib . lock ( iba ) ;
for ( uint i = 0 ; i < nbQuads ; + + i )
{
uint ti0 = i * 2 ;
uint ti1 = ti0 + 1 ;
uint bl = ti0 ;
uint tl = ti0 + 1 ;
uint br = ti0 + 2 ;
uint tr = ti0 + 3 ;
iba . setTri ( ti0 * 3 , bl , tl , br ) ;
iba . setTri ( ti1 * 3 , br , tl , tr ) ;
}
}
IDriver * driver = static_cast < CDriverUser * > ( m_Driver ) - > getDriver ( ) ;
// m_Driver->setPolygonMode(UDriver::Line);
driver - > activeVertexBuffer ( vb ) ;
driver - > activeIndexBuffer ( ib ) ;
driver - > renderTriangles ( * umat . getObjectPtr ( ) , 0 , nbQuads * 2 ) ; //renderRawQuads(umat, 0, 128);
// m_Driver->setPolygonMode(UDriver::Filled);
// m_Driver->drawQuad(quadUV, umat);
m_Driver - > deleteMaterial ( umat ) ;
}
}
/// Returns true if a render target was fully drawn
bool CStereoOVR : : endRenderTarget ( )
{
// after rendering of course
// nlassert(m_SubStage > 1);
// End GUI render target
if ( m_Driver & & m_Stage = = 2 & & ( m_Driver - > getPolygonMode ( ) = = UDriver : : Filled ) )
{
// End GUI render target
nlassert ( m_GUITexture ) ;
CTextureUser texNull ;
( static_cast < CDriverUser * > ( m_Driver ) ) - > setRenderTarget ( texNull ) ;
}
// End of 3D Interface pass left
if ( m_Driver & & m_Stage = = 5 & & ( m_Driver - > getPolygonMode ( ) = = UDriver : : Filled ) )
{
// Render 2D GUI in 3D space, assume existing camera is OK
renderGUI ( ) ;
}
// End of 3D Interface pass right
if ( m_Driver & & m_Stage = = 6 & & ( m_Driver - > getPolygonMode ( ) = = UDriver : : Filled ) )
{
// Render 2D GUI in 3D space, assume existing camera is OK
renderGUI ( ) ;
// Recycle render target
m_Driver - > getRenderTargetManager ( ) . recycleRenderTarget ( m_GUITexture ) ;
m_GUITexture = NULL ;
}
// End 3D scene render target
2014-08-04 23:49:45 +00:00
if ( m_Driver & & m_Stage = = 6 & & ( m_Driver - > getPolygonMode ( ) = = UDriver : : Filled ) )
{
2014-08-05 00:55:26 +00:00
nlassert ( m_SceneTexture ) ;
2014-08-05 00:25:14 +00:00
//nldebug("OVR: End render target");
2014-08-05 00:55:26 +00:00
// m_Driver->endDefaultRenderTarget(NULL); // DEBUG
// end render target
CTextureUser texNull ;
( static_cast < CDriverUser * > ( m_Driver ) ) - > setRenderTarget ( texNull ) ;
// backup
bool fogEnabled = m_Driver - > fogEnabled ( ) ;
m_Driver - > enableFog ( false ) ;
2014-08-05 01:54:19 +00:00
// must clear everything to black (can we get a mesh to only handle the parts outside of the distortion mesh?)
m_Driver - > clearRGBABuffer ( CRGBA ( 0 , 0 , 0 , 255 ) ) ;
2014-08-05 00:55:26 +00:00
CDriverUser * dru = static_cast < CDriverUser * > ( m_Driver ) ;
IDriver * drv = dru - > getDriver ( ) ;
// set matrix mode
CViewport vp ;
m_Driver - > setViewport ( vp ) ;
m_Driver - > setMatrixMode2D11 ( ) ;
for ( uint eye = 0 ; eye < ovrEye_Count ; + + eye )
{
2014-08-05 01:54:19 +00:00
CMaterial * mat = m_UnlitMat . getObjectPtr ( ) ;
2014-08-05 00:55:26 +00:00
mat - > setTexture ( 0 , m_SceneTexture - > getITexture ( ) ) ;
2014-08-05 01:54:19 +00:00
mat - > setTexture ( 1 , m_SceneTexture - > getITexture ( ) ) ;
mat - > setTexture ( 2 , m_SceneTexture - > getITexture ( ) ) ;
mat - > setTexture ( 3 , m_SceneTexture - > getITexture ( ) ) ;
2014-08-05 00:55:26 +00:00
//m_Driver->setPolygonMode(UDriver::Line);
drv - > activeVertexBuffer ( m_VB [ eye ] ) ;
drv - > activeIndexBuffer ( m_IB [ eye ] ) ;
drv - > renderTriangles ( * mat , 0 , m_NbTris [ eye ] ) ;
//m_Driver->setPolygonMode(UDriver::Filled);
2014-08-05 01:54:19 +00:00
mat - > setTexture ( 0 , NULL ) ;
mat - > setTexture ( 1 , NULL ) ;
mat - > setTexture ( 2 , NULL ) ;
mat - > setTexture ( 3 , NULL ) ;
2014-08-05 00:55:26 +00:00
}
// restore
m_Driver - > enableFog ( fogEnabled ) ;
// recycle render target
m_Driver - > getRenderTargetManager ( ) . recycleRenderTarget ( m_SceneTexture ) ;
m_SceneTexture = NULL ;
2014-08-05 00:25:14 +00:00
return true ;
2014-08-04 23:49:45 +00:00
}
2014-08-05 01:54:19 +00:00
2014-08-04 16:30:25 +00:00
/*if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) // set to 4 to turn off distortion of 2d gui
{
nlassert ( m_SceneTexture ) ;
CTextureUser texNull ;
( static_cast < CDriverUser * > ( m_Driver ) ) - > setRenderTarget ( texNull ) ;
bool fogEnabled = m_Driver - > fogEnabled ( ) ;
m_Driver - > enableFog ( false ) ;
m_Driver - > setMatrixMode2D11 ( ) ;
CViewport vp = CViewport ( ) ;
m_Driver - > setViewport ( vp ) ;
uint32 width , height ;
m_Driver - > getWindowSize ( width , height ) ;
NL3D : : IDriver * drvInternal = ( static_cast < CDriverUser * > ( m_Driver ) ) - > getDriver ( ) ;
NL3D : : CMaterial * barrelMat = m_BarrelMat . getObjectPtr ( ) ;
barrelMat - > setTexture ( 0 , m_SceneTexture - > getITexture ( ) ) ;
drvInternal - > activePixelProgram ( m_PixelProgram ) ;
float w = float ( m_BarrelQuadLeft . V1 . x ) , // / float(width),
h = float ( m_BarrelQuadLeft . V2 . y ) , // / float(height),
x = float ( m_BarrelQuadLeft . V0 . x ) , /// / float(width),
y = float ( m_BarrelQuadLeft . V0 . y ) ; // / float(height);
float lensOffset = m_DevicePtr - > HMDInfo . LensSeparationDistance * 0.5f ;
float lensShift = m_DevicePtr - > HMDInfo . HScreenSize * 0.25f - lensOffset ;
float lensViewportShift = 4.0f * lensShift / m_DevicePtr - > HMDInfo . HScreenSize ;
float lensCenterX = x + ( w + lensViewportShift * 0.5f ) * 0.5f ;
float lensCenterY = y + h * 0.5f ;
float screenCenterX = x + w * 0.5f ;
float screenCenterY = y + h * 0.5f ;
float scaleX = ( w / 2 ) ;
float scaleY = ( h / 2 ) ;
float scaleInX = ( 2 / w ) ;
float scaleInY = ( 2 / h ) ;
drvInternal - > setUniform2f ( IDriver : : PixelProgram ,
m_PixelProgram - > ovrIndices ( ) . LensCenter ,
lensCenterX , lensCenterY ) ;
drvInternal - > setUniform2f ( IDriver : : PixelProgram ,
m_PixelProgram - > ovrIndices ( ) . ScreenCenter ,
screenCenterX , screenCenterY ) ;
drvInternal - > setUniform2f ( IDriver : : PixelProgram ,
m_PixelProgram - > ovrIndices ( ) . Scale ,
scaleX , scaleY ) ;
drvInternal - > setUniform2f ( IDriver : : PixelProgram ,
m_PixelProgram - > ovrIndices ( ) . ScaleIn ,
scaleInX , scaleInY ) ;
drvInternal - > setUniform4fv ( IDriver : : PixelProgram ,
m_PixelProgram - > ovrIndices ( ) . HmdWarpParam ,
1 , m_DevicePtr - > HMDInfo . DistortionK ) ;
m_Driver - > drawQuad ( m_BarrelQuadLeft , m_BarrelMat ) ;
x = w ;
lensCenterX = x + ( w - lensViewportShift * 0.5f ) * 0.5f ;
screenCenterX = x + w * 0.5f ;
drvInternal - > setUniform2f ( IDriver : : PixelProgram ,
m_PixelProgram - > ovrIndices ( ) . LensCenter ,
lensCenterX , lensCenterY ) ;
drvInternal - > setUniform2f ( IDriver : : PixelProgram ,
m_PixelProgram - > ovrIndices ( ) . ScreenCenter ,
screenCenterX , screenCenterY ) ;
m_Driver - > drawQuad ( m_BarrelQuadRight , m_BarrelMat ) ;
drvInternal - > activePixelProgram ( NULL ) ;
m_Driver - > enableFog ( fogEnabled ) ;
// Recycle render target
m_Driver - > getRenderTargetManager ( ) . recycleRenderTarget ( m_SceneTexture ) ;
m_SceneTexture = NULL ;
return true ;
} */
return false ;
}
NLMISC : : CQuat CStereoOVR : : getOrientation ( ) const
{
2014-08-04 23:49:45 +00:00
// broken
2014-08-05 00:25:14 +00:00
/*NLMISC::CQuat quat;
2014-08-04 23:49:45 +00:00
quat . identity ( ) ;
2014-08-05 00:25:14 +00:00
return quat ; */
2014-08-04 23:49:45 +00:00
2014-08-04 22:46:04 +00:00
if ( m_OrientationCached )
2014-08-04 16:30:25 +00:00
return m_OrientationCache ;
2014-08-04 22:46:04 +00:00
ovrTrackingState ts = ovrHmd_GetTrackingState ( m_DevicePtr , ovr_GetTimeInSeconds ( ) ) ; // TODO: Predict forward
if ( ts . StatusFlags & ovrStatus_OrientationTracked )
{
// get just the orientation
ovrQuatf quatovr = ts . HeadPose . ThePose . Orientation ;
NLMISC : : CMatrix coordsys ;
float csys [ ] = {
1.0f , 0.0f , 0.0f , 0.0f ,
0.0f , 0.0f , - 1.0f , 0.0f ,
0.0f , 1.0f , 0.0f , 0.0f ,
0.0f , 0.0f , 0.0f , 1.0f ,
} ;
coordsys . set ( csys ) ;
NLMISC : : CMatrix matovr ;
matovr . setRot ( NLMISC : : CQuat ( quatovr . x , quatovr . y , quatovr . z , quatovr . w ) ) ;
NLMISC : : CMatrix matr ;
2014-08-05 18:14:58 +00:00
// matr.rotateZ(NLMISC::Pi); // uncomment when backwards ...
2014-08-04 22:46:04 +00:00
matr . rotateX ( NLMISC : : Pi * 0.5f ) ; // fix this properly... :) (note: removing this allows you to use rift while lying down)
NLMISC : : CMatrix matnel = matr * matovr * coordsys ;
NLMISC : : CQuat finalquat = matnel . getRot ( ) ;
m_OrientationCache = finalquat ;
m_OrientationCached = true ;
return finalquat ;
}
else
{
nlwarning ( " OVR: No orientation returned " ) ;
// return old orientation
m_OrientationCached = true ;
return m_OrientationCache ;
}
2014-08-04 16:30:25 +00:00
}
/// Get GUI shift
void CStereoOVR : : getInterface2DShift ( uint cid , float & x , float & y , float distance ) const
{
}
void CStereoOVR : : setEyePosition ( const NLMISC : : CVector & v )
{
m_EyePosition = v ;
}
const NLMISC : : CVector & CStereoOVR : : getEyePosition ( ) const
{
return m_EyePosition ;
}
void CStereoOVR : : setScale ( float s )
{
m_EyePosition = m_EyePosition * ( s / m_Scale ) ;
m_Scale = s ;
}
2014-08-04 17:19:15 +00:00
2014-08-04 16:30:25 +00:00
void CStereoOVR : : listDevices ( std : : vector < CStereoDeviceInfo > & devicesOut )
{
2014-08-04 17:19:15 +00:00
if ( ! s_StereoOVRSystem . Init ( ) )
return ;
+ + s_DetectId ;
uint hmdDetect = ovrHmd_Detect ( ) ;
nldebug ( " OVR: Detected %u HMDs " , hmdDetect ) ;
2014-08-04 16:30:25 +00:00
2014-08-04 17:19:15 +00:00
for ( uint i = 0 ; i < hmdDetect ; + + i )
{
devicesOut . resize ( devicesOut . size ( ) + 1 ) ;
CStereoDeviceInfo & deviceInfoOut = devicesOut [ devicesOut . size ( ) - 1 ] ;
ovrHmd hmd = ovrHmd_Create ( i ) ;
CStereoOVRDeviceFactory * factory = new CStereoOVRDeviceFactory ( ) ;
factory - > DetectId = s_DetectId ;
factory - > DeviceIndex = i ;
factory - > DebugDevice = false ;
deviceInfoOut . Factory = factory ;
deviceInfoOut . Class = CStereoDeviceInfo : : StereoHMD ;
deviceInfoOut . Library = CStereoDeviceInfo : : OVR ;
deviceInfoOut . Manufacturer = hmd - > Manufacturer ;
deviceInfoOut . ProductName = hmd - > ProductName ;
deviceInfoOut . AllowAuto = true ;
deviceInfoOut . Serial = hmd - > SerialNumber ;
ovrHmd_Destroy ( hmd ) ;
}
# if !FINAL_VERSION
// Debug DK1
{
devicesOut . resize ( devicesOut . size ( ) + 1 ) ;
CStereoDeviceInfo & deviceInfoOut = devicesOut [ devicesOut . size ( ) - 1 ] ;
ovrHmd hmd = ovrHmd_CreateDebug ( ovrHmd_DK1 ) ;
CStereoOVRDeviceFactory * factory = new CStereoOVRDeviceFactory ( ) ;
2014-08-05 02:03:27 +00:00
factory - > DetectId = s_DetectId ;
2014-08-04 17:19:15 +00:00
factory - > DebugDevice = true ;
factory - > DebugDeviceType = ovrHmd_DK1 ;
deviceInfoOut . Factory = factory ;
deviceInfoOut . Class = CStereoDeviceInfo : : StereoHMD ;
deviceInfoOut . Library = CStereoDeviceInfo : : OVR ;
deviceInfoOut . Manufacturer = hmd - > Manufacturer ;
deviceInfoOut . ProductName = hmd - > ProductName ;
deviceInfoOut . AllowAuto = false ;
deviceInfoOut . Serial = " OVR-DK1-DEBUG " ;
ovrHmd_Destroy ( hmd ) ;
}
// Debug DK2
{
devicesOut . resize ( devicesOut . size ( ) + 1 ) ;
CStereoDeviceInfo & deviceInfoOut = devicesOut [ devicesOut . size ( ) - 1 ] ;
ovrHmd hmd = ovrHmd_CreateDebug ( ovrHmd_DK2 ) ;
CStereoOVRDeviceFactory * factory = new CStereoOVRDeviceFactory ( ) ;
2014-08-05 02:03:27 +00:00
factory - > DetectId = s_DetectId ;
2014-08-04 17:19:15 +00:00
factory - > DebugDevice = true ;
factory - > DebugDeviceType = ovrHmd_DK2 ;
deviceInfoOut . Factory = factory ;
deviceInfoOut . Class = CStereoDeviceInfo : : StereoHMD ;
deviceInfoOut . Library = CStereoDeviceInfo : : OVR ;
deviceInfoOut . Manufacturer = hmd - > Manufacturer ;
deviceInfoOut . ProductName = hmd - > ProductName ;
deviceInfoOut . AllowAuto = false ;
deviceInfoOut . Serial = " OVR-DK2-DEBUG " ;
ovrHmd_Destroy ( hmd ) ;
}
# endif
2014-08-04 16:30:25 +00:00
}
bool CStereoOVR : : isLibraryInUse ( )
{
2014-08-04 17:19:15 +00:00
nlassert ( s_DeviceCounter > = 0 ) ;
return s_DeviceCounter > 0 ;
2014-08-04 16:30:25 +00:00
}
void CStereoOVR : : releaseLibrary ( )
{
2014-08-04 17:19:15 +00:00
nlassert ( s_DeviceCounter = = 0 ) ;
s_StereoOVRSystem . Release ( ) ;
2014-08-04 16:30:25 +00:00
}
bool CStereoOVR : : isDeviceCreated ( )
{
2014-08-04 18:32:31 +00:00
return m_DevicePtr ! = NULL ;
2014-08-04 16:30:25 +00:00
}
} /* namespace NL3D */
# endif /* HAVE_LIBOVR */
/* end of file */