Beispiel #1
0
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
}
Beispiel #2
0
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))
}