void DistortionRenderer::RenderBothDistortionMeshes(void) { Device->BeginScene(); D3DCOLOR clearColor = D3DCOLOR_RGBA( (int)(RState.ClearColor[0] * 255.0f), (int)(RState.ClearColor[1] * 255.0f), (int)(RState.ClearColor[2] * 255.0f), (int)(RState.ClearColor[3] * 255.0f)); Device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER, clearColor, 0, 0); for (int eye=0; eye<2; eye++) { FOR_EACH_EYE * e = &eachEye[eye]; D3DVIEWPORT9 vp; vp.X=0; vp.Y=0; vp.Width=ScreenSize.w; vp.Height=ScreenSize.h; vp.MinZ=0; vp.MaxZ = 1; Device->SetViewport(&vp); Device->SetStreamSource( 0, e->dxVerts,0, sizeof(ovrDistortionVertex) ); Device->SetVertexDeclaration( VertexDecl ); Device->SetIndices( e->dxIndices ); Device->SetPixelShader( PixelShader ); Device->SetTexture( 0, e->texture); //Choose which vertex shader, with associated additional inputs if (RState.DistortionCaps & ovrDistortionCap_TimeWarp) { Device->SetVertexShader( VertexShaderTimewarp ); ovrMatrix4f timeWarpMatrices[2]; ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eye, RState.EyeRenderPoses[eye], timeWarpMatrices); //Need to transpose the matrices timeWarpMatrices[0] = Matrix4f(timeWarpMatrices[0]).Transposed(); timeWarpMatrices[1] = Matrix4f(timeWarpMatrices[1]).Transposed(); // Feed identity like matrices in until we get proper timewarp calculation going on Device->SetVertexShaderConstantF(4, (float *) &timeWarpMatrices[0],4); Device->SetVertexShaderConstantF(20,(float *) &timeWarpMatrices[1],4); } else { Device->SetVertexShader( VertexShader ); } //Set up vertex shader constants Device->SetVertexShaderConstantF( 0, ( FLOAT* )&(e->UVScaleOffset[0]), 1 ); Device->SetVertexShaderConstantF( 2, ( FLOAT* )&(e->UVScaleOffset[1]), 1 ); Device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST,0,0,e->numVerts,0,e->numIndices/3); } Device->EndScene(); }
//Draw void COculusVR::DrawScreen() { //clear wzClear(); // Adjust eye position and rotation from controls, maintaining y position from HMD. static float BodyYaw(3.141592f); static Vector3f HeadPos(0.0f, 0.0f, -5.0f); static ovrTrackingState HmdState; static ovrPosef eyeRenderPose[2]; ovrVector3f hmdToEyeViewOffset[2] = { EyeRenderDesc[0].HmdToEyeViewOffset, EyeRenderDesc[1].HmdToEyeViewOffset }; ovrHmd_GetEyePoses(Hmd, 0, hmdToEyeViewOffset, eyeRenderPose, &HmdState); /* debug wzSetSpriteScSize(1920, 1080); wzSetSpritePosition(0.0f, 0.0f, 0.0f); wzSetSpriteColor(1.0f, 1.0f, 1.0f, 1.0f); wzSetSpriteTexCoord(0.0f, 0.0f, 1.0f, 1.0f); wzSetSpriteSizeLeftUp((float)1920, (float)1080); wzSetSpriteTexture(&m_screenTex); wzSpriteDraw(); //Draw */ // Setup shader wzUseShader(&LensShader); wzSetTexture("texture0", &m_screenTex, 0); for ( int eyeNum = 0; eyeNum < 2; eyeNum++ ) { wzVector2 uvScale = {UVScaleOffset[eyeNum][0].x,-UVScaleOffset[eyeNum][0].y}; wzVector2 uvOffset = {UVScaleOffset[eyeNum][1].x,UVScaleOffset[eyeNum][1].y}; wzMatrix rotStart,rotEnd; wzUniformVector2("eyeToSourceUVscale", &uvScale); wzUniformVector2("eyeToSourceUVoffset", &uvOffset); ovrMatrix4f timeWarpMatrices[2]; ovrHmd_GetEyeTimewarpMatrices(Hmd, (ovrEyeType)eyeNum, eyeRenderPose[eyeNum], timeWarpMatrices); memcpy(&rotStart.m,&timeWarpMatrices[0],sizeof(ovrMatrix4f)); memcpy(&rotEnd.m,&timeWarpMatrices[1],sizeof(ovrMatrix4f)); wzUniformMatrix("eyeRotationStart", &rotStart); //Nb transposed when set wzUniformMatrix("eyeRotationEnd", &rotEnd); //Draw Mesh wzDrawMesh(&MeshBuffer[eyeNum]); } //DK2 Latency Tester unsigned char latencyColor[3]; ovrBool drawDk2LatencyQuad = ovrHmd_GetLatencyTest2DrawColor(Hmd, latencyColor); if(drawDk2LatencyQuad) { const int latencyQuadSize = 20; // only needs to be 1-pixel, but larger helps visual debugging wzSetViewport(Hmd->Resolution.w - latencyQuadSize, 0, latencyQuadSize, latencyQuadSize); wzSetClearColor(latencyColor[0] / 255.0f, latencyColor[1] / 255.0f, latencyColor[2] / 255.0f,0.0f); wzClear(); } }
void gkOculusDisortationRenderable::RP_ShaderSet() { m_material->getShader()->FX_SetFloat2( "EyeToSourceUVScale", Vec2(UVScaleOffset[m_eye_index][0].x, UVScaleOffset[m_eye_index][0].y)); m_material->getShader()->FX_SetFloat2( "EyeToSourceUVOffset", Vec2(UVScaleOffset[m_eye_index][1].x, UVScaleOffset[m_eye_index][1].y)); ovrMatrix4f timeWarpMatrices[2]; ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)m_eye_index, m_oculusDevice->eyeRenderPose[m_eye_index], timeWarpMatrices); m_material->getShader()->FX_SetValue( "EyeRotationStart", &(timeWarpMatrices[0]), sizeof(ovrMatrix4f) ); m_material->getShader()->FX_SetValue( "EyeRotationEnd", &(timeWarpMatrices[1]), sizeof(ovrMatrix4f) ); }
void OculusDevice::waitTillTime() { // Wait till time-warp point to reduce latency. ovr_WaitTillTime(m_frameTiming.TimewarpPointSeconds); // Get time warp properties for (int eyeIndex = 0; eyeIndex < ovrEye_Count; ++eyeIndex) { ovrHmd_GetEyeTimewarpMatrices(m_hmdDevice, (ovrEyeType)eyeIndex, m_headPose[eyeIndex], m_timeWarpMatrices[eyeIndex]); } }
void DistortionMeshRender(unsigned distortionCaps, ovrHmd HMD, double timwarpTimePoint, ovrPosef eyeRenderPoses[2], RenderDevice* pRender, Texture* pRendertargetTexture) { if (distortionCaps & ovrDistortionCap_TimeWarp) { // TIMEWARP // Wait till time-warp to reduce latency. ovr_WaitTillTime(timwarpTimePoint); } // Clear screen pRender->SetDefaultRenderTarget(); pRender->SetFullViewport(); pRender->Clear(0.0f, 0.0f, 0.0f, 0.0f); // Setup shader ShaderFill distortionShaderFill(DistortionData.Shaders); distortionShaderFill.SetTexture(0, pRendertargetTexture); distortionShaderFill.SetInputLayout(DistortionData.VertexIL); for(int eyeNum = 0; eyeNum < 2; eyeNum++) { // 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]); } pRender->SetDefaultRenderTarget(); }
void DistortionRenderer::RenderBothDistortionMeshes(void) { for (int eye=0; eye<2; eye++) { FOR_EACH_EYE * e = &eachEye[eye]; D3DVIEWPORT9 vp; vp.X=0; vp.Y=0; vp.Width=screenSize.w; vp.Height=screenSize.h; vp.MinZ=0; vp.MaxZ = 1; device->SetViewport(&vp); device->SetStreamSource( 0, e->dxVerts,0, sizeof(ovrDistortionVertex) ); device->SetVertexDeclaration( vertexDecl ); device->SetIndices( e->dxIndices ); device->SetPixelShader( pixelShader ); device->SetTexture( 0, e->texture); //Choose which vertex shader, with associated additional inputs if (distortionCaps & ovrDistortionCap_TimeWarp) { device->SetVertexShader( vertexShaderTimewarp ); ovrMatrix4f timeWarpMatrices[2]; ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eye, RState.EyeRenderPoses[eye], timeWarpMatrices); //Need to transpose the matrices timeWarpMatrices[0] = Matrix4f(timeWarpMatrices[0]).Transposed(); timeWarpMatrices[1] = Matrix4f(timeWarpMatrices[1]).Transposed(); // Feed identity like matrices in until we get proper timewarp calculation going on device->SetVertexShaderConstantF(4, (float *) &timeWarpMatrices[0],4); device->SetVertexShaderConstantF(20,(float *) &timeWarpMatrices[1],4); } else { device->SetVertexShader( vertexShader ); } //Set up vertex shader constants device->SetVertexShaderConstantF( 0, ( FLOAT* )&(e->UVScaleOffset[0]), 1 ); device->SetVertexShaderConstantF( 2, ( FLOAT* )&(e->UVScaleOffset[1]), 1 ); device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST,0,0,e->numVerts,0,e->numIndices/3); } }
void DistortionMeshRender(unsigned distortionCaps, ovrHmd HMD, double timwarpTimePoint, ovrPosef eyeRenderPoses[2]) { if (distortionCaps & ovrDistortionCap_TimeWarp) { // TimeWarp(時間歪曲)を考慮する // 遅延を減らすために行うものらしい ovr_WaitTillTime(timwarpTimePoint); } // レンダーターゲットの設定 g_pImmediateContext->OMSetRenderTargets(1, &g_pRenderTargetView, NULL); // レンダーターゲットのクリア float ClearColor_[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; // R,G,B,A の順番 g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, ClearColor_); // ビューポートをウィンドウ全体に設定する D3D11_VIEWPORT vp; vp.Width = HMDDesc.Resolution.w; vp.Height = HMDDesc.Resolution.h; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; g_pImmediateContext->RSSetViewports(1, &vp); // ゆがませるメッシュを作成する UINT stride = sizeof(SimpleVertex), offset = 0; g_pImmediateContext->VSSetShader(g_pVertexShaderOculus, NULL, 0); g_pImmediateContext->VSSetConstantBuffers(0, 1, &g_pConstantBufferOculus); g_pImmediateContext->PSSetShader(g_pPixelShaderOculus, NULL, 0); g_pImmediateContext->PSSetShaderResources(0, 1, &g_pShaderResViewOculus); g_pImmediateContext->PSSetSamplers(0, 1, &g_pSamplerLinear); //インプットレイアウトのセット g_pImmediateContext->IASetInputLayout(g_pVertexLayoutOculus); //それぞれの目に対するメッシュデータを描画する for (int eyeNum = 0; eyeNum < 2; eyeNum++) { // コンスタントバッファに適用するための値を設定する。 OculusRiftSettings ocrSet; ocrSet.EyeToSourceUVScale.x = UVScaleOffset[eyeNum][0].x; ocrSet.EyeToSourceUVScale.y = UVScaleOffset[eyeNum][0].y; ocrSet.EyeToSourceUVOffset.x = UVScaleOffset[eyeNum][1].x; ocrSet.EyeToSourceUVOffset.y = UVScaleOffset[eyeNum][1].y; if (distortionCaps & ovrDistortionCap_TimeWarp) { // TimeWarp(時間歪曲)を考慮する ovrMatrix4f timeWarpMatrices[2]; ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eyeNum, eyeRenderPoses[eyeNum], timeWarpMatrices); //シェーダーで memcpy_s(&ocrSet.EyeRotationStart,64,&timeWarpMatrices[0],64); memcpy_s(&ocrSet.EyeRotationEnd, 64, &timeWarpMatrices[1], 64); } //頂点バッファとインデックスバッファのセット UINT stride = sizeof(DistortionVertex), offset = 0; g_pImmediateContext->IASetVertexBuffers(0, 1, &g_pVertexBufferOculus[eyeNum], &stride, &offset); g_pImmediateContext->IASetIndexBuffer(g_pIndexBufferOculus[eyeNum], DXGI_FORMAT_R16_UINT, 0); // コンスタントバッファに転送します。 g_pImmediateContext->UpdateSubresource(g_pConstantBufferOculus, 0, NULL, &ocrSet, 0, 0); // ゆがませるメッシュを描画します。 g_pImmediateContext->DrawIndexed(oculusIndexCount,0, 0); } }
//------------------------------------------------------------------------------------- void ProcessAndRender() { static ovrPosef eyeRenderPose[2]; // Start timing #if SDK_RENDER ovrHmd_BeginFrame(HMD, 0); #else ovrHmd_BeginFrameTiming(HMD, 0); // Retrieve data useful for handling the Health and Safety Warning - unused, but here for reference ovrHSWDisplayState hswDisplayState; ovrHmd_GetHSWDisplayState(HMD, &hswDisplayState); #endif // Adjust eye position and rotation from controls, maintaining y position from HMD. static float BodyYaw(3.141592f); static Vector3f HeadPos(0.0f, 1.6f, -5.0f); // HeadPos.y = ovrHmd_GetFloat(HMD, OVR_KEY_EYE_HEIGHT, HeadPos.y); bool freezeEyeRender = Util_RespondToControls(BodyYaw, HeadPos, eyeRenderPose[1].Orientation); pRender->BeginScene(); // Render the two undistorted eye views into their render buffers. if (!freezeEyeRender) // freeze to debug for time warp { pRender->SetRenderTarget ( pRendertargetTexture ); pRender->SetViewport (Recti(0,0, pRendertargetTexture->GetWidth(), pRendertargetTexture->GetHeight() )); pRender->Clear(); for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++) { ovrEyeType eye = HMD->EyeRenderOrder[eyeIndex]; eyeRenderPose[eye] = ovrHmd_GetEyePose(HMD, eye); // Get view and projection matrices Matrix4f rollPitchYaw = Matrix4f::RotationY(BodyYaw); Matrix4f finalRollPitchYaw = rollPitchYaw * Matrix4f(eyeRenderPose[eye].Orientation); Vector3f finalUp = finalRollPitchYaw.Transform(Vector3f(0,1,0)); Vector3f finalForward = finalRollPitchYaw.Transform(Vector3f(0,0,-1)); Vector3f shiftedEyePos = HeadPos + rollPitchYaw.Transform(eyeRenderPose[eye].Position); Matrix4f view = Matrix4f::LookAtRH(shiftedEyePos, shiftedEyePos + finalForward, finalUp); Matrix4f proj = ovrMatrix4f_Projection(EyeRenderDesc[eye].Fov, 0.01f, 10000.0f, true); pRender->SetViewport(Recti(EyeRenderViewport[eye])); pRender->SetProjection(proj); pRender->SetDepthMode(true, true); pRoomScene->Render(pRender, Matrix4f::Translation(EyeRenderDesc[eye].ViewAdjust) * view); } } pRender->FinishScene(); #if SDK_RENDER // Let OVR do distortion rendering, Present and flush/sync ovrHmd_EndFrame(HMD, eyeRenderPose, &EyeTexture[0].Texture); #else // Clear screen pRender->SetDefaultRenderTarget(); pRender->SetFullViewport(); pRender->Clear(0.0f, 0.0f, 0.0f, 0.0f); // Setup shader ShaderFill distortionShaderFill(Shaders); distortionShaderFill.SetTexture(0, pRendertargetTexture); distortionShaderFill.SetInputLayout(VertexIL); for(int eyeNum = 0; eyeNum < 2; eyeNum++) { // Get and set shader constants Shaders->SetUniform2f("EyeToSourceUVScale", UVScaleOffset[eyeNum][0].x, UVScaleOffset[eyeNum][0].y); Shaders->SetUniform2f("EyeToSourceUVOffset", UVScaleOffset[eyeNum][1].x, UVScaleOffset[eyeNum][1].y); ovrMatrix4f timeWarpMatrices[2]; ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eyeNum, eyeRenderPose[eyeNum], timeWarpMatrices); Shaders->SetUniform4x4f("EyeRotationStart", timeWarpMatrices[0]); //Nb transposed when set Shaders->SetUniform4x4f("EyeRotationEnd", timeWarpMatrices[1]); //Nb transposed when set // Perform distortion pRender->Render(&distortionShaderFill, MeshVBs[eyeNum], MeshIBs[eyeNum],sizeof(ovrDistortionVertex)); } pRender->SetDefaultRenderTarget(); pRender->Present( true ); // Vsync enabled // Only flush GPU for ExtendDesktop; not needed in Direct App Renering with Oculus driver. if (HMD->HmdCaps & ovrHmdCap_ExtendDesktop) pRender->WaitUntilGpuIdle(); ovrHmd_EndFrameTiming(HMD); #endif }
void OVR_Present(qboolean loading) { int fade = vr_ovr_distortion_fade->value != 0.0f; float desaturate = 0.0; if (positionTracked && trackingState.StatusFlags & ovrStatus_PositionConnected && vr_ovr_trackingloss->value > 0) { if (hasPositionLock) { float yawDiff = (fabsf(cameraYaw) - 105.0f) * 0.04; float xBound,yBound,zBound; vec_t temp[4][4], fin[4][4]; int i = 0; vec3_t euler; vec4_t pos = {0.0,0.0,0.0,1.0}; vec4_t out = {0,0,0,0}; ovrPosef camera, head; vec4_t quat; camera = trackingState.CameraPose; head = trackingState.HeadPose.ThePose; pos[0] = -(head.Position.x - camera.Position.x); pos[1] = head.Position.y - camera.Position.y; pos[2] = -(head.Position.z - camera.Position.z); VR_OVR_QuatToEuler(camera.Orientation,euler); EulerToQuat(euler,quat); QuatToRotation(quat,temp); MatrixMultiply (cameraFrustum,temp,fin); for (i=0; i<4; i++) { out[i] = fin[i][0]*pos[0] + fin[i][1]*pos[1] + fin[i][2]*pos[2] + fin[i][3]*pos[3]; } xBound = (fabsf(out[0]) - 0.6f) * 6.25f; yBound = (fabsf(out[1]) - 0.45f) * 6.25f; zBound = (fabsf(out[2] - 0.5f) - 0.5f) * 10.0f; yawDiff = clamp(yawDiff,0.0,1.0); xBound = clamp(xBound,0.0,1.0); yBound = clamp(yBound,0.0,1.0); zBound = clamp(zBound,0.0,1.0); desaturate = max(max(max(xBound,yBound),zBound),yawDiff); } else { desaturate = 1.0; } } GL_ClearColor(0.0, 0.0, 0.0, 1.0); R_Clear(); GL_SetDefaultClearColor(); { int i = 0; r_ovr_shader_t *currentShader; qboolean warp =(qboolean) (!loading && withinFrame && vr_ovr_timewarp->value); if (warp) { currentShader = &ovr_timewarp_shaders[useChroma]; ovr_WaitTillTime(frameTime.TimewarpPointSeconds); } else { currentShader = &ovr_distortion_shaders[useChroma]; } glDisableClientState (GL_COLOR_ARRAY); glDisableClientState (GL_TEXTURE_COORD_ARRAY); glDisableClientState (GL_VERTEX_ARRAY); glEnableVertexAttribArray (0); glEnableVertexAttribArray (1); glEnableVertexAttribArray (2); glEnableVertexAttribArray (3); glEnableVertexAttribArray (4); glUseProgram(currentShader->shader->program); if (hmd->Type >= ovrHmd_DK2 && vr_ovr_lumoverdrive->value) { int lastFrame = (currentFrame ? 0 : 1); static float overdriveScaleRegularRise = 0.1f; static float overdriveScaleRegularFall = 0.05f; // falling issues are hardly visible GL_MBind(1,offscreen[lastFrame].texture); glUniform2f(currentShader->uniform.OverdriveScales,overdriveScaleRegularRise, overdriveScaleRegularFall); } else { glUniform2f(currentShader->uniform.OverdriveScales,0,0); } glUniform2f(currentShader->uniform.InverseResolution,1.0/glState.currentFBO->width,1.0/glState.currentFBO->height); glUniform1i(currentShader->uniform.VignetteFade,fade); glUniform1f(currentShader->uniform.Desaturate, desaturate); for (i = 0; i < 2; i++) { // hook for rendering in different order int eye = i; GL_MBind(0,renderInfo[eye].eyeFBO.texture); R_BindIVBO(&renderInfo[eye].eye,distortion_attribs,5); glUniform2f(currentShader->uniform.EyeToSourceUVScale, renderInfo[eye].UVScaleOffset[0].x, renderInfo[eye].UVScaleOffset[0].y); glUniform2f(currentShader->uniform.EyeToSourceUVOffset, renderInfo[eye].UVScaleOffset[1].x, renderInfo[eye].UVScaleOffset[1].y); if (warp) { ovrPosef framePose = trackingState.HeadPose.ThePose; ovrMatrix4f timeWarpMatrices[2]; ovrHmd_GetEyeTimewarpMatrices(hmd, (ovrEyeType)eye, framePose, timeWarpMatrices); glUniformMatrix4fv(currentShader->uniform.EyeRotationStart,1,GL_TRUE,(GLfloat *) timeWarpMatrices[0].M); glUniformMatrix4fv(currentShader->uniform.EyeRotationEnd,1,GL_TRUE,(GLfloat *) timeWarpMatrices[1].M); } R_DrawIVBO(&renderInfo[eye].eye); R_ReleaseIVBO(); } if (vr_ovr_lumoverdrive->value) { GL_MBind(1,0); currentFrame = (currentFrame ? 0 : 1); } GL_MBind(0,0); glUseProgram(0); glDisableVertexAttribArray (0); glDisableVertexAttribArray (1); glDisableVertexAttribArray (2); glDisableVertexAttribArray (3); glDisableVertexAttribArray (4); glEnableClientState (GL_COLOR_ARRAY); glEnableClientState (GL_TEXTURE_COORD_ARRAY); glEnableClientState (GL_VERTEX_ARRAY); // glTexCoordPointer (2, GL_FLOAT, sizeof(texCoordArray[0][0]), texCoordArray[0][0]); // glVertexPointer (3, GL_FLOAT, sizeof(vertexArray[0]), vertexArray[0]); } }
//------------------------------------------------------------------------------------- void ProcessAndRender() { #if 0 //HRESULT hr = pRender->Device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); //OVR_ASSERT(SUCCEEDED(hr)); pRender->Clear(); pRender->BeginScene(); Vector3f eye(0.0f, 0.0f, -5.0f); Vector3f lookat(0.0f, 0.0f, 0.0f); Vector3f up(0.0f, 1.0f, 0.0f); Matrix4f view = Matrix4f::LookAtLH(eye, lookat, up); //Matrix4f proj = Matrix4f::PerspectiveLH(3.14145f / 2, 800.0f / 600.0f, 1.0f, 10000.0f); ovrFovPort fov = { 1, 1, 1, 1 }; Matrix4f proj = ovrMatrix4f_Projection(fov, 1.0f, 10000.0f, false); pRender->SetProjection(proj); pRoomScene->Render(pRender, view); pRender->EndScene(); pRender->Present(); #endif static ovrPosef eyeRenderPose[2]; ovrHmd_BeginFrameTiming(HMD, 0); // Adjust eye position and rotation from controls, maintaining y position from HMD. static float BodyYaw(3.141592f); static Vector3f HeadPos(0.0f, 1.6f, -5.0f); HeadPos.y = ovrHmd_GetFloat(HMD, OVR_KEY_EYE_HEIGHT, HeadPos.y); bool freezeEyeRender = false; pRender->BeginScene(); if (!freezeEyeRender) { pRender->SetRenderTarget(pRendertargetTexture); pRender->SetViewport(Recti(0, 0, pRendertargetTexture->Width, pRendertargetTexture->Height)); pRender->Clear(); for (int eyeIndex = 0; eyeIndex < ovrEye_Count; ++eyeIndex) { ovrEyeType eye = HMD->EyeRenderOrder[eyeIndex]; eyeRenderPose[eye] = ovrHmd_GetEyePose(HMD, eye); // Get view and projection matrices Matrix4f rollPitchYaw = Matrix4f::RotationY(BodyYaw); Matrix4f finalRollPitchYaw = rollPitchYaw * Matrix4f(eyeRenderPose[eye].Orientation); Vector3f finalUp = finalRollPitchYaw.Transform(Vector3f(0, 1, 0)); Vector3f finalForward = finalRollPitchYaw.Transform(Vector3f(0, 0, -1)); Vector3f shiftedEyePos = HeadPos + rollPitchYaw.Transform(eyeRenderPose[eye].Position); //Matrix4f view = Matrix4f::LookAtRH(shiftedEyePos, shiftedEyePos + finalForward, finalUp); //Matrix4f proj = ovrMatrix4f_Projection(EyeRenderDesc[eye].Fov, 0.01f, 10000.0f, true); Matrix4f view = Matrix4f::LookAtLH(shiftedEyePos, shiftedEyePos + finalForward, finalUp); Matrix4f proj = ovrMatrix4f_Projection(EyeRenderDesc[eye].Fov, 0.01f, 10000.0f, false); pRender->SetViewport(Recti(EyeRenderViewport[eye])); pRender->SetProjection(proj); pRender->SetDepthMode(true, true); pRoomScene->Render(pRender, Matrix4f::Translation(EyeRenderDesc[eye].ViewAdjust) * view); } } pRender->SetDefaultRenderTarget(); pRender->SetFullViewport(); pRender->Clear(0.0f, 0.0f, 0.0f, 0.0f); ShaderFill distortionShaderFill(DistortionShaders); distortionShaderFill.SetTexture(0, pRendertargetTexture); for (int eyeNum = 0; eyeNum < ovrEye_Count; eyeNum++) { // Get and set shader constants DistortionShaders->SetUniform2f("EyeToSourceUVScale", UVScaleOffset[eyeNum][0].x, UVScaleOffset[eyeNum][0].y); DistortionShaders->SetUniform2f("EyeToSourceUVOffset", UVScaleOffset[eyeNum][1].x, UVScaleOffset[eyeNum][1].y); ovrMatrix4f timeWarpMatrices[2]; ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eyeNum, eyeRenderPose[eyeNum], timeWarpMatrices); DistortionShaders->SetUniform4x4f("EyeRotationStart", timeWarpMatrices[0]); //Nb transposed when set DistortionShaders->SetUniform4x4f("EyeRotationEnd", timeWarpMatrices[1]); //Nb transposed when set // Perform distortion pRender->Render(&distortionShaderFill, DistortionDecl, MeshVBs[eyeNum], MeshIBs[eyeNum], sizeof(ovrDistortionVertex), Matrix4f(), MeshVBCnts[eyeNum], MeshIBCnts[eyeNum], Prim_Triangles); //Render(fill, vertices, indices, stride, Matrix4f(), 0,(int)vertices->GetSize(), Prim_Triangles, false); //(&distortionShaderFill, MeshVBs[eyeNum], MeshIBs[eyeNum],sizeof(ovrDistortionVertex)); } /* pRender->SetDefaultRenderTarget(); pRender->SetFullViewport(); pRender->Clear(0.0f, 0.0f, 0.0f, 0.0f); Vector3f eye(0.0f, 0.0f, -5.0f); Vector3f lookat(0.0f, 0.0f, 0.0f); Vector3f up(0.0f, 1.0f, 0.0f); Matrix4f view = Matrix4f::LookAtLH(eye, lookat, up); Matrix4f proj = Matrix4f::PerspectiveLH(3.14145f / 4, 800.0f / 600.0f, 1.0f, 10000.0f); pRender->Proj = proj; pScene->Render(pRender, view); */ //pRender->SetDefaultRenderTarget(); pRender->EndScene(); pRender->Present(); //if (HMD->HmdCaps & ovrHmdCap_ExtendDesktop) // pRender->WaitUntilG ovrHmd_EndFrameTiming(HMD); }
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); }