Add glsl pixel program for stereo distortion
--HG-- branch : multipass-stereo
This commit is contained in:
parent
ac2e087fbf
commit
87b24bc4ab
6 changed files with 189 additions and 45 deletions
|
@ -266,6 +266,9 @@ public:
|
||||||
// Build feature info, called automatically by the driver after compile succeeds
|
// Build feature info, called automatically by the driver after compile succeeds
|
||||||
void buildInfo(CSource *source);
|
void buildInfo(CSource *source);
|
||||||
|
|
||||||
|
// Override this to build additional info in a subclass
|
||||||
|
virtual void buildInfo();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// The progam source
|
/// The progam source
|
||||||
std::vector<NLMISC::CSmartPtr<CSource> > m_Sources;
|
std::vector<NLMISC::CSmartPtr<CSource> > m_Sources;
|
||||||
|
|
|
@ -66,7 +66,7 @@ class ITexture;
|
||||||
class CTextureUser;
|
class CTextureUser;
|
||||||
class CStereoOVRDevicePtr;
|
class CStereoOVRDevicePtr;
|
||||||
class CStereoOVRDeviceHandle;
|
class CStereoOVRDeviceHandle;
|
||||||
class CPixelProgram;
|
class CPixelProgramOVR;
|
||||||
|
|
||||||
#define NL_STEREO_MAX_USER_CAMERAS 8
|
#define NL_STEREO_MAX_USER_CAMERAS 8
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ private:
|
||||||
NL3D::UMaterial m_BarrelMat;
|
NL3D::UMaterial m_BarrelMat;
|
||||||
NLMISC::CQuadUV m_BarrelQuadLeft;
|
NLMISC::CQuadUV m_BarrelQuadLeft;
|
||||||
NLMISC::CQuadUV m_BarrelQuadRight;
|
NLMISC::CQuadUV m_BarrelQuadRight;
|
||||||
CPixelProgram *m_PixelProgram;
|
NLMISC::CRefPtr<CPixelProgramOVR> m_PixelProgram;
|
||||||
NLMISC::CVector m_EyePosition;
|
NLMISC::CVector m_EyePosition;
|
||||||
float m_Scale;
|
float m_Scale;
|
||||||
|
|
||||||
|
|
|
@ -204,6 +204,13 @@ void IGPUProgram::buildInfo(CSource *source)
|
||||||
features.MaterialFlags &= ~CGPUProgramFeatures::MaterialAmbient;
|
features.MaterialFlags &= ~CGPUProgramFeatures::MaterialAmbient;
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
buildInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IGPUProgram::buildInfo()
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace NL3D */
|
} /* namespace NL3D */
|
||||||
|
|
|
@ -72,6 +72,7 @@ namespace NL3D {
|
||||||
extern const char *g_StereoOVR_fp40;
|
extern const char *g_StereoOVR_fp40;
|
||||||
extern const char *g_StereoOVR_arbfp1;
|
extern const char *g_StereoOVR_arbfp1;
|
||||||
extern const char *g_StereoOVR_ps_2_0;
|
extern const char *g_StereoOVR_ps_2_0;
|
||||||
|
extern const char *g_StereoOVR_glsl330f;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -233,43 +234,106 @@ CStereoOVR::~CStereoOVR()
|
||||||
--s_DeviceCounter;
|
--s_DeviceCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CPixelProgramOVR : public CPixelProgram
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct COVRIndices
|
||||||
|
{
|
||||||
|
uint LensCenter;
|
||||||
|
uint ScreenCenter;
|
||||||
|
uint Scale;
|
||||||
|
uint ScaleIn;
|
||||||
|
uint HmdWarpParam;
|
||||||
|
};
|
||||||
|
|
||||||
|
CPixelProgramOVR()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
CSource *source = new CSource();
|
||||||
|
source->Profile = glsl330f;
|
||||||
|
source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages;
|
||||||
|
source->setSourcePtr(g_StereoOVR_glsl330f);
|
||||||
|
addSource(source);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
CSource *source = new CSource();
|
||||||
|
source->Profile = fp40;
|
||||||
|
source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages;
|
||||||
|
source->setSourcePtr(g_StereoOVR_fp40);
|
||||||
|
source->ParamIndices["cLensCenter"] = 0;
|
||||||
|
source->ParamIndices["cScreenCenter"] = 1;
|
||||||
|
source->ParamIndices["cScale"] = 2;
|
||||||
|
source->ParamIndices["cScaleIn"] = 3;
|
||||||
|
source->ParamIndices["cHmdWarpParam"] = 4;
|
||||||
|
addSource(source);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
CSource *source = new CSource();
|
||||||
|
source->Profile = arbfp1;
|
||||||
|
source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages;
|
||||||
|
source->setSourcePtr(g_StereoOVR_arbfp1);
|
||||||
|
source->ParamIndices["cLensCenter"] = 0;
|
||||||
|
source->ParamIndices["cScreenCenter"] = 1;
|
||||||
|
source->ParamIndices["cScale"] = 2;
|
||||||
|
source->ParamIndices["cScaleIn"] = 3;
|
||||||
|
source->ParamIndices["cHmdWarpParam"] = 4;
|
||||||
|
addSource(source);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
CSource *source = new CSource();
|
||||||
|
source->Profile = ps_2_0;
|
||||||
|
source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages;
|
||||||
|
source->setSourcePtr(g_StereoOVR_ps_2_0);
|
||||||
|
source->ParamIndices["cLensCenter"] = 0;
|
||||||
|
source->ParamIndices["cScreenCenter"] = 1;
|
||||||
|
source->ParamIndices["cScale"] = 2;
|
||||||
|
source->ParamIndices["cScaleIn"] = 3;
|
||||||
|
source->ParamIndices["cHmdWarpParam"] = 4;
|
||||||
|
addSource(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~CPixelProgramOVR()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void buildInfo()
|
||||||
|
{
|
||||||
|
CPixelProgram::buildInfo();
|
||||||
|
|
||||||
|
m_OVRIndices.LensCenter = getUniformIndex("cLensCenter");
|
||||||
|
nlassert(m_OVRIndices.LensCenter != ~0);
|
||||||
|
m_OVRIndices.ScreenCenter = getUniformIndex("cScreenCenter");
|
||||||
|
nlassert(m_OVRIndices.ScreenCenter != ~0);
|
||||||
|
m_OVRIndices.Scale = getUniformIndex("cScale");
|
||||||
|
nlassert(m_OVRIndices.Scale != ~0);
|
||||||
|
m_OVRIndices.ScaleIn = getUniformIndex("cScaleIn");
|
||||||
|
nlassert(m_OVRIndices.ScaleIn != ~0);
|
||||||
|
m_OVRIndices.HmdWarpParam = getUniformIndex("cHmdWarpParam");
|
||||||
|
nlassert(m_OVRIndices.HmdWarpParam != ~0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const COVRIndices &ovrIndices() { return m_OVRIndices; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
COVRIndices m_OVRIndices;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
void CStereoOVR::setDriver(NL3D::UDriver *driver)
|
void CStereoOVR::setDriver(NL3D::UDriver *driver)
|
||||||
{
|
{
|
||||||
nlassert(!m_PixelProgram);
|
nlassert(!m_PixelProgram);
|
||||||
|
|
||||||
NL3D::IDriver *drvInternal = (static_cast<CDriverUser *>(driver))->getDriver();
|
NL3D::IDriver *drvInternal = (static_cast<CDriverUser *>(driver))->getDriver();
|
||||||
|
|
||||||
m_PixelProgram = new CPixelProgram();
|
if (drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures())
|
||||||
|
|
||||||
IGPUProgram::CSource *source = new IGPUProgram::CSource();
|
|
||||||
source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages;
|
|
||||||
source->Profile = IGPUProgram::none;
|
|
||||||
if (drvInternal->supportPixelProgram(CPixelProgram::fp40) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures())
|
|
||||||
{
|
{
|
||||||
nldebug("VR: fp40");
|
m_PixelProgram = new CPixelProgramOVR();
|
||||||
source->Profile = IGPUProgram::fp40;
|
if (!drvInternal->compilePixelProgram(m_PixelProgram))
|
||||||
source->setSourcePtr(g_StereoOVR_fp40);
|
{
|
||||||
m_PixelProgram->addSource(source);
|
m_PixelProgram.kill();
|
||||||
}
|
}
|
||||||
else if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures())
|
|
||||||
{
|
|
||||||
nldebug("VR: arbfp1");
|
|
||||||
source->Profile = IGPUProgram::arbfp1;
|
|
||||||
source->setSourcePtr(g_StereoOVR_arbfp1);
|
|
||||||
m_PixelProgram->addSource(source);
|
|
||||||
}
|
|
||||||
else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0))
|
|
||||||
{
|
|
||||||
nldebug("VR: ps_2_0");
|
|
||||||
source->Profile = IGPUProgram::ps_2_0;
|
|
||||||
source->setSourcePtr(g_StereoOVR_ps_2_0);
|
|
||||||
m_PixelProgram->addSource(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!drvInternal->compilePixelProgram(m_PixelProgram))
|
|
||||||
{
|
|
||||||
delete m_PixelProgram;
|
|
||||||
m_PixelProgram = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_PixelProgram)
|
if (m_PixelProgram)
|
||||||
|
@ -590,11 +654,27 @@ bool CStereoOVR::endRenderTarget()
|
||||||
float scaleInX = (2 / w);
|
float scaleInX = (2 / w);
|
||||||
float scaleInY = (2 / h);
|
float scaleInY = (2 / h);
|
||||||
|
|
||||||
drvInternal->setUniform2f(IDriver::PixelProgram, 0, lensCenterX, lensCenterY);
|
|
||||||
drvInternal->setUniform2f(IDriver::PixelProgram, 1, screenCenterX, screenCenterY);
|
drvInternal->setUniform2f(IDriver::PixelProgram,
|
||||||
drvInternal->setUniform2f(IDriver::PixelProgram, 2, scaleX, scaleY);
|
m_PixelProgram->ovrIndices().LensCenter,
|
||||||
drvInternal->setUniform2f(IDriver::PixelProgram, 3, scaleInX, scaleInY);
|
lensCenterX, lensCenterY);
|
||||||
drvInternal->setUniform4fv(IDriver::PixelProgram, 4, 1, m_DevicePtr->HMDInfo.DistortionK);
|
|
||||||
|
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);
|
m_Driver->drawQuad(m_BarrelQuadLeft, m_BarrelMat);
|
||||||
|
|
||||||
|
@ -602,8 +682,15 @@ bool CStereoOVR::endRenderTarget()
|
||||||
lensCenterX = x + (w - lensViewportShift * 0.5f) * 0.5f;
|
lensCenterX = x + (w - lensViewportShift * 0.5f) * 0.5f;
|
||||||
screenCenterX = x + w * 0.5f;
|
screenCenterX = x + w * 0.5f;
|
||||||
|
|
||||||
drvInternal->setUniform2f(IDriver::PixelProgram, 0, lensCenterX, lensCenterY);
|
|
||||||
drvInternal->setUniform2f(IDriver::PixelProgram, 1, screenCenterX, screenCenterY);
|
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);
|
m_Driver->drawQuad(m_BarrelQuadRight, m_BarrelMat);
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ const char *g_StereoOVR_fp40 =
|
||||||
//#var float2 cScale : : c[2] : 3 : 1
|
//#var float2 cScale : : c[2] : 3 : 1
|
||||||
//#var float2 cScaleIn : : c[3] : 4 : 1
|
//#var float2 cScaleIn : : c[3] : 4 : 1
|
||||||
//#var float4 cHmdWarpParam : : c[4] : 5 : 1
|
//#var float4 cHmdWarpParam : : c[4] : 5 : 1
|
||||||
//#var sampler2D cTex0 : TEX0 : texunit 0 : 6 : 1
|
//#var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1
|
||||||
//#var float4 oCol : $vout.COLOR : COL : 7 : 1
|
//#var float4 oCol : $vout.COLOR : COL : 7 : 1
|
||||||
//#const c[5] = 0.25 0.5 0
|
//#const c[5] = 0.25 0.5 0
|
||||||
"PARAM c[6] = { program.env[0..4],\n" // program.local->program.env!
|
"PARAM c[6] = { program.env[0..4],\n" // program.local->program.env!
|
||||||
|
@ -81,6 +81,7 @@ const char *g_StereoOVR_fp40 =
|
||||||
"ENDIF;\n"
|
"ENDIF;\n"
|
||||||
"END\n";
|
"END\n";
|
||||||
//# 24 instructions, 2 R-regs, 1 H-regs
|
//# 24 instructions, 2 R-regs, 1 H-regs
|
||||||
|
|
||||||
const char *g_StereoOVR_arbfp1 =
|
const char *g_StereoOVR_arbfp1 =
|
||||||
"!!ARBfp1.0\n"
|
"!!ARBfp1.0\n"
|
||||||
//# cgc version 3.1.0013, build date Apr 18 2012
|
//# cgc version 3.1.0013, build date Apr 18 2012
|
||||||
|
@ -102,7 +103,7 @@ const char *g_StereoOVR_arbfp1 =
|
||||||
//#var float2 cScale : : c[2] : 3 : 1
|
//#var float2 cScale : : c[2] : 3 : 1
|
||||||
//#var float2 cScaleIn : : c[3] : 4 : 1
|
//#var float2 cScaleIn : : c[3] : 4 : 1
|
||||||
//#var float4 cHmdWarpParam : : c[4] : 5 : 1
|
//#var float4 cHmdWarpParam : : c[4] : 5 : 1
|
||||||
//#var sampler2D cTex0 : TEX0 : texunit 0 : 6 : 1
|
//#var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1
|
||||||
//#var float4 oCol : $vout.COLOR : COL : 7 : 1
|
//#var float4 oCol : $vout.COLOR : COL : 7 : 1
|
||||||
//#const c[5] = 0.25 0.5 0 1
|
//#const c[5] = 0.25 0.5 0 1
|
||||||
"PARAM c[6] = { program.env[0..4],\n"
|
"PARAM c[6] = { program.env[0..4],\n"
|
||||||
|
@ -139,6 +140,7 @@ const char *g_StereoOVR_arbfp1 =
|
||||||
"CMP result.color, -R1.x, R0, c[5].z;\n"
|
"CMP result.color, -R1.x, R0, c[5].z;\n"
|
||||||
"END\n";
|
"END\n";
|
||||||
//# 28 instructions, 2 R-regs
|
//# 28 instructions, 2 R-regs
|
||||||
|
|
||||||
const char *g_StereoOVR_ps_2_0 =
|
const char *g_StereoOVR_ps_2_0 =
|
||||||
"ps_2_0\n"
|
"ps_2_0\n"
|
||||||
// cgc version 3.1.0013, build date Apr 18 2012
|
// cgc version 3.1.0013, build date Apr 18 2012
|
||||||
|
@ -160,7 +162,7 @@ const char *g_StereoOVR_ps_2_0 =
|
||||||
//var float2 cScale : : c[2] : 3 : 1
|
//var float2 cScale : : c[2] : 3 : 1
|
||||||
//var float2 cScaleIn : : c[3] : 4 : 1
|
//var float2 cScaleIn : : c[3] : 4 : 1
|
||||||
//var float4 cHmdWarpParam : : c[4] : 5 : 1
|
//var float4 cHmdWarpParam : : c[4] : 5 : 1
|
||||||
//var sampler2D cTex0 : TEX0 : texunit 0 : 6 : 1
|
//var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1
|
||||||
//var float4 oCol : $vout.COLOR : COL : 7 : 1
|
//var float4 oCol : $vout.COLOR : COL : 7 : 1
|
||||||
//const c[5] = -0.25 -0.5 0.25 0.5
|
//const c[5] = -0.25 -0.5 0.25 0.5
|
||||||
//const c[6] = 1 0
|
//const c[6] = 1 0
|
||||||
|
@ -199,4 +201,49 @@ const char *g_StereoOVR_ps_2_0 =
|
||||||
"texld r0, r3, s0\n"
|
"texld r0, r3, s0\n"
|
||||||
"cmp r0, -r1.x, r0, c6.y\n"
|
"cmp r0, -r1.x, r0, c6.y\n"
|
||||||
"mov oC0, r0\n";
|
"mov oC0, r0\n";
|
||||||
}
|
|
||||||
|
const char *g_StereoOVR_glsl330f =
|
||||||
|
"#version 330\n"
|
||||||
|
"\n"
|
||||||
|
"bool _TMP2;\n"
|
||||||
|
"bvec2 _TMP1;\n"
|
||||||
|
"vec2 _TMP3;\n"
|
||||||
|
"uniform vec2 cLensCenter;\n"
|
||||||
|
"uniform vec2 cScreenCenter;\n"
|
||||||
|
"uniform vec2 cScale;\n"
|
||||||
|
"uniform vec2 cScaleIn;\n"
|
||||||
|
"uniform vec4 cHmdWarpParam;\n"
|
||||||
|
"uniform sampler2D nlTex0;\n"
|
||||||
|
"vec2 _TMP10;\n"
|
||||||
|
"vec2 _b0011;\n"
|
||||||
|
"vec2 _a0011;\n"
|
||||||
|
"in vec4 nlTexCoord0;\n"
|
||||||
|
"out vec4 nlCol;\n"
|
||||||
|
"\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" vec2 _theta;\n"
|
||||||
|
" float _rSq;\n"
|
||||||
|
" vec2 _theta1;\n"
|
||||||
|
" vec2 _tc;\n"
|
||||||
|
"\n"
|
||||||
|
" _theta = (nlTexCoord0.xy - cLensCenter)*cScaleIn;\n"
|
||||||
|
" _rSq = _theta.x*_theta.x + _theta.y*_theta.y;\n"
|
||||||
|
" _theta1 = _theta*(cHmdWarpParam.x + cHmdWarpParam.y*_rSq + cHmdWarpParam.z*_rSq*_rSq + cHmdWarpParam.w*_rSq*_rSq*_rSq);\n"
|
||||||
|
" _tc = cLensCenter + cScale*_theta1;\n"
|
||||||
|
" _a0011 = cScreenCenter - vec2( 0.25, 0.5);\n"
|
||||||
|
" _b0011 = cScreenCenter + vec2( 0.25, 0.5);\n"
|
||||||
|
" _TMP3 = min(_b0011, _tc);\n"
|
||||||
|
" _TMP10 = max(_a0011, _TMP3);\n"
|
||||||
|
" _TMP1 = bvec2(_TMP10.x == _tc.x, _TMP10.y == _tc.y);\n"
|
||||||
|
" _TMP2 = _TMP1.x && _TMP1.y;\n"
|
||||||
|
" if (!_TMP2) {\n"
|
||||||
|
" nlCol = vec4(0, 0, 0, 0);\n"
|
||||||
|
" } else {\n"
|
||||||
|
" nlCol = texture(nlTex0, _tc);\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end of file */
|
||||||
|
|
|
@ -32,7 +32,7 @@ void pp_oculus_vr(
|
||||||
uniform float2 cScale,
|
uniform float2 cScale,
|
||||||
uniform float2 cScaleIn,
|
uniform float2 cScaleIn,
|
||||||
uniform float4 cHmdWarpParam,
|
uniform float4 cHmdWarpParam,
|
||||||
uniform sampler2D cTex0 : TEX0,
|
uniform sampler2D nlTex0 : TEX0,
|
||||||
|
|
||||||
// Output color
|
// Output color
|
||||||
out float4 oCol : COLOR)
|
out float4 oCol : COLOR)
|
||||||
|
@ -49,6 +49,6 @@ void pp_oculus_vr(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
oCol = tex2D(cTex0, tc);
|
oCol = tex2D(nlTex0, tc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue