/******************************************************************************* * Copyright 2011 See AUTHORS file. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package com.badlogic.gdx.vr; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Camera; import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.glutils.FrameBuffer; import com.badlogic.gdx.math.Quaternion; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.viewport.ScreenViewport; import com.badlogic.gdx.utils.viewport.Viewport; import com.badlogic.gdx.vr.SplitViewport.SizeInformation; import com.badlogic.gdx.vr.SplitViewport.SizeType; import com.badlogic.gdx.vr.SplitViewport.SubView; /** * @author Daniel Holderbaum */ public class VirtualRealityRenderer { public Array<VirtualRealityRenderListener> listeners = new Array<VirtualRealityRenderListener>(); private boolean distortionCorrected; private FrameBuffer leftFBO, rightFBO; private SplitViewport splitViewport = new SplitViewport(new ScreenViewport()); public VirtualRealityRenderer() { splitViewport.row(new SizeInformation(SizeType.RELATIVE, 1f)); splitViewport.add(new SubView(new SizeInformation(SizeType.RELATIVE, 0.5f), VirtualReality.head.getLeftEye())); splitViewport.add(new SubView(new SizeInformation(SizeType.RELATIVE, 0.5f), VirtualReality.head.getRightEye())); } public void dispose() { if (leftFBO != null) { leftFBO.dispose(); leftFBO = null; } if (rightFBO != null) { rightFBO.dispose(); rightFBO = null; } } /** * Sets whether distortion correction is enabled. * * Enabled by default. Changes will be effective from the first frame after * this call. */ public void setDistortionCorrection(boolean enabled) { this.distortionCorrected = enabled; } public void render() { VirtualReality.distortionRenderer.frameStarted(); VirtualReality.distortionRenderer.projectionChanged(VirtualReality.head.getLeftEye(), VirtualReality.head.getRightEye()); for (VirtualRealityRenderListener listener : listeners) { listener.frameStarted(); } int screenWidth = Gdx.graphics.getWidth(); int screenHeight = Gdx.graphics.getHeight(); if (VirtualReality.head.isCyclops()) { VirtualReality.head.getCyclopsEye().update(screenWidth, screenHeight); renderEye(VirtualReality.head.getCyclopsEye(), new Vector3()); } else { splitViewport.update(screenWidth, screenHeight); splitViewport.activateSubViewport(0, 0, false); renderEye(VirtualReality.head.getLeftEye(), new Vector3(-VirtualReality.head.getInterpupillaryDistance() / 2f, 0, 0)); splitViewport.activateSubViewport(0, 1, false); renderEye(VirtualReality.head.getRightEye(), new Vector3(VirtualReality.head.getInterpupillaryDistance() / 2f, 0, 0)); } for (VirtualRealityRenderListener listener : listeners) { listener.frameEnded(); } VirtualReality.distortionRenderer.frameEnded(); } public void resize(int screenWidth, int screenHeight) { // TODO: set up the FBOs // TODO: what happens in case the FBO size won't be PoT? FrameBuffer fbo = new FrameBuffer(Format.RGBA4444, screenWidth, screenHeight, false); } private void renderEye(Viewport eye, Vector3 eyeOffset) { Camera camera = eye.getCamera(); Vector3 eyePosition = camera.position; eyePosition.set(VirtualReality.body.position); Vector3 headOffset = new Vector3(0, VirtualReality.head.getEyeHeight() / 2f, 0); headOffset.mul(VirtualReality.body.orientation); eyePosition.add(headOffset); Quaternion eyeOrientation = new Quaternion(); eyeOrientation.set(VirtualReality.head.getOrientation()); eyeOrientation.mul(VirtualReality.body.orientation); eyeOffset.mul(eyeOrientation); eyePosition.add(eyeOffset); Vector3 eyeDirection = new Vector3(0, 0, -1); eyeDirection.mul(eyeOrientation); Vector3 eyeUp = new Vector3(0, 1, 0); eyeUp.mul(eyeOrientation); camera.position.set(eyePosition); camera.direction.set(eyeDirection); camera.up.set(eyeUp); camera.update(true); for (VirtualRealityRenderListener listener : listeners) { listener.render(camera); } } }