    
    
local demo_dir = gh_utils.get_demo_dir() 		

local lib_dir = gh_utils.get_lib_dir() 		
dofile(lib_dir .. "lua/vk.lua")




    
winW, winH = gh_window.getsize(0)





-----------------------------------------------------------------------
--

fixed_rt_size = 1

if (fixed_rt_size == 1) then
	rt_w = 1024
	rt_h = 1024
else
	rt_w = winW
	rt_h = winH
end

rt01 = gh_render_target.create(rt_w, rt_h)




-----------------------------------------------------------------------
--
cmd = gh_vk.command_buffer_create(0)













-----------------------------------------------------------------------
--

--[[

layout (std140, binding = 0) uniform uniforms_t
{ 
  mat4 camera1_projection; // Offset = 0
  mat4 camera1_view; // Offset = 64
  mat4 camera2_view_projection; // Offset = 2*64
  mat4 camera_ortho1_view_projection; // Offset = 3*64
  mat4 camera_ortho2_view_projection; // Offset = 4*64
  mat4 fullscreen_quad_transform; // Offset = 5*64
  mat4 mesh_transform; // Offset = 6*64
  mat4 mesh2_transform; // Offset = 7*64
  vec4 bkg_uv_tiling; // Offset = 8*64
  vec4 mesh_uv_tiling; // Offset = 8*64 + 16
} ub;

--]]



function UpdateCamera1Transform(ub, cam)
  local buffer_offset_bytes = 0
  gh_gpu_buffer.set_matrix4x4(ub, buffer_offset_bytes, cam, "camera_projection")
  
  buffer_offset_bytes = 64
  gh_gpu_buffer.set_matrix4x4(ub, buffer_offset_bytes, cam, "camera_view")  
end

function UpdateCamera2Transform(ub, cam)
  local buffer_offset_bytes = 2*64
  gh_gpu_buffer.set_matrix4x4(ub, buffer_offset_bytes, cam, "camera_view_projection")
end

function UpdateCameraOrtho1Transform(ub, cam)
  local buffer_offset_bytes = 3*64
  gh_gpu_buffer.set_matrix4x4(ub, buffer_offset_bytes, cam, "camera_view_projection")
end

function UpdateCameraOrtho2Transform(ub, cam)
  local buffer_offset_bytes = 4*64
  gh_gpu_buffer.set_matrix4x4(ub, buffer_offset_bytes, cam, "camera_view_projection")
end

function UpdateFullscreenQuadTransform(ub, obj)
  local buffer_offset_bytes = 5*64
  gh_gpu_buffer.set_matrix4x4(ub, buffer_offset_bytes, obj, "object_global_transform")
end


function UpdateMeshTransform(ub, obj)
  local buffer_offset_bytes = 6*64
  gh_gpu_buffer.set_matrix4x4(ub, buffer_offset_bytes, obj, "object_global_transform")
end


function UpdateMesh2Transform(ub, obj)
  local buffer_offset_bytes = 7*64
  gh_gpu_buffer.set_matrix4x4(ub, buffer_offset_bytes, obj, "object_global_transform")
end


function UpdateBkgUVTiling(ub, s, t)
  local buffer_offset_bytes = 8*64
  gh_gpu_buffer.set_value_4f(ub, buffer_offset_bytes, s, t, 0, 0)
end

function UpdateMeshUVTiling(ub, s, t)
  local buffer_offset_bytes = 8*64 + 16
  gh_gpu_buffer.set_value_4f(ub, buffer_offset_bytes, s, t, 0, 0)
end


local ub_size = 1024
ub1 = gh_gpu_buffer.create("UNIFORM", "NONE", ub_size, "")
gh_gpu_buffer.bind(ub1)
gh_gpu_buffer.map(ub1)









