From 0bcb0d6ffd43e5d4b35309500616a9995901550f Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 9 Sep 2013 20:49:59 +0200 Subject: [PATCH] Add glsl pixel program for stereo distortion --- code/nel/include/nel/3d/gpu_program.h | 3 + code/nel/include/nel/3d/stereo_ovr.h | 4 +- code/nel/src/3d/gpu_program.cpp | 7 ++ code/nel/src/3d/stereo_ovr.cpp | 161 ++++++++++++++++++++------ code/nel/src/3d/stereo_ovr_fp.cpp | 55 ++++++++- code/snowballs2/bin/pp_oculus_vr.cg | 4 +- 6 files changed, 189 insertions(+), 45 deletions(-) diff --git a/code/nel/include/nel/3d/gpu_program.h b/code/nel/include/nel/3d/gpu_program.h index d1b234dee..0d8d30a61 100644 --- a/code/nel/include/nel/3d/gpu_program.h +++ b/code/nel/include/nel/3d/gpu_program.h @@ -266,6 +266,9 @@ public: // Build feature info, called automatically by the driver after compile succeeds void buildInfo(CSource *source); + // Override this to build additional info in a subclass + virtual void buildInfo(); + protected: /// The progam source std::vector > m_Sources; diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index c2dccf930..ba6895bf0 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -66,7 +66,7 @@ class ITexture; class CTextureUser; class CStereoOVRDevicePtr; class CStereoOVRDeviceHandle; -class CPixelProgram; +class CPixelProgramOVR; #define NL_STEREO_MAX_USER_CAMERAS 8 @@ -161,7 +161,7 @@ private: NL3D::UMaterial m_BarrelMat; NLMISC::CQuadUV m_BarrelQuadLeft; NLMISC::CQuadUV m_BarrelQuadRight; - CPixelProgram *m_PixelProgram; + NLMISC::CRefPtr m_PixelProgram; NLMISC::CVector m_EyePosition; float m_Scale; diff --git a/code/nel/src/3d/gpu_program.cpp b/code/nel/src/3d/gpu_program.cpp index 55f07e32b..ee16f1104 100644 --- a/code/nel/src/3d/gpu_program.cpp +++ b/code/nel/src/3d/gpu_program.cpp @@ -204,6 +204,13 @@ void IGPUProgram::buildInfo(CSource *source) features.MaterialFlags &= ~CGPUProgramFeatures::MaterialAmbient; } }*/ + + buildInfo(); +} + +void IGPUProgram::buildInfo() +{ + } } /* namespace NL3D */ diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index ac2350f3c..cedfe3434 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -72,6 +72,7 @@ namespace NL3D { extern const char *g_StereoOVR_fp40; extern const char *g_StereoOVR_arbfp1; extern const char *g_StereoOVR_ps_2_0; +extern const char *g_StereoOVR_glsl330f; namespace { @@ -233,43 +234,106 @@ CStereoOVR::~CStereoOVR() --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) { nlassert(!m_PixelProgram); NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); - m_PixelProgram = new CPixelProgram(); - - IGPUProgram::CSource *source = new IGPUProgram::CSource(); - source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages; - source->Profile = IGPUProgram::none; - if (drvInternal->supportPixelProgram(CPixelProgram::fp40) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) + if (drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) { - nldebug("VR: fp40"); - 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)) - { - delete m_PixelProgram; - m_PixelProgram = NULL; + m_PixelProgram = new CPixelProgramOVR(); + if (!drvInternal->compilePixelProgram(m_PixelProgram)) + { + m_PixelProgram.kill(); + } } if (m_PixelProgram) @@ -590,11 +654,27 @@ bool CStereoOVR::endRenderTarget() float scaleInX = (2 / w); float scaleInY = (2 / h); - drvInternal->setUniform2f(IDriver::PixelProgram, 0, lensCenterX, lensCenterY); - drvInternal->setUniform2f(IDriver::PixelProgram, 1, screenCenterX, screenCenterY); - drvInternal->setUniform2f(IDriver::PixelProgram, 2, scaleX, scaleY); - drvInternal->setUniform2f(IDriver::PixelProgram, 3, scaleInX, scaleInY); - drvInternal->setUniform4fv(IDriver::PixelProgram, 4, 1, m_DevicePtr->HMDInfo.DistortionK); + + 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); @@ -602,8 +682,15 @@ bool CStereoOVR::endRenderTarget() lensCenterX = x + (w - lensViewportShift * 0.5f) * 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); diff --git a/code/nel/src/3d/stereo_ovr_fp.cpp b/code/nel/src/3d/stereo_ovr_fp.cpp index b81ee8421..940be0bfe 100644 --- a/code/nel/src/3d/stereo_ovr_fp.cpp +++ b/code/nel/src/3d/stereo_ovr_fp.cpp @@ -44,7 +44,7 @@ const char *g_StereoOVR_fp40 = //#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 sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 //#var float4 oCol : $vout.COLOR : COL : 7 : 1 //#const c[5] = 0.25 0.5 0 "PARAM c[6] = { program.env[0..4],\n" // program.local->program.env! @@ -81,6 +81,7 @@ const char *g_StereoOVR_fp40 = "ENDIF;\n" "END\n"; //# 24 instructions, 2 R-regs, 1 H-regs + const char *g_StereoOVR_arbfp1 = "!!ARBfp1.0\n" //# 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 cScaleIn : : c[3] : 4 : 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 //#const c[5] = 0.25 0.5 0 1 "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" "END\n"; //# 28 instructions, 2 R-regs + const char *g_StereoOVR_ps_2_0 = "ps_2_0\n" // 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 cScaleIn : : c[3] : 4 : 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 //const c[5] = -0.25 -0.5 0.25 0.5 //const c[6] = 1 0 @@ -199,4 +201,49 @@ const char *g_StereoOVR_ps_2_0 = "texld r0, r3, s0\n" "cmp r0, -r1.x, r0, c6.y\n" "mov oC0, r0\n"; -} \ No newline at end of file + +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 */ diff --git a/code/snowballs2/bin/pp_oculus_vr.cg b/code/snowballs2/bin/pp_oculus_vr.cg index 1d84e0d54..c7de282ef 100644 --- a/code/snowballs2/bin/pp_oculus_vr.cg +++ b/code/snowballs2/bin/pp_oculus_vr.cg @@ -32,7 +32,7 @@ void pp_oculus_vr( uniform float2 cScale, uniform float2 cScaleIn, uniform float4 cHmdWarpParam, - uniform sampler2D cTex0 : TEX0, + uniform sampler2D nlTex0 : TEX0, // Output color out float4 oCol : COLOR) @@ -49,6 +49,6 @@ void pp_oculus_vr( } else { - oCol = tex2D(cTex0, tc); + oCol = tex2D(nlTex0, tc); } }