コード例 #1
0
ファイル: Renderer.cpp プロジェクト: GameEngineKoblenz/GeKo
void Renderer::renderReflections(float camNear, float camFar)
{
  if (!m_shaderRLR)
    init(m_windowWidth, m_windowHeight);

  bindFBO();

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  m_shaderRLR->bind();


  m_shaderRLR->sendSampler2D("positionTexture", m_gBuffer->getColorTexture(0), 0);
  m_shaderRLR->sendSampler2D("normalTexture", m_gBuffer->getColorTexture(1), 1);
  m_shaderRLR->sendSampler2D("colorTexture", getLastFBO()->getColorTexture(2), 2);
  m_shaderRLR->sendSampler2D("depthBuffer", m_gBuffer->getDepthTexture(), 3);

  m_shaderRLR->sendMat4("projectionMatrix", m_currentProjectionMatrix);

  m_shaderRLR->sendInt("screenWidth", m_windowWidth);
  m_shaderRLR->sendInt("screenHeight", m_windowHeight);

  m_shaderRLR->sendFloat("zNear", camNear);
  m_shaderRLR->sendFloat("zFar", camFar);

  m_shaderRLR->sendFloat("reflectivity", *m_screenSpaceReflectionsStrength);

  m_sfq.renderGeometry();

  m_shaderRLR->unbind();
  unbindFBO();
}
コード例 #2
0
ファイル: RiftAppSkeleton.cpp プロジェクト: cleoag/RiftRay
void RiftAppSkeleton::display_buffered(bool setViewport) const
{
    bindFBO(m_renderBuffer, m_fboScale);
    _drawSceneMono();
    unbindFBO();

    glDisable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);

    if (setViewport)
    {
        const int w = m_Cfg.OGL.Header.RTSize.w;
        const int h = m_Cfg.OGL.Header.RTSize.h;
        glViewport(0, 0, w, h);
    }

    // Present FBO to screen
    const GLuint prog = m_presentFbo.prog();
    glUseProgram(prog);
    m_presentFbo.bindVAO();
    {
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, m_renderBuffer.tex);
        glUniform1i(m_presentFbo.GetUniLoc("fboTex"), 0);

        // This is the only uniform that changes per-frame
        glUniform1f(m_presentFbo.GetUniLoc("fboScale"), m_fboScale);

        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    }
    glBindVertexArray(0);
    glUseProgram(0);
}
コード例 #3
0
ファイル: Renderer.cpp プロジェクト: GameEngineKoblenz/GeKo
void Renderer::renderDeferredShading()
{
  if (!m_shaderDSLighting || !m_shaderDSCompositing)
    init(m_windowWidth, m_windowHeight);

  if (!m_dsLightColor || !m_dsLightRootNode)
    throw std::string("Error in renderDeferredShading - Light Color or Light Root Node was not set");

  FBO *a = new FBO(m_windowWidth,m_windowHeight,3,false,false);

  a->bind();

  glCullFace(GL_FRONT);
  glEnable(GL_CULL_FACE);
  glDisable(GL_DEPTH_TEST);
  glEnable(GL_BLEND);
  glBlendFunc(GL_ONE, GL_ONE);
  glClearColor(0, 0, 0, 0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  m_shaderDSLighting->bind();

  m_shaderDSLighting->sendMat4("viewMatrix", m_currentViewMatrix);
  m_shaderDSLighting->sendMat4("projectionMatrix", m_currentProjectionMatrix);

  m_shaderDSLighting->sendSampler2D("positionMap", m_gBuffer->getColorTexture(0), 0);
  m_shaderDSLighting->sendSampler2D("normalMap", m_gBuffer->getColorTexture(1), 1);

  m_shaderDSLighting->sendInt("windowWidth", m_windowWidth);
  m_shaderDSLighting->sendInt("windowHeight", m_windowHeight);

  m_shaderDSLighting->sendVec3("lightColor", *m_dsLightColor);

  m_dsLightRootNode->render(*m_shaderDSLighting);

  glDisable(GL_CULL_FACE);
  glEnable(GL_DEPTH_TEST);
  glDisable(GL_BLEND);
  glClearColor(1.0, 1.0, 1.0, 0.0);
  m_shaderDSLighting->unbind();
  a->unbind();

  //COMPOSITING TEIL ===============================
  bindFBO();
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  m_shaderDSCompositing->bind();

  m_shaderDSCompositing->sendSampler2D("colorMap", getLastFBO()->getColorTexture(2), 0);
  m_shaderDSCompositing->sendSampler2D("lightMap", a->getColorTexture(2), 1);

  m_sfq.renderGeometry();

  m_shaderDSCompositing->unbind();
  unbindFBO();

  delete a;
}
コード例 #4
0
ファイル: RiftAppSkeleton.cpp プロジェクト: cleoag/RiftRay
void RiftAppSkeleton::RenderThumbnails()
{
    std::vector<Pane*>& panes = m_paneScene.m_panes;
    for (std::vector<Pane*>::iterator it = panes.begin();
        it != panes.end();
        ++it)
    {
        ShaderPane* pP = reinterpret_cast<ShaderPane*>(*it);
        if (pP == NULL)
            continue;
        ShaderToy* pSt = pP->m_pShadertoy;

        // Render a view of the shader to the FBO
        // We must keep the previously bound FBO and restore
        GLint bound_fbo = 0;
        glGetIntegerv(GL_FRAMEBUFFER_BINDING, &bound_fbo);
        bindFBO(pP->m_paneRenderBuffer);

        //pP->DrawToFBO();
        {
            const glm::vec3 hp = pSt->GetHeadPos();
            const glm::vec3 LookVec(0.0f, 0.0f, -1.0f);
            const glm::vec3 up(0.0f, 1.0f, 0.0f);

            ovrPosef eyePose;
            eyePose.Orientation = OVR::Quatf();
            eyePose.Position = OVR::Vector3f();
            const OVR::Matrix4f view = _MakeModelviewMatrix(
                eyePose,
                OVR::Vector3f(0.0f),
                static_cast<float>(M_PI),
                OVR::Vector3f(hp.x, hp.y, hp.z));

            const glm::mat4 persp = glm::perspective(
                90.0f,
                static_cast<float>(pP->m_paneRenderBuffer.w) / static_cast<float>(pP->m_paneRenderBuffer.h),
                0.004f,
                500.0f);

            const bool wasDrawing = m_shaderToyScene.m_bDraw;
            m_shaderToyScene.m_bDraw = true;
            m_shaderToyScene.SetShaderToy(pSt);
            m_shaderToyScene.RenderForOneEye(&view.Transposed().M[0][0], glm::value_ptr(persp));
            m_shaderToyScene.m_bDraw = wasDrawing;
            m_shaderToyScene.SetShaderToy(NULL);
        }

        unbindFBO();
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo);
    }
}
コード例 #5
0
ファイル: Renderer.cpp プロジェクト: GameEngineKoblenz/GeKo
void Renderer::renderBlur()
{
	if (!m_shaderBlur)
		init(m_windowWidth, m_windowHeight);

	bindFBO();
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	m_shaderBlur->bind();
	
	m_shaderBlur->sendSampler2D("image", getLastFBO()->getColorTexture(2), 2);
	m_shaderBlur->sendFloat("blurstrength", *m_blurStrength);
	m_sfq.renderGeometry();

	m_shaderBlur->unbind();
	unbindFBO();
}
コード例 #6
0
ファイル: PaneScene.cpp プロジェクト: chansonyan/RiftRay
void PaneScene::RenderPrePass() const
{
    // We must keep the previously bound FBO and restore
    GLint bound_fbo = 0;
    glGetIntegerv(GL_FRAMEBUFFER_BINDING, &bound_fbo);
    for (std::vector<Pane*>::const_iterator it = m_panes.begin();
        it != m_panes.end();
        ++it)
    {
        const Pane* pP = *it;
        if (pP == NULL)
            continue;

        bindFBO(pP->m_paneRenderBuffer);
        pP->DrawToFBO();
        unbindFBO();
    }
    glBindFramebuffer(GL_FRAMEBUFFER, bound_fbo);
}
コード例 #7
0
ファイル: Renderer.cpp プロジェクト: GameEngineKoblenz/GeKo
void Renderer::renderAntiAliasing()
{
  if (!m_shaderFXAA)
    init(m_windowWidth, m_windowHeight);

  bindFBO();
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  m_shaderFXAA->bind();

  m_shaderFXAA->sendSampler2D("colorTexture", getLastFBO()->getColorTexture(2), 2);
  m_shaderFXAA->sendInt("fboWidth", m_windowWidth);
  m_shaderFXAA->sendInt("fboHeight", m_windowHeight);

  m_sfq.renderGeometry();

  m_shaderFXAA->unbind();
  unbindFBO();
}
コード例 #8
0
ファイル: Renderer.cpp プロジェクト: GameEngineKoblenz/GeKo
void Renderer::renderDoF(Scene& scene)
{
	if (!m_shaderDepth || !m_shaderDoF)
		init(m_windowWidth, m_windowHeight);

	m_smFBO->bind();

	//Clear Shadow Map
	glClear(GL_DEPTH_BUFFER_BIT);

	//Set the shader for the light pass. This shader is highly optimized because the scene depth is the only thing that matters here!
	m_shaderDepth->bind();
	m_shaderDepth->sendMat4("viewMatrix", m_currentViewMatrix);
	m_shaderDepth->sendMat4("projectionMatrix", m_currentProjectionMatrix);

	//Render the scene
	scene.render(*m_shaderDepth);

	//Restore the default framebuffer
	m_shaderDepth->unbind();
	m_smFBO->unbind();

	bindFBO();
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	m_shaderDoF->bind();

	m_shaderDoF->sendSampler2D("tex", getLastFBO()->getColorTexture(2), 2);
	m_shaderDoF->sendSampler2D("depth", m_smFBO->getDepthTexture(), 1);

	m_shaderDoF->sendFloat("focus_depth", *m_focusDepth);

	m_sfq.renderGeometry();

	m_shaderDoF->unbind();

	unbindFBO();
}
コード例 #9
0
ファイル: Renderer.cpp プロジェクト: GameEngineKoblenz/GeKo
void Renderer::renderSSAO()
{
  if (!m_shaderSSAOcalc || !m_shaderSSAOblur || !m_shaderSSAOfinal)
    init(m_windowWidth, m_windowHeight);

  FBO *a = new FBO(m_windowWidth, m_windowHeight, 3, false, false);
  FBO *b = new FBO(m_windowWidth, m_windowHeight, 3, false, false);

  a->bind();
  glClearColor(1, 1, 1, 1);

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  m_shaderSSAOcalc->bind();

  m_shaderSSAOcalc->sendSampler2D("positionMap", m_gBuffer->getColorTexture(0), 0);
  m_shaderSSAOcalc->sendSampler2D("normalMap", m_gBuffer->getColorTexture(1), 1);
  m_shaderSSAOcalc->sendMat4("sceneProjectionMatrix", m_currentProjectionMatrix);
  m_shaderSSAOcalc->sendFloat("radius", *m_ssaoRadius);
  m_shaderSSAOcalc->sendFloat("quality", *m_ssaoQuality);

  m_sfq.renderGeometry();

  m_shaderSSAOcalc->unbind();
  a->unbind();



  //Blur #1 SSAO calculation
  b->bind();

  //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  m_shaderSSAOblur->bind();
  m_shaderSSAOblur->sendSampler2D("colortexture", a->getColorTexture(2), 0);
  m_shaderSSAOblur->sendInt("secondPass", 0);
  m_sfq.renderGeometry();

  m_shaderSSAOblur->unbind();
  b->unbind();



  //Blur #2 SSAO calculation
  a->bind();
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  m_shaderSSAOblur->bind();
  m_shaderSSAOblur->sendSampler2D("colortexture", b->getColorTexture(2), 0);
  m_shaderSSAOblur->sendFloat("secondPass", 1);
  m_sfq.renderGeometry();

  m_shaderSSAOblur->unbind();
  a->unbind();

  glClearColor(0, 0, 0, 0);


  //COLOR COMPOSITING
  bindFBO();
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  m_shaderSSAOfinal->bind();
  m_shaderSSAOfinal->sendSampler2D("colorMap", getLastFBO()->getColorTexture(2), 0);
  m_shaderSSAOfinal->sendSampler2D("ssaoMap", a->getColorTexture(2), 1);
  m_sfq.renderGeometry();
  m_shaderSSAOfinal->unbind();
  unbindFBO();

  delete a;
  delete b;
}
コード例 #10
0
ファイル: RiftAppSkeleton.cpp プロジェクト: cleoag/RiftRay
void RiftAppSkeleton::display_sdk() //const
{
    ovrHmd hmd = m_Hmd;
    if (hmd == NULL)
        return;

    //const ovrFrameTiming hmdFrameTiming =
    ovrHmd_BeginFrame(m_Hmd, 0);

    bindFBO(m_renderBuffer);

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // For passing to EndFrame once rendering is done
    ovrPosef renderPose[2];
    ovrTexture eyeTexture[2];

    for (int eyeIndex=0; eyeIndex<ovrEye_Count; eyeIndex++)
    {
        const ovrEyeType eye = hmd->EyeRenderOrder[eyeIndex];
        const ovrPosef eyePose = ovrHmd_GetEyePose(m_Hmd, eye);
        m_eyeOri = eyePose.Orientation; // cache this for movement direction
        _StoreHmdPose(eyePose);

        const ovrGLTexture& otex = l_EyeTexture[eye];
        const ovrRecti& rvp = otex.OGL.Header.RenderViewport;
        glViewport(
            rvp.Pos.x,
            rvp.Pos.y,
            rvp.Size.w,
            rvp.Size.h
            );

        const OVR::Matrix4f proj = ovrMatrix4f_Projection(
            m_EyeRenderDesc[eye].Fov,
            0.01f, 10000.0f, true);

        const OVR::Matrix4f view = _MakeModelviewMatrix(
            eyePose,
            -OVR::Vector3f(m_EyeRenderDesc[eye].ViewAdjust), // not sure why negative...
            m_chassisYaw,
            m_chassisPos);

        const OVR::Matrix4f scaledView = _MakeModelviewMatrix(
            eyePose,
            -OVR::Vector3f(m_EyeRenderDesc[eye].ViewAdjust), // not sure why negative...
            m_chassisYaw,
            m_chassisPos,
            m_headSize);

        _resetGLState();

        _DrawScenes(&view.Transposed().M[0][0], &proj.Transposed().M[0][0], rvp, &scaledView.Transposed().M[0][0]);

        renderPose[eyeIndex] = eyePose;
        eyeTexture[eyeIndex] = l_EyeTexture[eye].Texture;
    }
    unbindFBO();

    ovrHmd_EndFrame(m_Hmd, renderPose, eyeTexture);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glUseProgram(0);
}
コード例 #11
0
ファイル: RiftAppSkeleton.cpp プロジェクト: cleoag/RiftRay
///@todo Even though this function shares most of its code with client rendering,
/// which appears to work fine, it is non-convergable. It appears that the projection
/// matrices for each eye are too far apart? Could be modelview...
void RiftAppSkeleton::display_stereo_undistorted() //const
{
    ovrHmd hmd = m_Hmd;
    if (hmd == NULL)
        return;

    //ovrFrameTiming hmdFrameTiming =
    ovrHmd_BeginFrameTiming(hmd, 0);

    bindFBO(m_renderBuffer, m_fboScale);

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++)
    {
        ovrEyeType eye = hmd->EyeRenderOrder[eyeIndex];
        ovrPosef eyePose = ovrHmd_GetEyePose(hmd, eye);

        const ovrGLTexture& otex = l_EyeTexture[eye];
        const ovrRecti& rvp = otex.OGL.Header.RenderViewport;
        const ovrRecti rsc = {
            static_cast<int>(m_fboScale * rvp.Pos.x),
            static_cast<int>(m_fboScale * rvp.Pos.y),
            static_cast<int>(m_fboScale * rvp.Size.w),
            static_cast<int>(m_fboScale * rvp.Size.h)
        };
        glViewport(rsc.Pos.x, rsc.Pos.y, rsc.Size.w, rsc.Size.h);

        OVR::Quatf orientation = OVR::Quatf(eyePose.Orientation);
        OVR::Matrix4f proj = ovrMatrix4f_Projection(
            m_EyeRenderDesc[eye].Fov,
            0.01f, 10000.0f, true);

        //m_EyeRenderDesc[eye].DistortedViewport;
        OVR::Vector3f EyePos = m_chassisPos;
        OVR::Matrix4f view = OVR::Matrix4f(orientation.Inverted())
            * OVR::Matrix4f::RotationY(m_chassisYaw)
            * OVR::Matrix4f::Translation(-EyePos);
        OVR::Matrix4f eyeview = OVR::Matrix4f::Translation(m_EyeRenderDesc[eye].ViewAdjust) * view;

        _resetGLState();

        _DrawScenes(&eyeview.Transposed().M[0][0], &proj.Transposed().M[0][0], rvp);
    }
    unbindFBO();

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);

    // Present FBO to screen
    const GLuint prog = m_presentFbo.prog();
    glUseProgram(prog);
    m_presentFbo.bindVAO();
    {
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, m_renderBuffer.tex);
        glUniform1i(m_presentFbo.GetUniLoc("fboTex"), 0);

        // This is the only uniform that changes per-frame
        glUniform1f(m_presentFbo.GetUniLoc("fboScale"), m_fboScale);

        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    }
    glBindVertexArray(0);
    glUseProgram(0);

    ovrHmd_EndFrameTiming(hmd);
}
コード例 #12
0
ファイル: RiftAppSkeleton.cpp プロジェクト: cleoag/RiftRay
void RiftAppSkeleton::display_client() //const
{
    ovrHmd hmd = m_Hmd;
    if (hmd == NULL)
        return;

    //ovrFrameTiming hmdFrameTiming =
    ovrHmd_BeginFrameTiming(hmd, 0);

    bindFBO(m_renderBuffer, m_fboScale);

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++)
    {
        const ovrEyeType eye = hmd->EyeRenderOrder[eyeIndex];
        const ovrPosef eyePose = ovrHmd_GetEyePose(hmd, eye);
        m_eyeOri = eyePose.Orientation; // cache this for movement direction
        _StoreHmdPose(eyePose);

        const ovrGLTexture& otex = l_EyeTexture[eye];
        const ovrRecti& rvp = otex.OGL.Header.RenderViewport;
        const ovrRecti rsc = {
            static_cast<int>(m_fboScale * rvp.Pos.x),
            static_cast<int>(m_fboScale * rvp.Pos.y),
            static_cast<int>(m_fboScale * rvp.Size.w),
            static_cast<int>(m_fboScale * rvp.Size.h)
        };
        glViewport(rsc.Pos.x, rsc.Pos.y, rsc.Size.w, rsc.Size.h);

        const OVR::Matrix4f proj = ovrMatrix4f_Projection(
            m_EyeRenderDesc[eye].Fov,
            0.01f, 10000.0f, true);

        ///@todo Should we be using this variable?
        //m_EyeRenderDesc[eye].DistortedViewport;

        const OVR::Matrix4f view = _MakeModelviewMatrix(
            eyePose,
            m_EyeRenderDesc[eye].ViewAdjust,
            m_chassisYaw,
            m_chassisPos);

        const OVR::Matrix4f scaledView = _MakeModelviewMatrix(
            eyePose,
            m_EyeRenderDesc[eye].ViewAdjust,
            m_chassisYaw,
            m_chassisPos,
            m_headSize);

        _resetGLState();

        _DrawScenes(&view.Transposed().M[0][0], &proj.Transposed().M[0][0], rsc, &scaledView.Transposed().M[0][0]);
    }
    unbindFBO();


    // Set full viewport...?
    const int w = m_Cfg.OGL.Header.RTSize.w;
    const int h = m_Cfg.OGL.Header.RTSize.h;
    glViewport(0, 0, w, h);

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);

    // Now draw the distortion mesh...
    for(int eyeNum = 0; eyeNum < 2; eyeNum++)
    {
        const ShaderWithVariables& eyeShader = eyeNum == 0 ?
            m_presentDistMeshL :
            m_presentDistMeshR;
        const GLuint prog = eyeShader.prog();
        glUseProgram(prog);
        //glBindVertexArray(eyeShader.m_vao);
        {
            const ovrDistortionMesh& mesh = m_DistMeshes[eyeNum];
            glBindBuffer(GL_ARRAY_BUFFER, 0);

            const int a_pos =  glGetAttribLocation(prog, "vPosition");
            glVertexAttribPointer(a_pos, 4, GL_FLOAT, GL_FALSE, sizeof(ovrDistortionVertex), &mesh.pVertexData[0].ScreenPosNDC.x);
            glEnableVertexAttribArray(a_pos);

            const int a_texR =  glGetAttribLocation(prog, "vTexR");
            if (a_texR > -1)
            {
                glVertexAttribPointer(a_texR, 2, GL_FLOAT, GL_FALSE, sizeof(ovrDistortionVertex), &mesh.pVertexData[0].TanEyeAnglesR);
                glEnableVertexAttribArray(a_texR);
            }

            const int a_texG =  glGetAttribLocation(prog, "vTexG");
            if (a_texG > -1)
            {
                glVertexAttribPointer(a_texG, 2, GL_FLOAT, GL_FALSE, sizeof(ovrDistortionVertex), &mesh.pVertexData[0].TanEyeAnglesG);
                glEnableVertexAttribArray(a_texG);
            }

            const int a_texB =  glGetAttribLocation(prog, "vTexB");
            if (a_texB > -1)
            {
                glVertexAttribPointer(a_texB, 2, GL_FLOAT, GL_FALSE, sizeof(ovrDistortionVertex), &mesh.pVertexData[0].TanEyeAnglesB);
                glEnableVertexAttribArray(a_texB);
            }

            ovrVector2f uvoff =
                m_uvScaleOffsetOut[2*eyeNum + 1];
                //DistortionData.UVScaleOffset[eyeNum][0];
            ovrVector2f uvscale =
                m_uvScaleOffsetOut[2*eyeNum + 0];
                //DistortionData.UVScaleOffset[eyeNum][1];

            glUniform2f(eyeShader.GetUniLoc("EyeToSourceUVOffset"), uvoff.x, uvoff.y);
            glUniform2f(eyeShader.GetUniLoc("EyeToSourceUVScale"), uvscale.x, uvscale.y);


#if 0
            // Setup shader constants
            DistortionData.Shaders->SetUniform2f(
                "EyeToSourceUVScale",
                DistortionData.UVScaleOffset[eyeNum][0].x,
                DistortionData.UVScaleOffset[eyeNum][0].y);
            DistortionData.Shaders->SetUniform2f(
                "EyeToSourceUVOffset",
                DistortionData.UVScaleOffset[eyeNum][1].x,
                DistortionData.UVScaleOffset[eyeNum][1].y);

            if (distortionCaps & ovrDistortionCap_TimeWarp)
            { // TIMEWARP - Additional shader constants required
                ovrMatrix4f timeWarpMatrices[2];
                ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eyeNum, eyeRenderPoses[eyeNum], timeWarpMatrices);
                //WARNING!!! These matrices are transposed in SetUniform4x4f, before being used by the shader.
                DistortionData.Shaders->SetUniform4x4f("EyeRotationStart", Matrix4f(timeWarpMatrices[0]));
                DistortionData.Shaders->SetUniform4x4f("EyeRotationEnd", Matrix4f(timeWarpMatrices[1]));
            }

            // Perform distortion
            pRender->Render(
                &distortionShaderFill,
                DistortionData.MeshVBs[eyeNum],
                DistortionData.MeshIBs[eyeNum]);
#endif

            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, m_renderBuffer.tex);
            glUniform1i(eyeShader.GetUniLoc("fboTex"), 0);

            // This is the only uniform that changes per-frame
            glUniform1f(eyeShader.GetUniLoc("fboScale"), m_fboScale);


            glDrawElements(
                GL_TRIANGLES,
                mesh.IndexCount,
                GL_UNSIGNED_SHORT,
                &mesh.pIndexData[0]);
        }
        glBindVertexArray(0);
        glUseProgram(0);
    }

    ovrHmd_EndFrameTiming(hmd);
}