diff --git a/Projects/Android/jni/RTCWVR/RTCWVR_SurfaceView.c b/Projects/Android/jni/RTCWVR/RTCWVR_SurfaceView.c index 974de25..2d6895d 100644 --- a/Projects/Android/jni/RTCWVR/RTCWVR_SurfaceView.c +++ b/Projects/Android/jni/RTCWVR/RTCWVR_SurfaceView.c @@ -571,6 +571,17 @@ void ovrFramebuffer_Destroy( ovrFramebuffer * frameBuffer ) ovrFramebuffer_Clear( frameBuffer ); } +void GPUWaitSync() +{ + GLsync syncBuff = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + GLenum status = glClientWaitSync(syncBuff, GL_SYNC_FLUSH_COMMANDS_BIT, 1000 * 1000 * 50); // Wait for a max of 50ms... + if (status != GL_CONDITION_SATISFIED) + { + LOGE("Error on glClientWaitSync: %d\n", status); + } + glDeleteSync(syncBuff); +} + void ovrFramebuffer_SetCurrent( ovrFramebuffer * frameBuffer ) { LOAD_GLES2(glBindFramebuffer); @@ -583,32 +594,6 @@ void ovrFramebuffer_SetNone() GL( gles_glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 ) ); } -GLsync syncBuff = NULL; - -void GPUDropSync() -{ - if (syncBuff != NULL) - { - glDeleteSync(syncBuff); - } - - syncBuff = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); -} - -void GPUWaitSync() -{ - if( syncBuff ) - { - GLenum status = glClientWaitSync(syncBuff, GL_SYNC_FLUSH_COMMANDS_BIT, 1000 * 1000 * 50); // Wait for a max of 50ms... - if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED) - { - LOGE("Error on glClientWaitSync: %d\n", status); - } - glDeleteSync(syncBuff); - syncBuff = NULL; - } -} - void ovrFramebuffer_Resolve( ovrFramebuffer * frameBuffer ) { // Discard the depth buffer, so the tiler won't need to write it back out to memory. @@ -617,8 +602,6 @@ void ovrFramebuffer_Resolve( ovrFramebuffer * frameBuffer ) // Flush this frame worth of commands. glFlush(); - - //GPUDropSync(); } void ovrFramebuffer_Advance( ovrFramebuffer * frameBuffer ) @@ -1293,7 +1276,7 @@ void RTCWVR_ResyncClientYawWithGameYaw() //Allow 3 frames for the yaw to sync, first is this frame which is the old yaw //second is the next frame which _should_ be the new yaw, but just in case it isn't //we resync on the 3rd frame as well - resyncClientYawWithGameYaw = 3; + resyncClientYawWithGameYaw = 5; } void RTCWVR_Init() @@ -1707,6 +1690,7 @@ void RTCWVR_submitFrame() vrapi_SubmitFrame2(gAppState.Ovr, &frameDesc); } + RTCWVR_incrementFrameIndex(); } diff --git a/Projects/Android/jni/rtcw/src/cgame/cg_draw.c b/Projects/Android/jni/rtcw/src/cgame/cg_draw.c index 186b936..c1e20e5 100644 --- a/Projects/Android/jni/rtcw/src/cgame/cg_draw.c +++ b/Projects/Android/jni/rtcw/src/cgame/cg_draw.c @@ -349,7 +349,7 @@ void CG_Draw3DModel( float x, float y, float w, float h, qhandle_t model, qhandl } //Indicate to renderer it should be trying any view angle adjustments - refdef.viewangles[YAW] = -1000; + refdef.viewangles[YAW] = -1001; trap_R_ClearScene(); trap_R_AddRefEntityToScene( &ent ); @@ -3391,7 +3391,7 @@ static void CG_Draw2D( void ) { // don't draw any status if dead if ( cg.snap->ps.stats[STAT_HEALTH] > 0 ) { - CG_DrawCrosshair(); +// CG_DrawCrosshair(); if ( cg_drawStatus.integer ) { Menu_PaintAll(); @@ -3573,7 +3573,7 @@ void CG_DrawActive( int stereoView ) { cg.refdef.worldscale = cg_worldScale.value; - VectorCopy(cg.refdefViewAngles, cg.refdef.viewangles); + cg.refdef.viewangles[YAW] = -1001; // clear around the rendered view if sized down // CG_TileClear(); // (SA) moved down diff --git a/Projects/Android/jni/rtcw/src/cgame/cg_view.c b/Projects/Android/jni/rtcw/src/cgame/cg_view.c index ffe8805..78a1426 100644 --- a/Projects/Android/jni/rtcw/src/cgame/cg_view.c +++ b/Projects/Android/jni/rtcw/src/cgame/cg_view.c @@ -1419,8 +1419,7 @@ void CG_DrawSkyBoxPortal( void ) { cg.refdef.time = cg.time; - //Indicate to renderer it should be trying any view angle adjustments - cg.refdef.viewangles[YAW] = -1000; + VectorCopy(cg.refdefViewAngles, cg.refdef.viewangles); // draw the skybox trap_R_RenderScene( &cg.refdef ); diff --git a/Projects/Android/jni/rtcw/src/cgame/cg_weapons.c b/Projects/Android/jni/rtcw/src/cgame/cg_weapons.c index 031b1fd..905f1bf 100644 --- a/Projects/Android/jni/rtcw/src/cgame/cg_weapons.c +++ b/Projects/Android/jni/rtcw/src/cgame/cg_weapons.c @@ -1758,8 +1758,10 @@ static void CG_WeaponAnimation( playerState_t *ps, weaponInfo_t *weapon, int *we void convertFromVR(vec3_t in, vec3_t offset, vec3_t out) { - vec3_t temp; - VectorScale(in, cg_worldScale.value, temp); + vec3_t vrSpace; + VectorSet(vrSpace, in[0], in[1], in[2]); + vec3_t temp; + VectorScale(vrSpace, cg_worldScale.value, temp); if (offset) { VectorAdd(temp, offset, out); @@ -1780,7 +1782,7 @@ static void CG_CalculateWeaponPosition( vec3_t origin, vec3_t angles ) { convertFromVR(cgVR->weaponoffset, cg.refdef.vieworg, origin); VectorCopy(cgVR->weaponangles, angles); - angles[YAW] = cg.refdefViewAngles[YAW] - (cgVR->weaponangles[YAW] - cgVR->hmdorientation[YAW]); + angles[YAW] = cg.refdefViewAngles[YAW] + (cgVR->hmdorientation[YAW] - cgVR->weaponangles[YAW]); return; float scale; @@ -3058,12 +3060,12 @@ void CG_AddViewWeapon( playerState_t *ps ) { } - // drop gun lower at higher fov +/* // drop gun lower at higher fov if ( cg_fov.integer > 90 ) { fovOffset = -0.2 * ( cg_fov.integer - 90 ); } else { fovOffset = 0; - } + }*/ if ( ps->weapon > WP_NONE ) { // DHM - Nerve :: handle WP_CLASS_SPECIAL for different classes @@ -3105,7 +3107,7 @@ void CG_AddViewWeapon( playerState_t *ps ) { VectorMA( hand.origin, gunoff[0], cg.refdef.viewaxis[0], hand.origin ); VectorMA( hand.origin, gunoff[1], cg.refdef.viewaxis[1], hand.origin ); - VectorMA( hand.origin, ( gunoff[2] + fovOffset ), cg.refdef.viewaxis[2], hand.origin ); + VectorMA( hand.origin, gunoff[2], cg.refdef.viewaxis[2], hand.origin ); AnglesToAxis( angles, hand.axis ); diff --git a/Projects/Android/jni/rtcw/src/client/cl_cgame.c b/Projects/Android/jni/rtcw/src/client/cl_cgame.c index 0ff4572..7b5081d 100644 --- a/Projects/Android/jni/rtcw/src/client/cl_cgame.c +++ b/Projects/Android/jni/rtcw/src/client/cl_cgame.c @@ -966,6 +966,7 @@ CL_InitCGame Should only by called by CL_StartHunkUsers ==================== */ +void RTCWVR_ResyncClientYawWithGameYaw(); void CL_InitCGame( void ) { const char *info; const char *mapname; @@ -1024,6 +1025,8 @@ void CL_InitCGame( void ) { // Ridah, update the memory usage file CL_UpdateLevelHunkUsage(); + + RTCWVR_ResyncClientYawWithGameYaw(); } diff --git a/Projects/Android/jni/rtcw/src/client/cl_scrn.c b/Projects/Android/jni/rtcw/src/client/cl_scrn.c index 4a7c0a4..56a83bd 100644 --- a/Projects/Android/jni/rtcw/src/client/cl_scrn.c +++ b/Projects/Android/jni/rtcw/src/client/cl_scrn.c @@ -542,7 +542,7 @@ void RTCWVR_processHaptics(); void RTCWVR_getHMDOrientation(); qboolean RTCWVR_processMessageQueue(); void RTCWVR_getTrackedRemotesOrientation(); -void GPUWaitSync(); +void GPUDropSync(); void SCR_UpdateScreen( void ) { static int recursive; @@ -565,14 +565,10 @@ void SCR_UpdateScreen( void ) { RTCWVR_processHaptics(); - //GPUWaitSync(); - //Draw twice for Quest SCR_DrawScreenField( STEREO_LEFT ); - RTCWVR_finishEyeBuffer(0); - //Only need to do this when viewing screen mode - //if (RTCWVR_useScreenLayer()) + //This won't perform the submit eye buffers { if (com_speeds->integer) { re.EndFrame(STEREO_LEFT, &time_frontend, &time_backend); @@ -581,14 +577,21 @@ void SCR_UpdateScreen( void ) { } } - SCR_DrawScreenField( STEREO_RIGHT ); - RTCWVR_finishEyeBuffer(1); + RTCWVR_finishEyeBuffer(0); + SCR_DrawScreenField( STEREO_RIGHT ); + + //This will perform the submit eye buffers if ( com_speeds->integer ) { re.EndFrame( STEREO_RIGHT, &time_frontend, &time_backend ); } else { re.EndFrame( STEREO_RIGHT, NULL, NULL ); } + RTCWVR_finishEyeBuffer(1); + + //And we're done + re.SubmitStereoFrame(); + recursive = 0; } diff --git a/Projects/Android/jni/rtcw/src/renderer/tr_cmds.c b/Projects/Android/jni/rtcw/src/renderer/tr_cmds.c index d51ee79..c8579bb 100644 --- a/Projects/Android/jni/rtcw/src/renderer/tr_cmds.c +++ b/Projects/Android/jni/rtcw/src/renderer/tr_cmds.c @@ -545,43 +545,57 @@ Returns the number of msec spent in the back end ============= */ void RE_EndFrame( int stereoFrame, int *frontEndMsec, int *backEndMsec ) { - swapBuffersCommand_t *cmd; - if ( !tr.registered ) { - return; - } + swapBuffersCommand_t *cmd; - cmd = R_GetCommandBuffer(sizeof(*cmd)); - if (!cmd) { - return; - } - - if (stereoFrame == 2) { - cmd->commandId = RC_SWAP_BUFFERS; - } else { - cmd->commandId = RC_FLUSH; + if ( !tr.registered ) { + return; } - if (stereoFrame == 2) - { - R_IssueRenderCommands( qtrue ); - } - else - { - R_IssueRenderCommands( qfalse ); + cmd = R_GetCommandBuffer(sizeof(*cmd)); + if (!cmd) { + return; } - // use the other buffers next frame, because another CPU - // may still be rendering into the current ones - R_ToggleSmpFrame(); + cmd->commandId = RC_FLUSH; + + R_IssueRenderCommands( qfalse ); if (frontEndMsec) { - *frontEndMsec = tr.frontEndMsec; + *frontEndMsec = tr.frontEndMsec; } tr.frontEndMsec = 0; if (backEndMsec) { - *backEndMsec = backEnd.pc.msec; + *backEndMsec = backEnd.pc.msec; } backEnd.pc.msec = 0; } + +/* +============= +RE_EndFrame + +Returns the number of msec spent in the back end +============= +*/ +void RE_SubmitStereoFrame( ) { + swapBuffersCommand_t *cmd; + + if ( !tr.registered ) { + return; + } + + cmd = R_GetCommandBuffer(sizeof(*cmd)); + if (!cmd) { + return; + } + + cmd->commandId = RC_SWAP_BUFFERS; + + R_IssueRenderCommands( qtrue ); + + // use the other buffers next frame, because another CPU + // may still be rendering into the current ones + R_ToggleSmpFrame(); +} diff --git a/Projects/Android/jni/rtcw/src/renderer/tr_init.c b/Projects/Android/jni/rtcw/src/renderer/tr_init.c index 25c5066..dc46973 100644 --- a/Projects/Android/jni/rtcw/src/renderer/tr_init.c +++ b/Projects/Android/jni/rtcw/src/renderer/tr_init.c @@ -1441,6 +1441,7 @@ refexport_t *GetRefAPI( int apiVersion, refimport_t *rimp ) { re.BeginFrame = RE_BeginFrame; re.EndFrame = RE_EndFrame; + re.SubmitStereoFrame= RE_SubmitStereoFrame; re.MarkFragments = R_MarkFragments; re.LerpTag = R_LerpTag; diff --git a/Projects/Android/jni/rtcw/src/renderer/tr_local.h b/Projects/Android/jni/rtcw/src/renderer/tr_local.h index 11892f3..98d42a6 100644 --- a/Projects/Android/jni/rtcw/src/renderer/tr_local.h +++ b/Projects/Android/jni/rtcw/src/renderer/tr_local.h @@ -1774,6 +1774,7 @@ void RE_StretchPicGradient( float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader, const float *gradientColor, int gradientType ); void RE_BeginFrame( stereoFrame_t stereoFrame ); void RE_EndFrame( int stereoFrame, int *frontEndMsec, int *backEndMsec ); +void RE_SubmitStereoFrame(); void SaveJPG( char * filename, int quality, int image_width, int image_height, unsigned char *image_buffer ); // font stuff diff --git a/Projects/Android/jni/rtcw/src/renderer/tr_public.h b/Projects/Android/jni/rtcw/src/renderer/tr_public.h index 6711f6e..54da8a1 100644 --- a/Projects/Android/jni/rtcw/src/renderer/tr_public.h +++ b/Projects/Android/jni/rtcw/src/renderer/tr_public.h @@ -100,6 +100,9 @@ typedef struct { void ( *EndFrame )( stereoFrame_t stereoFrame, int *frontEndMsec, int *backEndMsec ); + void ( *SubmitStereoFrame )( ); + + int ( *MarkFragments )( int numPoints, const vec3_t *points, const vec3_t projection, int maxPoints, vec3_t pointBuffer, int maxFragments, markFragment_t *fragmentBuffer ); diff --git a/Projects/Android/jni/rtcw/src/renderer/tr_scene.c b/Projects/Android/jni/rtcw/src/renderer/tr_scene.c index 8cab7e6..0f2d8c8 100644 --- a/Projects/Android/jni/rtcw/src/renderer/tr_scene.c +++ b/Projects/Android/jni/rtcw/src/renderer/tr_scene.c @@ -534,15 +534,7 @@ void RE_RenderScene( const refdef_t *fd ) { //This is just madness, but it makes for smooth head tracking static float yaw = 0; static float last_hmd_yaw = 0; - if (fd->viewangles[YAW] == -1000) // MAGIC NUMBER! - { - //This is default behaviour for when this code - //is called for rendering the weapon or the sky box - VectorCopy( fd->viewaxis[0], parms.or.axis[0] ); - VectorCopy( fd->viewaxis[1], parms.or.axis[1] ); - VectorCopy( fd->viewaxis[2], parms.or.axis[2] ); - } - else if ((RTCWVR_useScreenLayer() || resyncClientYawWithGameYaw > 0)) + if ((RTCWVR_useScreenLayer() || resyncClientYawWithGameYaw > 0)) { //Resyncing with known game yaw yaw = fd->viewangles[YAW]; @@ -551,6 +543,15 @@ void RE_RenderScene( const refdef_t *fd ) { VectorCopy( fd->viewaxis[2], parms.or.axis[2] ); if (fd->stereoView == 1 && resyncClientYawWithGameYaw > 0) resyncClientYawWithGameYaw--; } + else if (fd->viewangles[YAW] == -1001) // MAGIC NUMBER! + { + //Normal "in-game" behaviour, use pitch and roll from HMD but use + //a yaw that we believe is the same as the game server's yaw, adjusted by our last HMD movement + vec3_t viewAngles; + VectorCopy(vr.hmdorientation, viewAngles); + viewAngles[YAW] = yaw; + AnglesToAxis(viewAngles, parms.or.axis); + } else { //Normal "in-game" behaviour, use pitch and roll from HMD but use