-
Notifications
You must be signed in to change notification settings - Fork 11
/
scene_vr.lua
128 lines (92 loc) · 5.46 KB
/
scene_vr.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
-- Display a scene in VR
hg = require("harfang")
hg.InputInit()
hg.WindowSystemInit()
res_x, res_y = 1280, 720
win = hg.RenderInit("Harfang - OpenVR Scene", res_x, res_y, hg.RF_VSync | hg.RF_MSAA4X)
hg.AddAssetsFolder("resources_compiled")
pipeline = hg.CreateForwardPipeline()
res = hg.PipelineResources()
render_data = hg.SceneForwardPipelineRenderData() -- this object is used by the low-level scene rendering API to share view-independent data with both eyes
-- OpenVR initialization
if not hg.OpenVRInit() then
os.exit()
end
vr_left_fb = hg.OpenVRCreateEyeFrameBuffer(hg.OVRAA_MSAA4x)
vr_right_fb = hg.OpenVRCreateEyeFrameBuffer(hg.OVRAA_MSAA4x)
-- Create models
vtx_layout = hg.VertexLayoutPosFloatNormUInt8()
cube_mdl = hg.CreateCubeModel(vtx_layout, 1, 1, 1)
cube_ref = res:AddModel('cube', cube_mdl)
ground_mdl = hg.CreateCubeModel(vtx_layout, 50, 0.01, 50)
ground_ref = res:AddModel('ground', ground_mdl)
-- Load shader
prg_ref = hg.LoadPipelineProgramRefFromAssets('core/shader/pbr.hps', res, hg.GetForwardPipelineInfo())
-- Create materials
function create_material(ubc, orm)
mat = hg.Material()
hg.SetMaterialProgram(mat, prg_ref)
hg.SetMaterialValue(mat, "uBaseOpacityColor", ubc)
hg.SetMaterialValue(mat, "uOcclusionRoughnessMetalnessColor", orm)
return mat
end
-- Create scene
scene = hg.Scene()
scene.canvas.color = hg.Color(255 / 255, 255 / 255, 217 / 255, 1)
scene.environment.ambient = hg.Color(15 / 255, 12 / 255, 9 / 255, 1)
lgt = hg.CreateSpotLight(scene, hg.TransformationMat4(hg.Vec3(-8, 4, -5), hg.Vec3(hg.Deg(19), hg.Deg(59), 0)), 0, hg.Deg(5), hg.Deg(30), hg.Color.White, hg.Color.White, 10, hg.LST_Map, 0.0001)
back_lgt = hg.CreatePointLight(scene, hg.TranslationMat4(hg.Vec3(2.4, 1, 0.5)), 10, hg.Color(94 / 255, 255 / 255, 228 / 255, 1), hg.Color(94 / 255, 1, 228 / 255, 1), 0)
mat_cube = create_material(hg.Vec4(255 / 255, 230 / 255, 20 / 255, 1), hg.Vec4(1, 0.658, 0., 1))
hg.CreateObject(scene, hg.TransformationMat4(hg.Vec3(0, 0.5, 0), hg.Vec3(0, hg.Deg(70), 0)), cube_ref, {mat_cube})
mat_ground = create_material(hg.Vec4(255 / 255, 120 / 255, 147 / 255, 1), hg.Vec4(1, 1, 0.1, 1))
hg.CreateObject(scene, hg.TranslationMat4(hg.Vec3(0, 0, 0)), ground_ref, {mat_ground})
-- Setup 2D rendering to display eyes textures
quad_layout = hg.VertexLayout()
quad_layout:Begin():Add(hg.A_Position, 3, hg.AT_Float):Add(hg.A_TexCoord0, 3, hg.AT_Float):End()
quad_model = hg.CreatePlaneModel(quad_layout, 1, 1, 1, 1)
quad_render_state = hg.ComputeRenderState(hg.BM_Alpha, hg.DT_Disabled, hg.FC_Disabled)
eye_t_size = res_x / 2.5
eye_t_x = (res_x - 2 * eye_t_size) / 6 + eye_t_size / 2
quad_matrix = hg.TransformationMat4(hg.Vec3(0, 0, 0), hg.Vec3(hg.Deg(90), hg.Deg(0), hg.Deg(0)), hg.Vec3(eye_t_size, 1, eye_t_size))
tex0_program = hg.LoadProgramFromAssets("shaders/sprite")
quad_uniform_set_value_list = hg.UniformSetValueList()
quad_uniform_set_value_list:clear()
quad_uniform_set_value_list:push_back(hg.MakeUniformSetValue("color", hg.Vec4(1, 1, 1, 1)))
quad_uniform_set_texture_list = hg.UniformSetTextureList()
-- Main loop
while not hg.ReadKeyboard():Key(hg.K_Escape) and hg.IsWindowOpen(win) do
dt = hg.TickClock()
scene:Update(dt)
actor_body_mtx = hg.TransformationMat4(hg.Vec3(-1.3, .45, -2), hg.Vec3(0, 0, 0))
vr_state = hg.OpenVRGetState(actor_body_mtx, 0.01, 1000)
left, right = hg.OpenVRStateToViewState(vr_state)
vid = 0 -- keep track of the next free view id
passId = hg.SceneForwardPipelinePassViewId()
-- Prepare view-independent render data once
vid, passId = hg.PrepareSceneForwardPipelineCommonRenderData(vid, scene, render_data, pipeline, res, passId)
vr_eye_rect = hg.IntRect(0, 0, vr_state.width, vr_state.height)
-- Prepare the left eye render data then draw to its framebuffer
vid, passId = hg.PrepareSceneForwardPipelineViewDependentRenderData(vid, left, scene, render_data, pipeline, res, passId)
vid, passId = hg.SubmitSceneToForwardPipeline(vid, scene, vr_eye_rect, left, pipeline, render_data, res, vr_left_fb:GetHandle())
-- Prepare the right eye render data then draw to its framebuffer
vid, passId = hg.PrepareSceneForwardPipelineViewDependentRenderData(vid, right, scene, render_data, pipeline, res, passId)
vid, passId = hg.SubmitSceneToForwardPipeline(vid, scene, vr_eye_rect, right, pipeline, render_data, res, vr_right_fb:GetHandle())
-- Display the VR eyes texture to the backbuffer
hg.SetViewRect(vid, 0, 0, res_x, res_y)
vs = hg.ComputeOrthographicViewState(hg.TranslationMat4(hg.Vec3(0, 0, 0)), res_y, 0.1, 100, hg.ComputeAspectRatioX(res_x, res_y))
hg.SetViewTransform(vid, vs.view, vs.proj)
quad_uniform_set_texture_list:clear()
quad_uniform_set_texture_list:push_back(hg.MakeUniformSetTexture("s_tex", hg.OpenVRGetColorTexture(vr_left_fb), 0))
hg.SetT(quad_matrix, hg.Vec3(eye_t_x, 0, 1))
hg.DrawModel(vid, quad_model, tex0_program, quad_uniform_set_value_list, quad_uniform_set_texture_list, quad_matrix, quad_render_state)
quad_uniform_set_texture_list:clear()
quad_uniform_set_texture_list:push_back(hg.MakeUniformSetTexture("s_tex", hg.OpenVRGetColorTexture(vr_right_fb), 0))
hg.SetT(quad_matrix, hg.Vec3(-eye_t_x, 0, 1))
hg.DrawModel(vid, quad_model, tex0_program, quad_uniform_set_value_list, quad_uniform_set_texture_list, quad_matrix, quad_render_state)
hg.Frame()
hg.OpenVRSubmitFrame(vr_left_fb, vr_right_fb)
hg.UpdateWindow(win)
end
hg.DestroyForwardPipeline(pipeline)
hg.RenderShutdown()
hg.DestroyWindow(win)