parent
d45813adfc
commit
ce92c13289
3 changed files with 171 additions and 34 deletions
|
@ -63,6 +63,7 @@ class ITexture;
|
|||
class CTextureUser;
|
||||
class CStereoOVRDevicePtr;
|
||||
class CStereoOVRDeviceHandle;
|
||||
class CPixelProgram;
|
||||
|
||||
#define NL_STEREO_MAX_USER_CAMERAS 8
|
||||
|
||||
|
@ -147,6 +148,7 @@ private:
|
|||
NL3D::CTextureUser *m_BarrelTexU;
|
||||
NL3D::UMaterial m_BarrelMat;
|
||||
NLMISC::CQuadUV m_BarrelQuad;
|
||||
CPixelProgram *m_PixelProgram;
|
||||
|
||||
}; /* class CStereoOVR */
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ using namespace std;
|
|||
namespace NL3D {
|
||||
|
||||
extern const char *g_StereoOVR_arbfp1;
|
||||
extern const char *g_StereoOVR_ps_2_0;
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -163,7 +164,7 @@ public:
|
|||
OVR::HMDInfo HMDInfo;
|
||||
};
|
||||
|
||||
CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_BarrelTexU(NULL)
|
||||
CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_BarrelTexU(NULL), m_PixelProgram(NULL)
|
||||
{
|
||||
++s_DeviceCounter;
|
||||
m_DevicePtr = new CStereoOVRDevicePtr();
|
||||
|
@ -211,6 +212,9 @@ CStereoOVR::~CStereoOVR()
|
|||
m_BarrelTexU = NULL;
|
||||
m_BarrelTex = NULL; // CSmartPtr
|
||||
|
||||
delete m_PixelProgram;
|
||||
m_PixelProgram = NULL;
|
||||
|
||||
m_Driver = NULL;
|
||||
|
||||
if (m_DevicePtr->SensorDevice)
|
||||
|
@ -227,49 +231,84 @@ CStereoOVR::~CStereoOVR()
|
|||
|
||||
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);
|
||||
nlassert(!m_PixelProgram);
|
||||
|
||||
NL3D::IDriver *drvInternal = (static_cast<CDriverUser *>(driver))->getDriver();
|
||||
/*static const char *program_arbfp1 =
|
||||
"!!ARBfp1.0\n"
|
||||
"PARAM c[1] = { { 1, 0 } };\n"
|
||||
"MOV result.color.xzw, c[0].xyyx;\n"
|
||||
"TEX result.color.y, fragment.texcoord[0], texture[0], 2D;\n"
|
||||
"END\n";
|
||||
static const char *program_ps_2_0 =
|
||||
"ps_2_0\n"
|
||||
"dcl_2d s0\n"
|
||||
"def c0, 1.00000000, 0.00000000, 0, 0\n"
|
||||
"dcl t0.xy\n"
|
||||
"texld r0, t0, s0\n"
|
||||
"mov r0.z, c0.y\n"
|
||||
"mov r0.xw, c0.x\n"
|
||||
"mov oC0, r0\n";*/
|
||||
/*if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1))
|
||||
{
|
||||
nldebug("VR: arbfp1");
|
||||
m_PixelProgram = new CPixelProgram(program_arbfp1);
|
||||
}
|
||||
else */ if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0))
|
||||
{
|
||||
nldebug("VR: ps_2_0");
|
||||
m_PixelProgram = new CPixelProgram(g_StereoOVR_ps_2_0);
|
||||
}
|
||||
|
||||
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);
|
||||
if (m_PixelProgram)
|
||||
{
|
||||
m_Driver = driver;
|
||||
|
||||
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_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_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_BarrelMat = m_Driver->createMaterial();
|
||||
m_BarrelMat.initUnlit();
|
||||
m_BarrelMat.setColor(CRGBA::White);
|
||||
m_BarrelMat.setBlend (false);
|
||||
m_BarrelMat.setAlphaTest (false);
|
||||
NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr();
|
||||
barrelMat->setShader(NL3D::CMaterial::PostProcessing);
|
||||
barrelMat->setBlendFunc(CMaterial::one, CMaterial::zero);
|
||||
barrelMat->setZWrite(false);
|
||||
barrelMat->setZFunc(CMaterial::always);
|
||||
barrelMat->setDoubleSided(true);
|
||||
barrelMat->setTexture(0, m_BarrelTex);
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
nlwarning("VR: No pixel program support");
|
||||
}
|
||||
}
|
||||
|
||||
void CStereoOVR::getScreenResolution(uint &width, uint &height)
|
||||
|
@ -473,10 +512,46 @@ bool CStereoOVR::endRenderTarget()
|
|||
{
|
||||
CTextureUser cu;
|
||||
(static_cast<CDriverUser *>(m_Driver))->setRenderTarget(cu);
|
||||
bool fogEnabled = m_Driver->fogEnabled();
|
||||
m_Driver->enableFog(false);
|
||||
|
||||
m_Driver->setMatrixMode2D11();
|
||||
m_Driver->setViewport(CViewport());
|
||||
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_BarrelTex);
|
||||
drvInternal->activePixelProgram(m_PixelProgram);
|
||||
|
||||
float w = float(vp.getWidth()),// / float(width),
|
||||
h = float(vp.getHeight()),// / float(height),
|
||||
x = float(vp.getX()),/// / float(width),
|
||||
y = float(vp.getY());// / 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->setPixelProgramConstant(0, lensCenterX, lensCenterY, 0.f, 0.f);
|
||||
drvInternal->setPixelProgramConstant(1, screenCenterX, screenCenterY, 0.f, 0.f);
|
||||
drvInternal->setPixelProgramConstant(2, scaleX, scaleY, 0.f, 0.f);
|
||||
drvInternal->setPixelProgramConstant(3, scaleInX, scaleInY, 0.f, 0.f);
|
||||
drvInternal->setPixelProgramConstant(4, 1, m_DevicePtr->HMDInfo.DistortionK);
|
||||
|
||||
|
||||
m_Driver->drawQuad(m_BarrelQuad, m_BarrelMat);
|
||||
drvInternal->activePixelProgram(NULL);
|
||||
m_Driver->enableFog(fogEnabled);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -78,5 +78,65 @@ const char *g_StereoOVR_arbfp1 =
|
|||
"CMP R1.x, -R1, c[5].z, c[5].w;\n"
|
||||
"CMP result.color, -R1.x, R0, c[5].z;\n"
|
||||
"END\n";
|
||||
const char *g_StereoOVR_ps_2_0 =
|
||||
//# 28 instructions, 2 R-regs
|
||||
"ps_2_0\n"
|
||||
// cgc version 3.1.0013, build date Apr 18 2012
|
||||
// command line args: -profile ps_2_0
|
||||
// source file: pp_oculus_vr.cg
|
||||
//vendor NVIDIA Corporation
|
||||
//version 3.1.0.13
|
||||
//profile ps_2_0
|
||||
//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.25 0.5
|
||||
//const c[6] = 1 0
|
||||
"dcl_2d s0\n"
|
||||
"def c5, -0.25000000, -0.50000000, 0.25000000, 0.50000000\n"
|
||||
"def c6, 1.00000000, 0.00000000, 0, 0\n"
|
||||
"dcl t0.xy\n"
|
||||
"add r0.xy, t0, -c0\n"
|
||||
"mul r4.xy, r0, c3\n"
|
||||
"mul r0.x, r4.y, r4.y\n"
|
||||
"mad r0.x, r4, r4, r0\n"
|
||||
"mul r1.x, r0, c4.w\n"
|
||||
"mul r1.x, r1, r0\n"
|
||||
"mad r3.x, r0, c4.y, c4\n"
|
||||
"mul r2.x, r0, c4.z\n"
|
||||
"mad r2.x, r0, r2, r3\n"
|
||||
"mad r0.x, r1, r0, r2\n"
|
||||
"mul r0.xy, r4, r0.x\n"
|
||||
"mul r0.xy, r0, c2\n"
|
||||
"add r3.xy, r0, c0\n"
|
||||
"mov r1.x, c5.z\n"
|
||||
"mov r1.y, c5.w\n"
|
||||
"mov r2.xy, c1\n"
|
||||
"add r2.xy, r1, r2\n"
|
||||
"mov r1.xy, c1\n"
|
||||
"min r2.xy, r2, r3\n"
|
||||
"add r1.xy, c5, r1\n"
|
||||
"max r1.xy, r1, r2\n"
|
||||
"add r1.xy, r1, -r3\n"
|
||||
"abs r1.xy, r1\n"
|
||||
"cmp r1.xy, -r1, c6.x, c6.y\n"
|
||||
"mul_pp r1.x, r1, r1.y\n"
|
||||
"abs_pp r1.x, r1\n"
|
||||
"cmp_pp r1.x, -r1, c6, c6.y\n"
|
||||
"abs_pp r1.x, r1\n"
|
||||
"texld r0, r3, s0\n"
|
||||
"cmp r0, -r1.x, r0, c6.y\n"
|
||||
"mov oC0, r0\n";
|
||||
}
|
Loading…
Reference in a new issue