Split screen
Two cameras render the scene directly into separate halves of the window using viewports. Split screen can also be composed by rendering each view to a surface first, but viewports make this simple case more direct and immediate.
local natiny = require("natiny")
if not natiny.backend.init(arg and arg[1] or natiny.backend.AUTO) then
os.exit(1)
end
local window = natiny.window.create("Natiny - Split screen cameras", 960, 640)
natiny.window.set_scale_mode(window, natiny.window.SCALE_MODE_STRETCH)
local BG = { 21 / 255, 30 / 255, 44 / 255 } -- #151E2C
local function load_mesh(path)
local resource = natiny.resource.load(path)
local mesh = natiny.mesh.load(resource)
natiny.resource.destroy(resource)
return mesh
end
-- Two models stand next to each other around the centre of the scene.
local platform_mesh = load_mesh("data/common/models/platform.glb")
local barrel_mesh = load_mesh("data/common/models/barrel.glb")
local box_mesh = load_mesh("data/common/models/box_01.glb")
local platform = natiny.model.create(platform_mesh)
local barrel = natiny.model.create(barrel_mesh)
local box = natiny.model.create(box_mesh)
natiny.entity.set_position(barrel, natiny.entity.SPACE_WORLD, -0.45, 0.0, 0.0)
natiny.entity.set_position(box, natiny.entity.SPACE_WORLD, 0.45, 0.25, 0.0)
-- The pivot is the centre of the orbit. The camera is its child, so rotating
-- only the pivot moves the camera around both models.
local pivot = natiny.pivot.create()
natiny.entity.set_position(pivot, natiny.entity.SPACE_WORLD, 0.0, 0.4, 0.0)
-- Left viewport: the original elevated side view.
local side_camera = natiny.camera.create()
natiny.entity.set_parent(side_camera, pivot)
natiny.entity.set_position(side_camera, natiny.entity.SPACE_LOCAL, 0.0, 2.0, 3.0)
natiny.entity.look_at(side_camera, 0.0, 0.4, 0.0)
natiny.camera.set_fov(side_camera, 55.0)
natiny.camera.set_clip(side_camera, 0.1, 100.0)
-- Right viewport: a view straight down. Its position does not move around the
-- pivot's Y axis, but its orientation rotates together with the side camera.
local top_camera = natiny.camera.create()
natiny.entity.set_parent(top_camera, pivot)
natiny.entity.set_position(top_camera, natiny.entity.SPACE_LOCAL, 0.0, 4.0, 0.0)
natiny.entity.set_rotation(top_camera, natiny.entity.SPACE_LOCAL, -90.0, 0.0, 0.0)
natiny.camera.set_fov(top_camera, 55.0)
natiny.camera.set_clip(top_camera, 0.1, 100.0)
local ORBIT_SPEED = 25.0 -- degrees per second
natiny.backend.loop(function(dt)
natiny.entity.rotate(
pivot,
natiny.entity.SPACE_LOCAL,
0.0,
ORBIT_SPEED * dt,
0.0
)
natiny.window.bind(window, function()
natiny.render.clear(BG[1], BG[2], BG[3], 1.0)
local width = natiny.window.get_width(window)
local height = natiny.window.get_height(window)
local left_width = math.floor(width / 2)
local right_width = width - left_width
natiny.render.viewport_begin(0, 0, left_width, height, function()
natiny.camera.bind(side_camera, function()
natiny.render.tag("model")
end)
end)
natiny.render.viewport_begin(left_width, 0, right_width, height, function()
natiny.camera.bind(top_camera, function()
natiny.render.tag("model")
end)
end)
end)
end)
natiny.backend.shutdown()