- Fix for different sprite image in each eye
- When player dies, switch to big screen mode (comfort)
- Massive improvement to the look up/down so it doesn't skew any more
- No need for lens correction offset calculation due to above fix
This commit is contained in:
Simon 2016-03-22 20:23:05 +00:00
parent 7ca2268ef1
commit 7fa8ea10f4
10 changed files with 91 additions and 121 deletions

View file

@ -7,8 +7,8 @@ android {
applicationId "com.drbeef.dvr"
minSdkVersion 16
targetSdkVersion 19
versionCode 2
versionName '1.0.1'
versionCode 3
versionName '1.0.2'
}
buildTypes {
release {

View file

@ -275,6 +275,7 @@ JNIEXPORT jint JNICALL Java_doom_util_Natives_setVideoMode
extern gamestate_t gamestate;
extern boolean menuactive;
extern boolean demoplayback;
extern player_t *viewplayer;
JNIEXPORT jint JNICALL Java_doom_util_Natives_gameState
(JNIEnv * env, jclass cls)
@ -282,7 +283,8 @@ JNIEXPORT jint JNICALL Java_doom_util_Natives_gameState
return (int)gamestate +
(int) automapmode +
menuactive ? 1 : 0 +
demoplayback ? 1 : 0;
demoplayback ? 1 : 0 +
viewplayer ? (viewplayer->health > 0 ? 0 : 1) : 1;
}

View file

@ -304,8 +304,8 @@ static void R_AddLine (seg_t *line)
curline = line;
angle1 = R_PointToAngle (line->v1->x, line->v1->y);
angle2 = R_PointToAngle (line->v2->x, line->v2->y);
angle1 = R_PointToAngle (line->v1->x, line->v1->y, 0);
angle2 = R_PointToAngle (line->v2->x, line->v2->y, 0);
// Clip to view edges.
span = angle1 - angle2;
@ -440,8 +440,8 @@ static boolean R_CheckBBox(const fixed_t *bspcoord)
return true;
check = checkcoord[boxpos];
angle1 = R_PointToAngle (bspcoord[check[0]], bspcoord[check[1]]) - viewangle;
angle2 = R_PointToAngle (bspcoord[check[2]], bspcoord[check[3]]) - viewangle;
angle1 = R_PointToAngle (bspcoord[check[0]], bspcoord[check[1]], 0) - viewangle;
angle2 = R_PointToAngle (bspcoord[check[2]], bspcoord[check[3]], 0) - viewangle;
}
// cph - replaced old code, which was unclear and badly commented

View file

