Create stereo render target, see #43

This commit is contained in:
kaetemi 2013-07-01 23:23:54 +02:00
parent fcd9344ad5
commit 6b33f0c5b8
5 changed files with 180 additions and 10 deletions

View file

@ -92,7 +92,7 @@ public:
virtual ~IStereoDisplay();
/// Sets driver and generates necessary render targets
virtual void setDriver(NL3D::UDriver &driver) = 0;
virtual void setDriver(NL3D::UDriver *driver) = 0;
/// Gets the required screen resolution for this device
virtual void getScreenResolution(uint &width, uint &height) = 0;
@ -124,7 +124,7 @@ public:
/// Returns non-NULL if a new render target was set
virtual UTexture *beginRenderTarget(bool set) = 0;
/// Returns true if a render target was fully drawn
virtual bool endRenderTarget(bool render) = 0;
virtual bool endRenderTarget(bool unset) = 0;
static const char *getLibraryName(CStereoDeviceInfo::TStereoDeviceLibrary library);
static void listDevices(std::vector<CStereoDeviceInfo> &devicesOut);

View file

@ -49,14 +49,18 @@
// NeL includes
#include <nel/misc/smart_ptr.h>
#include <nel/misc/geom_ext.h>
// Project includes
#include <nel/3d/stereo_hmd.h>
#include <nel/3d/frustum.h>
#include <nel/3d/viewport.h>
#include <nel/3d/u_material.h>
namespace NL3D {
class ITexture;
class CTextureUser;
class CStereoOVRDevicePtr;
class CStereoOVRDeviceHandle;
@ -75,7 +79,7 @@ public:
virtual ~CStereoOVR();
/// Sets driver and generates necessary render targets
virtual void setDriver(NL3D::UDriver &driver);
virtual void setDriver(NL3D::UDriver *driver);
/// Gets the required screen resolution for this device
virtual void getScreenResolution(uint &width, uint &height);
@ -107,7 +111,7 @@ public:
/// Returns non-NULL if a new render target was set, always NULL if not using render targets
virtual UTexture *beginRenderTarget(bool set);
/// Returns true if a render target was fully drawn, always false if not using render targets
virtual bool endRenderTarget(bool render);
virtual bool endRenderTarget(bool unset);
/// Get the HMD orientation
@ -138,6 +142,11 @@ private:
CMatrix m_CameraMatrix[NL_STEREO_MAX_USER_CAMERAS];
mutable bool m_OrientationCached;
mutable NLMISC::CQuat m_OrientationCache;
UDriver *m_Driver;
NLMISC::CSmartPtr<NL3D::ITexture> m_BarrelTex;
NL3D::CTextureUser *m_BarrelTexU;
NL3D::UMaterial m_BarrelMat;
NLMISC::CQuadUV m_BarrelQuad;
}; /* class CStereoOVR */

View file

@ -692,6 +692,7 @@ SOURCE_GROUP(Stereo FILES
stereo_hmd.cpp
../../include/nel/3d/stereo_hmd.h
stereo_ovr.cpp
stereo_ovr_fp.cpp
../../include/nel/3d/stereo_ovr.h)
NL_TARGET_LIB(nel3d ${HEADERS} ${SRC})

View file

@ -53,6 +53,12 @@
// 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
@ -61,6 +67,8 @@ using namespace std;
namespace NL3D {
extern const char *g_StereoOVR_arbfp1;
namespace {
class CStereoOVRLog : public OVR::Log
@ -155,7 +163,7 @@ public:
OVR::HMDInfo HMDInfo;
};
CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false)
CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_BarrelTexU(NULL)
{
++s_DeviceCounter;
m_DevicePtr = new CStereoOVRDevicePtr();
@ -194,6 +202,17 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_Sub
CStereoOVR::~CStereoOVR()
{
if (!m_BarrelMat.empty())
{
m_BarrelMat.getObjectPtr()->setTexture(0, NULL);
m_Driver->deleteMaterial(m_BarrelMat);
}
delete m_BarrelTexU;
m_BarrelTexU = NULL;
m_BarrelTex = NULL; // CSmartPtr
m_Driver = NULL;
if (m_DevicePtr->SensorDevice)
m_DevicePtr->SensorDevice->Release();
m_DevicePtr->SensorDevice.Clear();
@ -206,9 +225,51 @@ CStereoOVR::~CStereoOVR()
--s_DeviceCounter;
}
void CStereoOVR::setDriver(NL3D::UDriver &driver)
void CStereoOVR::setDriver(NL3D::UDriver *driver)
{
// ...
m_Driver = driver;
// Do not allow weird stuff.
uint32 width, height;
driver->getWindowSize(width, height);
nlassert(width == m_DevicePtr->HMDInfo.HResolution);
nlassert(height == m_DevicePtr->HMDInfo.VResolution);
NL3D::IDriver *drvInternal = (static_cast<CDriverUser *>(driver))->getDriver();
m_BarrelTex = new CTextureBloom(); // lol bloom
m_BarrelTex->setReleasable(false);
m_BarrelTex->resize(width, height);
m_BarrelTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff);
m_BarrelTex->setWrapS(ITexture::Clamp);
m_BarrelTex->setWrapT(ITexture::Clamp);
m_BarrelTex->setRenderTarget(true);
drvInternal->setupTexture(*m_BarrelTex);
m_BarrelTexU = new CTextureUser(m_BarrelTex);
m_BarrelMat = m_Driver->createMaterial();
NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr();
m_BarrelMat.initUnlit();
m_BarrelMat.setColor(CRGBA::White);
m_BarrelMat.setBlend (false);
m_BarrelMat.setAlphaTest (false);
barrelMat->setBlendFunc(CMaterial::one, CMaterial::zero);
barrelMat->setZWrite(false);
barrelMat->setZFunc(CMaterial::always);
barrelMat->setDoubleSided(true);
barrelMat->setTexture(0, m_BarrelTex);
m_BarrelQuad.V0 = CVector(0.f, 0.f, 0.5f);
m_BarrelQuad.V1 = CVector(1.f, 0.f, 0.5f);
m_BarrelQuad.V2 = CVector(1.f, 1.f, 0.5f);
m_BarrelQuad.V3 = CVector(0.f, 1.f, 0.5f);
float newU = drvInternal->isTextureRectangle(m_BarrelTex) ? (float)width : 1.f;
float newV = drvInternal->isTextureRectangle(m_BarrelTex) ? (float)height : 1.f;
m_BarrelQuad.Uv0 = CUV(0.f, 0.f);
m_BarrelQuad.Uv1 = CUV(newU, 0.f);
m_BarrelQuad.Uv2 = CUV(newU, newV);
m_BarrelQuad.Uv3 = CUV(0.f, newV);
}
void CStereoOVR::getScreenResolution(uint &width, uint &height)
@ -391,15 +452,32 @@ bool CStereoOVR::wantInterface2D()
UTexture *CStereoOVR::beginRenderTarget(bool set)
{
// render target always set before driver clear
nlassert(m_SubStage == 1);
// nlassert(m_SubStage <= 1);
if (m_Stage == 1)
{
if (set)
{
(static_cast<CDriverUser *>(m_Driver))->setRenderTarget(*m_BarrelTexU, 0, 0, 0, 0);
}
return m_BarrelTexU;
}
return NULL;
}
/// Returns true if a render target was fully drawn
bool CStereoOVR::endRenderTarget( bool render)
bool CStereoOVR::endRenderTarget(bool unset)
{
// after rendering of course
nlassert(m_SubStage > 1);
// nlassert(m_SubStage > 1);
if (m_Stage == 4)
{
if (unset)
{
CTextureUser cu;
(static_cast<CDriverUser *>(m_Driver))->setRenderTarget(cu);
}
return true;
}
return false;
}

