protected double getHeadTranslationScale(IDelegateView view) { Position eyePosition = view.getEyePosition(); DrawContext dc = view.getDC(); if (dc == null) { return Math.abs(eyePosition.elevation); } double altitude = ViewUtil.computeElevationAboveSurface(dc, eyePosition); return Math.abs(altitude); }
@Override public Matrix computeProjection( IDelegateView view, Angle horizontalFieldOfView, double nearDistance, double farDistance) { if (!shouldRenderForHMD()) { return view.computeProjection(horizontalFieldOfView, nearDistance, farDistance); } return RiftUtils.toMatrix( Hmd.getPerspectiveProjection(eyeFov[eye], (float) nearDistance, (float) farDistance, true)); }
@Override public void beforeComputeMatrices(IDelegateView view) { if (shouldRenderForHMD()) { // double hfovRadians = Math.atan(eyeFov[eye].LeftTan) + Math.atan(eyeFov[eye].RightTan); // double vfovRadians = Math.atan(eyeFov[eye].UpTan) + Math.atan(eyeFov[eye].DownTan); // view.setFieldOfView(Angle.fromRadians(hfovRadians)); // TODO hmmm, something about the reported Oculus FOV above and the World Wind's View FOV // don't mix very well, so set it manually to a high FOV to ensure all tiles are rendered: view.setFieldOfView(Angle.fromDegrees(130)); } }
@Override public void draw(IDelegateView view, DrawContext dc, DrawableSceneController sc) { GL2 gl = dc.getGL().getGL2(); init(gl); if (distortionShader.isCreationFailed()) { view.draw(dc, sc); return; } Rectangle oldViewport = view.getViewport(); hmd.beginFrameTiming(++frameCount); { Posef[] eyePoses = hmd.getEyePoses(frameCount, eyeOffsets); // RiftLogger.logPose(eyePoses); renderEyes = true; frameBuffer.bind(gl); { sc.clearFrame(dc); for (int i = 0; i < ovrEye_Count; i++) { int eye = hmd.EyeRenderOrder[i]; Posef pose = eyePoses[eye]; this.eyePoses[eye].Orientation = pose.Orientation; this.eyePoses[eye].Position = pose.Position; this.eye = eye; gl.glViewport( eyeRenderViewport[eye].Pos.x, eyeRenderViewport[eye].Pos.y, eyeRenderViewport[eye].Size.w, eyeRenderViewport[eye].Size.h); sc.applyView(dc); sc.draw(dc); } } frameBuffer.unbind(gl); renderEyes = false; OGLStackHandler oglsh = new OGLStackHandler(); oglsh.pushAttrib(gl, GL2.GL_ENABLE_BIT); oglsh.pushClientAttrib(gl, GL2.GL_CLIENT_VERTEX_ARRAY_BIT); try { gl.glViewport(0, 0, hmd.Resolution.w, hmd.Resolution.h); gl.glDisable(GL2.GL_DEPTH_TEST); gl.glEnable(GL2.GL_TEXTURE_2D); gl.glActiveTexture(GL2.GL_TEXTURE0); gl.glBindTexture(GL2.GL_TEXTURE_2D, frameBuffer.getTexture().getId()); for (int eyeNum = 0; eyeNum < ovrEye_Count; eyeNum++) { OvrMatrix4f[] timeWarpMatricesRowMajor = new OvrMatrix4f[2]; hmd.getEyeTimewarpMatrices(eyeNum, eyePoses[eyeNum], timeWarpMatricesRowMajor); distortionShader.use( gl, uvScaleOffset[eyeNum][0].x, -uvScaleOffset[eyeNum][0].y, uvScaleOffset[eyeNum][1].x, 1 - uvScaleOffset[eyeNum][1].y, timeWarpMatricesRowMajor[0].M, timeWarpMatricesRowMajor[1].M); gl.glClientActiveTexture(GL2.GL_TEXTURE0); gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY); gl.glEnableClientState(GL2.GL_COLOR_ARRAY); gl.glBindBuffer( GL2.GL_ARRAY_BUFFER, distortionObjects[eyeNum][DistortionObjects.vbo.ordinal()]); { int stride = 10 * 4; gl.glVertexPointer(4, GL2.GL_FLOAT, stride, 0); gl.glTexCoordPointer(2, GL2.GL_FLOAT, stride, 4 * 4); gl.glColorPointer(4, GL2.GL_FLOAT, stride, 6 * 4); gl.glBindBuffer( GL2.GL_ELEMENT_ARRAY_BUFFER, distortionObjects[eyeNum][DistortionObjects.ibo.ordinal()]); { gl.glDrawElements(GL2.GL_TRIANGLES, indicesCount, GL2.GL_UNSIGNED_INT, 0); } gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, 0); } gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0); distortionShader.unuse(gl); } } finally { oglsh.pop(gl); } } hmd.endFrameTiming(); // apply the old viewport, and ensure that the view is updated for the next picking round gl.glViewport(oldViewport.x, oldViewport.y, oldViewport.width, oldViewport.height); sc.applyView(dc); view.firePropertyChange( AVKey.VIEW, null, view); // make the view draw repeatedly for oculus rotation }
@Override public void pick(IDelegateView view, DrawContext dc, DrawableSceneController sc) { view.pick(dc, sc); sc.clearFrame(dc); fixViewportCenterPosition(dc, sc); }
@Override public Matrix computeModelView(IDelegateView view) { pretransformedModelView = view.computeModelView(); return transformModelView(pretransformedModelView, view); }