@ -180,12 +180,22 @@ PUREFUNC int R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line)
#include <math.h>
angle_t R_PointToAngle(fixed_t x, fixed_t y)
angle_t R_PointToAngle(fixed_t x, fixed_t y, int usePlayer)
{
static fixed_t oldx, oldy;
static angle_t oldresult;
if (usePlayer == 0)
{
x -= viewx; y -= viewy;
}
else
{
//SB- use player position rather than view position (as these will have stereo offset included
//and can mean different sprites for each eye!)
x -= viewplayer->mo->x;
y -= viewplayer->mo->y;
}
if ( /* !render_precise && */
// e6y: here is where "slime trails" can SOMETIMES occur

View file

@ -104,7 +104,7 @@ extern const lighttable_t *fixedcolormap;
PUREFUNC int R_PointOnSide(fixed_t x, fixed_t y, const node_t *node);
PUREFUNC int R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line);
angle_t R_PointToAngle(fixed_t x, fixed_t y);
angle_t R_PointToAngle(fixed_t x, fixed_t y, int usePlayer);
angle_t R_PointToAngle2(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2);
subsector_t *R_PointInSubsector(fixed_t x, fixed_t y);

View file

@ -534,7 +534,7 @@ static void R_ProjectSprite (mobj_t* thing, int lightlevel)
if (sprframe->rotate)
{
// choose a different rotation based on player view
angle_t ang = R_PointToAngle(fx, fy);
angle_t ang = R_PointToAngle(fx, fy, 1);
unsigned rot = (ang-thing->angle+(unsigned)(ANG45/2)*9)>>29;
lump = sprframe->lump[rot];
flip = (boolean) sprframe->flip[rot];

View file

@ -300,6 +300,9 @@ public class MainActivity
hmdPitch = -eulerAngles[0] / (M_PI / 180.0f);
hmdRoll = -eulerAngles[2] / (M_PI / 180.0f);
//Store head view
headTransform.getHeadView(openGL.headView, 0);
if (!mShowingSpashScreen && mWADChooser.choosingWAD())
{
return;
@ -367,111 +370,74 @@ public class MainActivity
@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) {
GLES20.glViewport(eye.getViewport().x,
eye.getViewport().y,
eye.getViewport().width,
eye.getViewport().height);
GLES20.glViewport(eye.getViewport().x, eye.getViewport().y,
eye.getViewport().width, eye.getViewport().height);
//Clear the viewport
GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
GLES20.glScissor(eye.getViewport().x,
eye.getViewport().y,
eye.getViewport().width,
eye.getViewport().height);
GLES20.glScissor(eye.getViewport().x, eye.getViewport().y,
eye.getViewport().width, eye.getViewport().height);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
GLES20.glUseProgram(openGL.sp_Image);
if (Natives.gameState() != 0 || mShowingSpashScreen) {
// Apply the eye transformation to the camera.
Matrix.multiplyMM(openGL.view, 0, eye.getEyeView(), 0, openGL.camera, 0);
float modelScreen[] = new float[16];
Matrix.setIdentityM(modelScreen, 0);
// Set the position of the screen
if (mShowingSpashScreen)
{
Matrix.translateM(modelScreen, 0, 0, 0, openGL.splashScreenDistance);
Matrix.scaleM(modelScreen, 0, openGL.screenScale, openGL.screenScale, 1.0f);
float mAngle = 180.0f * (float)((System.currentTimeMillis() % 2000) / 2000.0f);
if (mAngle > 90.0f) mAngle += 180.0f;
Matrix.rotateM(modelScreen, 0, mAngle, 0.0f, 1.0f, 0.0f);
}
else if (Natives.gameState() != 0)
{
//Drawing Virtual Screen
Matrix.translateM(modelScreen, 0, 0, 0, openGL.screenDistance);
//Make virtual screen wider than high
Matrix.scaleM(modelScreen, 0, openGL.screenScale*1.3f, openGL.screenScale, 1.0f);
}
else
{
float screenDist = openGL.gameScreenDistance;
float f = (hmdPitch / 90.0f);
if (f > 0.125f)
screenDist *= (1.0f + (f - 0.125f) * 2.0f);
//In Game - ensure screen is always "in-front" of us, whatever direction we are facing
Matrix.translateM(modelScreen, 0, (float)(Math.sin(M_PI * (hmdYaw / 180f))) * screenDist, 0,
(float)(Math.cos(M_PI * (hmdYaw / 180f))) * screenDist);
Matrix.rotateM(modelScreen, 0, hmdYaw, 0.0f, 1.0f, 0.0f);
Matrix.scaleM(modelScreen, 0, openGL.screenScale, openGL.screenScale, openGL.screenScale);
}
// Build the ModelView and ModelViewProjection matrices
// for calculating screen position.
float[] perspective = eye.getPerspective(0.1f, 100.0f);
// Object first appears directly in front of user.
Matrix.setIdentityM(openGL.modelScreen, 0);
Matrix.translateM(openGL.modelScreen, 0, 0, 0, -openGL.screenDistance);
Matrix.scaleM(openGL.modelScreen, 0, openGL.screenScale*1.5f, openGL.screenScale*1.5f, 1.0f);
// Set the position of the screen
if (mShowingSpashScreen) {
float mAngle = 180.0f * (float)((System.currentTimeMillis() % 2000) / 2000.0f);
if (mAngle > 90.0f) mAngle += 180.0f;
Matrix.rotateM(openGL.modelScreen, 0, mAngle, 0.0f, 1.0f, 0.0f);
if (Natives.gameState() != 0 || mShowingSpashScreen) {
Matrix.multiplyMM(openGL.view, 0, eye.getEyeView(), 0, openGL.camera, 0);
}
else {
//centre eye view - no stereo depth required
Matrix.multiplyMM(openGL.view, 0, openGL.headView, 0, openGL.camera, 0);
}
Matrix.multiplyMM(openGL.modelView, 0, openGL.view, 0, openGL.modelScreen, 0);
Matrix.multiplyMM(openGL.modelView, 0, openGL.view, 0, modelScreen, 0);
Matrix.multiplyMM(openGL.modelViewProjection, 0, perspective, 0, openGL.modelView, 0);
GLES20.glVertexAttribPointer(openGL.positionParam, 3, GLES20.GL_FLOAT, false, 0, openGL.screenVertices);
} else {
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 pitchWidthScaler = 0;
float f = -(eulerAngles[0]/M_PI);
if (f > 0.125f)
pitchWidthScaler = (int)(((f - 0.125f)/2.0f) * eye.getViewport().width);
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
Matrix.translateM(openGL.view, 0, eye.getViewport().width / 2, eye.getViewport().height / 2, 0);
//rotate for head roll
Matrix.rotateM(openGL.view, 0, (int) hmdRoll, 0, 0, 1);
//translate back to where it was before
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
GLES20.glVertexAttribPointer(openGL.positionParam, 3, GLES20.GL_FLOAT, false, 0, openGL.vertexBuffer);
}
// Prepare the texturecoordinates
GLES20.glVertexAttribPointer(openGL.texCoordParam, 2, GLES20.GL_FLOAT, false, 0, openGL.uvBuffer);
@ -487,6 +453,7 @@ public class MainActivity
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, splashTexture[0]);
}
else {
//Actually Draw Doom
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, openGL.fbo[eye.getType()-1].ColorTexture[0]);
}
@ -852,18 +819,4 @@ public class MainActivity
if (mAudioMgr != null)
mAudioMgr.setMusicVolume(volume);
}
/**
* Send a key event to the native layer
*
* @param type
* @param sym
*/
private void sendNativeKeyEvent(int type, int sym) {
try {
Natives.keyEvent(type, sym);
} catch (UnsatisfiedLinkError e) {
Log.e(TAG, e.toString());
}
}
}

