Add glsl pixel program for stereo distortion

This commit is contained in:
kaetemi 2013-09-09 20:49:59 +02:00
parent 057eab4680
commit 0bcb0d6ffd
6 changed files with 189 additions and 45 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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 */

View file

@ -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;
source->setSourcePtr(g_StereoOVR_fp40);
m_PixelProgram->addSource(source);
}
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)) if (!drvInternal->compilePixelProgram(m_PixelProgram))
{ {
delete m_PixelProgram; m_PixelProgram.kill();
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);

View file

@ -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 */

View 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);
} }
} }