Add basic compute simulation (disabled)
[lovr-particles] / main.lua
1 local mat4 = lovr.math.mat4
2
3 local nParticles = 2 ^ 16
4 local batchSize = 128
5 local batches = nParticles / batchSize
6
7 local features
8 local shaders = {}
9 local blocks = {}
10 local meshes = {}
11 local compute = {}
12
13 function lovr.load()
14 features = lovr.graphics.getFeatures()
15
16 shaders.particles = lovr.graphics.newShader("shaders/particles.vert", "shaders/particles.frag")
17
18 blocks.particles = lovr.graphics.newShaderBlock("compute", {
19 particles = {"mat4", nParticles},
20 }, { readable = true, writable = true })
21 shaders.particles:sendBlock('particleData', blocks.particles)
22 shaders.particles:send("batchSize", batchSize)
23
24 meshes.particle = makeParticleMesh(batchSize)
25
26 compute.particles = lovr.graphics.newComputeShader("shaders/particles.comp")
27 compute.particles:sendBlock('particleData', blocks.particles)
28 compute.particles:send("dt", 0.0)
29
30 local initial = initialParticleData(nParticles, range(-2, 2), range(0, 4), range(-2, 2), range(0.005, 0.01))
31 blocks.particles:send("particles", initial)
32 end
33
34 function lovr.draw()
35 lovr.graphics.clear()
36 local x, y, z = lovr.headset.getPose("head")
37 -- lovr.graphics.compute(compute.particles, batches)
38 shaders.particles:send("headPos", {x, y, z})
39
40 lovr.graphics.setColor(0.6, 0.1, 0)
41 lovr.graphics.setShader(nil)
42 for _, hand in ipairs(lovr.headset.getHands()) do
43 local x, y, z, a, ax, ay, az = lovr.headset.getPose(hand)
44 lovr.graphics.cube("fill", x, y, z, 0.1, a, ax, ay, az)
45 end
46
47 withDepthTest("lequal", false, function()
48 lovr.graphics.setColor(1, 1, 1)
49 lovr.graphics.setShader(shaders.particles)
50 meshes.particle:draw(mat4(), batches)
51 end)
52 end
53
54 function makeParticleMesh(size)
55 local format = { {'vertPosition', 'float', 2}, }
56 local verts = {}
57 local vertMap = {}
58 local insert = table.insert
59 for chunk = 1, size do
60 insert(verts, { 1, 1})
61 insert(verts, { 1, -1})
62 insert(verts, {-1, -1})
63 insert(verts, {-1, 1})
64 local base = 4 * (chunk - 1)
65 insert(vertMap, 3 + base)
66 insert(vertMap, 2 + base)
67 insert(vertMap, 1 + base)
68 insert(vertMap, 4 + base)
69 insert(vertMap, 3 + base)
70 insert(vertMap, 1 + base)
71 end
72 local mesh = lovr.graphics.newMesh(format, verts, "triangles", "static")
73 mesh:setVertexMap(vertMap)
74 return mesh
75 end
76
77 function range(min, max)
78 local scale = max - min
79 return function()
80 return min + lovr.math.random() * scale
81 end
82 end
83
84 function initialParticleData(size, xRange, yRange, zRange, sRange)
85 local particles = {}
86 local insert = table.insert
87 for i = 1, size do
88 insert(particles, {
89 xRange(), yRange(), zRange(), sRange(),
90 xRange(), yRange(), zRange(), 1,
91 0, 0, 0, 0,
92 0, 0, 0, 0,
93 })
94 end
95 return particles
96 end
97
98 function withDepthTest(compareMode, write, callback)
99 local oldComp, oldWrite = lovr.graphics.getDepthTest()
100 lovr.graphics.setDepthTest(compareMode, write)
101 callback()
102 lovr.graphics.setDepthTest(oldComp, oldWrite)
103 end