win = require("window") color = require("color") world = require("world") sprites = require("sprites") shader_shim = require("shader_shim") hc = require("party.hc.init") log = require("log") assert(world.world_x, "No world_x" .. debug.traceback()) -- Process the world into buffers to send to the shader view_angle = math.pi / 4 near_plane = 0.01 far_plane = 100 aspect = win.width / win.height -- 2.5D model-view matrix: scale down and offset camera s_mv = mat4( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, -2, 1 ) p_mv = math.perspective(math.rad(85), aspect, near_plane, far_plane) sd = sprites.floor w1 = sprites.wall -- Each point needs: -- vec3 position (x,y,z) -- vec2 (u,v) up_down_hall = (x,y) -> r = { --floor vec3(x,y,0), vec3(x+1,y,0), vec3(x+1,y-1,0), vec3(x+1,y-1,0), vec3(x,y-1,0), vec3(x,y,0), -- Left wall vec3(x,y,1), vec3(x,y,0), vec3(x,y-1,0), vec3(x,y-1,0), vec3(x,y-1,1), vec3(x,y,1), --Right wall vec3(x+1,y,0), vec3(x+1,y,1), vec3(x+1,y-1,1), vec3(x+1,y-1,1), vec3(x+1,y-1,0), vec3(x+1,y,0), } r room = (x,y,w,h,left_holes,right_holes,top_holes,bottom_holes) -> left_holes\sort() right_holes\sort() top_holes\sort() bottom_holes\sort() r = { --floor vec3(x,y,0) vec3(x+w,y,0), vec3(x+w,y-h,0), vec3(x+w,y-h,0), vec3(x,y-h,0), vec3(x,y,0), --left wall } r barrel = (x,y,w,h) -> tris = 18 rad = (w/2) l = x - (w/2) j = x + (w/2) t = h b = 0 f = y - (w/2) n = y + (w/2) r = { --top vec3(l,f,h), vec3(l,n,h), vec3(j,n,h), vec3(j,n,h), vec3(j,f,h), vec3(l,f,h), } step = (2*math.pi)/tris for i = 0,2*math.pi,step r[#r+1] =vec3(x + math.cos(i)*rad,y + math.sin(i)*n,h) r[#r+1] =vec3(x + math.cos(i+step)*rad,math.sin(i+step)*n,h) r[#r+1] =vec3(x + math.cos(i+step)*rad,math.sin(i+step)*n,0) r[#r+1] =vec3(x + math.cos(i+step)*rad,math.sin(i+step)*n,0) r[#r+1] =vec3(x + math.cos(i)*rad,math.sin(i)*n,0) r[#r+1] =vec3(x + math.cos(i)*rad,math.sin(i)*n,h) r barrel_uv = (x,y,w,h) -> tris = 18 r = { vec4(w1.s1,w1.t1,1,1), vec4(w1.s1,w1.t2,1,1), vec4(w1.s2,w1.t2,1,1), vec4(w1.s2,w1.t2,1,1), vec4(w1.s2,w1.t1,1,1), vec4(w1.s1,w1.t1,1,1), } step = (2*math.pi)/tris for i = 0,2*math.pi,step perc = (i / (2*math.pi)) nextperc = ((i+step) / (2*math.pi)) srange = w1.s2 - w1.s1 trange = w1.t2 - w1.t1 sstart = w1.s1 + (srange * perc) send = w1.s1 + (srange * nextperc) tstart = w1.t1 tend = w1.t2 r[#r+1] = vec4(sstart ,tstart,1,1) r[#r+1] = vec4(sstart ,tend,1,1) r[#r+1] = vec4(send ,tend,1,1) r[#r+1] = vec4(send ,tend,1,1) r[#r+1] = vec4(send ,tstart,1,1) r[#r+1] = vec4(sstart ,tstart,1,1) r barrel_r = (x,y,w,h) -> r = {-1,-1,1,1,1,-1,0,0,0,0,0,0} r -- uvs are s,t,smult, tmult up_down_hall_uv = (x,y) -> r = { --floor vec4(sd.s1,sd.t1,1,1), vec4(sd.s2,sd.t1,1,1), vec4(sd.s2,sd.t2,1,1), vec4(sd.s2,sd.t2,1,1), vec4(sd.s1,sd.t2,1,1), vec4(sd.s1,sd.t1,1,1), -- left wall vec4(w1.s1,w1.t1,1,1), vec4(w1.s1,w1.t2,1,1), vec4(w1.s2,w1.t2,1,1), vec4(w1.s2,w1.t2,1,1), vec4(w1.s2,w1.t1,1,1), vec4(w1.s1,w1.t1,1,1), -- right wall vec4(w1.s2,w1.t2,1,1), vec4(w1.s2,w1.t1,1,1), vec4(w1.s1,w1.t1,1,1), vec4(w1.s1,w1.t1,1,1), vec4(w1.s1,w1.t2,1,1), vec4(w1.s2,w1.t2,1,1), } r up_down_hall_r = (x,y) -> r = { 0,0,0,0,0,0 0,0,0,0,0,0 0,0,0,0,0,0 0,0,0,0,0,0 0,0,0,0,0,0 0,0,0,0,0,0 } r -- Barrel? add_verts = (tbl, new) -> for i = 1, #new tbl[#tbl+1] = new[i] world_geom = {} world_uv = {} world_r = {} add_verts(world_geom, up_down_hall(0,-1)) add_verts(world_uv, up_down_hall_uv(0,0)) add_verts(world_r, up_down_hall_r(0,0)) add_verts(world_geom, up_down_hall(0,1)) add_verts(world_uv, up_down_hall_uv(0,0)) add_verts(world_r, up_down_hall_r(0,0)) add_verts(world_geom, up_down_hall(0,0)) add_verts(world_uv, up_down_hall_uv(0,0)) add_verts(world_r, up_down_hall_r(0,0)) add_verts(world_geom, barrel(-1,0,0.5,0.5)) add_verts(world_uv, barrel_uv(-1,0,0.5,0.5)) add_verts(world_r, barrel_r(-1,0,0.5,0.5)) --add_verts(world_geom, barrel(0.5,0.5,0.5,0.5)) --add_verts(world_uv, barrel_uv(0.5,0.5,0.5,0.5)) --add_verts(world_r, barrel_r(0.5,0.5,0.5,0.5)) --sprites["diffuse"].texture.wrap = "repeat" --sprites["normals"].texture.wrap = "repeat" test_world = { vec3(0,0,0), vec3(1,0,0), vec3(0,1,0) } test_uvs = { vec4(sd.s1,sd.t1,1,1), vec4(sd.s2,sd.t1,1,1), vec4(sd.s2,sd.t2,1,1), } test_r = { 0,0,0 } -- How big should our buffer for the world be? -- Let's call it at up to 100 players --MAX_PLAYERS = 128 MAX_PLAYERS = 8 --MAX_LEVEL_TRIS = 1 * 1024 * 1024 -- 1M level triangles? MAX_LEVEL_TRIS = 1024 -- testing? buffer_tris = (MAX_PLAYERS * 2) + MAX_LEVEL_TRIS geom_buffer = am.buffer(buffer_tris * 3 * 12) --am.vec3_array uv_buffer = am.buffer(buffer_tris * 3 * 16) --am.vec2_array geom_view = geom_buffer\view("vec3") uv_view = uv_buffer\view("vec4") for i = 1, #world_geom geom_view[i] = world_geom[i] for i = 1, #world_uv uv_view[i] = world_uv[i] world.geom_view = geom_view world.uv_view = uv_view buf_cursor = #world_geom -- the vertex number shimworld = shader_shim.world depth_test = am.depth_test("less") shimworld\append(depth_test) --cull = am.cull_face("back") --depth_test\append(cull) --{ --MV: s_mv --P: mat4(1) --world_x: math.sin(am.current_time!) * 2 --world_y: math.cos(am.current_time!) * 2 ----world_x: 0, ----world_y: 0, --world: geom_view, --texuv: uv_view, ----world: am.vec3_array(world_geom) ----texuv: am.vec4_array(world_uv) ----r: am.float_array(world_r) ----world:am.vec3_array(test_world) ----texuv: am.vec4_array(test_uvs) ----r: am.float_array(test_r) --time: am.current_time(), --textures: sprites.floor.texture --} -- In the example we have -- am.group (buildings_group) -- ^ many am.bind(...) -- ^ am.draw("triangles") bind = am.group! depth_test\append(bind) add = (n) -> assert(n.tris) assert(n.populate_buf) assert(n.properties) assert(n.properties.graphic) --assert(buf_cursor + n_tris < buffer_tris, "Not enough tris! Had " .. buf_cursor .. " and wanted " .. n_tris .. " so we sould end up with " .. (buf_cursor + n_tris) .. " but we only have " .. buffer_tris) n_tris = n\tris! log.info(string.format("Adding %d tris to buffer at %d",n_tris, buf_cursor),{"graphics"}) geom_buffer = am.buffer(n_tris * 3 * 12) --am.vec3_array uv_buffer = am.buffer(n_tris * 3 * 16) --am.vec2_array geom_view = geom_buffer\view("vec3") uv_view = uv_buffer\view("vec4") texture = n.properties.graphic.texture n\populate_buf(geom_view, uv_view, 1) tbind = am.bind({ MV: s_mv P: p_mv world_x: math.sin(am.current_time!) * 2 world_y: math.cos(am.current_time!) * 2 world: geom_view, texuv: uv_view, time: am.current_time! textures: texture }) tbind\append(am.draw("triangles")) bind\append(tbind) n.node = tbind --buf_cursor += n_tris * 6 remove = (n) -> bind\remove(n.node) clear = () -> log.info("Clearing shader!") geom_view\set(vec3(0,0,0),1,buf_cursor) uv_view\set(vec4(0,0,0,0),1,buf_cursor) buf_cursor = 1 --draw = am.draw("triangles", 1, buf_cursor) --bind\append(draw) --world.geom = binds.geom --world.texuv = binds.texuv shimworld\action(() => binds = bind\all("bind") binds.time = am.current_time! --bind.world_x = math.sin(am.current_time!) * 2 --bind.world_y = math.cos(am.current_time!) * 2 binds.world_x = world.world_x binds.world_y = world.world_y ) node = shimworld --node = shader_shim.world\append(am.depth_test("less")\append(am.cull_face("front")\append(am.bind({ -- should cull front --MV: s_mv --P: mat4(1) --color: color.am_color.highlight, --world_x: 0, --world_y: 0, --world: am.vec3_array(world_geom) --texuv: am.vec4_array(world_uv) --r: am.float_array(world_r) ----world:am.vec3_array(test_world) ----texuv: am.vec4_array(test_uvs) ----r: am.float_array(test_r) --time: am.current_time(), --textures: sprites.floor1_diffuse.texture --})\append(am.draw("triangles"))))) --node\action(() => --bind = self("bind") --bind.time = am.current_time! --bind.world_x = math.sin(am.current_time!) * 2 --bind.world_y = math.cos(am.current_time!) * 2 ----bind.world_x = world.world_x ----bind.world_y = world.world_y --) { :add :clear :remove node: node bind: node("bind") }