-----------------------------------------------------------------------
-- Perspective camera.
--
local aspect = winW / winH
camera_params = { fov=60, znear=0.1, zfar=1000.0 }
camera = gh_camera.create_persp(camera_params.fov, aspect, camera_params.znear, camera_params.zfar)
gh_camera.set_viewport(camera, 0, 0, winW, winH)
gh_camera.set_position(camera, 0, 5, 15)
gh_camera.set_lookat(camera, 0, 0, 0, 1)
gh_camera.set_upvec(camera, 0, 1, 0, 0)



local w2 = winW/2
local h2 = winH/2
camera_ortho = gh_camera.create_ortho(-w2, w2, -h2, h2, 1.0, 10.0)
gh_camera.set_viewport(camera_ortho, 0, 0, winW, winH)
gh_camera.set_position(camera_ortho, 0, 0, 4)







-----------------------------------------------------------------------
--
local vertex_shader = demo_dir .. "spirv/10-rt-viewer-vs.spv"
local pixel_shader = demo_dir .. "spirv/10-rt-viewer-ps.spv"
rt_viewer_shader = gh_gpu_program.vk_create_from_spirv_module_file("rt_viewer_shader",   vertex_shader, "main",     pixel_shader, "main",    "", "",    "", "",     "", "",    "", "") 

vertex_shader = demo_dir .. "spirv/10-phong-vs.spv"
pixel_shader = demo_dir .. "spirv/10-phong-ps.spv"
phong_shader = gh_gpu_program.vk_create_from_spirv_module_file("phong_shader",   vertex_shader, "main",     pixel_shader, "main",    "", "",    "", "",     "", "",    "", "") 

vertex_shader = demo_dir .. "spirv/10-texture-vs.spv"
pixel_shader = demo_dir .. "spirv/10-texture-ps.spv"
texture_shader = gh_gpu_program.vk_create_from_spirv_module_file("texture_shader",   vertex_shader, "main",     pixel_shader, "main",    "", "",    "", "",     "", "",    "", "") 




-----------------------------------------------------------------------
--
local PF_U8_RGBA = 3
tex0 = gh_texture.create_from_file_v5(demo_dir .. "textures/t08.jpg", PF_U8_RGBA)
tex1 = gh_texture.create_from_file_v5(demo_dir .. "textures/14027.jpg", PF_U8_RGBA)



-----------------------------------------------------------------------
--
local anisotropy = 1.0
sampler1 = gh_vk.sampler_create("LINEAR", "CLAMP", anisotropy, 0)
sampler2 = gh_vk.sampler_create("LINEAR", "WRAP", anisotropy, 0)




-----------------------------------------------------------------------
--

local ub_binding_point = 0
local tex_binding_point = 1


ds1 = gh_vk.descriptorset_create()
gh_vk.descriptorset_add_resource_gpu_buffer(ds1, ub1, ub_binding_point, SHADER_STAGE_VERTEX)
tex0_res_index = gh_vk.descriptorset_add_resource_texture(ds1, tex0, sampler2, 1, SHADER_STAGE_FRAGMENT)
tex1_res_index = gh_vk.descriptorset_add_resource_texture(ds1, tex1, sampler2, 2, SHADER_STAGE_FRAGMENT)
gh_vk.descriptorset_build(ds1)
gh_vk.descriptorset_update(ds1)




ds2 = gh_vk.descriptorset_create()
gh_vk.descriptorset_add_resource_gpu_buffer(ds2, ub1, ub_binding_point, SHADER_STAGE_VERTEX)
tex_binding_point = 1
local color_index = 0
rt_tex_res_index = gh_vk.descriptorset_add_resource_rt_color(ds2, rt01, color_index, sampler1, tex_binding_point, SHADER_STAGE_FRAGMENT)
gh_vk.descriptorset_build(ds2)
gh_vk.descriptorset_update(ds2)





