func NewParticleSystem(position, direction glm.Vec3, size int) *ParticleSystem { ps := ParticleSystem{} ps.root = position ps.direction = direction ps.transformfeedbacks = gl2.GenTransformFeedbacks(2) MustNotGLError() ps.buffers = gl2.GenBuffers(2) MustNotGLError() ps.particles = make([]Particle, size) ps.isFirst = true ps.program = gl2.CreateProgram() vss, err := CompileShader(vs, gl2.VERTEX_SHADER) if err != nil { D(err) } ps.program.AttachShader(vss.Loc) gss, err := CompileShader(gs, gl2.GEOMETRY_SHADER) if err != nil { D(err) } ps.program.AttachShader(gss.Loc) fss, err := CompileShader(fs, gl2.FRAGMENT_SHADER) if err != nil { D(err) } ps.program.AttachShader(fss.Loc) ps.program.Link() if !ps.program.GetLinkStatus() { var logLength int32 gl.GetProgramiv(uint32(ps.program), gl.INFO_LOG_LENGTH, &logLength) log := strings.Repeat("\x00", int(logLength+1)) gl.GetProgramInfoLog(uint32(ps.program), logLength, nil, gl.Str(log)) } ps.gDeltaTimeMillis = ps.program.GetUniformLocation("gDeltaTimeMillis") ps.gTime = ps.program.GetUniformLocation("gTime") ps.gRandomTexture = ps.program.GetUniformLocation("gRandomTexture") ps.gLauncherLifetime = ps.program.GetUniformLocation("gLauncherLifetime") ps.gShellLifetime = ps.program.GetUniformLocation("gShellLifetime") ps.gSecondaryShellLifetime = ps.program.GetUniformLocation("gSecondaryShellLifetime") ps.particles[0].Lifetime = 0 ps.particles[0].Position = position ps.particles[0].Velocity = glm.Vec3{0, 0, 0} ps.particles[0].Type = Launcher for i := 0; i < len(ps.buffers); i++ { ps.transformfeedbacks[i].Bind() MustNotGLError() ps.buffers[i].Bind(gl2.ARRAY_BUFFER) MustNotGLError() ps.buffers[i].Data(gl2.ARRAY_BUFFER, int(unsafe.Sizeof(Particle{}))*len(ps.particles), unsafe.Pointer(&ps.particles[0]), gl2.DYNAMIC_DRAW) MustNotGLError() ps.transformfeedbacks[i].BindBufferBase(gl2.TRANSFORM_FEEDBACK_BUFFER, 0, ps.buffers[i]) MustNotGLError() } return &ps }
//NewProgram will create an OpenGL program from the given shaders, any combinations can be used func NewProgram(shaders ...Shader) (gl.Program, error) { program := gl.CreateProgram() for _, shader := range shaders { program.AttachShader(shader.Loc) } program.Link() if !program.GetLinkStatus() { return 0, fmt.Errorf("failed to link program: %v", program.GetInfoLog()) } return program, nil }