protected void initDistortion(GL2 gl) { // Configure Stereo settings. OvrSizei recommendedTex0Size = hmd.getFovTextureSize(ovrEye_Left, hmd.DefaultEyeFov[0], 1f); OvrSizei recommendedTex1Size = hmd.getFovTextureSize(ovrEye_Right, hmd.DefaultEyeFov[1], 1f); int x = recommendedTex0Size.w + recommendedTex1Size.w; int y = Math.max(recommendedTex0Size.h, recommendedTex1Size.h); OvrSizei renderTargetSize = new OvrSizei(x, y); frameBuffer.resize(gl, new Dimension(x, y)); // Initialize eye rendering information. eyeRenderViewport[0].Pos = new OvrVector2i(0, 0); eyeRenderViewport[0].Size = new OvrSizei(renderTargetSize.w / 2, renderTargetSize.h); eyeRenderViewport[1].Pos = new OvrVector2i((renderTargetSize.w + 1) / 2, 0); eyeRenderViewport[1].Size = eyeRenderViewport[0].Size; distortionShader.create(gl); distortionObjects = new int[ovrEye_Count][DistortionObjects.count.ordinal()]; for (int eyeNum = 0; eyeNum < ovrEye_Count; eyeNum++) { int distortionCaps = ovrDistortionCap_Chromatic | ovrDistortionCap_TimeWarp | ovrDistortionCap_Vignette; DistortionMesh meshData = hmd.createDistortionMesh(eyeNum, eyeFov[eyeNum], distortionCaps); DistortionVertex[] distortionVertices = new DistortionVertex[meshData.VertexCount]; meshData.pVertexData.toArray(distortionVertices); { initDistortionVBOs(gl, eyeNum, distortionVertices); } short[] indicesData = meshData.pIndexData.getPointer().getShortArray(0, meshData.IndexCount); indicesCount = indicesData.length; { initDistortionIBO(gl, eyeNum, indicesData); } eyeRenderDescs[eyeNum] = hmd.getRenderDesc(eyeNum, eyeFov[eyeNum]); uvScaleOffset[eyeNum] = Hmd.getRenderScaleAndOffset(eyeFov[eyeNum], renderTargetSize, eyeRenderViewport[eyeNum]); eyeOffsets[eyeNum].x = eyeRenderDescs[eyeNum].HmdToEyeViewOffset.x; eyeOffsets[eyeNum].y = eyeRenderDescs[eyeNum].HmdToEyeViewOffset.y; eyeOffsets[eyeNum].z = eyeRenderDescs[eyeNum].HmdToEyeViewOffset.z; } }
@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 }