From 7fa8ea10f4e18dfa41125045b70a1cf1bd0141e7 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 22 Mar 2016 20:23:05 +0000 Subject: [PATCH] Fixes - 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 --- app/build.gradle | 4 +- app/jni/prboom/jni_doom.c | 4 +- app/jni/prboom/r_bsp.c | 8 +- app/jni/prboom/r_main.c | 14 +- app/jni/prboom/r_main.h | 2 +- app/jni/prboom/r_things.c | 2 +- .../java/com/drbeef/dvr/MainActivity.java | 157 ++++++------------ app/src/main/java/com/drbeef/dvr/OpenGL.java | 14 +- .../main/java/com/drbeef/dvr/WADChooser.java | 4 +- local.properties | 3 +- 10 files changed, 91 insertions(+), 121 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index f592b96..27c7acd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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 { diff --git a/app/jni/prboom/jni_doom.c b/app/jni/prboom/jni_doom.c index 2ac93a6..39b5d15 100644 --- a/app/jni/prboom/jni_doom.c +++ b/app/jni/prboom/jni_doom.c @@ -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; } diff --git a/app/jni/prboom/r_bsp.c b/app/jni/prboom/r_bsp.c index e9ce6c5..3ec4201 100644 --- a/app/jni/prboom/r_bsp.c +++ b/app/jni/prboom/r_bsp.c @@ -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 diff --git a/app/jni/prboom/r_main.c b/app/jni/prboom/r_main.c index 746d284..f887c32 100644 --- a/app/jni/prboom/r_main.c +++ b/app/jni/prboom/r_main.c @@ -180,12 +180,22 @@ PUREFUNC int R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line) #include -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; - x -= viewx; y -= viewy; + 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 diff --git a/app/jni/prboom/r_main.h b/app/jni/prboom/r_main.h index a4428eb..cb3ee93 100644 --- a/app/jni/prboom/r_main.h +++ b/app/jni/prboom/r_main.h @@ -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); diff --git a/app/jni/prboom/r_things.c b/app/jni/prboom/r_things.c index b46a074..1346085 100644 --- a/app/jni/prboom/r_things.c +++ b/app/jni/prboom/r_things.c @@ -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]; diff --git a/app/src/main/java/com/drbeef/dvr/MainActivity.java b/app/src/main/java/com/drbeef/dvr/MainActivity.java index e3898dd..efdacb6 100644 --- a/app/src/main/java/com/drbeef/dvr/MainActivity.java +++ b/app/src/main/java/com/drbeef/dvr/MainActivity.java @@ -52,7 +52,7 @@ public class MainActivity { private static final String TAG = "DVR"; - OpenGL openGL = null; + OpenGL openGL = null; // Audio Cache Manager private AudioManager mAudioMgr; @@ -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,110 +370,73 @@ 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); - // Build the ModelView and ModelViewProjection matrices - // for calculating screen position. - float[] perspective = eye.getPerspective(0.1f, 100.0f); + // 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); - // 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); - } - - Matrix.multiplyMM(openGL.modelView, 0, openGL.view, 0, openGL.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); + 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); + + 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, modelScreen, 0); + Matrix.multiplyMM(openGL.modelViewProjection, 0, perspective, 0, openGL.modelView, 0); + GLES20.glVertexAttribPointer(openGL.positionParam, 3, GLES20.GL_FLOAT, false, 0, openGL.screenVertices); // 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()); - } - } } diff --git a/app/src/main/java/com/drbeef/dvr/OpenGL.java b/app/src/main/java/com/drbeef/dvr/OpenGL.java index 4be858c..5b99f98 100644 --- a/app/src/main/java/com/drbeef/dvr/OpenGL.java +++ b/app/src/main/java/com/drbeef/dvr/OpenGL.java @@ -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; diff --git a/app/src/main/java/com/drbeef/dvr/WADChooser.java b/app/src/main/java/com/drbeef/dvr/WADChooser.java index a53dc09..e48b499 100644 --- a/app/src/main/java/com/drbeef/dvr/WADChooser.java +++ b/app/src/main/java/com/drbeef/dvr/WADChooser.java @@ -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; diff --git a/local.properties b/local.properties index 228b60e..fb24c09 100644 --- a/local.properties +++ b/local.properties @@ -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