View file

@ -0,0 +1,82 @@
/************************************************************************************
Filename : stereo_ovf_fp.cpp
Content : Barrel fragment program compiled to a blob of assembly
Created : July 01, 2013
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************************/
namespace NL3D {
const char *g_StereoOVR_arbfp1 =
"!!ARBfp1.0\n"
//# cgc version 3.1.0013, build date Apr 18 2012
//# command line args: -profile arbfp1
//# source file: pp_oculus_vr.cg
//#vendor NVIDIA Corporation
//#version 3.1.0.13
//#profile arbfp1
//#program pp_oculus_vr
//#semantic pp_oculus_vr.cLensCenter
//#semantic pp_oculus_vr.cScreenCenter
//#semantic pp_oculus_vr.cScale
//#semantic pp_oculus_vr.cScaleIn
//#semantic pp_oculus_vr.cHmdWarpParam
//#semantic pp_oculus_vr.cTex0 : TEX0
//#var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1
//#var float2 cLensCenter : : c[0] : 1 : 1
//#var float2 cScreenCenter : : c[1] : 2 : 1
//#var float2 cScale : : c[2] : 3 : 1
//#var float2 cScaleIn : : c[3] : 4 : 1
//#var float4 cHmdWarpParam : : c[4] : 5 : 1
//#var sampler2D cTex0 : TEX0 : texunit 0 : 6 : 1
//#var float4 oCol : $vout.COLOR : COL : 7 : 1
//#const c[5] = 0.25 0.5 0 1
"PARAM c[6] = { program.local[0..4],\n"
" { 0.25, 0.5, 0, 1 } };\n"
"TEMP R0;\n"
"TEMP R1;\n"
"ADD R0.xy, fragment.texcoord[0], -c[0];\n"
"MUL R0.xy, R0, c[3];\n"
"MUL R0.z, R0.y, R0.y;\n"
"MAD R0.z, R0.x, R0.x, R0;\n"
"MUL R0.w, R0.z, c[4];\n"
"MUL R0.w, R0, R0.z;\n"
"MAD R1.y, R0.z, c[4], c[4].x;\n"
"MUL R1.x, R0.z, c[4].z;\n"
"MAD R1.x, R0.z, R1, R1.y;\n"
"MAD R0.z, R0.w, R0, R1.x;\n"
"MUL R0.xy, R0, R0.z;\n"
"MOV R0.zw, c[5].xyxy;\n"
"ADD R1.xy, R0.zwzw, c[1];\n"
"MUL R0.xy, R0, c[2];\n"
"ADD R0.xy, R0, c[0];\n"
"MIN R1.xy, R1, R0;\n"
"ADD R0.zw, -R0, c[1].xyxy;\n"
"MAX R0.zw, R0, R1.xyxy;\n"
"ADD R0.zw, R0, -R0.xyxy;\n"
"ABS R0.zw, R0;\n"
"CMP R0.zw, -R0, c[5].z, c[5].w;\n"
"MUL R0.z, R0, R0.w;\n"
"ABS R0.z, R0;\n"
"CMP R0.z, -R0, c[5], c[5].w;\n"
"ABS R1.x, R0.z;\n"
"TEX R0, R0, texture[0], 2D;\n"
"CMP R1.x, -R1, c[5].z, c[5].w;\n"
"CMP result.color, -R1.x, R0, c[5].z;\n"
"END\n";
//# 28 instructions, 2 R-regs
}