CJB
I stand corrected, your method does work with out distortion or stuttering.
Now I can see the 3D effect. I forgot about the local commands and was unaware that the setcameraposition()
command removes any local offset. I have updated the demo code here because I added
joystick control of movement.
//Designed by Stab In The Dark Software at gonefishing@stabInthedarksoftware.com
//This VR method uses a pre distorted object plane with distorted UV data.
//This is a better method than using a pixel shader with sprites to distort the final render.
//It is based on this article on the google carboard method. http://smus.com/vr-lens-distortion/
//Tested on an LG Stylo3 and a Tzumi Dream Vision headset.
// Project: VR Predistorted Mesh Render
// Created: 2017-06-09
SetErrorMode(2)
SetResolutionMode( 1 ) //Force High resolution buffer on HR devices.
SetWindowTitle( "VR Predistorted Mesh Render" )
SetWindowSize( 1280, 720, 0 ) // Set to same resolution as mobile device for testing on PC.
SetImmersiveMode(1) // Allows app to use entire screen on Android. Must be called before setting resolution.
SetVirtualResolution( 1920, 1080 ) //Should be same aspect ratio as mobile device but does not need to be the same resolution.
SetOrientationAllowed(0,0,1,0) // Force Landscape only for VR.
SetSyncRate(60,0) //We need a minimum 60 fps for VR.
SetScissor(0,0,0,0) // Use the maximum available screen space, no black borders
UseNewDefaultFonts(1) // Since version 2.0.22 we can use nicer default fonts
SetClearColor(0,0,0) // Set to black for VR
SetGenerateMipmaps(1)
SetAntialiasMode( 1 )
SetCameraPosition( 1, 2000.0, 560.0, -3250.0 )
VR_Setup()
LoadWorld()
CompleteRawJoystickDetection()
do
Print( ScreenFPS() )
VR_Update( 8.0 )
loop
function VR_Setup()
global vr_CamPosX as float
global vr_CamPosY as float
global vr_CamPosZ as float
global vr_LeftMesh as integer
global vr_RightMesh as integer
global vr_ShadersID as integer
global vr_RenderImageIDL as integer
global vr_RenderImageIDR as integer
global vr_MagnetY as float
global vr_OldMagnetY as float
global vr_MagneticState as integer
vr_MagneticState = 0
global vr_OldMagneticState as integer
vr_OldMagneticState = 0
global vr_MagnetDist as float
vr_RightMesh = LoadObject( "objects/Barreled Plane25.x" ) // If distortion is too much for your lenses try the "objects/Barreled Plane12.6.x"
SetObjectPosition( vr_RightMesh, 34.1, 0.0, 0.0 )
SetObjectLightMode( vr_RightMesh, 0 )
vr_LeftMesh = LoadObject( "objects/Barreled Plane25.x" ) // If distortion is too much for your lenses try the "objects/Barreled Plane12.6.x"
SetObjectPosition( vr_LeftMesh, -34.1, 0.0, 0.0 )
SetObjectLightMode( vr_LeftMesh, 0 )
vr_RenderImageIDL = CreateRenderImage( 1024, 1024, 0, 1 ) // must be a power of 2 for mipmapping, 1024 gives best results and FPS.
SetImageWrapU(vr_RenderImageIDL,1)
SetImageWrapV(vr_RenderImageIDL,1)
vr_RenderImageIDR = CreateRenderImage( 1024, 1024, 0, 1 ) // must be a power of 2 for mipmapping, 1024 gives best results and FPS.
SetImageWrapU(vr_RenderImageIDR,1)
SetImageWrapV(vr_RenderImageIDR,1)
testImageID = LoadImage( "objects/steelPanelTiled.png" )
SetImageWrapU(testImageID,1)
SetImageWrapV(testImageID,1)
SetObjectImage( vr_LeftMesh, vr_RenderImageIDL, 0 )
SetObjectImage( vr_RightMesh, vr_RenderImageIDR, 0 )
vr_CamPosX = GetCameraX( 1 )
vr_CamPosY = GetCameraY( 1 )
vr_CamPosZ = GetCameraZ( 1 )
endfunction
function VR_Update( seperation as float)
if GetMagneticSensorExists()
vr_OldMagnetY = vr_MagnetY
vr_MagnetY =GetRawMagneticY()
vr_MagnetDist = vr_MagnetY - vr_OldMagnetY
vr_OldMagneticState = vr_MagneticState
if vr_MagnetDist > 8.0 then vr_MagneticState = 1
if vr_MagnetDist < -8.0 then vr_MagneticState = 0
endif
if GetGyroSensorExists()
SetCameraRotationQuat(1,GetRawRotationVectorW2(),GetRawRotationVectorX2(),GetRawRotationVectorY2(),GetRawRotationVectorZ2())
endif
//Unremark this to use magnetic switch for forward movement.
//Foward Camera movement with magnetic switch based on camera rotation
//vr_CamPosX= vr_CamPosX - (vr_MagneticState * 50.0 * sin( GetCameraAngleY(1) * -1.0 ) * getframetime())
//vr_CamPosZ = vr_CamPosZ + (vr_MagneticState * 50.0 * cos( GetCameraAngleY(1) * -1.0 ) * getframetime())
//Forward Camera movement with bluetooth joystick based on camera rotation
if GetJoystickExists()
rawJoyY# = GetRawJoystickY(1)
//Print( rawJoyY# )
if rawJoyY# <> 0.0
rawJoyY# = GetRawJoystickY(1) * 1.5 //Increase speed
endif
vr_CamPosX = vr_CamPosX + ( rawJoyY# * 50.0 * sin( GetCameraAngleY(1) * -1.0 ) * getframetime())
vr_CamPosZ = vr_CamPosZ - ( rawJoyY# * 50.0 * cos( GetCameraAngleY(1) * -1.0 ) * getframetime())
endif
//Strafe Camera Movement with bluetooth joystick based on camera rotation
if GetJoystickExists()
rawJoyX# = GetRawJoystickX(1)
//Print( rawJoyX# )
if rawJoyX# <> 0.0
rawJoyX# = GetRawJoystickX(1) * 2.5 //Increase speed
endif
vr_CamPosX = vr_CamPosX + ( rawJoyX# * 50.0 *cos( GetCameraAngleY(1) ) * getframetime())
vr_CamPosZ = vr_CamPosZ - ( rawJoyX# * 50.0 *sin( GetCameraAngleY(1) ) * getframetime())
endif
Update( 0 )
SetCameraFOV( 1, 110.0 ) //Set a larger field of view for the render grab
SetCameraAspect( 1, 0.8888888 ) // Sets camera aspect to half of the virtual width divided by the virtual height.
SetCameraPosition( 1, vr_CamPosX, vr_CamPosY, vr_CamPosZ )
SetRenderToImage( vr_RenderImageIDL, -1 )
ClearScreen()
Render3D()
MoveCameraLocalX( 1, seperation )
SetRenderToImage( vr_RenderImageIDR, -1 )
ClearScreen()
Render3D()
SetRenderToScreen()
SetCameraFOV( 1, 70.0 ) //Set the field of view back to normal for the viewing of the VR render object planes
SetCameraAspect( 1, 1.7777777 ) // set it back to default for viewing of meshes.
SetCameraPosition ( 1, 0.0, 0.0, -97.5 ) //Set the camera back to location where VR render object planes are located.
SetCameraLookAt( 1, 0.0, 0.0, 0.0, 0.0 ) //Make sure the camera looks at VR render object planes squarely.
//Draws the center line on screen
drawline( getvirtualwidth() / 2 - 3, 0, getvirtualwidth() / 2 - 3, GetVirtualHeight(), 255, 0, 0 ) // left line red
drawline( getvirtualwidth() / 2, 0, getvirtualwidth() / 2, GetVirtualHeight(), 255, 255, 255 ) // center line white
drawline( getvirtualwidth() / 2 + 3, 0, getvirtualwidth() / 2 + 3, GetVirtualHeight(), 0, 255, 0 ) // right line green
Render()
Swap()
endfunction
function LoadWorld()
CreateText(1,"")
SetTextAlignment(1,1)
SetTextPosition(1,getvirtualwidth()/2,getvirtualheight()/2)
SetTextSize(1,80)
CreateText(2,"")
SetTextAlignment(2,1)
SetTextPosition(2,getvirtualwidth()/2.0,80.0)
SetTextSize(2,50)
settextstring(1,"Loading Metro Theatre Scene")
settextstring(2,"Artwork by Mark Blosser")
shaderindex=1
LoadShader(shaderindex,"level/vertex.vs","level/pixel.ps")
`
rem Load lightmaps
dim lm[10]
lm[0]=LoadImage("level/0.png")
lm[1]=LoadImage("level/1.png")
for t=0 to 1
SetImageWrapU(lm[t],1)
SetImageWrapV(lm[t],1)
next t
`
rem Load all OBJ making up world (created in FPS Creator)
objmax=50
for obj=1 to objmax
obj$="level/mesh"+str(obj)+".obj"
LoadObject(obj,obj$,0)
if obj>=1 and obj<=7
tex$="level/mesh"+str(obj)+"-1.jpg"
else
tex$="level/mesh"+str(obj)+"-0.jpg"
endif
texname$=left(tex$,len(tex$)-4)
lm$=right(texname$,1)
if lm$="-" then lm$="0"
teximg=LoadImage(tex$)
SetImageWrapU(teximg,1)
SetImageWrapV(teximg,1)
SetObjectImage(obj,teximg,0)
SetObjectImage(obj,lm[val(lm$)],1)
SetObjectShader(obj,shaderindex)
`
//SetObjectRotation(obj,0,0,90)
`
rem Progress status
perc#=obj
perc#=perc#/objmax
perc=perc#*100
SetTextString(1,"Metro Theatre - "+str(perc)+"%")
Sync()
next obj
DeleteText(1)
DeleteText(2)
endfunction
The coffee is lovely dark and deep,and I have code to write before I sleep.