mirror of
https://github.com/DrBeef/DVR.git
synced 2024-11-10 06:42:05 +00:00
Several Tweaks
- Lens Correction Offset - Use shoulder triggers for run/shoot - Tidying up a little - Slight increase in stereo depth
This commit is contained in:
parent
bb1d69ee9c
commit
7ca2268ef1
7 changed files with 129 additions and 63 deletions
|
@ -7,8 +7,8 @@ android {
|
|||
applicationId "com.drbeef.dvr"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 19
|
||||
versionCode 1
|
||||
versionName '1.0.0'
|
||||
versionCode 2
|
||||
versionName '1.0.1'
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
|
|
|
@ -63,7 +63,7 @@ tic_vars_t tic_vars;
|
|||
|
||||
view_vars_t original_view_vars;
|
||||
|
||||
fixed_t r_stereo_offset = 0x30000;
|
||||
fixed_t r_stereo_offset = 0x38000;
|
||||
|
||||
extern int realtic_clock_rate;
|
||||
void D_Display(void);
|
||||
|
@ -121,7 +121,7 @@ void R_InterpolateView (player_t *player, fixed_t frac, int eye)
|
|||
|
||||
//More we roll, less we stereo
|
||||
float mult = 1.0f;
|
||||
mult -= fabs(hmdRoll)/22.5f;
|
||||
mult -= fabs(hmdRoll)/30.0f;
|
||||
if (mult < 0.0f)
|
||||
mult = 0.0f;
|
||||
|
||||
|
|
|
@ -12,7 +12,9 @@ import android.opengl.GLES20;
|
|||
import android.opengl.Matrix;
|
||||
import android.os.Bundle;
|
||||
import android.os.Vibrator;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.InputDevice;
|
||||
|
@ -20,9 +22,11 @@ import android.view.Window;
|
|||
import android.view.WindowManager;
|
||||
|
||||
import com.google.vrtoolkit.cardboard.CardboardActivity;
|
||||
import com.google.vrtoolkit.cardboard.CardboardDeviceParams;
|
||||
import com.google.vrtoolkit.cardboard.CardboardView;
|
||||
import com.google.vrtoolkit.cardboard.Eye;
|
||||
import com.google.vrtoolkit.cardboard.HeadTransform;
|
||||
import com.google.vrtoolkit.cardboard.ScreenParams;
|
||||
import com.google.vrtoolkit.cardboard.Viewport;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
|
@ -48,10 +52,7 @@ public class MainActivity
|
|||
{
|
||||
private static final String TAG = "DVR";
|
||||
|
||||
//Head orientation
|
||||
private float[] eulerAngles = new float[3];
|
||||
|
||||
OpenGL openGL = null;
|
||||
OpenGL openGL = null;
|
||||
|
||||
// Audio Cache Manager
|
||||
private AudioManager mAudioMgr;
|
||||
|
@ -62,6 +63,12 @@ public class MainActivity
|
|||
// height of mBitmap
|
||||
private int mDoomHeight;
|
||||
|
||||
//Head orientation
|
||||
private float[] eulerAngles = new float[3];
|
||||
private float hmdYaw;
|
||||
private float hmdPitch;
|
||||
private float hmdRoll;
|
||||
|
||||
//-1 means start button isn't pressed
|
||||
private long startButtonDownCounter = -1;
|
||||
//Don't allow the trigger to fire more than once per 200ms
|
||||
|
@ -83,9 +90,12 @@ public class MainActivity
|
|||
//Can't rebuild eye buffers until surface changed flag recorded
|
||||
public static boolean mSurfaceChanged = false;
|
||||
|
||||
float lensCentreOffset = -1.0f;
|
||||
|
||||
private boolean mShowingSpashScreen = true;
|
||||
private int[] splashTexture = new int[1];
|
||||
private MediaPlayer mPlayer;
|
||||
private int mPlayerVolume = 100;
|
||||
|
||||
|
||||
static {
|
||||
|
@ -286,9 +296,9 @@ public class MainActivity
|
|||
public void onNewFrame(HeadTransform headTransform) {
|
||||
|
||||
headTransform.getEulerAngles(eulerAngles, 0);
|
||||
float yaw = eulerAngles[1] / (M_PI / 180.0f);
|
||||
float pitch = -eulerAngles[0] / (M_PI / 180.0f);
|
||||
float roll = -eulerAngles[2] / (M_PI / 180.0f);
|
||||
hmdYaw = eulerAngles[1] / (M_PI / 180.0f);
|
||||
hmdPitch = -eulerAngles[0] / (M_PI / 180.0f);
|
||||
hmdRoll = -eulerAngles[2] / (M_PI / 180.0f);
|
||||
|
||||
if (!mShowingSpashScreen && mWADChooser.choosingWAD())
|
||||
{
|
||||
|
@ -306,20 +316,32 @@ public class MainActivity
|
|||
argv = args.split(" ");
|
||||
String dvr= DoomTools.GetDVRFolder();
|
||||
Natives.DoomInit(argv, dvr);
|
||||
|
||||
mDVRInitialised = true;
|
||||
|
||||
if (mPlayer != null) {
|
||||
mPlayer.stop();
|
||||
mPlayer.release();
|
||||
mPlayer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mDVRInitialised) {
|
||||
//Fade out intro music
|
||||
if (mPlayer != null) {
|
||||
mPlayerVolume--;
|
||||
if (mPlayerVolume == 0) {
|
||||
mPlayer.stop();
|
||||
mPlayer.release();
|
||||
mPlayer = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
float log1 = AudioManager.getLogVolume(mPlayerVolume);
|
||||
mPlayer.setVolume(log1, log1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
long newState = Natives.gameState();
|
||||
if (newState == 0)
|
||||
Natives.DoomStartFrame(pitch, yaw, roll);
|
||||
Natives.DoomStartFrame(hmdPitch, hmdYaw, hmdRoll);
|
||||
else
|
||||
Natives.DoomStartFrame(0, 0, 0);
|
||||
|
||||
|
@ -332,29 +354,42 @@ public class MainActivity
|
|||
cardboardView.resetHeadTracker();
|
||||
}
|
||||
}
|
||||
|
||||
if (mDVRInitialised) {
|
||||
//Get all the DOOM drawing done here, minimise time between eye calls
|
||||
Natives.DoomDrawEye(0);
|
||||
openGL.CopyBitmapToTexture(mDoomBitmap, openGL.fbo[0].ColorTexture[0]);
|
||||
Natives.DoomDrawEye(1);
|
||||
openGL.CopyBitmapToTexture(mDoomBitmap, openGL.fbo[1].ColorTexture[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDrawEye(Eye eye) {
|
||||
|
||||
if (lensCentreOffset == -1.0f) {
|
||||
//Now calculate the auto lens centre correction
|
||||
CardboardDeviceParams device = cardboardView.getHeadMountedDisplay().getCardboardDeviceParams();
|
||||
ScreenParams scr = cardboardView.getScreenParams();
|
||||
Display display = getWindowManager().getDefaultDisplay();
|
||||
DisplayMetrics met = new DisplayMetrics();
|
||||
display.getMetrics(met);
|
||||
float dpmil = (met.xdpi / 25.4f);
|
||||
float qscreen = (scr.getWidthMeters() * 1000.0f) / 4.0f;
|
||||
float halflens = (device.getInterLensDistance() * 1000.0f) / 2.0f;
|
||||
//Multiply by small fudge factor (25%)
|
||||
lensCentreOffset = ((halflens - qscreen) * dpmil) * 1.25f;
|
||||
//Viewport size is not the same as screen resolution, so convert
|
||||
lensCentreOffset = (lensCentreOffset / (scr.getWidth() / 2.0f)) * eye.getViewport().width;
|
||||
}
|
||||
|
||||
|
||||
if (!mShowingSpashScreen && mWADChooser.choosingWAD())
|
||||
{
|
||||
mWADChooser.onDrawEye(eye, this);
|
||||
}
|
||||
else if (mDVRInitialised || mShowingSpashScreen) {
|
||||
|
||||
if (mShowingSpashScreen) {
|
||||
GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
|
||||
GLES20.glScissor(eye.getViewport().x, eye.getViewport().y,
|
||||
eye.getViewport().width, eye.getViewport().height);
|
||||
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
|
||||
} else {
|
||||
Natives.DoomDrawEye(eye.getType() - 1);
|
||||
|
||||
//Now we'll have a populated bitmap, copy to the fbo colour buffer
|
||||
openGL.CopyBitmapToTexture(mDoomBitmap, openGL.fbo.ColorTexture[0]);
|
||||
}
|
||||
|
||||
GLES20.glViewport(eye.getViewport().x,
|
||||
eye.getViewport().y,
|
||||
eye.getViewport().width,
|
||||
|
@ -367,7 +402,7 @@ public class MainActivity
|
|||
eye.getViewport().y,
|
||||
eye.getViewport().width,
|
||||
eye.getViewport().height);
|
||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
|
||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
GLES20.glUseProgram(openGL.sp_Image);
|
||||
|
||||
|
@ -397,37 +432,40 @@ public class MainActivity
|
|||
|
||||
} else {
|
||||
|
||||
// Create the triangles for orthographic projection (if required)
|
||||
int w = (int) (eye.getViewport().width * 0.82f);
|
||||
int h = (int) (eye.getViewport().height * 0.7f);
|
||||
int x = (int) ((eye.getType() == Eye.Type.LEFT) ? 0 : (eye.getViewport().width - w));
|
||||
int y = (int) (eye.getViewport().height * 0.15f);
|
||||
float widthScaler = 0.76f;
|
||||
float heightScaler = 0.64f;
|
||||
|
||||
// Create the triangles for orthographic projection
|
||||
int w = (int) (eye.getViewport().width * widthScaler);
|
||||
int h = (int) (eye.getViewport().height * heightScaler);
|
||||
int x = (int) (eye.getViewport().width * ((1.0f-widthScaler)/2.0f));;
|
||||
int y = (int) (eye.getViewport().height * ((1.0f-heightScaler)/2.0f));
|
||||
|
||||
int pitchOffset = (int)(-(eulerAngles[0]/M_PI)*(eye.getViewport().height));
|
||||
|
||||
int widthScaler = 0;
|
||||
int pitchWidthScaler = 0;
|
||||
float f = -(eulerAngles[0]/M_PI);
|
||||
if (f > 0.125f)
|
||||
widthScaler = (int)(((f - 0.125f)/2.0f) * eye.getViewport().width);
|
||||
pitchWidthScaler = (int)(((f - 0.125f)/2.0f) * eye.getViewport().width);
|
||||
|
||||
openGL.SetupTriangle(x+widthScaler, y, w-widthScaler*2, h);
|
||||
int l = (int)lensCentreOffset;
|
||||
if (eye.getType() == Eye.Type.LEFT)
|
||||
l = -l;
|
||||
openGL.SetupTriangle(x + pitchWidthScaler, y, w - pitchWidthScaler * 2, h);
|
||||
|
||||
// Calculate the projection and view transformation
|
||||
Matrix.orthoM(openGL.view, 0, 0, eye.getViewport().width, 0, eye.getViewport().height, 0, 50);
|
||||
//Translate so origin is centre of image
|
||||
if (eye.getType() == Eye.Type.LEFT)
|
||||
Matrix.translateM(openGL.view, 0, w / 2, eye.getViewport().height / 2, 0);
|
||||
else
|
||||
Matrix.translateM(openGL.view, 0, eye.getViewport().width - w / 2, eye.getViewport().height / 2, 0);
|
||||
Matrix.translateM(openGL.view, 0, eye.getViewport().width / 2, eye.getViewport().height / 2, 0);
|
||||
//rotate for head roll
|
||||
Matrix.rotateM(openGL.view, 0, (int) (-(eulerAngles[2] / M_PI) * 180.f), 0, 0, 1);
|
||||
Matrix.rotateM(openGL.view, 0, (int) hmdRoll, 0, 0, 1);
|
||||
//translate back to where it was before
|
||||
if (eye.getType() == Eye.Type.LEFT)
|
||||
Matrix.translateM(openGL.view, 0, -w / 2, -eye.getViewport().height / 2, 0);
|
||||
else
|
||||
Matrix.translateM(openGL.view, 0, w / 2 - eye.getViewport().width, -eye.getViewport().height / 2, 0);
|
||||
//Now apply head pitch transformation
|
||||
Matrix.translateM(openGL.view, 0, (float)(Math.cos(eulerAngles[2]) * l) - eye.getViewport().width / 2,
|
||||
(float)(Math.sin(eulerAngles[2]) * l) - eye.getViewport().height / 2, 0);
|
||||
|
||||
//Now apply head hmdPitch transformation
|
||||
Matrix.translateM(openGL.view, 0, 0, pitchOffset, 0);
|
||||
//Matrix.translateM(openGL.view, 0, l, 0, 0);
|
||||
Matrix.multiplyMM(openGL.modelViewProjection, 0, openGL.view, 0, openGL.camera, 0);
|
||||
|
||||
// Prepare the triangle coordinate data
|
||||
|
@ -449,7 +487,7 @@ public class MainActivity
|
|||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, splashTexture[0]);
|
||||
}
|
||||
else {
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, openGL.fbo.ColorTexture[0]);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, openGL.fbo[eye.getType()-1].ColorTexture[0]);
|
||||
}
|
||||
|
||||
// Set the sampler texture unit to our fbo's color texture
|
||||
|
@ -477,9 +515,9 @@ public class MainActivity
|
|||
|
||||
if (!mShowingSpashScreen && mWADChooser.choosingWAD())
|
||||
{
|
||||
if (eulerAngles[1] / (M_PI / 180.0f) > 15.0f)
|
||||
if (hmdYaw > 15.0f)
|
||||
mWADChooser.MoveNext();
|
||||
else if (eulerAngles[1] / (M_PI / 180.0f) < -15.0f)
|
||||
else if (hmdYaw < -15.0f)
|
||||
mWADChooser.MovePrev();
|
||||
else
|
||||
mWADChooser.SelectWAD();
|
||||
|
@ -524,9 +562,9 @@ public class MainActivity
|
|||
{
|
||||
if (action == KeyEvent.ACTION_UP &&
|
||||
keyCode == KeyEvent.KEYCODE_BUTTON_A) {
|
||||
if (eulerAngles[1] / (M_PI / 180.0f) > 10.0f)
|
||||
if (hmdYaw > 15.0f)
|
||||
mWADChooser.MoveNext();
|
||||
else if (eulerAngles[1] / (M_PI / 180.0f) < -10.0f)
|
||||
else if (hmdYaw < -15.0f)
|
||||
mWADChooser.MovePrev();
|
||||
else
|
||||
mWADChooser.SelectWAD();
|
||||
|
@ -612,6 +650,8 @@ public class MainActivity
|
|||
// 1 - Generic BT gamepad
|
||||
// 2 - Samsung gamepad that uses different axes for right stick
|
||||
int gamepadType = 0;
|
||||
int lTrigAction = KeyEvent.ACTION_UP;
|
||||
int rTrigAction = KeyEvent.ACTION_UP;
|
||||
|
||||
@Override
|
||||
public boolean onGenericMotionEvent(MotionEvent event) {
|
||||
|
@ -647,6 +687,26 @@ public class MainActivity
|
|||
Natives.motionEvent(0, (int)(rx * 30), 0);
|
||||
break;
|
||||
}
|
||||
|
||||
//Fire weapon using shoulder trigger
|
||||
float axisRTrigger = max(event.getAxisValue(MotionEvent.AXIS_RTRIGGER),
|
||||
event.getAxisValue(MotionEvent.AXIS_GAS));
|
||||
int newRTrig = axisRTrigger > 0.6 ? KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP;
|
||||
if (rTrigAction != newRTrig)
|
||||
{
|
||||
Natives.keyEvent(newRTrig, DoomTools.KEY_RCTRL);
|
||||
rTrigAction = newRTrig;
|
||||
}
|
||||
|
||||
//Run using L shoulder
|
||||
float axisLTrigger = max(event.getAxisValue(MotionEvent.AXIS_LTRIGGER),
|
||||
event.getAxisValue(MotionEvent.AXIS_BRAKE));
|
||||
int newLTrig = axisLTrigger > 0.6 ? KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP;
|
||||
if (lTrigAction != newLTrig)
|
||||
{
|
||||
Natives.keyEvent(newLTrig, DoomTools.KEY_RSHIFT);
|
||||
lTrigAction = newLTrig;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -744,7 +804,8 @@ public class MainActivity
|
|||
mDoomBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
|
||||
|
||||
openGL.SetBitmap(mDoomBitmap);
|
||||
openGL.CreateFBO(mDoomWidth, mDoomHeight);
|
||||
openGL.CreateFBO(openGL.fbo[0], mDoomWidth, mDoomHeight);
|
||||
openGL.CreateFBO(openGL.fbo[1], mDoomWidth, mDoomHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -43,7 +43,8 @@ public class OpenGL {
|
|||
modelView = new float[16];
|
||||
|
||||
//Create the FBOs
|
||||
fbo = new DVRFBO();
|
||||
fbo[0] = new DVRFBO();
|
||||
fbo[1] = new DVRFBO();
|
||||
}
|
||||
|
||||
public void onSurfaceCreated(EGLConfig config) {
|
||||
|
@ -176,10 +177,10 @@ public class OpenGL {
|
|||
return shader;
|
||||
}
|
||||
//FBO render eye buffer
|
||||
public DVRFBO fbo;
|
||||
public DVRFBO fbo[] = new DVRFBO[2];
|
||||
|
||||
|
||||
boolean CreateFBO( int width, int height)
|
||||
boolean CreateFBO(DVRFBO fbo, int width, int height)
|
||||
{
|
||||
Log.d("DVR", "CreateFBO");
|
||||
// Create the color buffer texture.
|
||||
|
@ -217,7 +218,7 @@ public class OpenGL {
|
|||
return true;
|
||||
}
|
||||
|
||||
void DestroyFBO( )
|
||||
void DestroyFBO(DVRFBO fbo)
|
||||
{
|
||||
GLES20.glDeleteFramebuffers( 1, fbo.FrameBuffer, 0 );
|
||||
fbo.FrameBuffer[0] = 0;
|
||||
|
|
|
@ -151,7 +151,7 @@ public class WADChooser {
|
|||
canvas.drawText(">", 228, 116, paint);
|
||||
}
|
||||
|
||||
openGL.CopyBitmapToTexture(bitmap, openGL.fbo.ColorTexture[0]);
|
||||
openGL.CopyBitmapToTexture(bitmap, openGL.fbo[0].ColorTexture[0]);
|
||||
}
|
||||
|
||||
public void onDrawEye(Eye eye, Context ctx) {
|
||||
|
@ -240,7 +240,7 @@ public class WADChooser {
|
|||
IntBuffer activeTex0 = IntBuffer.allocate(2);
|
||||
GLES20.glGetIntegerv(GLES20.GL_TEXTURE_BINDING_2D, activeTex0);
|
||||
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, openGL.fbo.ColorTexture[0]);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, openGL.fbo[0].ColorTexture[0]);
|
||||
|
||||
// Set the sampler texture unit to our fbo's color texture
|
||||
GLES20.glUniform1i(openGL.samplerParam, 0);
|
||||
|
|
|
@ -124,7 +124,7 @@ public class AudioClip
|
|||
if ( mPlayer != null) {
|
||||
if (vol > 100)
|
||||
vol = 100;
|
||||
float log1=1.0f - (float)(Math.log(101-vol)/Math.log(101));
|
||||
float log1 = AudioManager.getLogVolume(vol);
|
||||
mPlayer.setVolume(log1, log1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,11 @@ public class AudioManager
|
|||
private AudioManager(Context ctx) {
|
||||
mContext = ctx;
|
||||
}
|
||||
|
||||
|
||||
static public float getLogVolume(int volume) {
|
||||
return 1.0f - (float)(Math.log(101-volume)/Math.log(101));
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a sound by name & volume
|
||||
* @param name example "pistol" when firing the gun
|
||||
|
|
Loading…
Reference in a new issue