func New() (s *Space, err error) { s = new(Space) s.accelProgram, err = loadShader() if err != nil { return nil, err } gl.GenVertexArrays(1, &s.vao) gl.GenBuffers(1, &s.vbo) gl.UseProgram(s.accelProgram) gl.BindVertexArray(s.vao) gl.BindBufferBase(gl.SHADER_STORAGE_BUFFER, 0, s.vbo) return s, nil }
func (s *Space) Step(dt float64) { var prevProgram int32 gl.GetIntegerv(gl.CURRENT_PROGRAM, &prevProgram) gl.UseProgram(s.accelProgram) gl.BindVertexArray(s.vao) gl.BindBufferBase(gl.SHADER_STORAGE_BUFFER, 0, s.vbo) gl.BufferData( gl.SHADER_STORAGE_BUFFER, len(s.Particles)*int(unsafe.Sizeof(gpuParticle{})), nil, gl.DYNAMIC_COPY) { // send mappedParticles, err := sliceMapParticlesBuffer(gl.WRITE_ONLY, len(s.Particles)) if err != nil { panic(err) } for i, p := range s.Particles { mappedParticles[i] = gpuParticle{ position: [2]float32{float32(p.Position.X), float32(p.Position.Y)}, mass: float32(p.Mass), } } gl.UnmapBuffer(gl.SHADER_STORAGE_BUFFER) } gl.DispatchCompute(uint32(len(s.Particles))/WORK_GROUP_LOCAL_SIZE, 1, 1) gl.MemoryBarrier(gl.SHADER_STORAGE_BARRIER_BIT) { // receive mappedParticles, err := sliceMapParticlesBuffer(gl.READ_ONLY, len(s.Particles)) if err != nil { panic(err) } for i, q := range mappedParticles { p := &s.Particles[i] p.Position = p.Position.Add(p.Velocity.Mul(dt)).Add( p.Acceleration.Mul(dt * dt).Mul(0.5)) oldAcceleration := p.Acceleration p.Acceleration = vect.V{ float64(q.acceleration[0]), float64(q.acceleration[1]), } p.Velocity = p.Velocity.Add( p.Acceleration.Add(oldAcceleration).Mul(0.5).Mul(dt)) } gl.UnmapBuffer(gl.SHADER_STORAGE_BUFFER) } gl.UseProgram(uint32(prevProgram)) }