diff options
Diffstat (limited to 'LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp')
-rw-r--r-- | LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp | 868 |
1 files changed, 323 insertions, 545 deletions
diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp index a953d73..21b6509 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp @@ -15,422 +15,12 @@ otherwise accompanies this software in either electronic or hard copy form. #include "CAPI_GL_DistortionRenderer.h" +#include "CAPI_GL_DistortionShaders.h" + #include "../../OVR_CAPI_GL.h" namespace OVR { namespace CAPI { namespace GL { - -static const char SimpleQuad_vs[] = - "uniform vec2 PositionOffset;\n" - "uniform vec2 Scale;\n" - - "attribute vec3 Position;\n" - - "void main()\n" - "{\n" - " gl_Position = vec4(Position.xy * Scale + PositionOffset, 0.5, 1.0);\n" - "}\n"; - -const OVR::CAPI::GL::ShaderBase::Uniform SimpleQuad_vs_refl[] = -{ - { "PositionOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "Scale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, -}; - -static const char SimpleQuad_fs[] = - "uniform vec4 Color;\n" - - "void main()\n" - "{\n" - " gl_FragColor = Color;\n" - "}\n"; - -const OVR::CAPI::GL::ShaderBase::Uniform SimpleQuad_fs_refl[] = -{ - { "Color", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 16 }, -}; - - -static const char Distortion_vs[] = - "uniform vec2 EyeToSourceUVScale;\n" - "uniform vec2 EyeToSourceUVOffset;\n" - - "attribute vec2 Position;\n" - "attribute vec4 Color;\n" - "attribute vec2 TexCoord0;\n" - - "varying vec4 oColor;\n" - "varying vec2 oTexCoord0;\n" - - "void main()\n" - "{\n" - " gl_Position.x = Position.x;\n" - " gl_Position.y = Position.y;\n" - " gl_Position.z = 0.5;\n" - " gl_Position.w = 1.0;\n" - // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). - // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) - " oTexCoord0 = TexCoord0 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " oTexCoord0.y = 1-oTexCoord0.y;\n" - " oColor = Color;\n" // Used for vignette fade. - "}\n"; - -const OVR::CAPI::GL::ShaderBase::Uniform Distortion_vs_refl[] = -{ - { "EyeToSourceUVScale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, -}; - -static const char Distortion_fs[] = - "uniform sampler2D Texture0;\n" - - "varying vec4 oColor;\n" - "varying vec2 oTexCoord0;\n" - - "void main()\n" - "{\n" - " gl_FragColor = texture2D(Texture0, oTexCoord0);\n" - " gl_FragColor.a = 1.0;\n" - "}\n"; - - -static const char DistortionTimewarp_vs[] = - "uniform vec2 EyeToSourceUVScale;\n" - "uniform vec2 EyeToSourceUVOffset;\n" - "uniform mat4 EyeRotationStart;\n" - "uniform mat4 EyeRotationEnd;\n" - - "attribute vec2 Position;\n" - "attribute vec4 Color;\n" - "attribute vec2 TexCoord0;\n" - - "varying vec4 oColor;\n" - "varying vec2 oTexCoord0;\n" - - "void main()\n" - "{\n" - " gl_Position.x = Position.x;\n" - " gl_Position.y = Position.y;\n" - " gl_Position.z = 0.0;\n" - " gl_Position.w = 1.0;\n" - - // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). - // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD. - " vec3 TanEyeAngle = vec3 ( TexCoord0.x, TexCoord0.y, 1.0 );\n" - - // Accurate time warp lerp vs. faster -#if 1 - // Apply the two 3x3 timewarp rotations to these vectors. - " vec3 TransformedStart = (EyeRotationStart * vec4(TanEyeAngle, 0)).xyz;\n" - " vec3 TransformedEnd = (EyeRotationEnd * vec4(TanEyeAngle, 0)).xyz;\n" - // And blend between them. - " vec3 Transformed = mix ( TransformedStart, TransformedEnd, Color.a );\n" -#else - " mat3 EyeRotation = mix ( EyeRotationStart, EyeRotationEnd, Color.a );\n" - " vec3 Transformed = EyeRotation * TanEyeAngle;\n" -#endif - - // Project them back onto the Z=1 plane of the rendered images. - " float RecipZ = 1.0 / Transformed.z;\n" - " vec2 Flattened = vec2 ( Transformed.x * RecipZ, Transformed.y * RecipZ );\n" - - // These are now still in TanEyeAngle space. - // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) - " vec2 SrcCoord = Flattened * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " oTexCoord0 = SrcCoord;\n" - " oTexCoord0.y = 1-oTexCoord0.y;\n" - " oColor = Color.r;\n" // Used for vignette fade. - "}\n"; - -const OVR::CAPI::GL::ShaderBase::Uniform DistortionTimewarp_vs_refl[] = -{ - { "EyeToSourceUVScale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, -}; - - -static const char DistortionPositionalTimewarp_vs[] = - "#version 150\n" - - "uniform sampler2D Texture0;\n" - "uniform vec2 EyeToSourceUVScale;\n" - "uniform vec2 EyeToSourceUVOffset;\n" - "uniform vec2 DepthProjector;\n" - "uniform vec2 DepthDimSize;\n" - "uniform mat4 EyeRotationStart;\n" - "uniform mat4 EyeRotationEnd;\n" - - "in vec2 Position;\n" - "in vec4 Color;\n" - "in vec2 TexCoord0;\n" - "in vec2 TexCoord1;\n" - "in vec2 TexCoord2;\n" - - "out vec4 oColor;\n" - "out vec2 oTexCoord0;\n" - - "vec4 PositionFromDepth(vec2 inTexCoord)\n" - "{\n" - " vec2 eyeToSourceTexCoord = inTexCoord * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " eyeToSourceTexCoord.y = 1 - eyeToSourceTexCoord.y;\n" - " float depth = texelFetch(Texture0, ivec2(eyeToSourceTexCoord * DepthDimSize), 0).x;\n" - " float linearDepth = DepthProjector.y / (depth - DepthProjector.x);\n" - " vec4 retVal = vec4(inTexCoord, 1, 1);\n" - " retVal.xyz *= linearDepth;\n" - " return retVal;\n" - "}\n" - - "vec2 TimewarpTexCoordToWarpedPos(vec2 inTexCoord, float a)\n" - "{\n" - // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). - // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD. - // Apply the 4x4 timewarp rotation to these vectors. - " vec4 inputPos = PositionFromDepth(inTexCoord);\n" - " vec3 transformed = mix ( EyeRotationStart * inputPos, EyeRotationEnd * inputPos, a ).xyz;\n" - // Project them back onto the Z=1 plane of the rendered images. - " vec2 flattened = transformed.xy / transformed.z;\n" - // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye) - " vec2 noDepthUV = flattened * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - //" float depth = texture2DLod(Texture0, noDepthUV, 0).r;\n" - " return noDepthUV.xy;\n" - "}\n" - - "void main()\n" - "{\n" - " gl_Position.x = Position.x;\n" - " gl_Position.y = Position.y;\n" - " gl_Position.z = 0.0;\n" - " gl_Position.w = 1.0;\n" - - // warped positions are a bit more involved, hence a separate function - " oTexCoord0 = TimewarpTexCoordToWarpedPos(TexCoord0, Color.a);\n" - " oTexCoord0.y = 1-oTexCoord0.y;\n" - - " oColor = vec4(Color.r); // Used for vignette fade.\n" - "}\n"; - -const OVR::CAPI::GL::ShaderBase::Uniform DistortionPositionalTimewarp_vs_refl[] = -{ - { "EyeToSourceUVScale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, -}; - - -static const char DistortionChroma_vs[] = - "uniform vec2 EyeToSourceUVScale;\n" - "uniform vec2 EyeToSourceUVOffset;\n" - - "attribute vec2 Position;\n" - "attribute vec4 Color;\n" - "attribute vec2 TexCoord0;\n" - "attribute vec2 TexCoord1;\n" - "attribute vec2 TexCoord2;\n" - - "varying vec4 oColor;\n" - "varying vec2 oTexCoord0;\n" - "varying vec2 oTexCoord1;\n" - "varying vec2 oTexCoord2;\n" - - "void main()\n" - "{\n" - " gl_Position.x = Position.x;\n" - " gl_Position.y = Position.y;\n" - " gl_Position.z = 0.5;\n" - " gl_Position.w = 1.0;\n" - - // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). - // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) - " oTexCoord0 = TexCoord0 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " oTexCoord0.y = 1-oTexCoord0.y;\n" - " oTexCoord1 = TexCoord1 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " oTexCoord1.y = 1-oTexCoord1.y;\n" - " oTexCoord2 = TexCoord2 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " oTexCoord2.y = 1-oTexCoord2.y;\n" - - " oColor = Color;\n" // Used for vignette fade. - "}\n"; - -const OVR::CAPI::GL::ShaderBase::Uniform DistortionChroma_vs_refl[] = -{ - { "EyeToSourceUVScale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, -}; - -static const char DistortionChroma_fs[] = - "uniform sampler2D Texture0;\n" - - "varying vec4 oColor;\n" - "varying vec2 oTexCoord0;\n" - "varying vec2 oTexCoord1;\n" - "varying vec2 oTexCoord2;\n" - - "void main()\n" - "{\n" - " float ResultR = texture2D(Texture0, oTexCoord0).r;\n" - " float ResultG = texture2D(Texture0, oTexCoord1).g;\n" - " float ResultB = texture2D(Texture0, oTexCoord2).b;\n" - - " gl_FragColor = vec4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0);\n" - "}\n"; - - -static const char DistortionTimewarpChroma_vs[] = - "uniform vec2 EyeToSourceUVScale;\n" - "uniform vec2 EyeToSourceUVOffset;\n" - "uniform mat4 EyeRotationStart;\n" - "uniform mat4 EyeRotationEnd;\n" - - "attribute vec2 Position;\n" - "attribute vec4 Color;\n" - "attribute vec2 TexCoord0;\n" - "attribute vec2 TexCoord1;\n" - "attribute vec2 TexCoord2;\n" - - "varying vec4 oColor;\n" - "varying vec2 oTexCoord0;\n" - "varying vec2 oTexCoord1;\n" - "varying vec2 oTexCoord2;\n" - - "void main()\n" - "{\n" - " gl_Position.x = Position.x;\n" - " gl_Position.y = Position.y;\n" - " gl_Position.z = 0.0;\n" - " gl_Position.w = 1.0;\n" - - // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). - // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD. - " vec3 TanEyeAngleR = vec3 ( TexCoord0.x, TexCoord0.y, 1.0 );\n" - " vec3 TanEyeAngleG = vec3 ( TexCoord1.x, TexCoord1.y, 1.0 );\n" - " vec3 TanEyeAngleB = vec3 ( TexCoord2.x, TexCoord2.y, 1.0 );\n" - - // Accurate time warp lerp vs. faster -#if 1 - // Apply the two 3x3 timewarp rotations to these vectors. - " vec3 TransformedRStart = (EyeRotationStart * vec4(TanEyeAngleR, 0)).xyz;\n" - " vec3 TransformedGStart = (EyeRotationStart * vec4(TanEyeAngleG, 0)).xyz;\n" - " vec3 TransformedBStart = (EyeRotationStart * vec4(TanEyeAngleB, 0)).xyz;\n" - " vec3 TransformedREnd = (EyeRotationEnd * vec4(TanEyeAngleR, 0)).xyz;\n" - " vec3 TransformedGEnd = (EyeRotationEnd * vec4(TanEyeAngleG, 0)).xyz;\n" - " vec3 TransformedBEnd = (EyeRotationEnd * vec4(TanEyeAngleB, 0)).xyz;\n" - - // And blend between them. - " vec3 TransformedR = mix ( TransformedRStart, TransformedREnd, Color.a );\n" - " vec3 TransformedG = mix ( TransformedGStart, TransformedGEnd, Color.a );\n" - " vec3 TransformedB = mix ( TransformedBStart, TransformedBEnd, Color.a );\n" -#else - " mat3 EyeRotation = mix ( EyeRotationStart, EyeRotationEnd, Color.a );\n" - " vec3 TransformedR = EyeRotation * TanEyeAngleR;\n" - " vec3 TransformedG = EyeRotation * TanEyeAngleG;\n" - " vec3 TransformedB = EyeRotation * TanEyeAngleB;\n" -#endif - - // Project them back onto the Z=1 plane of the rendered images. - " float RecipZR = 1.0 / TransformedR.z;\n" - " float RecipZG = 1.0 / TransformedG.z;\n" - " float RecipZB = 1.0 / TransformedB.z;\n" - " vec2 FlattenedR = vec2 ( TransformedR.x * RecipZR, TransformedR.y * RecipZR );\n" - " vec2 FlattenedG = vec2 ( TransformedG.x * RecipZG, TransformedG.y * RecipZG );\n" - " vec2 FlattenedB = vec2 ( TransformedB.x * RecipZB, TransformedB.y * RecipZB );\n" - - // These are now still in TanEyeAngle space. - // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) - " vec2 SrcCoordR = FlattenedR * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " vec2 SrcCoordG = FlattenedG * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " vec2 SrcCoordB = FlattenedB * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - - " oTexCoord0 = SrcCoordR;\n" - " oTexCoord0.y = 1-oTexCoord0.y;\n" - " oTexCoord1 = SrcCoordG;\n" - " oTexCoord1.y = 1-oTexCoord1.y;\n" - " oTexCoord2 = SrcCoordB;\n" - " oTexCoord2.y = 1-oTexCoord2.y;\n" - - " oColor = Color.r;\n" // Used for vignette fade. - "}\n"; - -const OVR::CAPI::GL::ShaderBase::Uniform DistortionTimewarpChroma_vs_refl[] = -{ - { "EyeToSourceUVScale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, - { "EyeRotationStart", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 16, 64 }, - { "EyeRotationEnd", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 80, 64 }, -}; - - -static const char DistortionPositionalTimewarpChroma_vs[] = - "#version 150\n" - "uniform sampler2D Texture0;\n" - "uniform sampler2D Texture1;\n" - "uniform vec2 EyeToSourceUVScale;\n" - "uniform vec2 EyeToSourceUVOffset;\n" - "uniform vec2 DepthProjector;\n" - "uniform vec2 DepthDimSize;\n" - "uniform mat4 EyeRotationStart;\n" - "uniform mat4 EyeRotationEnd;\n" - - "in vec2 Position;\n" - "in vec4 Color;\n" - "in vec2 TexCoord0;\n" - "in vec2 TexCoord1;\n" - "in vec2 TexCoord2;\n" - - "out vec4 oColor;\n" - "out vec2 oTexCoord0;\n" - "out vec2 oTexCoord1;\n" - "out vec2 oTexCoord2;\n" - - "vec4 PositionFromDepth(vec2 inTexCoord)\n" - "{\n" - " vec2 eyeToSourceTexCoord = inTexCoord * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " eyeToSourceTexCoord.y = 1 - eyeToSourceTexCoord.y;\n" - " float depth = texelFetch(Texture1, ivec2(eyeToSourceTexCoord * DepthDimSize), 0).x;\n" - " float linearDepth = DepthProjector.y / (depth - DepthProjector.x);\n" - " vec4 retVal = vec4(inTexCoord, 1, 1);\n" - " retVal.xyz *= linearDepth;\n" - " return retVal;\n" - "}\n" - - "vec2 TimewarpTexCoordToWarpedPos(vec2 inTexCoord, float a)\n" - "{\n" - // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). - // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD. - // Apply the 4x4 timewarp rotation to these vectors. - " vec4 inputPos = PositionFromDepth(inTexCoord);\n" - " vec3 transformed = mix ( EyeRotationStart * inputPos, EyeRotationEnd * inputPos, a ).xyz;\n" - // Project them back onto the Z=1 plane of the rendered images. - " vec2 flattened = transformed.xy / transformed.z;\n" - // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye) - " vec2 noDepthUV = flattened * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - //" float depth = texture2DLod(Texture1, noDepthUV, 0).r;\n" - " return noDepthUV.xy;\n" - "}\n" - - "void main()\n" - "{\n" - " gl_Position.x = Position.x;\n" - " gl_Position.y = Position.y;\n" - " gl_Position.z = 0.0;\n" - " gl_Position.w = 1.0;\n" - - // warped positions are a bit more involved, hence a separate function - " oTexCoord0 = TimewarpTexCoordToWarpedPos(TexCoord0, Color.a);\n" - " oTexCoord0.y = 1-oTexCoord0.y;\n" - " oTexCoord1 = TimewarpTexCoordToWarpedPos(TexCoord1, Color.a);\n" - " oTexCoord1.y = 1-oTexCoord1.y;\n" - " oTexCoord2 = TimewarpTexCoordToWarpedPos(TexCoord2, Color.a);\n" - " oTexCoord2.y = 1-oTexCoord2.y;\n" - - " oColor = vec4(Color.r); // Used for vignette fade.\n" - "}\n"; - -const OVR::CAPI::GL::ShaderBase::Uniform DistortionPositionalTimewarpChroma_vs_refl[] = -{ - { "EyeToSourceUVScale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, -}; - - // Distortion pixel shader lookup. // Bit 0: Chroma Correction // Bit 1: Timewarp @@ -461,8 +51,6 @@ static ShaderInfo DistortionVertexShaderLookup[DistortionVertexShaderCount] = SI_REFL__(DistortionChroma_vs), SI_REFL__(DistortionTimewarp_vs), SI_REFL__(DistortionTimewarpChroma_vs) - //SI_REFL__(DistortionPositionalTimewarp_vs), - //SI_REFL__(DistortionPositionalTimewarpChroma_vs) }; static ShaderInfo DistortionPixelShaderLookup[DistortionPixelShaderCount] = @@ -473,8 +61,8 @@ static ShaderInfo DistortionPixelShaderLookup[DistortionPixelShaderCount] = void DistortionShaderBitIndexCheck() { - OVR_COMPILER_ASSERT(ovrDistortion_Chromatic == 1); - OVR_COMPILER_ASSERT(ovrDistortion_TimeWarp == 2); + OVR_COMPILER_ASSERT(ovrDistortionCap_Chromatic == 1); + OVR_COMPILER_ASSERT(ovrDistortionCap_TimeWarp == 2); } @@ -504,7 +92,10 @@ struct LatencyVertex DistortionRenderer::DistortionRenderer(ovrHmd hmd, FrameTimeManager& timeManager, const HMDRenderState& renderState) : CAPI::DistortionRenderer(ovrRenderAPI_OpenGL, hmd, timeManager, renderState) + , LatencyVAO(0) { + DistortionMeshVAOs[0] = 0; + DistortionMeshVAOs[1] = 0; } DistortionRenderer::~DistortionRenderer() @@ -517,17 +108,17 @@ CAPI::DistortionRenderer* DistortionRenderer::Create(ovrHmd hmd, FrameTimeManager& timeManager, const HMDRenderState& renderState) { +#if !defined(OVR_OS_MAC) InitGLExtensions(); - +#endif return new DistortionRenderer(hmd, timeManager, renderState); } bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, - unsigned hmdCaps, unsigned distortionCaps) + unsigned distortionCaps) { - // TBD: Decide if hmdCaps are needed here or are a part of RenderState - OVR_UNUSED(hmdCaps); + GfxState = *new GraphicsState(); const ovrGLConfig* config = (const ovrGLConfig*)apiConfig; @@ -539,15 +130,20 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, memset(&RParams, 0, sizeof(RParams)); return true; } - - if (!config->OGL.WglContext || !config->OGL.GdiDc) - return false; - RParams.GdiDc = config->OGL.GdiDc; RParams.Multisample = config->OGL.Header.Multisample; RParams.RTSize = config->OGL.Header.RTSize; - RParams.WglContext = config->OGL.WglContext; - RParams.Window = config->OGL.Window; +#if defined(OVR_OS_WIN32) + RParams.Window = (config->OGL.Window) ? config->OGL.Window : GetActiveWindow(); +#elif defined(OVR_OS_LINUX) + RParams.Disp = (config->OGL.Disp) ? config->OGL.Disp : XOpenDisplay(NULL); + RParams.Win = config->OGL.Win; + if (!RParams.Win) + { + int unused; + XGetInputFocus(RParams.Disp, &RParams.Win, &unused); + } +#endif DistortionCaps = distortionCaps; @@ -564,37 +160,36 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, void DistortionRenderer::SubmitEye(int eyeId, ovrTexture* eyeTexture) { - //Doesn't do a lot in here?? + // Doesn't do a lot in here?? const ovrGLTexture* tex = (const ovrGLTexture*)eyeTexture; - //Write in values + // Write in values eachEye[eyeId].texture = tex->OGL.TexId; if (tex) { - //Its only at this point we discover what the viewport of the texture is. - //because presumably we allow users to realtime adjust the resolution. - //Which begs the question - why did we ask them what viewport they were - //using before, which gave them a set of UV offsets. In fact, our - //asking for eye mesh must be entirely independed of these viewports, - //presumably only to get the parameters. - - ovrEyeDesc ed = RState.EyeRenderDesc[eyeId].Desc; - ed.TextureSize = tex->OGL.Header.TextureSize; - ed.RenderViewport = tex->OGL.Header.RenderViewport; - - ovrHmd_GetRenderScaleAndOffset(HMD, ed, DistortionCaps, eachEye[eyeId].UVScaleOffset); - + // Its only at this point we discover what the viewport of the texture is. + // because presumably we allow users to realtime adjust the resolution. + eachEye[eyeId].TextureSize = tex->OGL.Header.TextureSize; + eachEye[eyeId].RenderViewport = tex->OGL.Header.RenderViewport; + + const ovrEyeRenderDesc& erd = RState.EyeRenderDesc[eyeId]; + + ovrHmd_GetRenderScaleAndOffset( erd.Fov, + eachEye[eyeId].TextureSize, eachEye[eyeId].RenderViewport, + eachEye[eyeId].UVScaleOffset ); + pEyeTextures[eyeId]->UpdatePlaceholderTexture(tex->OGL.TexId, tex->OGL.Header.TextureSize); } } -void DistortionRenderer::EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor) -{ +void DistortionRenderer::EndFrame(bool swapBuffers, + unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor) +{ if (!TimeManager.NeedDistortionTimeMeasurement()) { - if (RState.DistortionCaps & ovrDistortion_TimeWarp) + if (RState.DistortionCaps & ovrDistortionCap_TimeWarp) { // Wait for timewarp distortion if it is time and Gpu idle FlushGpuAndWaitTillTime(TimeManager.GetFrameTiming().TimewarpPointTime); @@ -626,18 +221,38 @@ void DistortionRenderer::EndFrame(bool swapBuffers, unsigned char* latencyTester if (swapBuffers) { - bool useVsync = ((RState.HMDCaps & ovrHmdCap_NoVSync) == 0); - BOOL success; + bool useVsync = ((RState.EnabledHmdCaps & ovrHmdCap_NoVSync) == 0); int swapInterval = (useVsync) ? 1 : 0; +#if defined(OVR_OS_WIN32) if (wglGetSwapIntervalEXT() != swapInterval) - wglSwapIntervalEXT(swapInterval); + wglSwapIntervalEXT(swapInterval); - success = SwapBuffers(RParams.GdiDc); + HDC dc = GetDC(RParams.Window); + BOOL success = SwapBuffers(dc); + ReleaseDC(RParams.Window, dc); OVR_ASSERT(success); + OVR_UNUSED(success); +#elif defined(OVR_OS_MAC) + CGLContextObj context = CGLGetCurrentContext(); + GLint currentSwapInterval = 0; + CGLGetParameter(context, kCGLCPSwapInterval, ¤tSwapInterval); + if (currentSwapInterval != swapInterval) + CGLSetParameter(context, kCGLCPSwapInterval, &swapInterval); + + CGLFlushDrawable(context); +#elif defined(OVR_OS_LINUX) + static const char* extensions = glXQueryExtensionsString(RParams.Disp, 0); + static bool supportsVSync = (extensions != NULL && strstr(extensions, "GLX_EXT_swap_control")); + if (supportsVSync) + { + GLuint currentSwapInterval = 0; + glXQueryDrawable(RParams.Disp, RParams.Win, GLX_SWAP_INTERVAL_EXT, ¤tSwapInterval); + if (currentSwapInterval != swapInterval) + glXSwapIntervalEXT(RParams.Disp, RParams.Win, swapInterval); + } - // Force GPU to flush the scene, resulting in the lowest possible latency. - // It's critical that this flush is *after* present. - WaitUntilGpuIdle(); + glXSwapBuffers(RParams.Disp, RParams.Win); +#endif } } @@ -670,6 +285,109 @@ double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime) // How long we waited return newTime - initialTime; } + + +DistortionRenderer::GraphicsState::GraphicsState() +{ + const char* glVersionString = (const char*)glGetString(GL_VERSION); + OVR_DEBUG_LOG(("GL_VERSION STRING: %s", (const char*)glVersionString)); + char prefix[64]; + bool foundVersion = false; + + for (int i = 10; i < 30; ++i) + { + int major = i / 10; + int minor = i % 10; + OVR_sprintf(prefix, 64, "%d.%d", major, minor); + if (strstr(glVersionString, prefix) == glVersionString) + { + GlMajorVersion = major; + GlMinorVersion = minor; + foundVersion = true; + break; + } + } + + if (!foundVersion) + { + glGetIntegerv(GL_MAJOR_VERSION, &GlMajorVersion); + glGetIntegerv(GL_MAJOR_VERSION, &GlMinorVersion); + } + + OVR_ASSERT(GlMajorVersion >= 2); + + if (GlMajorVersion >= 3) + { + SupportsVao = true; + } + else + { + const char* extensions = (const char*)glGetString(GL_EXTENSIONS); + SupportsVao = (strstr("GL_ARB_vertex_array_object", extensions) != NULL); + } +} + + +void DistortionRenderer::GraphicsState::ApplyBool(GLenum Name, GLint Value) +{ + if (Value != 0) + glEnable(Name); + else + glDisable(Name); +} + + +void DistortionRenderer::GraphicsState::Save() +{ + glGetIntegerv(GL_VIEWPORT, Viewport); + glGetFloatv(GL_COLOR_CLEAR_VALUE, ClearColor); + glGetIntegerv(GL_DEPTH_TEST, &DepthTest); + glGetIntegerv(GL_CULL_FACE, &CullFace); + glGetIntegerv(GL_CURRENT_PROGRAM, &Program); + glGetIntegerv(GL_ACTIVE_TEXTURE, &ActiveTexture); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &TextureBinding); + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &VertexArray); + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &FrameBufferBinding); + glGetIntegerv(GL_BLEND, &Blend); + glGetIntegerv(GL_COLOR_WRITEMASK, ColorWritemask); + glGetIntegerv(GL_DITHER, &Dither); + glGetIntegerv(GL_RASTERIZER_DISCARD, &RasterizerDiscard); + if (GlMajorVersion >= 3 && GlMajorVersion >= 2) + glGetIntegerv(GL_SAMPLE_MASK, &SampleMask); + glGetIntegerv(GL_SCISSOR_TEST, &ScissorTest); + + IsValid = true; +} + + +void DistortionRenderer::GraphicsState::Restore() +{ + // Don't allow restore-before-save. + if (!IsValid) + return; + + glViewport(Viewport[0], Viewport[1], Viewport[2], Viewport[3]); + glClearColor(ClearColor[0], ClearColor[1], ClearColor[2], ClearColor[3]); + + ApplyBool(GL_DEPTH_TEST, DepthTest); + ApplyBool(GL_CULL_FACE, CullFace); + + glUseProgram(Program); + glActiveTexture(ActiveTexture); + glBindTexture(GL_TEXTURE_2D, TextureBinding); + if (SupportsVao) + glBindVertexArray(VertexArray); + glBindFramebuffer(GL_FRAMEBUFFER, FrameBufferBinding); + + ApplyBool(GL_BLEND, Blend); + + glColorMask((GLboolean)ColorWritemask[0], (GLboolean)ColorWritemask[1], (GLboolean)ColorWritemask[2], (GLboolean)ColorWritemask[3]); + ApplyBool(GL_DITHER, Dither); + ApplyBool(GL_RASTERIZER_DISCARD, RasterizerDiscard); + if (GlMajorVersion >= 3 && GlMajorVersion >= 2) + ApplyBool(GL_SAMPLE_MASK, SampleMask); + ApplyBool(GL_SCISSOR_TEST, ScissorTest); +} void DistortionRenderer::initBuffersAndShaders() @@ -681,9 +399,11 @@ void DistortionRenderer::initBuffersAndShaders() // double startT = ovr_GetTimeInSeconds(); - if (!ovrHmd_CreateDistortionMesh( HMD, RState.EyeRenderDesc[eyeNum].Desc, + if (!ovrHmd_CreateDistortionMesh( HMD, + RState.EyeRenderDesc[eyeNum].Eye, + RState.EyeRenderDesc[eyeNum].Fov, RState.DistortionCaps, - UVScaleOffset[eyeNum], &meshData) ) + &meshData) ) { OVR_ASSERT(false); continue; @@ -711,9 +431,9 @@ void DistortionRenderer::initBuffersAndShaders() } DistortionMeshVBs[eyeNum] = *new Buffer(&RParams); - DistortionMeshVBs[eyeNum]->Data ( Buffer_Vertex, pVBVerts, sizeof(DistortionVertex) * meshData.VertexCount ); + DistortionMeshVBs[eyeNum]->Data ( Buffer_Vertex | Buffer_ReadOnly, pVBVerts, sizeof(DistortionVertex) * meshData.VertexCount ); DistortionMeshIBs[eyeNum] = *new Buffer(&RParams); - DistortionMeshIBs[eyeNum]->Data ( Buffer_Index, meshData.pIndexData, ( sizeof(INT16) * meshData.IndexCount ) ); + DistortionMeshIBs[eyeNum]->Data ( Buffer_Index | Buffer_ReadOnly, meshData.pIndexData, ( sizeof(SInt16) * meshData.IndexCount ) ); OVR_FREE ( pVBVerts ); ovrHmd_DestroyDistortionMesh( &meshData ); @@ -723,8 +443,22 @@ void DistortionRenderer::initBuffersAndShaders() } void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* rightEyeTexture) -{ +{ + GraphicsState* glState = (GraphicsState*)GfxState.GetPtr(); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); setViewport( Recti(0,0, RParams.RTSize.w, RParams.RTSize.h) ); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + glDisable(GL_DITHER); + glDisable(GL_RASTERIZER_DISCARD); + if (glState->GlMajorVersion >= 3 && glState->GlMajorVersion >= 2) + glDisable(GL_SAMPLE_MASK); + glDisable(GL_SCISSOR_TEST); glClearColor( RState.ClearColor[0], @@ -732,19 +466,17 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ RState.ClearColor[2], RState.ClearColor[3] ); - glClearDepth(0); - - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + glClear(GL_COLOR_BUFFER_BIT); for (int eyeNum = 0; eyeNum < 2; eyeNum++) { ShaderFill distortionShaderFill(DistortionShader); distortionShaderFill.SetTexture(0, eyeNum == 0 ? leftEyeTexture : rightEyeTexture); - DistortionShader->SetUniform2f("EyeToSourceUVScale", UVScaleOffset[eyeNum][0].x, UVScaleOffset[eyeNum][0].y); - DistortionShader->SetUniform2f("EyeToSourceUVOffset", UVScaleOffset[eyeNum][1].x, UVScaleOffset[eyeNum][1].y); + DistortionShader->SetUniform2f("EyeToSourceUVScale", eachEye[eyeNum].UVScaleOffset[0].x, eachEye[eyeNum].UVScaleOffset[0].y); + DistortionShader->SetUniform2f("EyeToSourceUVOffset", eachEye[eyeNum].UVScaleOffset[1].x, eachEye[eyeNum].UVScaleOffset[1].y); - if (DistortionCaps & ovrDistortion_TimeWarp) + if (DistortionCaps & ovrDistortionCap_TimeWarp) { ovrMatrix4f timeWarpMatrices[2]; ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eyeNum, @@ -755,12 +487,12 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ DistortionShader->SetUniform4x4f("EyeRotationEnd", Matrix4f(timeWarpMatrices[1]).Transposed()); renderPrimitives(&distortionShaderFill, DistortionMeshVBs[eyeNum], DistortionMeshIBs[eyeNum], - NULL, 0, (int)DistortionMeshVBs[eyeNum]->GetSize(), Prim_Triangles, true); + 0, (int)DistortionMeshIBs[eyeNum]->GetSize()/2, Prim_Triangles, &DistortionMeshVAOs[eyeNum], true); } else { renderPrimitives(&distortionShaderFill, DistortionMeshVBs[eyeNum], DistortionMeshIBs[eyeNum], - NULL, 0, (int)DistortionMeshVBs[eyeNum]->GetSize(), Prim_Triangles, true); + 0, (int)DistortionMeshIBs[eyeNum]->GetSize()/2, Prim_Triangles, &DistortionMeshVAOs[eyeNum], true); } } } @@ -818,7 +550,7 @@ void DistortionRenderer::renderLatencyQuad(unsigned char* latencyTesterDrawColor for(int eyeNum = 0; eyeNum < 2; eyeNum++) { SimpleQuadShader->SetUniform2f("PositionOffset", eyeNum == 0 ? -0.4f : 0.4f, 0.0f); - renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, NULL, 0, numQuadVerts, Prim_TriangleStrip, false); + renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, 0, numQuadVerts, Prim_TriangleStrip, &LatencyVAO, false); } } @@ -843,16 +575,16 @@ void DistortionRenderer::renderLatencyPixel(unsigned char* latencyTesterPixelCol Vector2f scale(2.0f / RParams.RTSize.w, 2.0f / RParams.RTSize.h); SimpleQuadShader->SetUniform2f("Scale", scale.x, scale.y); SimpleQuadShader->SetUniform2f("PositionOffset", 1.0f, 1.0f); - renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, NULL, 0, numQuadVerts, Prim_TriangleStrip, false); + renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, 0, numQuadVerts, Prim_TriangleStrip, &LatencyVAO, false); } void DistortionRenderer::renderPrimitives( const ShaderFill* fill, Buffer* vertices, Buffer* indices, - Matrix4f* viewMatrix, int offset, int count, - PrimitiveType rprim, bool useDistortionVertex) + int offset, int count, + PrimitiveType rprim, GLuint* vao, bool isDistortionMesh) { - ShaderSet* shaders = (ShaderSet*) ((ShaderFill*)fill)->GetShaders(); + GraphicsState* glState = (GraphicsState*)GfxState.GetPtr(); GLenum prim; switch (rprim) @@ -867,128 +599,173 @@ void DistortionRenderer::renderPrimitives( prim = GL_TRIANGLE_STRIP; break; default: - assert(0); + OVR_ASSERT(false); return; } fill->Set(); - if (shaders->ProjLoc >= 0) - glUniformMatrix4fv(shaders->ProjLoc, 1, 0, &StdUniforms.Proj.M[0][0]); - if (shaders->ViewLoc >= 0 && viewMatrix != NULL) - glUniformMatrix4fv(shaders->ViewLoc, 1, 0, &viewMatrix->Transposed().M[0][0]); - - //if (shaders->UsesLighting && Lighting->Version != shaders->LightingVer) - //{ - // shaders->LightingVer = Lighting->Version; - // Lighting->Set(shaders); - //} - - glBindBuffer(GL_ARRAY_BUFFER, ((Buffer*)vertices)->GLBuffer); - for (int i = 0; i < 5; i++) - glEnableVertexAttribArray(i); GLuint prog = fill->GetShaders()->Prog; - if (useDistortionVertex) + if (vao != NULL) { - GLint posLoc = glGetAttribLocation(prog, "Position"); - GLint colLoc = glGetAttribLocation(prog, "Color"); - GLint tc0Loc = glGetAttribLocation(prog, "TexCoord0"); - GLint tc1Loc = glGetAttribLocation(prog, "TexCoord1"); - GLint tc2Loc = glGetAttribLocation(prog, "TexCoord2"); - - glVertexAttribPointer(posLoc, 2, GL_FLOAT, false, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, Pos)); - glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, true, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, Col)); - glVertexAttribPointer(tc0Loc, 2, GL_FLOAT, false, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, TexR)); - glVertexAttribPointer(tc1Loc, 2, GL_FLOAT, false, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, TexG)); - glVertexAttribPointer(tc2Loc, 2, GL_FLOAT, false, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, TexB)); - } - else - { - GLint posLoc = glGetAttribLocation(prog, "Position"); + if (*vao != 0) + { + glBindVertexArray(*vao); - glVertexAttribPointer(posLoc, 3, GL_FLOAT, false, sizeof(LatencyVertex), (char*)offset + offsetof(LatencyVertex, Pos)); + if (isDistortionMesh) + glDrawElements(prim, count, GL_UNSIGNED_SHORT, NULL); + else + glDrawArrays(prim, 0, count); + } + else + { + if (glState->SupportsVao) + { + glGenVertexArrays(1, vao); + glBindVertexArray(*vao); + } + + int attributeCount = (isDistortionMesh) ? 5 : 1; + int* locs = new int[attributeCount]; + + glBindBuffer(GL_ARRAY_BUFFER, ((Buffer*)vertices)->GLBuffer); + + if (isDistortionMesh) + { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ((Buffer*)indices)->GLBuffer); + + locs[0] = glGetAttribLocation(prog, "Position"); + locs[1] = glGetAttribLocation(prog, "Color"); + locs[2] = glGetAttribLocation(prog, "TexCoord0"); + locs[3] = glGetAttribLocation(prog, "TexCoord1"); + locs[4] = glGetAttribLocation(prog, "TexCoord2"); + + glVertexAttribPointer(locs[0], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, Pos)); + glVertexAttribPointer(locs[1], 4, GL_UNSIGNED_BYTE, true, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, Col)); + glVertexAttribPointer(locs[2], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, TexR)); + glVertexAttribPointer(locs[3], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, TexG)); + glVertexAttribPointer(locs[4], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, TexB)); + } + else + { + locs[0] = glGetAttribLocation(prog, "Position"); + + glVertexAttribPointer(locs[0], 3, GL_FLOAT, false, sizeof(LatencyVertex), reinterpret_cast<char*>(offset)+offsetof(LatencyVertex, Pos)); + } + + for (int i = 0; i < attributeCount; ++i) + glEnableVertexAttribArray(locs[i]); + + if (isDistortionMesh) + glDrawElements(prim, count, GL_UNSIGNED_SHORT, NULL); + else + glDrawArrays(prim, 0, count); + + + if (!glState->SupportsVao) + { + for (int i = 0; i < attributeCount; ++i) + glDisableVertexAttribArray(locs[i]); + } + + delete[] locs; + } } - - if (indices) - { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ((Buffer*)indices)->GLBuffer); - glDrawElements(prim, count, GL_UNSIGNED_SHORT, NULL); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } - else - { - glDrawArrays(prim, 0, count); - } - - for (int i = 0; i < 5; i++) - glDisableVertexAttribArray(i); } void DistortionRenderer::setViewport(const Recti& vp) { - int wh; - if (CurRenderTarget) - wh = CurRenderTarget->Height; - else - { - RECT rect; - BOOL success = GetWindowRect(RParams.Window, &rect); - OVR_ASSERT(success); - OVR_UNUSED(success); - wh = rect.bottom - rect.top; - } - glViewport(vp.x, wh-vp.y-vp.h, vp.w, vp.h); - - //glEnable(GL_SCISSOR_TEST); - //glScissor(vp.x, wh-vp.y-vp.h, vp.w, vp.h); + glViewport(vp.x, vp.y, vp.w, vp.h); } void DistortionRenderer::initShaders() { + GraphicsState* glState = (GraphicsState*)GfxState.GetPtr(); + + const char* shaderPrefix = + (glState->GlMajorVersion < 3 || (glState->GlMajorVersion == 3 && glState->GlMinorVersion < 2)) ? + glsl2Prefix : glsl3Prefix; + { - ShaderInfo vsShaderByteCode = DistortionVertexShaderLookup[DistortionVertexShaderBitMask & DistortionCaps]; - Ptr<GL::VertexShader> vtxShader = *new GL::VertexShader( + ShaderInfo vsInfo = DistortionVertexShaderLookup[DistortionVertexShaderBitMask & DistortionCaps]; + + size_t vsSize = strlen(shaderPrefix)+vsInfo.ShaderSize; + char* vsSource = new char[vsSize]; + OVR_strcpy(vsSource, vsSize, shaderPrefix); + OVR_strcat(vsSource, vsSize, vsInfo.ShaderData); + + Ptr<GL::VertexShader> vs = *new GL::VertexShader( &RParams, - (void*)vsShaderByteCode.ShaderData, vsShaderByteCode.ShaderSize, - vsShaderByteCode.ReflectionData, vsShaderByteCode.ReflectionSize); + (void*)vsSource, vsSize, + vsInfo.ReflectionData, vsInfo.ReflectionSize); DistortionShader = *new ShaderSet; - DistortionShader->SetShader(vtxShader); + DistortionShader->SetShader(vs); - ShaderInfo psShaderByteCode = DistortionPixelShaderLookup[DistortionPixelShaderBitMask & DistortionCaps]; + delete[](vsSource); + + ShaderInfo psInfo = DistortionPixelShaderLookup[DistortionPixelShaderBitMask & DistortionCaps]; + + size_t psSize = strlen(shaderPrefix)+psInfo.ShaderSize; + char* psSource = new char[psSize]; + OVR_strcpy(psSource, psSize, shaderPrefix); + OVR_strcat(psSource, psSize, psInfo.ShaderData); Ptr<GL::FragmentShader> ps = *new GL::FragmentShader( &RParams, - (void*)psShaderByteCode.ShaderData, psShaderByteCode.ShaderSize, - psShaderByteCode.ReflectionData, psShaderByteCode.ReflectionSize); + (void*)psSource, psSize, + psInfo.ReflectionData, psInfo.ReflectionSize); DistortionShader->SetShader(ps); + + delete[](psSource); } - { - Ptr<GL::VertexShader> vtxShader = *new GL::VertexShader( + { + size_t vsSize = strlen(shaderPrefix)+sizeof(SimpleQuad_vs); + char* vsSource = new char[vsSize]; + OVR_strcpy(vsSource, vsSize, shaderPrefix); + OVR_strcat(vsSource, vsSize, SimpleQuad_vs); + + Ptr<GL::VertexShader> vs = *new GL::VertexShader( &RParams, - (void*)SimpleQuad_vs, sizeof(SimpleQuad_vs), - SimpleQuad_vs_refl, sizeof(SimpleQuad_vs_refl) / sizeof(SimpleQuad_vs_refl[0])); + (void*)vsSource, vsSize, + SimpleQuad_vs_refl, sizeof(SimpleQuad_vs_refl) / sizeof(SimpleQuad_vs_refl[0])); SimpleQuadShader = *new ShaderSet; - SimpleQuadShader->SetShader(vtxShader); + SimpleQuadShader->SetShader(vs); + + delete[](vsSource); + + size_t psSize = strlen(shaderPrefix)+sizeof(SimpleQuad_fs); + char* psSource = new char[psSize]; + OVR_strcpy(psSource, psSize, shaderPrefix); + OVR_strcat(psSource, psSize, SimpleQuad_fs); Ptr<GL::FragmentShader> ps = *new GL::FragmentShader( &RParams, - (void*)SimpleQuad_fs, sizeof(SimpleQuad_fs), + (void*)psSource, psSize, SimpleQuad_fs_refl, sizeof(SimpleQuad_fs_refl) / sizeof(SimpleQuad_fs_refl[0])); - SimpleQuadShader->SetShader(ps); + SimpleQuadShader->SetShader(ps); + + delete[](psSource); } } void DistortionRenderer::destroy() { + GraphicsState* glState = (GraphicsState*)GfxState.GetPtr(); + for(int eyeNum = 0; eyeNum < 2; eyeNum++) { + if (glState->SupportsVao) + glDeleteVertexArrays(1, &DistortionMeshVAOs[eyeNum]); + + DistortionMeshVAOs[eyeNum] = 0; + DistortionMeshVBs[eyeNum].Clear(); DistortionMeshIBs[eyeNum].Clear(); } @@ -1001,6 +778,7 @@ void DistortionRenderer::destroy() } LatencyTesterQuadVB.Clear(); + LatencyVAO = 0; } }}} // OVR::CAPI::GL |