/**
* Copyright 2013 Mark Browning, StellaArtois
* Licensed under the LGPL 3.0 or later (See LICENSE.md for details)
*
* Contains code from Minecraft, copyright Mojang AB
*/
package com.mtbs3d.minecrift;
import java.lang.reflect.Field;
import java.nio.FloatBuffer;
import java.util.*;
import com.mtbs3d.minecrift.api.PluginManager;
import com.mtbs3d.minecrift.render.DistortionParams;
import com.mtbs3d.minecrift.render.QuaternionHelper;
import com.mtbs3d.minecrift.render.ShaderHelper;
import com.mtbs3d.minecrift.settings.VRSettings;
import com.mtbs3d.minecrift.utils.Utils;
import de.fruitfly.ovr.EyeRenderParams;
import de.fruitfly.ovr.OculusRift;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.*;
import com.mtbs3d.minecrift.api.IOrientationProvider;
import com.mtbs3d.minecrift.control.JoystickAim;
import net.minecraft.src.*;
import org.lwjgl.util.vector.Quaternion;
import org.lwjgl.util.vector.Vector4f;
import paulscode.sound.SoundSystem;
import static java.lang.Math.ceil;
public class VRRenderer extends EntityRenderer
{
// FBO stuff
//Status & initialization
int _previousDisplayWidth = 0;
int _previousDisplayHeight = 0;
public boolean _FBOInitialised = false;
boolean guiYawOrientationResetRequested = true;
// Shader Programs
int _Distortion_shaderProgramId = -1;
int _Lanczos_shaderProgramId = -1;
int _FXAA_shaderProgramId = -1;
int _DistortionShader_DistortionMapUniform = -1;
int _DistortionShader_RenderTextureUniform = -1;
int _DistortionShader_half_screenWidthUniform = -1;
int _DistortionShader_LeftLensCenterUniform = -1;
int _DistortionShader_RightLensCenterUniform = -1;
int _DistortionShader_LeftScreenCenterUniform = -1;
int _DistortionShader_RightScreenCenterUniform = -1;
int _DistortionShader_ScaleUniform = -1;
int _DistortionShader_ScaleInUniform = -1;
int _DistortionShader_HmdWarpParamUniform = -1;
int _DistortionShader_ChromAbParamUniform = -1;
int _LanczosShader_texelWidthOffsetUniform = -1;
int _LanczosShader_texelHeightOffsetUniform = -1;
int _LanczosShader_inputImageTextureUniform = -1;
int _FXAA_RenderTextureUniform = -1;
int _FXAA_RenderedTextureSizeUniform = -1;
FBOParams fxaaFBO; // fxaa filter
FBOParams guiFBO; //This is where the GUI is rendered; it is rendered into main world as an object
FBOParams preDistortionFBO; //This is where the world is rendered
FBOParams postDistortionFBO;
FBOParams postSuperSampleFBO;
Quaternion orientation = QuaternionHelper.IDENTITY_QUATERNION;
FloatBuffer cameraMatrix4f = QuaternionHelper.quatToMatrix4fFloatBuf(orientation);
AxisAlignedBB bb;
// Render
DistortionParams distortParams;
// Sound system
Field _soundManagerSndSystemField = null;
// Enable / disable GUI menu rendering. Useful to display black only
// during game load transitions until the world is running.
public boolean blankGUIUntilWorldValid = false;
// Debug
double start = System.currentTimeMillis();
// Ghetto frame timing test
long startFrameRenderNanos = 0;
long endFrameTimeNanos = 0;
Deque<Long> frameTimeNanos = new ArrayDeque<Long>();
long startVSyncPeriodNanos = 0;
long vsyncPeriodNanos = 0;
long medianFrameTimeNanos = 0;
/*
* MC: the minecraft world rendering code, below
* GUI: the guiFBO, with GUI rendered into it
* OUT: graphics card output FB
* preD: preDistoritonFBO
* postD: postDistortionFBO
* pSS : postSuperSampleFBO
*
* No distortion, no supersample, output of world render is true video output FB
*
* +----+
* MC -render-> |OUT |
* ^ +----+
* |
* +----+
* GUI->|GUI |
* +----+
*
* Distortion, no supersample
*
* +----+ +----+
* MC -render-> |preD| -distort-> |OUT |
* ^ +----+ +----+
* |
* +----+
* GUI->|GUI |
* +----+
*
* Distortion, supersample
*
* +--------+ +--------+ +----+
* | | | | | | +----+
* MC -render-> | preD | -distort-> | postD | -supersample1-> |pSS | -supersample2-> |OUT |
* ^ +--------+ +--------+ +----+ +----+
* |
* +----+
* GUI->|GUI |
* +----+
*
* No distortion, supersample
*
* +--------+ +----+
* | | | | +----+
* MC -render-> | postD | -supersample1-> |pSS | -supersample2-> |OUT |
* ^ +--------+ +----+ +----+
* |
* +----+
* GUI->|GUI |
* +----+
*
*/
GuiAchievement guiAchievement;
EyeRenderParams eyeRenderParams;
double renderOriginX;
double renderOriginY;
double renderOriginZ;
float headYaw = 0.0F; //relative to head tracker reference frame, absolute
float headPitch = 0.0F;
float headRoll = 0.0F;
float prevHeadYaw = 0.0F;
float prevHeadPitch = 0.0F;
float prevHeadRoll = 0.0F;
float guiHeadYaw = 0.0f; //Not including mouse
float camRelX;
float camRelY;
float camRelZ;
float crossX;
float crossY;
float crossZ;
float lookX; //In world coordinates
float lookY;
float lookZ;
float aimX; //In world coordinates
float aimY;
float aimZ;
float aimYaw;
float aimPitch;
private boolean guiShowingLastFrame = false; //Used for detecting when UI is shown, fixing the guiYaw
// Calibration
private CalibrationHelper calibrationHelper;
private float INITIAL_CALIBRATION_TEXT_SCALE = 0.0065f;
private int CALIBRATION_TEXT_WORDWRAP_LEN = 40;
private boolean sndSystemReflect = true;
public VRRenderer(Minecraft par1Minecraft, GuiAchievement guiAchiv)
{
super( par1Minecraft );
this.guiAchievement = guiAchiv;
if (this.mc.vrSettings.calibrationStrategy == VRSettings.CALIBRATION_STRATEGY_AT_STARTUP)
startCalibration();
}
private float checkCameraCollision(
double camX, double camY, double camZ,
double camXOffset, double camYOffset, double camZOffset, float distance )
{
//This loop offsets at [-.1, -.1, -.1], [.1,-.1,-.1], [.1,.1,-.1] etc... for all 8 directions
for (int var20 = 0; var20 < 8; ++var20)
{
final float MIN_DISTANCE = (this.mc.vrSettings.getIPD() / 2.0f) + 0.06F;
float var21 = (float)((var20 & 1) * 2 - 1);
float var22 = (float)((var20 >> 1 & 1) * 2 - 1);
float var23 = (float)((var20 >> 2 & 1) * 2 - 1);
var21 *= 0.1F;
var22 *= 0.1F;
var23 *= 0.1F;
MovingObjectPosition var24 = this.mc.theWorld.clip(
this.mc.theWorld.getWorldVec3Pool().getVecFromPool(camX + var21, camY + var22, camZ + var23),
this.mc.theWorld.getWorldVec3Pool().getVecFromPool(camX - camXOffset + var21, camY - camYOffset + var22, camZ - camZOffset + var23));
if (var24 != null && this.mc.theWorld.isBlockOpaqueCube(var24.blockX, var24.blockY, var24.blockZ))
{
double var25 = var24.hitVec.distanceTo(this.mc.theWorld.getWorldVec3Pool().getVecFromPool(camX, camY, camZ)) - MIN_DISTANCE;
if (var25 < distance )
{
distance = (float)var25;
}
}
}
return distance;
}
/**
* sets up projection, view effects, camera position/rotation
*/
private void setupCameraTransform(float renderPartialTicks, int renderSceneNumber)
{
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
if (renderSceneNumber == 0)
{
// Left eye
FloatBuffer leftProj = eyeRenderParams.gl_getLeftProjectionMatrix();
GL11.glLoadMatrix(leftProj);
//mc.checkGLError("Set left projection");
}
else
{
// Right eye
FloatBuffer rightProj = eyeRenderParams.gl_getRightProjectionMatrix();
GL11.glLoadMatrix(rightProj);
//mc.checkGLError("Set right projection");
}
float var5;
if (this.mc.playerController != null && this.mc.playerController.enableEverythingIsScrewedUpMode())
{
var5 = 0.6666667F;
GL11.glScalef(1.0F, var5, 1.0F);
}
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
//First, IPD transformation
if (renderSceneNumber == 0)
{
// Left eye
FloatBuffer leftEyeTransform = eyeRenderParams.gl_getLeftViewportTransform();
GL11.glMultMatrix(leftEyeTransform);
}
else
{
// Right eye
FloatBuffer rightEyeTransform = eyeRenderParams.gl_getRightViewportTransform();
GL11.glMultMatrix(rightEyeTransform);
}
// Camera height offset
float cameraYOffset = 1.62f - (this.mc.vrSettings.getPlayerEyeHeight() - this.mc.vrSettings.neckBaseToEyeHeight);
EntityLivingBase entity = this.mc.renderViewEntity;
if( entity != null )
{
//Do in-game camera adjustments if renderViewEntity exists
//A few game effects
this.hurtCameraEffect(renderPartialTicks);
if (this.mc.gameSettings.viewBobbing)
{
this.setupViewBobbing(renderPartialTicks);
}
var5 = this.mc.thePlayer.prevTimeInPortal + (this.mc.thePlayer.timeInPortal - this.mc.thePlayer.prevTimeInPortal) * renderPartialTicks;
if (var5 > 0.0F)
{
byte var6 = 20;
if (this.mc.thePlayer.isPotionActive(Potion.confusion))
{
var6 = 7;
}
float var7 = 5.0F / (var5 * var5 + 5.0F) - var5 * 0.04F;
var7 *= var7;
GL11.glRotatef(((float)this.rendererUpdateCount + renderPartialTicks) * (float)var6, 0.0F, 1.0F, 1.0F);
GL11.glScalef(1.0F / var7, 1.0F, 1.0F);
GL11.glRotatef(-((float)this.rendererUpdateCount + renderPartialTicks) * (float)var6, 0.0F, 1.0F, 1.0F);
}
if (this.mc.gameSettings.thirdPersonView > 0)
{
float thirdPersonCameraDist = this.thirdPersonDistanceTemp + (this.thirdPersonDistance - this.thirdPersonDistanceTemp) * renderPartialTicks;
float thirdPersonYaw;
float thirdPersonPitch;
if (this.mc.gameSettings.debugCamEnable)
{
thirdPersonYaw = this.prevDebugCamYaw + (this.debugCamYaw - this.prevDebugCamYaw) * renderPartialTicks;
thirdPersonPitch = this.prevDebugCamPitch + (this.debugCamPitch - this.prevDebugCamPitch) * renderPartialTicks;
GL11.glTranslatef(0.0F, 0.0F, (float)(-thirdPersonCameraDist));
GL11.glRotatef(thirdPersonYaw, 1.0F, 0.0F, 0.0F);
GL11.glRotatef(thirdPersonPitch, 0.0F, 1.0F, 0.0F);
}
else
{
thirdPersonYaw = cameraYaw;
thirdPersonPitch = cameraPitch;
if (this.mc.gameSettings.thirdPersonView == 2)
{
thirdPersonPitch += 180.0F;
}
float PIOVER180 = (float)(Math.PI/180);
//For doing camera collision detection
double camX = renderOriginX + camRelX;
double camY = renderOriginY + camRelY - cameraYOffset;
double camZ = renderOriginZ + camRelZ;
float camXOffset = -MathHelper.sin(thirdPersonYaw * PIOVER180) * MathHelper.cos(thirdPersonPitch * PIOVER180 ) * thirdPersonCameraDist;
float camZOffset = MathHelper.cos(thirdPersonYaw * PIOVER180) * MathHelper.cos(thirdPersonPitch * PIOVER180 ) * thirdPersonCameraDist;
float camYOffset = -MathHelper.sin(thirdPersonPitch * PIOVER180) * thirdPersonCameraDist;
thirdPersonCameraDist = checkCameraCollision(camX, camY, camZ, camXOffset, camYOffset, camZOffset, thirdPersonCameraDist);
if (this.mc.gameSettings.thirdPersonView == 2)
{
GL11.glRotatef(180.0F, 0.0F, 1.0F, 0.0F);
}
GL11.glRotatef(cameraPitch - thirdPersonPitch, 1.0F, 0.0F, 0.0F);
GL11.glRotatef(cameraYaw - thirdPersonYaw, 0.0F, 1.0F, 0.0F);
GL11.glTranslatef(0.0F, 0.0F, (float)(-thirdPersonCameraDist));
GL11.glRotatef(thirdPersonYaw - cameraYaw, 0.0F, 1.0F, 0.0F);
GL11.glRotatef(thirdPersonPitch - cameraPitch, 1.0F, 0.0F, 0.0F);
}
}
}
if (!this.mc.gameSettings.debugCamEnable)
{
// if (this.mc.vrSettings.useQuaternions)
// {
// //GL11.glMultMatrix(cameraMatrix4f); // This doesn't work currently - we still need
// // the weird +180...
//
// // So do this instead...
// float[] rawYawPitchRoll = OculusRift.getEulerAngles(orientation.x,
// orientation.y,
// orientation.z,
// orientation.w,
// 1f,
// OculusRift.HANDED_L,
// OculusRift.ROTATE_CCW);
//
// if (this.mc.gameSettings.thirdPersonView == 2)
// GL11.glRotatef(-rawYawPitchRoll[2], 0.0F, 0.0F, 1.0F);
// else
// GL11.glRotatef(rawYawPitchRoll[2], 0.0F, 0.0F, 1.0F);
//
// GL11.glRotatef(rawYawPitchRoll[1], 1.0F, 0.0F, 0.0F);
// GL11.glRotatef(rawYawPitchRoll[0] + 180.0F, 0.0F, 1.0F, 0.0F);
// }
// else
// {
if (this.mc.gameSettings.thirdPersonView == 2)
GL11.glRotatef(-this.cameraRoll, 0.0F, 0.0F, 1.0F);
else
GL11.glRotatef(this.cameraRoll, 0.0F, 0.0F, 1.0F);
GL11.glRotatef(this.cameraPitch, 1.0F, 0.0F, 0.0F);
GL11.glRotatef(this.cameraYaw + 180.0F, 0.0F, 1.0F, 0.0F);
// }
}
GL11.glTranslated(-camRelX, cameraYOffset - camRelY, -camRelZ);
if (this.debugViewDirection > 0)
{
int var8 = this.debugViewDirection - 1;
if (var8 == 1)
{
GL11.glRotatef(90.0F, 0.0F, 1.0F, 0.0F);
}
if (var8 == 2)
{
GL11.glRotatef(180.0F, 0.0F, 1.0F, 0.0F);
}
if (var8 == 3)
{
GL11.glRotatef(-90.0F, 0.0F, 1.0F, 0.0F);
}
if (var8 == 4)
{
GL11.glRotatef(90.0F, 1.0F, 0.0F, 0.0F);
}
if (var8 == 5)
{
GL11.glRotatef(-90.0F, 1.0F, 0.0F, 0.0F);
}
}
}
/**
* Sets the listener of sounds
*/
public void setSoundListenerOrientation()
{
SoundSystem sndSystem = null;
// Use reflection to get the sndManager
if (sndSystemReflect && _soundManagerSndSystemField == null)
{
try
{
_soundManagerSndSystemField = SoundManager.class.getDeclaredField("sndSystem");
System.out.println("VRRender: Reflected sndSystem");
}
catch (NoSuchFieldException e) {
try
{
_soundManagerSndSystemField = SoundManager.class.getDeclaredField("b"); //obfuscated name
System.out.println("VRRender: Reflected obfuscated b");
}
catch (NoSuchFieldException e1) {
System.out.println("VRRender: got sndSystem directly");
sndSystemReflect = false;
};
}
if (_soundManagerSndSystemField != null)
_soundManagerSndSystemField.setAccessible(true);
}
if(!sndSystemReflect ){
if( this.mc.sndManager != null )
sndSystem = this.mc.sndManager.sndSystem;
}
if (_soundManagerSndSystemField != null && this.mc.sndManager != null)
{
try
{
sndSystem = (SoundSystem)_soundManagerSndSystemField.get(this.mc.sndManager);
}
catch (IllegalArgumentException e) { }
catch (IllegalAccessException e) { };
}
float PIOVER180 = (float)(Math.PI/180);
Vec3 up = Vec3.createVectorHelper(0, 1, 0);
up.rotateAroundZ(-cameraRoll * PIOVER180);
up.rotateAroundX(-cameraPitch* PIOVER180);
up.rotateAroundY(-cameraYaw * PIOVER180);
if ( sndSystem != null && this.mc.gameSettings.soundVolume != 0.0F)
{
sndSystem.setListenerPosition((float)renderOriginX, (float)renderOriginY, (float)renderOriginZ);
sndSystem.setListenerOrientation(lookX, lookY, lookZ,
(float)up.xCoord, (float)up.yCoord, (float)up.zCoord);
}
if( mc.mumbleLink != null ) {
Vec3 forward = Vec3.createVectorHelper(0, 0 , -1);
forward.rotateAroundZ(-cameraRoll * PIOVER180);
forward.rotateAroundX(-cameraPitch* PIOVER180);
forward.rotateAroundY(-cameraYaw * PIOVER180);
mc.mumbleLink.updateMumble(
(float)renderOriginX, (float)renderOriginY, (float)renderOriginZ,
(float)forward.xCoord, (float)forward.yCoord, (float)forward.zCoord,
(float)up.xCoord, (float)up.yCoord, (float)up.zCoord);
}
}
public void updateCamera( float renderPartialTicks, boolean displayActive )
{
//int millis = (int)(System.currentTimeMillis() - start);
//System.out.println("Update camera! " + millis + "ms");
float PIOVER180 = (float)(Math.PI/180);
EntityLivingBase entity = this.mc.renderViewEntity;
//runs a step of calibration
if(calibrationHelper != null && calibrationHelper.allPluginsCalibrated())
{
calibrationHelper = null;
}
if (this.mc.vrSettings.posTrackResetPosition)
{
mc.positionTracker.resetOrigin();
mc.headTracker.resetOrigin();
resetGuiYawOrientation();
this.mc.vrSettings.posTrackResetPosition = false;
}
// Poll sensors. We may actually sleep inside this
// to reduce latency.
pollSensors();
if(JoystickAim.selectedJoystickMode != null)
JoystickAim.selectedJoystickMode.update( renderPartialTicks );
float lookYawOffset = mc.lookaimController.getBodyYawDegrees();
float lookPitchOffset = mc.lookaimController.getBodyPitchDegrees();
if (mc.headTracker.isInitialized() && this.mc.vrSettings.useHeadTracking)
{
this.mc.mcProfiler.startSection("oculus");
prevHeadYaw = headYaw;
prevHeadPitch = headPitch;
prevHeadRoll = headRoll;
if (this.mc.vrSettings.useQuaternions == false)
{
// Get Euler angles
headRoll = mc.headTracker.getHeadRollDegrees() * this.mc.vrSettings.getHeadTrackSensitivity();
headPitch = mc.headTracker.getHeadPitchDegrees() * this.mc.vrSettings.getHeadTrackSensitivity();
headYaw = mc.headTracker.getHeadYawDegrees() * this.mc.vrSettings.getHeadTrackSensitivity();
cameraPitch = (lookPitchOffset + headPitch )%180;
cameraYaw = (lookYawOffset + headYaw ) % 360;
cameraRoll = headRoll;
// Correct for gimbal lock prevention
if (cameraPitch > IOrientationProvider.MAXPITCH)
cameraPitch = IOrientationProvider.MAXPITCH;
else if (cameraPitch < -IOrientationProvider.MAXPITCH)
cameraPitch = -IOrientationProvider.MAXPITCH;
if (cameraRoll > IOrientationProvider.MAXROLL)
cameraRoll = IOrientationProvider.MAXROLL;
else if (cameraRoll < -IOrientationProvider.MAXROLL)
cameraRoll = -IOrientationProvider.MAXROLL;
}
else
{
// Get the tracker orientation quaternion
orientation = mc.headTracker.getOrientationQuaternion();
// TODO: This does not work currently
// Scale the rotation if necessary
if (this.mc.vrSettings.getHeadTrackSensitivity() != 1f)
{
// System.out.println(String.format("Head track sensitivity: %.2f", new Object[] {Float.valueOf(this.mc.vrSettings.headTrackSensitivity)}));
// QuaternionHelper.dump("RAW", orientation);
//
// Quaternion orientation1 = QuaternionHelper.clone(orientation);
// orientation1.normalise();
// Quaternion orientation2 = QuaternionHelper.clone(orientation);
// orientation2.normalise();
//
// Test 1
// //orientation = QuaternionHelper.pow(orientation, (float)Math.floor(this.mc.vrSettings.headTrackSensitivity));
//
// Test 2
// //Quaternion.mul(orientation2, QuaternionHelper.IDENTITY_QUATERNION, orientation);
// //Quaternion.mul(orientation1, orientation, orientation);
// //orientation.normalise();
//
// Test 3
// //orientation = QuaternionHelper.slerp2(QuaternionHelper.IDENTITY_QUATERNION, newOrientation, this.mc.vrSettings.headTrackSensitivity);
//
// QuaternionHelper.dump("NEW", orientation);
}
// Get 'raw' tracker orientation
float[] rawYawPitchRoll = OculusRift.getEulerAngles(orientation.x,
orientation.y,
orientation.z,
orientation.w,
1f,
OculusRift.HANDED_L,
OculusRift.ROTATE_CCW);
headYaw = rawYawPitchRoll[0];
headPitch = rawYawPitchRoll[1];
headRoll = rawYawPitchRoll[2];
// Apply pitch offset
Quaternion pitchCorrection = new Quaternion();
Vector4f vecAxisPitchAngle = new Vector4f(1f, 0f, 0f, -lookPitchOffset * PIOVER180);
pitchCorrection.setFromAxisAngle(vecAxisPitchAngle);
Quaternion.mul(pitchCorrection, orientation, orientation);
// Apply yaw offset
Quaternion yawCorrection = new Quaternion();
Vector4f vecAxisYawAngle = new Vector4f(0f, 1f, 0f, (-lookYawOffset * PIOVER180));
yawCorrection.setFromAxisAngle(vecAxisYawAngle);
Quaternion.mul(yawCorrection, orientation, orientation);
// Get camera orientation:
// Matrix
cameraMatrix4f = QuaternionHelper.quatToMatrix4fFloatBuf(orientation);
// Euler
float[] correctedYawPitchRoll = OculusRift.getEulerAngles(orientation.x,
orientation.y,
orientation.z,
orientation.w,
1f,
OculusRift.HANDED_L,
OculusRift.ROTATE_CCW);
cameraYaw = correctedYawPitchRoll[0];
cameraPitch = correctedYawPitchRoll[1];
cameraRoll = correctedYawPitchRoll[2];
}
if (this.mc.vrSettings.debugPose)
{
System.out.println(String.format("headYaw: %.2f, headPitch: %.2f, headRoll: %.2f", new Object[] {Float.valueOf(headYaw), Float.valueOf(headPitch), Float.valueOf(headRoll)}));
System.out.println(String.format("cameraYaw: %.2f, cameraPitch: %.2f, cameraRoll: %.2f", new Object[] {Float.valueOf(cameraYaw), Float.valueOf(cameraPitch), Float.valueOf(cameraRoll)}));
}
this.mc.mcProfiler.endSection();
}
else
{
cameraRoll = 0;
cameraPitch = lookPitchOffset;
cameraYaw = lookYawOffset;
}
if( entity != null )
{
//set movement direction
if( this.mc.vrSettings.lookMoveDecoupled )
entity.rotationYaw = lookYawOffset;
else
entity.rotationYaw = cameraYaw;
entity.rotationYawHead = cameraYaw;
entity.rotationPitch = cameraPitch;
}
if( this.mc.vrSettings.aimKeyholeWidthDegrees > 0 )
aimYaw = mc.lookaimController.getAimYaw();
else
aimYaw = cameraYaw;
if( this.mc.vrSettings.keyholeHeight > 0 )
aimPitch = mc.lookaimController.getAimPitch();
else
aimPitch = cameraPitch;
aimPitch -= this.mc.vrSettings.aimPitchOffset;
//TODO: not sure if headPitch or cameraPitch is better here... they really should be the same; silly
//people with their "pitch affects camera" settings.
//At any rate, using cameraPitch makes the UI look less silly
mc.positionTracker.update(headYaw, cameraPitch, cameraRoll, lookYawOffset, 0.0f, 0.0f);
//Do head/neck model in non-GL math so we can use camera location(between eyes)
Vec3 cameraOffset = mc.positionTracker.getCenterEyePosition();
cameraOffset.rotateAroundY((float)Math.PI);
//The worldOrigin is at player "eye height" (1.62) above foot position
camRelX = (float)cameraOffset.xCoord; camRelY = (float)cameraOffset.yCoord; camRelZ = (float)cameraOffset.zCoord;
if(this.mc.theWorld != null && this.mc.gameSettings.thirdPersonView == 0)
{
float fulldist = (float)(Math.sqrt( camRelX * camRelX + camRelY * camRelY + camRelZ * camRelZ ));
float cameraYOffset = 1.62f - (this.mc.vrSettings.getPlayerEyeHeight() - this.mc.vrSettings.neckBaseToEyeHeight);
float colldist = checkCameraCollision(renderOriginX, renderOriginY - cameraYOffset, renderOriginZ,
-camRelX, -camRelY, -camRelZ, fulldist );
if( colldist != fulldist )
{
// #47 Removed additional scale factor
float scale = colldist/fulldist;
camRelX *= scale;
camRelY *= scale;
camRelZ *= scale;
}
}
Vec3 look = Vec3.createVectorHelper(0, 0, 1);
look.rotateAroundX(-cameraPitch* PIOVER180);
look.rotateAroundY(-cameraYaw * PIOVER180);
lookX = (float)look.xCoord; lookY = (float)look.yCoord; lookZ = (float)look.zCoord;
Vec3 aim = Vec3.createVectorHelper(0, 0, 1);
aim.rotateAroundX(-aimPitch * PIOVER180);
aim.rotateAroundY(-aimYaw * PIOVER180);
aimX = (float)aim.xCoord; aimY = (float)aim.yCoord; aimZ = (float)aim.zCoord;
if(guiYawOrientationResetRequested)
{
//Hit once at startup and if reset requested (usually during calibration when an origin
//has been set)
guiHeadYaw = cameraYaw;
guiYawOrientationResetRequested = false;
guiShowingLastFrame = false;
}
}
public void renderGUIandWorld(float renderPartialTicks)
{
this.farPlaneDistance = (float)this.mc.gameSettings.ofRenderDistanceFine;
if (Config.isFogFancy())
{
this.farPlaneDistance *= 0.95F;
}
if (Config.isFogFast())
{
this.farPlaneDistance *= 0.83F;
}
if (this.prevFarPlaneDistance != this.farPlaneDistance)
{
_FBOInitialised = false;
this.prevFarPlaneDistance = this.farPlaneDistance;
}
//Ensure FBO are in place and initialized
if (!setupFBOs())
return;
boolean guiShowingThisFrame = false;
int mouseX = 0;
int mouseY = 0;
ScaledResolution var15 = new ScaledResolution(this.mc.gameSettings, this.mc.displayWidth, this.mc.displayHeight);
int var16 = var15.getScaledWidth();
int var17 = var15.getScaledHeight();
if ( (this.mc.theWorld != null && !this.mc.gameSettings.hideGUI && this.mc.thePlayer.getSleepTimer() == 0) || this.mc.currentScreen != null || this.mc.loadingScreen.isEnabled())
{
//Render all UI elements into guiFBO
mouseX = Mouse.getX() * var16 / this.mc.displayWidth;
mouseY = var17 - Mouse.getY() * var17 / this.mc.displayHeight - 1;
guiFBO.bindRenderTarget();
GL11.glViewport(0, 0, this.mc.displayWidth, this.mc.displayHeight);
GL11.glClearColor(0, 0, 0, 0);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT );
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0.0D, var15.getScaledWidth_double(), var15.getScaledHeight_double(), 0.0D, 1000.0D, 3000.0D);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
GL11.glTranslatef(0.0F, 0.0F, -2000.0F);
guiShowingThisFrame = true;
}
// Display loading / progress window if necessary
if (this.mc.loadingScreen.isEnabled())
{
this.mc.loadingScreen.vrRender(var16, var17);
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT );
}
else if (this.mc.theWorld != null && !this.mc.gameSettings.hideGUI && !this.blankGUIUntilWorldValid)
{
//Disable any forge gui crosshairs and helmet overlay (pumkinblur)
if( Reflector.ForgeGuiIngame_renderCrosshairs.exists())
{
Reflector.ForgeGuiIngame_renderCrosshairs.setValue(false);
Reflector.ForgeGuiIngame_renderHelmet.setValue(false);
}
//Draw in game GUI
this.mc.ingameGUI.renderGameOverlay(renderPartialTicks, this.mc.currentScreen != null, mouseX, mouseY);
guiAchievement.updateAchievementWindow();
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT );
}
if (this.blankGUIUntilWorldValid)
{
if (this.mc.theWorld != null)
this.blankGUIUntilWorldValid = false;
}
if( this.mc.loadingScreen.isEnabled() == false && this.mc.currentScreen != null && !this.blankGUIUntilWorldValid)
{
try
{
this.mc.currentScreen.drawScreen(mouseX, mouseY, renderPartialTicks);
}
catch (Throwable var13)
{
CrashReport var11 = CrashReport.makeCrashReport(var13, "Rendering screen");
throw new ReportedException(var11);
}
GL11.glDisable(GL11.GL_LIGHTING); //inventory messes up fog color sometimes... This fixes
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
drawMouseQuad( mouseX, mouseY );
}
//Setup render target
if (mc.vrSettings.useDistortion)
{
preDistortionFBO.bindRenderTarget();
}
else if (this.mc.vrSettings.useSupersample)
{
postDistortionFBO.bindRenderTarget();
eyeRenderParams._renderScale = 1.0f;
}
else
{
unbindFBORenderTarget();
eyeRenderParams._renderScale = 1.0f;
}
GL11.glClearColor(0, 0, 0, 1);
GL11.glEnable(GL11.GL_SCISSOR_TEST);
if (this.mc.theWorld != null)
{
//If we're in-game, render in-game stuff
this.mc.mcProfiler.startSection("level");
if (this.mc.renderViewEntity == null)
{
this.mc.renderViewEntity = this.mc.thePlayer;
}
EntityLivingBase renderViewEntity = this.mc.renderViewEntity;
this.mc.mcProfiler.endStartSection("center");
//Used by fog comparison, 3rd person camera/block collision detection
renderOriginX = renderViewEntity.lastTickPosX + (renderViewEntity.posX - renderViewEntity.lastTickPosX) * (double)renderPartialTicks;
renderOriginY = renderViewEntity.lastTickPosY + (renderViewEntity.posY - renderViewEntity.lastTickPosY) * (double)renderPartialTicks;
renderOriginZ = renderViewEntity.lastTickPosZ + (renderViewEntity.posZ - renderViewEntity.lastTickPosZ) * (double)renderPartialTicks;
if( this.mc.currentScreen == null )
{
this.mc.mcProfiler.endStartSection("pick");
getPointedBlock(renderPartialTicks);
}
// Update sound engine
setSoundListenerOrientation();
}
//Update gui Yaw
if( guiShowingThisFrame && !guiShowingLastFrame )
{
guiHeadYaw = this.cameraYaw - this.mc.lookaimController.getBodyYawDegrees();
}
guiShowingLastFrame = guiShowingThisFrame;
//Now, actually render world
for (int renderSceneNumber = 0; renderSceneNumber < 2; ++renderSceneNumber)
{
setupEyeViewport( renderSceneNumber );
this.mc.mcProfiler.endStartSection("camera");
//transform camera with pitch,yaw,roll + neck model + game effects
setupCameraTransform(renderPartialTicks, renderSceneNumber);
if( this.mc.theWorld != null )
{
GL11.glMatrixMode(GL11.GL_MODELVIEW );
GL11.glPushMatrix();
this.renderWorld(renderPartialTicks, 0L, renderSceneNumber );
this.disableLightmap(renderPartialTicks);
GL11.glMatrixMode(GL11.GL_MODELVIEW );
GL11.glPopMatrix();
}
else
{
GL11.glClear (GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer on the framebuffer to black
GL11.glDisable(GL11.GL_BLEND);
}
if( guiShowingThisFrame )
{
GL11.glPushMatrix();
GL11.glEnable(GL11.GL_TEXTURE_2D);
guiFBO.bindTexture();
// Prevent black border at top / bottom of GUI
GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
if (this.mc.theWorld != null && this.mc.vrSettings.hudLockToHead)
{
GL11.glLoadIdentity();
if (renderSceneNumber == 0)
GL11.glMultMatrix(eyeRenderParams.gl_getLeftViewportTransform());
else
GL11.glMultMatrix(eyeRenderParams.gl_getRightViewportTransform());
GL11.glRotatef(180f - this.mc.vrSettings.hudYawOffset, 0f, 1f, 0f);
GL11.glRotatef(-this.mc.vrSettings.hudPitchOffset, 1f, 0f, 0f);
// GL11.glRotatef(cameraRoll, 0f, 0f, 1f);
GL11.glTranslatef (0.0f, 0.0f, this.mc.vrSettings.hudDistance - this.mc.vrSettings.eyeProtrusion);
GL11.glRotatef( 180f, 0f, 1f, 0f);//Not sure why this is necessary... normals/backface culling maybe?
}
else
{
float guiYaw = 0f;
if( this.mc.theWorld != null)
{
if(this.mc.vrSettings.lookMoveDecoupled)
guiYaw = this.mc.lookaimController.getBodyYawDegrees();
else
guiYaw = guiHeadYaw + this.mc.lookaimController.getBodyYawDegrees();
guiYaw -= this.mc.vrSettings.hudYawOffset;
}
else
guiYaw = guiHeadYaw + this.mc.lookaimController.getBodyYawDegrees();
GL11.glRotatef(-guiYaw, 0f, 1f, 0f);
float guiPitch = 0f;
if (this.mc.theWorld != null)
guiPitch = -this.mc.vrSettings.hudPitchOffset;
// if( this.mc.vrSettings.allowMousePitchInput)
// guiPitch += this.mc.lookaimController.getBodyPitchDegrees();
GL11.glRotatef(guiPitch, 1f, 0f, 0f);
GL11.glTranslatef (0.0f, 0.0f, this.mc.vrSettings.hudDistance);
GL11.glRotatef( 180f, 0f, 1f, 0f);//Not sure why this is necessary... normals/backface culling maybe?
}
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
if( this.mc.theWorld != null )
GL11.glColor4f(1, 1, 1, this.mc.vrSettings.hudOpacity);
else
GL11.glColor4f(1, 1, 1, 1);
if (!this.mc.vrSettings.hudOcclusion)
GL11.glDisable(GL11.GL_DEPTH_TEST);
drawQuad2(this.mc.displayWidth,this.mc.displayHeight,this.mc.vrSettings.hudScale*this.mc.vrSettings.hudDistance);
GL11.glDisable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glPopMatrix();
unbindTexture();
//mc.checkGLError("GUI");
}
if( calibrationHelper != null )
{
float x = lookX*mc.vrSettings.hudDistance;
float y = lookY*mc.vrSettings.hudDistance;
float z = lookZ*mc.vrSettings.hudDistance;
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glPushMatrix();
GL11.glTranslatef(x,y,z);
GL11.glRotatef(-this.cameraYaw, 0.0F, 1.0F, 0.0F);
GL11.glRotatef(this.cameraPitch, 1.0F, 0.0F, 0.0F);
GL11.glRotatef(this.cameraRoll, 0.0F, 0.0F, 1.0F);
float textScale = (float)Math.sqrt((x*x + y*y + z*z));
GL11.glScalef(-INITIAL_CALIBRATION_TEXT_SCALE * textScale, -INITIAL_CALIBRATION_TEXT_SCALE * textScale, -INITIAL_CALIBRATION_TEXT_SCALE * textScale);
String calibrating = "Calibrating "+calibrationHelper.currentPlugin.getName()+"...";
mc.fontRenderer.drawStringWithShadow(calibrating, -mc.fontRenderer.getStringWidth(calibrating)/2, -8, /*white*/16777215);
String calibrationStep = calibrationHelper.calibrationStep;
// mc.fontRenderer.drawStringWithShadow(calibrationStep, -mc.fontRenderer.getStringWidth(calibrationStep)/2, 8, /*white*/16777215);
int column = 8;
ArrayList<String> wrapped = new ArrayList<String>();
Utils.wordWrap(calibrationStep, CALIBRATION_TEXT_WORDWRAP_LEN, wrapped);
for (String line : wrapped)
{
mc.fontRenderer.drawStringWithShadow(line, -mc.fontRenderer.getStringWidth(line)/2, column, /*white*/16777215);
column+=16;
}
GL11.glPopMatrix();
GL11.glEnable(GL11.GL_DEPTH_TEST);
}
}
GL11.glDisable(GL11.GL_SCISSOR_TEST);
doDistortionAndSuperSample();
checkLatencyTester();
// Finish frame
GL11.glFinish();
// Get end frame timings
endFrameTimeNanos = startVSyncPeriodNanos = System.nanoTime();
long frameTime = endFrameTimeNanos - startFrameRenderNanos;
addRenderFrameTimeNanos(frameTime);
mc.checkGLError("After render world and GUI");
}
private void checkLatencyTester()
{
// Latency tester
if (this.mc.hmdInfo != null)
{
// Get any 'test in progress' quad to draw
float[] rgba = this.mc.hmdInfo.latencyTesterDisplayScreenColor();
if (rgba != null)
{
// Latency tester is expecting a colored quad on screen...
drawLatencyTesterColoredQuad(rgba[0], rgba[1], rgba[2], rgba[3]);
}
//drawLatencyTesterColoredQuad(1f, 0f, 0f, 0.80f);
// Get any latency tester results...
String latencyTestResults = this.mc.hmdInfo.latencyTesterGetResultsString();
if (latencyTestResults != null)
{
// Display results
this.mc.printChatMessage(latencyTestResults);
System.out.println(latencyTestResults);
}
}
}
private boolean setupFBOs()
{
try {
if (this.mc.displayFBWidth != _previousDisplayWidth || this.mc.displayFBHeight != _previousDisplayHeight || !_FBOInitialised) {
_FBOInitialised = false;
_previousDisplayWidth = this.mc.displayFBWidth;
_previousDisplayHeight = this.mc.displayFBHeight;
_DistortionShader_DistortionMapUniform = -1;
_DistortionShader_RenderTextureUniform = -1;
_DistortionShader_half_screenWidthUniform = -1;
_DistortionShader_LeftLensCenterUniform = -1;
_DistortionShader_RightLensCenterUniform = -1;
_DistortionShader_LeftScreenCenterUniform = -1;
_DistortionShader_RightScreenCenterUniform = -1;
_DistortionShader_ScaleUniform = -1;
_DistortionShader_ScaleInUniform = -1;
_DistortionShader_HmdWarpParamUniform = -1;
_DistortionShader_ChromAbParamUniform = -1;
if (preDistortionFBO != null)
preDistortionFBO.delete();
preDistortionFBO = null;
if (guiFBO != null)
guiFBO.delete();
guiFBO = null;
if (fxaaFBO != null)
fxaaFBO.delete();
fxaaFBO = null;
if (postDistortionFBO != null)
postDistortionFBO.delete();
postDistortionFBO = null;
if (postSuperSampleFBO != null)
postSuperSampleFBO.delete();
postSuperSampleFBO = null;
_LanczosShader_texelWidthOffsetUniform = -1;
_LanczosShader_texelHeightOffsetUniform = -1;
_LanczosShader_inputImageTextureUniform = -1;
if (distortParams != null)
distortParams.delete();
}
if (!_FBOInitialised)
{
float distance = this.farPlaneDistance * 2.0F;
if (distance < 128.0F) {
distance = 128.0F;
}
//Setup eye render params
if (this.mc.vrSettings.useSupersample) {
eyeRenderParams = mc.hmdInfo.getEyeRenderParams(0,
0,
(int) ceil(this.mc.displayFBWidth * this.mc.vrSettings.superSampleScaleFactor),
(int) ceil(this.mc.displayFBHeight * this.mc.vrSettings.superSampleScaleFactor),
0.05F,
distance,
this.mc.vrSettings.fovScaleFactor,
this.mc.vrSettings.lensSeparationScaleFactor,
getDistortionFitX(),
getDistortionFitY(),
this.mc.vrSettings.getAspectRatioCorrectionMode());
} else {
eyeRenderParams = mc.hmdInfo.getEyeRenderParams(0,
0,
this.mc.displayFBWidth,
this.mc.displayFBHeight,
0.05F,
distance,
this.mc.vrSettings.fovScaleFactor,
this.mc.vrSettings.lensSeparationScaleFactor,
getDistortionFitX(),
getDistortionFitY(),
this.mc.vrSettings.getAspectRatioCorrectionMode());
}
System.out.println("[Minecrift] INITIALISE Display");
System.out.println("[Minecrift] Distortion: " + (this.mc.vrSettings.useDistortion ? "ON" : "OFF"));
System.out.println("[Minecrift] Display w: " + this.mc.displayFBWidth + ", h: " + this.mc.displayFBHeight);
System.out.println("[Minecrift] Renderscale: " + eyeRenderParams._renderScale);
if (this.mc.vrSettings.useSupersample)
System.out.println("[Minecrift] FSAA Scale: " + this.mc.vrSettings.superSampleScaleFactor);
else
System.out.println("[Minecrift] FSAA OFF");
if (this.mc.vrSettings.useSupersample) {
preDistortionFBO = new FBOParams("preDistortionFBO (SS)", GL11.GL_TEXTURE_2D, GL11.GL_RGBA8, GL11.GL_RGBA, GL11.GL_INT, (int) ceil(this.mc.displayFBWidth * eyeRenderParams._renderScale * this.mc.vrSettings.superSampleScaleFactor), (int) ceil(this.mc.displayFBHeight * eyeRenderParams._renderScale * this.mc.vrSettings.superSampleScaleFactor));
} else {
preDistortionFBO = new FBOParams("preDistortionFBO", GL11.GL_TEXTURE_2D, GL11.GL_RGBA8, GL11.GL_RGBA, GL11.GL_INT, (int) ceil(this.mc.displayFBWidth * eyeRenderParams._renderScale), (int) ceil(this.mc.displayFBHeight * eyeRenderParams._renderScale));
}
mc.checkGLError("FBO create");
if (this.mc.vrSettings.useDistortionTextureLookupOptimisation) {
if (this.mc.vrSettings.useChromaticAbCorrection) {
_Distortion_shaderProgramId = ShaderHelper.initShaders(BASIC_VERTEX_SHADER, OCULUS_DISTORTION_FRAGMENT_SHADER_WITH_CHROMATIC_ABERRATION_CORRECTION_DIST_MAP, false);
} else {
_Distortion_shaderProgramId = ShaderHelper.initShaders(BASIC_VERTEX_SHADER, OCULUS_DISTORTION_FRAGMENT_SHADER_NO_CHROMATIC_ABERRATION_CORRECTION_DIST_MAP, false);
}
} else {
if (this.mc.vrSettings.useChromaticAbCorrection) {
_Distortion_shaderProgramId = ShaderHelper.initShaders(BASIC_VERTEX_SHADER, OCULUS_DISTORTION_FRAGMENT_SHADER_WITH_CHROMATIC_ABERRATION_CORRECTION, false);
} else {
_Distortion_shaderProgramId = ShaderHelper.initShaders(BASIC_VERTEX_SHADER, OCULUS_DISTORTION_FRAGMENT_SHADER_NO_CHROMATIC_ABERRATION_CORRECTION, false);
}
}
// Setup uniform IDs
_DistortionShader_DistortionMapUniform = ARBShaderObjects.glGetUniformLocationARB(_Distortion_shaderProgramId, "distortionMap");
_DistortionShader_RenderTextureUniform = ARBShaderObjects.glGetUniformLocationARB(_Distortion_shaderProgramId, "bgl_RenderTexture");
_DistortionShader_half_screenWidthUniform = ARBShaderObjects.glGetUniformLocationARB(_Distortion_shaderProgramId, "half_screenWidth");
_DistortionShader_LeftLensCenterUniform = ARBShaderObjects.glGetUniformLocationARB(_Distortion_shaderProgramId, "LeftLensCenter");
_DistortionShader_RightLensCenterUniform = ARBShaderObjects.glGetUniformLocationARB(_Distortion_shaderProgramId, "RightLensCenter");
_DistortionShader_LeftScreenCenterUniform = ARBShaderObjects.glGetUniformLocationARB(_Distortion_shaderProgramId, "LeftScreenCenter");
_DistortionShader_RightScreenCenterUniform = ARBShaderObjects.glGetUniformLocationARB(_Distortion_shaderProgramId, "RightScreenCenter");
_DistortionShader_ScaleUniform = ARBShaderObjects.glGetUniformLocationARB(_Distortion_shaderProgramId, "Scale");
_DistortionShader_ScaleInUniform = ARBShaderObjects.glGetUniformLocationARB(_Distortion_shaderProgramId, "ScaleIn");
_DistortionShader_HmdWarpParamUniform = ARBShaderObjects.glGetUniformLocationARB(_Distortion_shaderProgramId, "HmdWarpParam");
_DistortionShader_ChromAbParamUniform = ARBShaderObjects.glGetUniformLocationARB(_Distortion_shaderProgramId, "ChromAbParam");
ShaderHelper.checkGLError("FBO init shader");
// GUI FBO
guiFBO = new FBOParams("guiFBO", GL11.GL_TEXTURE_2D, GL11.GL_RGBA8, GL11.GL_RGBA, GL11.GL_INT, this.mc.displayWidth, this.mc.displayHeight);
// FXAA FBO
if (this.mc.vrSettings.useFXAA) {
// Shader init
_FXAA_shaderProgramId = ShaderHelper.initShaders(BASIC_VERTEX_SHADER, FXAA_FRAGMENT_SHADER, false);
_FXAA_RenderTextureUniform = ARBShaderObjects.glGetUniformLocationARB(_FXAA_shaderProgramId, "sampler0");
_FXAA_RenderedTextureSizeUniform = ARBShaderObjects.glGetUniformLocationARB(_FXAA_shaderProgramId, "resolution");
if (this.mc.vrSettings.useSupersample) {
fxaaFBO = new FBOParams("fxaaFBO", GL11.GL_TEXTURE_2D, GL11.GL_RGBA8, GL11.GL_RGBA, GL11.GL_INT, (int) ceil(this.mc.displayFBWidth * this.mc.vrSettings.superSampleScaleFactor), (int) ceil(this.mc.displayFBHeight * this.mc.vrSettings.superSampleScaleFactor));
} else {
fxaaFBO = new FBOParams("fxaaFBO", GL11.GL_TEXTURE_2D, GL11.GL_RGBA8, GL11.GL_RGBA, GL11.GL_INT, this.mc.displayFBWidth, this.mc.displayFBHeight);
}
ShaderHelper.checkGLError("Init FXAA");
}
if (this.mc.vrSettings.useSupersample) {
// Lanczos downsample FBOs
postDistortionFBO = new FBOParams("postDistortionFBO (SS)", GL11.GL_TEXTURE_2D, GL11.GL_RGBA8, GL11.GL_RGBA, GL11.GL_INT, (int) ceil(this.mc.displayFBWidth * this.mc.vrSettings.superSampleScaleFactor), (int) ceil(this.mc.displayFBHeight * this.mc.vrSettings.superSampleScaleFactor));
postSuperSampleFBO = new FBOParams("postSuperSampleFBO (SS)", GL11.GL_TEXTURE_2D, GL11.GL_RGBA8, GL11.GL_RGBA, GL11.GL_INT, (int) ceil(this.mc.displayFBWidth), (int) ceil(this.mc.displayFBHeight * this.mc.vrSettings.superSampleScaleFactor));
mc.checkGLError("Lanczos FBO create");
_Lanczos_shaderProgramId = ShaderHelper.initShaders(LANCZOS_SAMPLER_VERTEX_SHADER, LANCZOS_SAMPLER_FRAGMENT_SHADER, true);
ShaderHelper.checkGLError("@1");
GL20.glValidateProgram(_Lanczos_shaderProgramId);
// Setup uniform IDs
_LanczosShader_texelWidthOffsetUniform = ARBShaderObjects.glGetUniformLocationARB(_Lanczos_shaderProgramId, "texelWidthOffset");
_LanczosShader_texelHeightOffsetUniform = ARBShaderObjects.glGetUniformLocationARB(_Lanczos_shaderProgramId, "texelHeightOffset");
_LanczosShader_inputImageTextureUniform = ARBShaderObjects.glGetUniformLocationARB(_Lanczos_shaderProgramId, "inputImageTexture");
ShaderHelper.checkGLError("FBO init Lanczos shader");
} else {
_Lanczos_shaderProgramId = -1;
_LanczosShader_texelWidthOffsetUniform = -1;
_LanczosShader_texelHeightOffsetUniform = -1;
_LanczosShader_inputImageTextureUniform = -1;
}
// Pre-calculate distortion map
distortParams = new DistortionParams(this.mc.hmdInfo.getHMDInfo(),
this.eyeRenderParams,
this.mc.displayFBWidth,
this.mc.displayFBHeight,
this.mc.vrSettings.useChromaticAbCorrection,
this.mc.vrSettings.useSupersample,
this.mc.vrSettings.superSampleScaleFactor);
// Get our refresh period
int Hz = Display.getDisplayMode().getFrequency();
if (Hz != 0)
vsyncPeriodNanos = 1000000000L / Hz;
else
vsyncPeriodNanos = 0;
_FBOInitialised = true;
}
}
catch (Exception ex)
{
// We had an issue. Set the usual suspects to defaults...
this.mc.vrSettings.useSupersample = false;
this.mc.vrSettings.superSampleScaleFactor = 2.0f;
this.mc.vrSettings.saveOptions();
return false;
}
return true;
}
private void setupEyeViewport( int renderSceneNumber )
{
this.mc.mcProfiler.endStartSection("clear");
if (renderSceneNumber == 0)
{
// Left eye
GL11.glViewport((int)ceil(eyeRenderParams._leftViewPortX * eyeRenderParams._renderScale),
(int)ceil(eyeRenderParams._leftViewPortY * eyeRenderParams._renderScale),
(int)ceil(eyeRenderParams._leftViewPortW * eyeRenderParams._renderScale),
(int)ceil(eyeRenderParams._leftViewPortH * eyeRenderParams._renderScale));
GL11.glScissor((int)ceil(eyeRenderParams._leftViewPortX * eyeRenderParams._renderScale),
(int)ceil(eyeRenderParams._leftViewPortY * eyeRenderParams._renderScale),
(int)ceil(eyeRenderParams._leftViewPortW * eyeRenderParams._renderScale),
(int)ceil(eyeRenderParams._leftViewPortH * eyeRenderParams._renderScale));
}
else
{
// Right eye
GL11.glViewport((int)ceil(eyeRenderParams._rightViewPortX * eyeRenderParams._renderScale),
(int)ceil(eyeRenderParams._rightViewPortY * eyeRenderParams._renderScale),
(int)ceil(eyeRenderParams._rightViewPortW * eyeRenderParams._renderScale),
(int)ceil(eyeRenderParams._rightViewPortH * eyeRenderParams._renderScale));
GL11.glScissor((int)ceil(eyeRenderParams._rightViewPortX * eyeRenderParams._renderScale),
(int)ceil(eyeRenderParams._rightViewPortY * eyeRenderParams._renderScale),
(int)ceil(eyeRenderParams._rightViewPortW * eyeRenderParams._renderScale),
(int)ceil(eyeRenderParams._rightViewPortH * eyeRenderParams._renderScale));
}
//mc.checkGLError("FBO viewport / scissor setup");
}
private void doDistortionAndSuperSample()
{
int FBWidth = this.mc.displayFBWidth;
int FBHeight = this.mc.displayFBHeight;
if (this.mc.vrSettings.useDistortion || this.mc.vrSettings.useSupersample || this.mc.vrSettings.useFXAA)
{
// Setup ortho projection
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
GL11.glTranslatef (0.0f, 0.0f, -0.7f);
}
if (this.mc.vrSettings.useSupersample)
{
FBWidth = (int)ceil(this.mc.displayFBWidth * this.mc.vrSettings.superSampleScaleFactor);
FBHeight = (int)ceil(this.mc.displayFBHeight * this.mc.vrSettings.superSampleScaleFactor);
}
if (mc.vrSettings.useDistortion)
{
//mc.checkGLError("Before distortion");
preDistortionFBO.bindTexture();
if (this.mc.vrSettings.useFXAA)
{
//chain into the FXAA FBO
fxaaFBO.bindRenderTarget();
}
else if (this.mc.vrSettings.useSupersample)
{
//chain into the superSample FBO
postDistortionFBO.bindRenderTarget();
}
else
{
unbindFBORenderTarget();
}
GL11.glClearColor (1.0f, 1.0f, 1.0f, 0.5f);
GL11.glClearDepth(1.0D);
GL11.glClear (GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer on the framebuffer to black
// Render onto the entire screen framebuffer
GL11.glViewport(0, 0, FBWidth, FBHeight);
// Set the distortion shader as in use
ARBShaderObjects.glUseProgramObjectARB(_Distortion_shaderProgramId);
// Set up the fragment shader uniforms
ARBShaderObjects.glUniform1iARB(_DistortionShader_RenderTextureUniform, 0);
if (this.mc.vrSettings.useDistortionTextureLookupOptimisation)
{
distortParams.bindTexture_Unit1();
ARBShaderObjects.glUniform1iARB(_DistortionShader_DistortionMapUniform, 1);
}
ARBShaderObjects.glUniform1iARB(_DistortionShader_half_screenWidthUniform, distortParams.half_screenWidth);
ARBShaderObjects.glUniform2fARB(_DistortionShader_LeftLensCenterUniform, distortParams.leftLensCenterX, distortParams.leftLensCenterY);
ARBShaderObjects.glUniform2fARB(_DistortionShader_RightLensCenterUniform, distortParams.rightLensCenterX, distortParams.rightLensCenterY);
ARBShaderObjects.glUniform2fARB(_DistortionShader_LeftScreenCenterUniform, distortParams.leftScreenCenterX, distortParams.leftScreenCenterY);
ARBShaderObjects.glUniform2fARB(_DistortionShader_RightScreenCenterUniform, distortParams.rightScreenCenterX, distortParams.rightScreenCenterY);
ARBShaderObjects.glUniform2fARB(_DistortionShader_ScaleUniform, distortParams.scaleX, distortParams.scaleY);
ARBShaderObjects.glUniform2fARB(_DistortionShader_ScaleInUniform, distortParams.scaleInX, distortParams.scaleInY);
ARBShaderObjects.glUniform4fARB(_DistortionShader_HmdWarpParamUniform, distortParams.DistortionK[0], distortParams.DistortionK[1], distortParams.DistortionK[2], distortParams.DistortionK[3]);
ARBShaderObjects.glUniform4fARB(_DistortionShader_ChromAbParamUniform, distortParams.ChromaticAb[0], distortParams.ChromaticAb[1], distortParams.ChromaticAb[2], distortParams.ChromaticAb[3]);
drawQuad();
// Stop shader use
ARBShaderObjects.glUseProgramObjectARB(0);
OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit);
//mc.checkGLError("After distortion");
}
if (this.mc.vrSettings.useFXAA)
{
fxaaFBO.bindTexture();
if (this.mc.vrSettings.useSupersample)
{
//chain into the superSample FBO
postDistortionFBO.bindRenderTarget();
}
else
{
unbindFBORenderTarget();
}
GL11.glClearColor (1.0f, 1.0f, 1.0f, 0.5f);
GL11.glClearDepth(1.0D);
GL11.glClear (GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer on the framebuffer to black
// Render onto the entire screen framebuffer
GL11.glViewport(0, 0, FBWidth, FBHeight);
// Set the distortion shader as in use
ARBShaderObjects.glUseProgramObjectARB(_FXAA_shaderProgramId);
// Set up the fragment shader uniforms
ARBShaderObjects.glUniform1iARB(_FXAA_RenderTextureUniform, 0);
ARBShaderObjects.glUniform2fARB(_FXAA_RenderedTextureSizeUniform, (float)FBWidth, (float)FBHeight);
drawQuad();
// Stop shader use
ARBShaderObjects.glUseProgramObjectARB(0);
OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit);
//ShaderHelper.checkGLError("After fxaa");
}
if (this.mc.vrSettings.useSupersample)
{
// Now switch to 1st pass target framebuffer
postSuperSampleFBO.bindRenderTarget();
// Bind the FBO
postDistortionFBO.bindTexture();
GL11.glClearColor (0.0f, 0.0f, 1.0f, 0.5f);
GL11.glClearDepth(1.0D);
GL11.glClear (GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer on the framebuffer to black
// Render onto the entire screen framebuffer
GL11.glViewport(0, 0, this.mc.displayFBWidth, FBHeight);
// Set the downsampling shader as in use
ARBShaderObjects.glUseProgramObjectARB(_Lanczos_shaderProgramId);
// Set up the fragment shader uniforms
ARBShaderObjects.glUniform1fARB(_LanczosShader_texelWidthOffsetUniform, 1.0f / (3.0f * (float)this.mc.displayFBWidth));
ARBShaderObjects.glUniform1fARB(_LanczosShader_texelHeightOffsetUniform, 0.0f);
ARBShaderObjects.glUniform1iARB(_LanczosShader_inputImageTextureUniform, 0);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
// Pass 1
drawQuad();
// mc.checkGLError("After Lanczos Pass1");
// Pass 2
// Now switch to 2nd pass screen framebuffer
unbindFBORenderTarget();
postSuperSampleFBO.bindTexture();
GL11.glViewport(0, 0, this.mc.displayFBWidth, this.mc.displayFBHeight);
GL11.glClearColor (0.0f, 0.0f, 1.0f, 0.5f);
GL11.glClearDepth(1.0D);
GL11.glClear (GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
// Bind the texture
GL13.glActiveTexture(GL13.GL_TEXTURE0);
// Set up the fragment shader uniforms for pass 2
ARBShaderObjects.glUniform1fARB(_LanczosShader_texelWidthOffsetUniform, 0.0f);
ARBShaderObjects.glUniform1fARB(_LanczosShader_texelHeightOffsetUniform, 1.0f / (3.0f * (float)this.mc.displayFBHeight));
ARBShaderObjects.glUniform1iARB(_LanczosShader_inputImageTextureUniform, 0);
drawQuad();
// Stop shader use
ARBShaderObjects.glUseProgramObjectARB(0);
// mc.checkGLError("After Lanczos Pass2");
}
}
public void renderWorld(float renderPartialTicks, long nextFrameTime, int renderSceneNumber )
{
RenderGlobal renderGlobal = this.mc.renderGlobal;
EffectRenderer effectRenderer = this.mc.effectRenderer;
EntityLivingBase renderViewEntity = this.mc.renderViewEntity;
//TODO: fog color isn't quite right yet when eyes split water/air
this.updateFogColor(renderPartialTicks);
GL11.glClearColor (fogColorRed, fogColorGreen, fogColorBlue, 0.5f);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glEnable(GL11.GL_DEPTH_TEST);
//mc.checkGLError("FBO init");
this.mc.mcProfiler.startSection("lightTex");
if (this.lightmapUpdateNeeded)
{
this.updateLightmap(renderPartialTicks);
}
ActiveRenderInfo.updateRenderInfo(this.mc.thePlayer, this.mc.gameSettings.thirdPersonView == 2);
this.mc.mcProfiler.endStartSection("frustrum");
ClippingHelperImpl.getInstance(); // setup clip, using current modelview / projection matrices
if (!Config.isSkyEnabled() && !Config.isSunMoonEnabled() && !Config.isStarsEnabled())
{
GL11.glDisable(GL11.GL_BLEND);
}
else
{
this.setupFog(-1, renderPartialTicks);
this.mc.mcProfiler.endStartSection("sky");
renderGlobal.renderSky(renderPartialTicks);
}
GL11.glEnable(GL11.GL_FOG);
this.setupFog(1, renderPartialTicks);
if (this.mc.gameSettings.ambientOcclusion != 0)
{
GL11.glShadeModel(GL11.GL_SMOOTH);
}
this.mc.mcProfiler.endStartSection("culling");
Frustrum frustrum = new Frustrum();
frustrum.setPosition(renderOriginX , renderOriginY, renderOriginZ);
this.mc.renderGlobal.clipRenderersByFrustum(frustrum, renderPartialTicks);
if (renderSceneNumber == 0 )
{
this.mc.mcProfiler.endStartSection("updatechunks");
while (!this.mc.renderGlobal.updateRenderers(renderViewEntity, false) && nextFrameTime != 0L)
{
long var15 = nextFrameTime - System.nanoTime();
if (var15 < 0L || var15 > 1000000000L)
{
break;
}
}
}
if (renderViewEntity.posY < 128.0D)
{
this.renderCloudsCheck(renderGlobal, renderPartialTicks);
}
this.mc.mcProfiler.endStartSection("prepareterrain");
this.setupFog(0, renderPartialTicks);
GL11.glEnable(GL11.GL_FOG);
this.mc.getTextureManager().bindTexture(TextureMap.locationBlocksTexture);
RenderHelper.disableStandardItemLighting();
this.mc.mcProfiler.endStartSection("terrain");
renderGlobal.sortAndRender(renderViewEntity, 0, (double) renderPartialTicks);
GL11.glShadeModel(GL11.GL_FLAT);
boolean var16 = Reflector.ForgeHooksClient.exists();
EntityPlayer var18;
if (this.debugViewDirection == 0)
{
RenderHelper.enableStandardItemLighting();
this.mc.mcProfiler.endStartSection("entities");
if (var16)
{
Reflector.callVoid(Reflector.ForgeHooksClient_setRenderPass, new Object[] {Integer.valueOf(0)});
}
//TODO: multiple render passes for entities?
renderGlobal.renderEntities(renderViewEntity.getPosition(renderPartialTicks), frustrum, renderPartialTicks);
if (var16)
{
Reflector.callVoid(Reflector.ForgeHooksClient_setRenderPass, new Object[] {Integer.valueOf(-1)});
}
RenderHelper.disableStandardItemLighting();
}
GL11.glDisable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glDepthMask(true);
this.setupFog(0, renderPartialTicks);
GL11.glEnable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_CULL_FACE);
this.mc.getTextureManager().bindTexture(TextureMap.locationBlocksTexture);
WrUpdates.resumeBackgroundUpdates();
if (Config.isWaterFancy())
{
this.mc.mcProfiler.endStartSection("water");
if (this.mc.gameSettings.ambientOcclusion != 0)
{
GL11.glShadeModel(GL11.GL_SMOOTH);
}
GL11.glColorMask(false, false, false, false);
int var17 = renderGlobal.renderAllSortedRenderers(1, (double)renderPartialTicks);
if (this.mc.gameSettings.anaglyph)
{
if (anaglyphField == 0)
{
GL11.glColorMask(false, true, true, true);
}
else
{
GL11.glColorMask(true, false, false, true);
}
}
else
{
GL11.glColorMask(true, true, true, true);
}
if (var17 > 0)
{
renderGlobal.renderAllSortedRenderers(1, (double)renderPartialTicks);
}
GL11.glShadeModel(GL11.GL_FLAT);
}
else
{
this.mc.mcProfiler.endStartSection("water");
renderGlobal.renderAllSortedRenderers( 1, (double) renderPartialTicks);
}
WrUpdates.pauseBackgroundUpdates();
if (var16 && this.debugViewDirection == 0)
{
RenderHelper.enableStandardItemLighting();
this.mc.mcProfiler.endStartSection("entities");
Reflector.callVoid(Reflector.ForgeHooksClient_setRenderPass, new Object[] {Integer.valueOf(1)});
this.mc.renderGlobal.renderEntities(renderViewEntity.getPosition(renderPartialTicks), frustrum, renderPartialTicks);
Reflector.callVoid(Reflector.ForgeHooksClient_setRenderPass, new Object[] {Integer.valueOf(-1)});
RenderHelper.disableStandardItemLighting();
}
GL11.glDepthMask(true);
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glDisable(GL11.GL_BLEND);
boolean renderOutline = this.mc.vrSettings.alwaysRenderBlockOutline || !this.mc.gameSettings.hideGUI;
if (this.mc.currentScreen == null && this.cameraZoom == 1.0D && renderViewEntity instanceof EntityPlayer && this.mc.objectMouseOver != null && !renderViewEntity.isInsideOfMaterial(Material.water) && renderOutline)
{
var18 = (EntityPlayer)renderViewEntity;
GL11.glDisable(GL11.GL_ALPHA_TEST);
this.mc.mcProfiler.endStartSection("outline");
if (!var16 || !Reflector.callBoolean(Reflector.ForgeHooksClient_onDrawBlockHighlight, new Object[] {renderGlobal, var18, this.mc.objectMouseOver, Integer.valueOf(0), var18.inventory.getCurrentItem(), Float.valueOf(renderPartialTicks)}))
{
renderGlobal.drawSelectionBox(var18, this.mc.objectMouseOver, 0, renderPartialTicks );
}
GL11.glEnable(GL11.GL_ALPHA_TEST);
}
if (this.mc.currentScreen == null && this.cameraZoom == 1.0D && renderViewEntity instanceof EntityPlayer && !renderViewEntity.isInsideOfMaterial(Material.water) && renderOutline && this.mc.vrSettings.showEntityOutline)
{
var18 = (EntityPlayer)renderViewEntity;
if (var18 != null)
{
GL11.glDisable(GL11.GL_ALPHA_TEST);
this.mc.mcProfiler.endStartSection("entityOutline");
if (this.bb != null)
drawBoundingBox(var18, this.bb, renderPartialTicks);
GL11.glEnable(GL11.GL_ALPHA_TEST);
}
}
this.mc.mcProfiler.endStartSection("destroyProgress");
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
renderGlobal.drawBlockDamageTexture(Tessellator.instance, renderViewEntity, renderPartialTicks);
GL11.glDisable(GL11.GL_BLEND);
this.mc.mcProfiler.endStartSection("weather");
this.renderRainSnow(renderPartialTicks);
GL11.glDisable(GL11.GL_FOG);
if (renderViewEntity.posY >= 128.0D)
{
this.renderCloudsCheck(renderGlobal, renderPartialTicks);
}
this.enableLightmap((double) renderPartialTicks);
this.mc.mcProfiler.endStartSection("litParticles");
RenderHelper.enableStandardItemLighting();
effectRenderer.renderLitParticles(renderViewEntity, renderPartialTicks);
RenderHelper.disableStandardItemLighting();
this.setupFog(0, renderPartialTicks);
this.mc.mcProfiler.endStartSection("particles");
effectRenderer.renderParticles(renderViewEntity, renderPartialTicks);
this.disableLightmap((double) renderPartialTicks);
if (var16)
{
this.mc.mcProfiler.endStartSection("FRenderLast");
Reflector.callVoid(Reflector.ForgeHooksClient_dispatchRenderLast, new Object[] {renderGlobal, Float.valueOf(renderPartialTicks)});
}
if (this.mc.vrSettings.renderFullFirstPersonModel == false)
{
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
this.renderHand(renderPartialTicks, renderSceneNumber);
}
GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); //white crosshair, with blending
//Draw crosshair
boolean renderCrosshair = this.mc.vrSettings.alwaysRenderInGameCrosshair || !this.mc.gameSettings.hideGUI;
if( this.mc.currentScreen == null && this.mc.gameSettings.thirdPersonView == 0 && renderCrosshair)
{
this.mc.mcProfiler.endStartSection("crosshair");
float crossDepth = (float)Math.sqrt((crossX*crossX + crossY*crossY + crossZ*crossZ));
float scale = 0.025f*crossDepth*this.mc.vrSettings.crosshairScale;
GL11.glPushMatrix();
GL11.glTranslatef(crossX, crossY, crossZ);
GL11.glRotatef(-this.aimYaw, 0.0F, 1.0F, 0.0F);
GL11.glRotatef(this.aimPitch, 1.0F, 0.0F, 0.0F);
if (this.mc.vrSettings.crosshairRollsWithHead)
GL11.glRotatef(this.cameraRoll, 0.0F, 0.0F, 1.0F);
GL11.glScalef(-scale, -scale, scale);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_ONE_MINUS_DST_COLOR, GL11.GL_ONE_MINUS_SRC_COLOR);
this.mc.getTextureManager().bindTexture(Gui.icons);
float var7 = 0.00390625F;
float var8 = 0.00390625F;
Tessellator.instance.startDrawingQuads();
Tessellator.instance.addVertexWithUV(- 1, + 1, 0, 0 , 16* var8);
Tessellator.instance.addVertexWithUV(+ 1, + 1, 0, 16*var7, 16* var8);
Tessellator.instance.addVertexWithUV(+ 1, - 1, 0, 16*var7, 0 );
Tessellator.instance.addVertexWithUV(- 1, - 1, 0, 0 , 0 );
Tessellator.instance.draw();
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glDisable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glPopMatrix();
//mc.checkGLError("crosshair");
}
this.mc.mcProfiler.endSection();
}
private void unbindFBORenderTarget()
{
try {
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);
}
catch (IllegalStateException ex)
{
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);
}
}
private void unbindTexture()
{
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
}
public void drawQuad()
{
// this func just draws a perfectly normal box with some texture coordinates
GL11.glBegin(GL11.GL_QUADS);
// Front Face
GL11.glTexCoord2f(0.0f, 0.0f); GL11.glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left Of The Texture and Quad
GL11.glTexCoord2f(1.0f, 0.0f); GL11.glVertex3f( 1.0f, -1.0f, 0.0f); // Bottom Right Of The Texture and Quad
GL11.glTexCoord2f(1.0f, 1.0f); GL11.glVertex3f( 1.0f, 1.0f, 0.0f); // Top Right Of The Texture and Quad
GL11.glTexCoord2f(0.0f, 1.0f); GL11.glVertex3f(-1.0f, 1.0f, 0.0f); // Top Left Of The Texture and Quad
GL11.glEnd();
}
public void drawLatencyTesterColoredQuad(float r, float g, float b, float a)
{
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND);
// Setup ortho projection
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
GL11.glTranslatef (0.0f, 0.0f, -0.7f);
// Cover the appropriate areas of the screen with the colored quad
GL11.glBegin(GL11.GL_QUADS);
GL11.glColor4f(r, g, b, a);
GL11.glVertex3f(-0.6f, -0.6f, 0.0f); // Bottom Left Of The Texture and Quad
GL11.glVertex3f( 0.6f, -0.6f, 0.0f); // Bottom Right Of The Texture and Quad
GL11.glVertex3f( 0.6f, 0.6f, 0.0f); // Top Right Of The Texture and Quad
GL11.glVertex3f(-0.6f, 0.6f, 0.0f); // Top Left Of The Texture and Quad
GL11.glEnd();
GL11.glDisable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_TEXTURE_2D);
}
public void drawQuad2(float displayWidth, float displayHeight, float scale)
{
float aspect = displayHeight / displayWidth;
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0.0f, 0.0f); GL11.glVertex3f(-1.0f * scale, -1.0f * aspect * scale, 0.0f); // Bottom Left Of The Texture and Quad
GL11.glTexCoord2f(1.0f, 0.0f); GL11.glVertex3f( 1.0f * scale, -1.0f * aspect * scale, 0.0f); // Bottom Right Of The Texture and Quad
GL11.glTexCoord2f(1.0f, 1.0f); GL11.glVertex3f( 1.0f * scale, 1.0f * aspect * scale, 0.0f); // Top Right Of The Texture and Quad
GL11.glTexCoord2f(0.0f, 1.0f); GL11.glVertex3f(-1.0f * scale, 1.0f * aspect * scale, 0.0f); // Top Left Of The Texture and Quad
GL11.glEnd();
}
public final String BASIC_VERTEX_SHADER =
"#version 110\n" +
"\n" +
"varying vec4 textCoord;\n" +
"\n" +
"void main() {\n" +
" gl_Position = ftransform(); //Transform the vertex position\n" +
" textCoord = gl_MultiTexCoord0; // Use Texture unit 0\n" +
"}\n";
public final String BASIC_VERTEX_SHADER_VBO =
"#version 120\n" +
"\n" +
" attribute vec4 in_Position;\n" +
" attribute vec4 in_Color;\n" +
" attribute vec2 in_TextureCoord;\n" +
" varying vec4 textCoord;\n" +
"\n" +
"void main() {\n" +
" gl_Position = vec4(in_Position.x, in_Position.y, 0.0, 1.0);\n" +
" textCoord = vec4(in_TextureCoord.s, in_TextureCoord.t, 0.0, 0.0);\n" +
"}\n";
public final String OCULUS_DISTORTION_FRAGMENT_SHADER_NO_CHROMATIC_ABERRATION_CORRECTION =
"#version 120\n" +
"\n" +
"uniform sampler2D bgl_RenderTexture;\n" +
"uniform sampler2D distortionMap;\n" +
"uniform int half_screenWidth;\n" +
"uniform vec2 LeftLensCenter;\n" +
"uniform vec2 RightLensCenter;\n" +
"uniform vec2 LeftScreenCenter;\n" +
"uniform vec2 RightScreenCenter;\n" +
"uniform vec2 Scale;\n" +
"uniform vec2 ScaleIn;\n" +
"uniform vec4 HmdWarpParam;\n" +
"uniform vec4 ChromAbParam;\n" +
"varying vec4 textCoord;\n" +
"\n" +
"// Scales input texture coordinates for distortion.\n" +
"vec2 HmdWarp(vec2 in01, vec2 LensCenter)\n" +
"{\n" +
" vec2 theta = (in01 - LensCenter) * ScaleIn; // Scales to [-1, 1]\n" +
" float rSq = theta.x * theta.x + theta.y * theta.y;\n" +
" vec2 rvector = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq +\n" +
" HmdWarpParam.z * rSq * rSq +\n" +
" HmdWarpParam.w * rSq * rSq * rSq);\n" +
" return LensCenter + Scale * rvector;\n" +
"}\n" +
"\n" +
"void main()\n" +
"{\n" +
" // The following two variables need to be set per eye\n" +
" vec2 LensCenter = gl_FragCoord.x < half_screenWidth ? LeftLensCenter : RightLensCenter;\n" +
" vec2 ScreenCenter = gl_FragCoord.x < half_screenWidth ? LeftScreenCenter : RightScreenCenter;\n" +
"\n" +
" vec2 oTexCoord = textCoord.xy;\n" +
" //vec2 oTexCoord = (gl_FragCoord.xy + vec2(0.5, 0.5)) / vec2(screenWidth, screenHeight);\n" +
"\n" +
" vec2 tc = HmdWarp(oTexCoord, LensCenter);\n" +
" if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc)))\n" +
" {\n" +
" gl_FragColor = vec4(vec3(0.0), 1.0);\n" +
" return;\n" +
" }\n" +
"\n" +
" //tc.x = gl_FragCoord.x < half_screenWidth ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5));\n" +
" //gl_FragColor = texture2D(bgl_RenderTexture, tc).aaaa * texture2D(bgl_RenderTexture, tc);\n" +
" gl_FragColor = texture2D(bgl_RenderTexture, tc);\n" +
"}\n";
public final String OCULUS_DISTORTION_FRAGMENT_SHADER_NO_CHROMATIC_ABERRATION_CORRECTION_DIST_MAP =
"#version 120\n" +
"\n" +
"#define highp\n" +
"uniform sampler2D bgl_RenderTexture;\n" +
"uniform sampler2D distortionMap;\n" +
"uniform int half_screenWidth;\n" +
"uniform vec2 LeftLensCenter;\n" +
"uniform vec2 RightLensCenter;\n" +
"uniform vec2 LeftScreenCenter;\n" +
"uniform vec2 RightScreenCenter;\n" +
"uniform vec2 Scale;\n" +
"uniform vec2 ScaleIn;\n" +
"uniform vec4 HmdWarpParam;\n" +
"uniform vec4 ChromAbParam;\n" +
"varying vec4 textCoord;\n" +
"\n" +
"void main()\n" +
"{\n" +
" vec2 tc = texture2D(distortionMap, textCoord.xy).rg;\n" +
" if (tc == vec2(-1.0, -1.0))\n" +
" gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n" +
" else\n" +
" gl_FragColor = texture2D(bgl_RenderTexture, tc);\n" +
"}\n";
public final String OCULUS_DISTORTION_FRAGMENT_SHADER_WITH_CHROMATIC_ABERRATION_CORRECTION =
"#version 120\n" +
"\n" +
"uniform sampler2D bgl_RenderTexture;\n" +
"uniform int half_screenWidth;\n" +
"uniform vec2 LeftLensCenter;\n" +
"uniform vec2 RightLensCenter;\n" +
"uniform vec2 LeftScreenCenter;\n" +
"uniform vec2 RightScreenCenter;\n" +
"uniform vec2 Scale;\n" +
"uniform vec2 ScaleIn;\n" +
"uniform vec4 HmdWarpParam;\n" +
"uniform vec4 ChromAbParam;\n" +
"varying vec4 textCoord;\n" +
"\n" +
"void main()\n" +
"{\n" +
" vec2 LensCenter = gl_FragCoord.x < half_screenWidth ? LeftLensCenter : RightLensCenter;\n" +
" vec2 ScreenCenter = gl_FragCoord.x < half_screenWidth ? LeftScreenCenter : RightScreenCenter;\n" +
"\n" +
" vec2 theta = (textCoord.xy - LensCenter) * ScaleIn;\n" +
" float rSq = theta.x * theta.x + theta.y * theta.y;\n" +
" vec2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n" +
"\n" +
" vec2 thetaBlue = theta1 * (ChromAbParam.w * rSq + ChromAbParam.z);\n" +
" vec2 tcBlue = thetaBlue * Scale + LensCenter;\n" +
"\n" +
" if (any(bvec2(clamp(tcBlue, ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tcBlue))) {\n" +
" gl_FragColor = vec4(vec3(0.0), 1.0);\n" +
" return;\n" +
" }\n" +
" float blue = texture2D(bgl_RenderTexture, tcBlue).b;\n" +
"\n" +
" vec2 tcGreen = theta1 * Scale + LensCenter;\n" +
" float green = texture2D(bgl_RenderTexture, tcGreen).g;\n" +
"\n" +
" vec2 thetaRed = theta1 * (ChromAbParam.y * rSq + ChromAbParam.x);\n" +
" vec2 tcRed = thetaRed * Scale + LensCenter;\n" +
" float red = texture2D(bgl_RenderTexture, tcRed).r;\n" +
"\n" +
" gl_FragColor = vec4(red, green, blue, 1.0);\n" +
"}\n";
public final String OCULUS_DISTORTION_FRAGMENT_SHADER_WITH_CHROMATIC_ABERRATION_CORRECTION_DIST_MAP =
"#version 120\n" +
"\n" +
"#define highp\n" +
"uniform sampler2D bgl_RenderTexture;\n" +
"uniform sampler2D distortionMap;\n" +
"uniform int half_screenWidth;\n" +
"uniform vec2 LeftLensCenter;\n" +
"uniform vec2 RightLensCenter;\n" +
"uniform vec2 LeftScreenCenter;\n" +
"uniform vec2 RightScreenCenter;\n" +
"uniform vec2 Scale;\n" +
"uniform vec2 ScaleIn;\n" +
"uniform vec4 HmdWarpParam;\n" +
"uniform vec4 ChromAbParam;\n" +
"varying vec4 textCoord;\n" +
"\n" +
"void main()\n" +
"{\n" +
" vec2 LensCenter = gl_FragCoord.x < half_screenWidth ? LeftLensCenter : RightLensCenter;\n" +
"\n" +
" vec2 theta = (textCoord.xy - LensCenter) * ScaleIn;\n" +
" float rSq = theta.x * theta.x + theta.y * theta.y;\n" +
" vec2 theta1 = texture2D(distortionMap, textCoord.xy).rg;\n" +
" if (theta1 == vec2(-1.0, -1.0)) {\n" +
" gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n" +
" return;\n" +
" }\n" +
"\n" +
" vec2 thetaBlue = theta1 * (ChromAbParam.w * rSq + ChromAbParam.z);\n" +
" vec2 tcBlue = thetaBlue * Scale + LensCenter;\n" +
" float blue = texture2D(bgl_RenderTexture, tcBlue).b;\n" +
"\n" +
" vec2 tcGreen = theta1 * Scale + LensCenter;\n" +
" float green = texture2D(bgl_RenderTexture, tcGreen).g;\n" +
"\n" +
" vec2 thetaRed = theta1 * (ChromAbParam.y * rSq + ChromAbParam.x);\n" +
" vec2 tcRed = thetaRed * Scale + LensCenter;\n" +
" float red = texture2D(bgl_RenderTexture, tcRed).r;\n" +
"\n" +
" gl_FragColor = vec4(red, green, blue, 1.0);\n" +
"}\n";
public final String LANCZOS_SAMPLER_VERTEX_SHADER =
"#version 120\n" +
"\n" +
" uniform float texelWidthOffset;\n" +
" uniform float texelHeightOffset;\n" +
"\n" +
" varying vec2 centerTextureCoordinate;\n" +
" varying vec2 oneStepLeftTextureCoordinate;\n" +
" varying vec2 twoStepsLeftTextureCoordinate;\n" +
" varying vec2 threeStepsLeftTextureCoordinate;\n" +
" varying vec2 fourStepsLeftTextureCoordinate;\n" +
" varying vec2 oneStepRightTextureCoordinate;\n" +
" varying vec2 twoStepsRightTextureCoordinate;\n" +
" varying vec2 threeStepsRightTextureCoordinate;\n" +
" varying vec2 fourStepsRightTextureCoordinate;\n" +
"\n" +
" void main()\n" +
" {\n" +
" gl_Position = ftransform();\n" +
"\n" +
" vec2 firstOffset = vec2(texelWidthOffset, texelHeightOffset);\n" +
" vec2 secondOffset = vec2(2.0 * texelWidthOffset, 2.0 * texelHeightOffset);\n" +
" vec2 thirdOffset = vec2(3.0 * texelWidthOffset, 3.0 * texelHeightOffset);\n" +
" vec2 fourthOffset = vec2(4.0 * texelWidthOffset, 4.0 * texelHeightOffset);\n" +
"\n" +
" vec2 textCoord = gl_MultiTexCoord0.xy;\n" +
" centerTextureCoordinate = textCoord;\n" +
" oneStepLeftTextureCoordinate = textCoord - firstOffset;\n" +
" twoStepsLeftTextureCoordinate = textCoord - secondOffset;\n" +
" threeStepsLeftTextureCoordinate = textCoord - thirdOffset;\n" +
" fourStepsLeftTextureCoordinate = textCoord - fourthOffset;\n" +
" oneStepRightTextureCoordinate = textCoord + firstOffset;\n" +
" twoStepsRightTextureCoordinate = textCoord + secondOffset;\n" +
" threeStepsRightTextureCoordinate = textCoord + thirdOffset;\n" +
" fourStepsRightTextureCoordinate = textCoord + fourthOffset;\n" +
" }\n";
public final String LANCZOS_SAMPLER_VERTEX_SHADER_VBO =
"#version 120\n" +
"\n" +
" attribute vec4 in_Position;\n" +
" attribute vec4 in_Color;\n" +
" attribute vec2 in_TextureCoord;\n" +
"\n" +
" uniform float texelWidthOffset;\n" +
" uniform float texelHeightOffset;\n" +
"\n" +
" varying vec2 centerTextureCoordinate;\n" +
" varying vec2 oneStepLeftTextureCoordinate;\n" +
" varying vec2 twoStepsLeftTextureCoordinate;\n" +
" varying vec2 threeStepsLeftTextureCoordinate;\n" +
" varying vec2 fourStepsLeftTextureCoordinate;\n" +
" varying vec2 oneStepRightTextureCoordinate;\n" +
" varying vec2 twoStepsRightTextureCoordinate;\n" +
" varying vec2 threeStepsRightTextureCoordinate;\n" +
" varying vec2 fourStepsRightTextureCoordinate;\n" +
"\n" +
" void main()\n" +
" {\n" +
" gl_Position = in_Position;\n" +
"\n" +
" vec2 firstOffset = vec2(texelWidthOffset, texelHeightOffset);\n" +
" vec2 secondOffset = vec2(2.0 * texelWidthOffset, 2.0 * texelHeightOffset);\n" +
" vec2 thirdOffset = vec2(3.0 * texelWidthOffset, 3.0 * texelHeightOffset);\n" +
" vec2 fourthOffset = vec2(4.0 * texelWidthOffset, 4.0 * texelHeightOffset);\n" +
"\n" +
" centerTextureCoordinate = in_TextureCoord;\n" +
" oneStepLeftTextureCoordinate = in_TextureCoord - firstOffset;\n" +
" twoStepsLeftTextureCoordinate = in_TextureCoord - secondOffset;\n" +
" threeStepsLeftTextureCoordinate = in_TextureCoord - thirdOffset;\n" +
" fourStepsLeftTextureCoordinate = in_TextureCoord - fourthOffset;\n" +
" oneStepRightTextureCoordinate = in_TextureCoord + firstOffset;\n" +
" twoStepsRightTextureCoordinate = in_TextureCoord + secondOffset;\n" +
" threeStepsRightTextureCoordinate = in_TextureCoord + thirdOffset;\n" +
" fourStepsRightTextureCoordinate = in_TextureCoord + fourthOffset;\n" +
" }\n";
public final String LANCZOS_SAMPLER_FRAGMENT_SHADER =
"#version 120\n" +
"\n" +
" uniform sampler2D inputImageTexture;\n" +
"\n" +
" varying vec2 centerTextureCoordinate;\n" +
" varying vec2 oneStepLeftTextureCoordinate;\n" +
" varying vec2 twoStepsLeftTextureCoordinate;\n" +
" varying vec2 threeStepsLeftTextureCoordinate;\n" +
" varying vec2 fourStepsLeftTextureCoordinate;\n" +
" varying vec2 oneStepRightTextureCoordinate;\n" +
" varying vec2 twoStepsRightTextureCoordinate;\n" +
" varying vec2 threeStepsRightTextureCoordinate;\n" +
" varying vec2 fourStepsRightTextureCoordinate;\n" +
"\n" +
" // sinc(x) * sinc(x/a) = (a * sin(pi * x) * sin(pi * x / a)) / (pi^2 * x^2)\n" +
" // Assuming a Lanczos constant of 2.0, and scaling values to max out at x = +/- 1.5\n" +
"\n" +
" void main()\n" +
" {\n" +
" vec4 fragmentColor = texture2D(inputImageTexture, centerTextureCoordinate) * 0.38026;\n" +
"\n" +
" fragmentColor += texture2D(inputImageTexture, oneStepLeftTextureCoordinate) * 0.27667;\n" +
" fragmentColor += texture2D(inputImageTexture, oneStepRightTextureCoordinate) * 0.27667;\n" +
"\n" +
" fragmentColor += texture2D(inputImageTexture, twoStepsLeftTextureCoordinate) * 0.08074;\n" +
" fragmentColor += texture2D(inputImageTexture, twoStepsRightTextureCoordinate) * 0.08074;\n" +
"\n" +
" fragmentColor += texture2D(inputImageTexture, threeStepsLeftTextureCoordinate) * -0.02612;\n" +
" fragmentColor += texture2D(inputImageTexture, threeStepsRightTextureCoordinate) * -0.02612;\n" +
"\n" +
" fragmentColor += texture2D(inputImageTexture, fourStepsLeftTextureCoordinate) * -0.02143;\n" +
" fragmentColor += texture2D(inputImageTexture, fourStepsRightTextureCoordinate) * -0.02143;\n" +
"\n" +
" gl_FragColor = fragmentColor;\n" +
" }\n";
public final String FXAA_FRAGMENT_SHADER =
"/**\n" +
" ** __ __|_ ___________________________________________________________________________ ___|__ __\n" +
" ** // /\\ _ /\\ \\\\ \n" +
" ** //____/ \\__ __ _____ _____ _____ _____ _____ | | __ _____ _____ __ __/ \\____\\\\ \n" +
" ** \\ \\ / / __| | | __| _ | | _ | | | __| | | __| | /\\ \\ / / \n" +
" ** \\____\\/_/ | | | | | | | | | | | __| | | | | | | | | | |__ \" \\_\\/____/ \n" +
" ** /\\ \\ |_____|_____|_____|__|__|_|_|_|__| | | |_____|_____|_____|_____| _ / /\\ \n" +
" ** / \\____\\ http://jogamp.org |_| /____/ \\ \n" +
" ** \\ / \"' _________________________________________________________________________ `\" \\ / \n" +
" ** \\/____. .____\\/ \n" +
" **\n" +
" ** Modified/Ported post-processing anti-aliasing filter by Timothy Lottes. Basically removed the vertex\n" +
" ** shader logic and integrated it into the fragment shader for better ease of use. For more explanation\n" +
" ** regarding FXAA post processing anti-aliasing see here:\n" +
" **\n" +
" ** http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf\n" +
" ** http://timothylottes.blogspot.com/2011/03/nvidia-fxaa.html\n" +
" **/\n" +
"#version 120\n" +
"#define FXAA_REDUCE_MIN (1.0/128.0)\n" +
"#define FXAA_REDUCE_MUL (1.0/8.0)\n" +
"#define FXAA_SPAN_MAX 8.0\n" +
"uniform sampler2D sampler0;\n" +
"uniform vec2 resolution;\n" +
"\n" +
"void main(){\n" +
" vec2 inverse_resolution=vec2(1.0/resolution.x,1.0/resolution.y);\n" +
" vec3 rgbNW = texture2D(sampler0, (gl_FragCoord.xy + vec2(-1.0,-1.0)) * inverse_resolution).xyz;\n" +
" vec3 rgbNE = texture2D(sampler0, (gl_FragCoord.xy + vec2(1.0,-1.0)) * inverse_resolution).xyz;\n" +
" vec3 rgbSW = texture2D(sampler0, (gl_FragCoord.xy + vec2(-1.0,1.0)) * inverse_resolution).xyz;\n" +
" vec3 rgbSE = texture2D(sampler0, (gl_FragCoord.xy + vec2(1.0,1.0)) * inverse_resolution).xyz;\n" +
" vec3 rgbM = texture2D(sampler0, gl_FragCoord.xy * inverse_resolution).xyz;\n" +
" vec3 luma = vec3(0.299, 0.587, 0.114);\n" +
" float lumaNW = dot(rgbNW, luma);\n" +
" float lumaNE = dot(rgbNE, luma);\n" +
" float lumaSW = dot(rgbSW, luma);\n" +
" float lumaSE = dot(rgbSE, luma);\n" +
" float lumaM = dot(rgbM, luma);\n" +
" float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));\n" +
" float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); \n" +
" vec2 dir;\n" +
" dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\n" +
" dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\n" +
" float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL),FXAA_REDUCE_MIN);\n" +
" float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);\n" +
" dir = min(vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),dir * rcpDirMin)) * inverse_resolution;\n" +
" vec3 rgbA = 0.5 * (texture2D(sampler0, gl_FragCoord.xy * inverse_resolution + dir * (1.0/3.0 - 0.5)).xyz + texture2D(sampler0, gl_FragCoord.xy * inverse_resolution + dir * (2.0/3.0 - 0.5)).xyz);\n" +
" vec3 rgbB = rgbA * 0.5 + 0.25 * (texture2D(sampler0, gl_FragCoord.xy * inverse_resolution + dir * - 0.5).xyz + texture2D(sampler0, gl_FragCoord.xy * inverse_resolution + dir * 0.5).xyz);\n" +
" float lumaB = dot(rgbB, luma);\n" +
" if((lumaB < lumaMin) || (lumaB > lumaMax)) {\n" +
" gl_FragColor = vec4(rgbA,1.0);\n" +
" } else {\n" +
" gl_FragColor = vec4(rgbB,1.0);\n" +
" }\n" +
"}";
private float getDistortionFitY()
{
float fit = 0.0f;
switch (this.mc.vrSettings.distortionFitPoint)
{
case 0:
fit = 1.0f;
break;
case 1:
fit = 0.8f;
break;
case 2:
fit = 0.6f;
break;
case 3:
fit = 0.4f;
break;
case 4:
fit = 0.2f;
break;
case 5:
default:
fit = 0.0f;
break;
case 6:
fit = 0.0f;
break;
case 7:
fit = 0.0f;
break;
case 8:
fit = 0.0f;
break;
case 9:
fit = 0.0f;
break;
case 10:
fit = 0.0f;
break;
case 11:
fit = 0.0f;
break;
case 12:
fit = 0.0f;
break;
case 13:
fit = 0.0f;
break;
case 14:
fit = 0.0f;
break;
}
return fit;
}
private float getDistortionFitX()
{
float fit = -1.0f;
switch (this.mc.vrSettings.distortionFitPoint)
{
case 0:
fit = -1.0f;
break;
case 1:
fit = -1.0f;
break;
case 2:
fit = -1.0f;
break;
case 3:
fit = -1.0f;
break;
case 4:
fit = -1.0f;
break;
case 5:
default:
fit = -1.0f;
break;
case 6:
fit = -0.9f;
break;
case 7:
fit = -0.8f;
break;
case 8:
fit = -0.7f;
break;
case 9:
fit = -0.6f;
break;
case 10:
fit = -0.5f;
break;
case 11:
fit = -0.4f;
break;
case 12:
fit = -0.3f;
break;
case 13:
fit = -0.2f;
break;
case 14:
fit = -0.1f;
break;
}
return fit;
}
private void drawMouseQuad( int mouseX, int mouseY )
{
GL11.glDisable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glColor3f(1, 1, 1);
this.mc.mcProfiler.endStartSection("mouse pointer");
this.mc.getTextureManager().bindTexture(Gui.icons);
this.mc.ingameGUI.drawTexturedModalRect(mouseX - 7, mouseY - 7, 0, 0, 16, 16);
GL11.glEnable(GL11.GL_BLEND);
}
private void getPointedBlock(float renderPartialTicks)
{
if (this.mc.renderViewEntity != null && this.mc.theWorld != null)
{
this.mc.pointedEntityLiving = null;
double blockReachDistance = (double)this.mc.playerController.getBlockReachDistance();
double entityReachDistance = blockReachDistance;
float cameraYOffset = 1.62f - (this.mc.vrSettings.getPlayerEyeHeight() - this.mc.vrSettings.neckBaseToEyeHeight);
Vec3 pos = Vec3.createVectorHelper(renderOriginX + camRelX, renderOriginY + camRelY - cameraYOffset, renderOriginZ + camRelZ);
Vec3 aim = Vec3.createVectorHelper(aimX, aimY, aimZ);
Vec3 endPos = pos.addVector(aim.xCoord*blockReachDistance,aim.yCoord*blockReachDistance ,aim.zCoord*blockReachDistance );
this.mc.objectMouseOver = this.mc.theWorld.clip(pos, endPos);
double crossDistance = 0;
if (this.mc.objectMouseOver != null)
{
entityReachDistance = this.mc.objectMouseOver.hitVec.distanceTo(pos);
crossDistance = entityReachDistance;
}
else
{
endPos = pos.addVector(aim.xCoord*128,aim.yCoord*128,aim.zCoord*128);
MovingObjectPosition crossPos = this.mc.theWorld.clip(pos, endPos);
if( crossPos != null )
{
crossDistance = crossPos.hitVec.distanceTo(pos);
}
}
if (this.mc.playerController.extendedReach())
{
blockReachDistance = 6.0D;
entityReachDistance = 6.0D;
}
else
{
if (blockReachDistance > 3.0D)
{
entityReachDistance = 3.0D;
}
blockReachDistance = entityReachDistance;
}
Vec3 otherpos = mc.renderViewEntity.getPosition(renderPartialTicks);
otherpos.yCoord -= (1.62f - (this.mc.vrSettings.getPlayerEyeHeight())); // Adjust for eye height - TODO: Need to account for neck model?
getPointedEntity(otherpos, aim, blockReachDistance, entityReachDistance);
// Get bounding box of pointedEntity
if (this.pointedEntity != null && this.pointedEntity.boundingBox != null)
{
this.bb = this.pointedEntity.boundingBox.expand(this.pointedEntity.getCollisionBorderSize(),
this.pointedEntity.getCollisionBorderSize(),
this.pointedEntity.getCollisionBorderSize());
// TODO: How to get distance from eye pos to bounding box ray trace intercept,
// and draw crosshair at that depth...?
}
// Set up crosshair position
crossX = (float)(aim.xCoord * crossDistance + pos.xCoord - renderOriginX);
crossY = (float)(aim.yCoord * crossDistance + pos.yCoord - renderOriginY);
crossZ = (float)(aim.zCoord * crossDistance + pos.zCoord - renderOriginZ);
}
}
public void getMouseOver(float par1)
{
//No-op for performance reasons (MouseOver set in render loop)
}
public void startCalibration()
{
calibrationHelper = new CalibrationHelper(mc);
}
public void resetGuiYawOrientation()
{
guiYawOrientationResetRequested = true;
}
/**
* Render player hand
*/
private void renderHand(float par1, int renderSceneNumber)
{
if (this.debugViewDirection <= 0)
{
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPushMatrix();
GL11.glLoadIdentity();
if (renderSceneNumber == 0)
{
// Left eye
FloatBuffer leftProj = eyeRenderParams.gl_getLeftProjectionMatrix();
GL11.glLoadMatrix(leftProj);
//mc.checkGLError("Set left projection");
}
else
{
// Right eye
FloatBuffer rightProj = eyeRenderParams.gl_getRightProjectionMatrix();
GL11.glLoadMatrix(rightProj);
//mc.checkGLError("Set right projection");
}
float var3 = 0.07F;
if (this.mc.gameSettings.anaglyph)
{
GL11.glTranslatef((float)(-(renderSceneNumber * 2 - 1)) * var3, 0.0F, 0.0F);
}
if (this.cameraZoom != 1.0D)
{
GL11.glTranslatef((float)this.cameraYaw, (float)(-this.cameraPitch), 0.0F);
GL11.glScaled(this.cameraZoom, this.cameraZoom, 1.0D);
}
if (this.mc.playerController.enableEverythingIsScrewedUpMode())
{
float var4 = 0.6666667F;
GL11.glScalef(1.0F, var4, 1.0F);
}
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glPushMatrix();
GL11.glLoadIdentity();
// IPD transformation
if (renderSceneNumber == 0)
{
// Left eye
FloatBuffer leftEyeTransform = eyeRenderParams.gl_getLeftViewportTransform();
GL11.glMultMatrix(leftEyeTransform);
}
else
{
// Right eye
FloatBuffer rightEyeTransform = eyeRenderParams.gl_getRightViewportTransform();
GL11.glMultMatrix(rightEyeTransform);
}
if (this.mc.gameSettings.anaglyph)
{
GL11.glTranslatef((float)(renderSceneNumber * 2 - 1) * 0.1F, 0.0F, 0.0F);
}
GL11.glPushMatrix();
this.hurtCameraEffect(par1);
if (this.mc.gameSettings.viewBobbing)
{
this.setupViewBobbing(par1);
}
if (this.mc.gameSettings.thirdPersonView == 0 && !this.mc.renderViewEntity.isPlayerSleeping() && !this.mc.playerController.enableEverythingIsScrewedUpMode())
{
this.enableLightmap((double)par1);
this.itemRenderer.renderItemInFirstPerson(par1);
this.disableLightmap((double)par1);
}
GL11.glPopMatrix();
if (this.mc.gameSettings.thirdPersonView == 0 && !this.mc.renderViewEntity.isPlayerSleeping())
{
this.itemRenderer.renderOverlays(par1);
this.hurtCameraEffect(par1);
}
if (this.mc.gameSettings.viewBobbing)
{
this.setupViewBobbing(par1);
}
GL11.glPopMatrix();
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPopMatrix();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
}
}
public void drawBoundingBox(EntityPlayer par1EntityPlayer, AxisAlignedBB bb, float par4)
{
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glColor4f(0.0F, 0.0F, 0.0F, 0.4F);
GL11.glLineWidth(2.0F);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glDepthMask(false);
float var5 = 0.002F;
double var7 = par1EntityPlayer.lastTickPosX + (par1EntityPlayer.posX - par1EntityPlayer.lastTickPosX) * (double)par4;
double var9 = par1EntityPlayer.lastTickPosY + (par1EntityPlayer.posY - par1EntityPlayer.lastTickPosY) * (double)par4;
double var11 = par1EntityPlayer.lastTickPosZ + (par1EntityPlayer.posZ - par1EntityPlayer.lastTickPosZ) * (double)par4;
drawOutlinedBoundingBox(bb.expand((double) var5, (double) var5, (double) var5).getOffsetBoundingBox(-var7, -var9, -var11));
GL11.glDepthMask(true);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_BLEND);
}
public void drawLine(EntityPlayer par1EntityPlayer, Vec3 start, Vec3 end, float par4)
{
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glColor4f(0.0F, 0.0F, 0.0F, 0.4F);
GL11.glLineWidth(2.0F);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glDepthMask(false);
float var5 = 0.002F;
double var7 = par1EntityPlayer.lastTickPosX + (par1EntityPlayer.posX - par1EntityPlayer.lastTickPosX) * (double)par4;
double var9 = par1EntityPlayer.lastTickPosY + (par1EntityPlayer.posY - par1EntityPlayer.lastTickPosY) * (double)par4;
double var11 = par1EntityPlayer.lastTickPosZ + (par1EntityPlayer.posZ - par1EntityPlayer.lastTickPosZ) * (double)par4;
Tessellator var2 = Tessellator.instance;
var2.startDrawing(GL11.GL_LINE_STRIP);
var2.addVertex(start.xCoord, start.yCoord, start.zCoord);
var2.addVertex(end.xCoord, end.yCoord, end.zCoord);
var2.draw();
GL11.glDepthMask(true);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_BLEND);
}
/**
* Draws lines for the edges of the bounding box.
*/
public void drawOutlinedBoundingBox(AxisAlignedBB par1AxisAlignedBB)
{
Tessellator var2 = Tessellator.instance;
var2.startDrawing(3);
var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.minY, par1AxisAlignedBB.minZ);
var2.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.minY, par1AxisAlignedBB.minZ);
var2.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.minY, par1AxisAlignedBB.maxZ);
var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.minY, par1AxisAlignedBB.maxZ);
var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.minY, par1AxisAlignedBB.minZ);
var2.draw();
var2.startDrawing(3);
var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.minZ);
var2.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.minZ);
var2.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.maxZ);
var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.maxZ);
var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.minZ);
var2.draw();
var2.startDrawing(1);
var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.minY, par1AxisAlignedBB.minZ);
var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.minZ);
var2.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.minY, par1AxisAlignedBB.minZ);
var2.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.minZ);
var2.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.minY, par1AxisAlignedBB.maxZ);
var2.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.maxZ);
var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.minY, par1AxisAlignedBB.maxZ);
var2.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.maxZ);
var2.draw();
}
private void pollSensors()
{
// Sleep if we can, so that we poll orientation and position and start rendering at the
// last possible moment; and still finish before VSync
if (this.mc.vrSettings.frameTimingEnableVsyncSleep && this.mc.gameSettings.enableVsync)
{
long pollAndRenderTimeNanos = getMedianRenderFrameTimeNanos();
long nanosSinceLastRefresh = System.nanoTime() - startVSyncPeriodNanos;
long sleepTimeNanos = vsyncPeriodNanos - pollAndRenderTimeNanos - nanosSinceLastRefresh - this.mc.vrSettings.frameTimingSleepSafetyBufferNanos;
if (sleepTimeNanos > 0)
sleepNanos(sleepTimeNanos);
}
// Get timing just before orient / position reading
startFrameRenderNanos = System.nanoTime();
// Poll for position, orientation, setting prediction time
if (this.mc.vrSettings.useHeadTrackPrediction && this.mc.vrSettings.headTrackPredictionTimeSecs == 0)
{
long timeDeltaInFutureNanos = getMedianRenderFrameTimeNanos() + this.mc.vrSettings.frameTimingPredictDeltaFromEndFrameNanos;
float timeDeltaInFutureSecs = ((float) timeDeltaInFutureNanos) / 1000000000f;
//System.out.println("Predict ahead secs: " + timeDeltaInFutureSecs);
PluginManager.pollAll(timeDeltaInFutureSecs);
}
else
{
PluginManager.pollAll(0.0f);
}
}
private static void sleepNanos (long nanoDelay)
{
final long end = System.nanoTime() + nanoDelay;
do
{
Thread.yield(); // This is a busy wait sadly...
}
while (System.nanoTime() < end);
}
private void addRenderFrameTimeNanos(long frameTime)
{
int i = 0;
medianFrameTimeNanos = frameTime;
if (this.mc.vrSettings.frameTimingSmoothOverFrameCount < 1)
this.mc.vrSettings.frameTimingSmoothOverFrameCount = 1;
if (this.mc.vrSettings.frameTimingSmoothOverFrameCount % 2 == 0)
{
// Need an odd number for this
this.mc.vrSettings.frameTimingSmoothOverFrameCount++;
}
frameTimeNanos.addFirst(frameTime);
while (frameTimeNanos.size() > this.mc.vrSettings.frameTimingSmoothOverFrameCount)
frameTimeNanos.removeLast();
if (frameTimeNanos.size() == this.mc.vrSettings.frameTimingSmoothOverFrameCount)
{
Long[] array = new Long[frameTimeNanos.size()];
for (Iterator itr = frameTimeNanos.iterator(); itr.hasNext(); i++)
{
array[i] = (Long)itr.next();
}
Arrays.sort(array);
medianFrameTimeNanos = array[array.length / 2];
}
}
private long getMedianRenderFrameTimeNanos()
{
return medianFrameTimeNanos;
}
}