-----------------------------------------------------------------------
--
-- Pipeline object for rendering the torus in the render target.
--
pso01 = gh_vk.pipeline_create("pso01", phong_shader, "")
gh_vk.pipeline_set_attrib_4i(pso01, "DEPTH_TEST", 1, 0, 0, 0)
gh_vk.pipeline_set_attrib_4i(pso01, "FILL_MODE", POLYGON_MODE_SOLID, 0, 0, 0)
gh_vk.pipeline_set_attrib_4i(pso01, "PRIMITIVE_TYPE", PRIMITIVE_TRIANGLE, 0, 0, 0)
gh_vk.pipeline_set_attrib_4i(pso01, "CULL_MODE", POLYGON_FACE_NONE, 0, 0, 0)
gh_vk.pipeline_set_attrib_4i(pso01, "CCW", 0, 0, 0, 0)
pso_valid = gh_vk.pipeline_build_v2(pso01, ds1, rt01)
if (pso_valid == 0) then
	print("ERROR: pipeline state pso01 is not valid.")
end


-- Pipeline object for rendering the background texture in the render target.
--
pso03 = gh_vk.pipeline_create("pso03", texture_shader, "")
gh_vk.pipeline_set_attrib_4i(pso03, "DEPTH_TEST", 0, 0, 0, 0)
gh_vk.pipeline_set_attrib_4i(pso03, "FILL_MODE", POLYGON_MODE_SOLID, 0, 0, 0)
gh_vk.pipeline_set_attrib_4i(pso03, "PRIMITIVE_TYPE", PRIMITIVE_TRIANGLE, 0, 0, 0)
gh_vk.pipeline_set_attrib_4i(pso03, "CULL_MODE", POLYGON_FACE_NONE, 0, 0, 0)
gh_vk.pipeline_set_attrib_4i(pso03, "CCW", 0, 0, 0, 0)
pso_valid = gh_vk.pipeline_build_v2(pso03, ds1, rt01)
if (pso_valid == 0) then
	print("ERROR: pipeline state pso03 is not valid.")
end



-- Pipeline object for rendering the render target texture on the box.
--
pso02 = gh_vk.pipeline_create("pso02", rt_viewer_shader, "")
gh_vk.pipeline_set_attrib_4i(pso02, "DEPTH_TEST", 1, 0, 0, 0)
gh_vk.pipeline_set_attrib_4i(pso02, "FILL_MODE", POLYGON_MODE_SOLID, 0, 0, 0)
gh_vk.pipeline_set_attrib_4i(pso02, "PRIMITIVE_TYPE", PRIMITIVE_TRIANGLE, 0, 0, 0)
gh_vk.pipeline_set_attrib_4i(pso02, "CULL_MODE", POLYGON_FACE_NONE, 0, 0, 0)
gh_vk.pipeline_set_attrib_4i(pso02, "CCW", 0, 0, 0, 0)
pso_valid = gh_vk.pipeline_build(pso02, ds2)
if (pso_valid == 0) then
	print("ERROR: pipeline state pso02 is not valid.")
end






-----------------------------------------------------------------------
--
mesh = gh_mesh.create_torus(6.0, 2.0, 50) -- 5000f / 2601v
gh_mesh.set_vertices_color(mesh, 1.0, 1.0, 0.0, 1.0)


fullscreen_quad = gh_mesh.create_quad(rt_w, rt_h)
gh_mesh.set_vertices_color(fullscreen_quad, 1.0, 1.0, 1.0, 1.0)


--quad = gh_mesh.create_quad(8, 5)
quad = gh_mesh.create_box(6, 6, 6, 2, 2, 2)
gh_mesh.set_vertices_color(quad, 1.0, 1.0, 1.0, 1.0)




--------------------------------------------------------------------------
--
UpdateCamera1Transform(ub1, camera)
UpdateCamera2Transform(ub1, camera)
UpdateCameraOrtho1Transform(ub1, camera_ortho)
UpdateCameraOrtho2Transform(ub1, camera_ortho)
UpdateFullscreenQuadTransform(ub1, fullscreen_quad)
UpdateMeshTransform(ub1, mesh)
UpdateMesh2Transform(ub1, quad)
UpdateBkgUVTiling(ub1, 1.0, 1.0)
UpdateMeshUVTiling(ub1, 1.0, 1.0)