View file

@ -40,6 +40,7 @@ public class OpenGL {
camera = new float[16];
view = new float[16];
modelViewProjection = new float[16];
headView = new float[16];
modelView = new float[16];
//Create the FBOs
@ -144,11 +145,14 @@ public class OpenGL {
public float[] modelScreen;
public float[] camera;
public float[] headView;
public float[] view;
public float[] modelViewProjection;
public float[] modelView;
public float screenDistance = 8f;
public float screenDistance = -8f;
public float splashScreenDistance = -12f;
public float gameScreenDistance = -3.45f;
public float screenScale = 3f;
public static final String vs_Image =
@ -241,10 +245,10 @@ public class OpenGL {
};
public static final float[] SCREEN_COORDS = new float[] {
-1.3f, -1.0f, 0.0f,
-1.3f, 1.0f, 0.0f,
1.3f, 1.0f, 0.0f,
1.3f, -1.0f, 0.0f
-1.0f, -1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
1.0f, -1.0f, 0.0f
};
public FloatBuffer vertexBuffer;

View file

@ -211,8 +211,8 @@ public class WADChooser {
// Object first appears directly in front of user.
Matrix.setIdentityM(openGL.modelScreen, 0);
Matrix.translateM(openGL.modelScreen, 0, 0, 0, -openGL.screenDistance);
Matrix.scaleM(openGL.modelScreen, 0, openGL.screenScale, openGL.screenScale, 1.0f);
Matrix.translateM(openGL.modelScreen, 0, 0, 0, openGL.screenDistance);
Matrix.scaleM(openGL.modelScreen, 0, openGL.screenScale * 1.3f, openGL.screenScale, 1.0f);
if (mTransitionStart != -1) {
long transVal = System.currentTimeMillis() - mTransitionStart;

View file

@ -7,5 +7,6 @@
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Thu Mar 03 19:58:29 GMT 2016
#Thu Mar 17 20:24:13 GMT 2016
ndk.dir=C\:\\Android\\android-ndk-r10e
sdk.dir=C\:\\Users\\Simon\\AppData\\Local\\Android\\sdk