func (this *LineRenderer) Render(Proj, View mgl.Mat4) { data := debug.Read() if len(data) > 0 { this.Prog.Use() this.vao.Bind() this.buffer.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, helpers.ByteSizeOfSlice(data), data, gl.STREAM_DRAW) this.RenLoc.Proj.UniformMatrix4f(false, renderstuff.GlMat4(&Proj)) this.RenLoc.View.UniformMatrix4f(false, renderstuff.GlMat4(&View)) gl.DrawArrays(gl.LINES, 0, len(data)) } }
func CreateShapeDataBuffer() gl.Buffer { fmt.Println("CreateShapeDataBuffer:") particleShape := []ParticleShapeVertex{ {mgl.Vec4{-R, -R, 0, 1}, mgl.Vec2{0, 1}}, {mgl.Vec4{R, -R, 0, 1}, mgl.Vec2{1, 1}}, {mgl.Vec4{R, R, 0, 1}, mgl.Vec2{1, 0}}, {mgl.Vec4{-R, R, 0, 1}, mgl.Vec2{0, 0}}, } particleShapeBuffer := gl.GenBuffer() particleShapeBuffer.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, helpers.ByteSizeOfSlice(particleShape), particleShape, gl.STATIC_DRAW) return particleShapeBuffer }
func NewParticleSystem(w *gamestate.World, numParticles int, Origin mgl.Vec3, initialSpeed, MaxLifetime float32) *ParticleSystem { vertices := make([]ParticleVertex, numParticles) directions := make([]NonTransformBuffer, numParticles) for i := range vertices { dir := mgl.Vec3{rand.Float32()*2 - 1, rand.Float32()*2 - 1, rand.Float32()*2 - 1} for dir.Len() > 1 { dir = mgl.Vec3{rand.Float32()*2 - 1, rand.Float32()*2 - 1, rand.Float32()*2 - 1} } dir = dir.Mul(initialSpeed) vertices[i] = ParticleVertex{ Pos1: Origin, Pos2: Origin.Sub(dir), Lifetime: rand.Float32() * MaxLifetime, } directions[i] = NonTransformBuffer{dir} } buffer1, buffer2, nonTransformBuffer := gl.GenBuffer(), gl.GenBuffer(), gl.GenBuffer() nonTransformBuffer.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, helpers.ByteSizeOfSlice(directions), directions, gl.STATIC_DRAW) buffer1.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, helpers.ByteSizeOfSlice(vertices), vertices, gl.STREAM_DRAW) buffer2.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, helpers.ByteSizeOfSlice(vertices), uintptr(0), gl.STREAM_DRAW) shapeData := CreateShapeDataBuffer() TransformProg := gl.CreateProgram() shader := helpers.MakeShader(gl.VERTEX_SHADER, "ParticleTFF.vs") TransformProg.AttachShader(shader) TransformProg.TransformFeedbackVaryings([]string{"v_Pos1", "v_Pos2", "v_Lifetime"}, gl.INTERLEAVED_ATTRIBS) TransformProg.Link() shader.Delete() TransformProg.Use() TransformLoc := ProgramLocations{} helpers.BindLocations("particle transform", TransformProg, &TransformLoc) renderProgram := helpers.MakeProgram("Particle.vs", "Particle.fs") renderProgram.Use() RenderLoc := RenderProgramLocations{} helpers.BindLocations("particle render", renderProgram, &RenderLoc) vaoTff1 := gl.GenVertexArray() vaoTff2 := gl.GenVertexArray() vaoRender1 := gl.GenVertexArray() vaoRender2 := gl.GenVertexArray() ps := ParticleSystem{ TransformProg: TransformProg, TransformLoc: TransformLoc, RenderProg: renderProgram, RenderLoc: RenderLoc, VaoTff1: vaoTff1, VaoTff2: vaoTff2, VaoRender1: vaoRender1, VaoRender2: vaoRender2, Data1: buffer1, Data2: buffer2, ShapeData: shapeData, NonTransformBuffer: nonTransformBuffer, NumParticles: numParticles, Origin: Origin, Gravity: -9.81 / 200, InitialSpeed: initialSpeed, MaxLifetime: MaxLifetime, } min_h, max_h := w.HeightMap.Bounds() W := float32(w.HeightMap.W) H := float32(w.HeightMap.H) TransformProg.Use() ps.SetUniforms() ps.SetVaos() TransformProg.Use() ps.TransformLoc.HeightMap.Uniform1i(constants.TextureHeightMap) ps.TransformLoc.LowerBound.Uniform3f(0, 0, min_h) ps.TransformLoc.UpperBound.Uniform3f(W, H, max_h) return &ps }
func LoadMeshToGpu(mesh *Mesh, renLoc *RenderLocations) (rd RenderData) { rd.VAO = gl.GenVertexArray() rd.VAO.Bind() { vertices := mesh.Vertices verticesType := reflect.TypeOf(vertices) if verticesType.Kind() != reflect.Slice { panic("Vertices is not a slice") } rd.Vertices = gl.GenBuffer() rd.Vertices.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, helpers.ByteSizeOfSlice(vertices), vertices, gl.STATIC_DRAW) rd.Numverts = reflect.ValueOf(vertices).Len() helpers.SetAttribPointers(renLoc, reflect.ValueOf(vertices).Index(0).Addr().Interface(), false) switch mesh.Mode { case Points: rd.Mode = gl.POINTS case LineStrip: rd.Mode = gl.LINE_STRIP case LineLoop: rd.Mode = gl.LINE_LOOP case Lines: rd.Mode = gl.LINES case TriangleStrip: rd.Mode = gl.TRIANGLE_STRIP case TriangleFan: rd.Mode = gl.TRIANGLE_FAN case Triangles: rd.Mode = gl.TRIANGLES default: panic("unsupported mode") } } if indices := mesh.Indices; indices != nil { indicesType := reflect.TypeOf(indices) if indicesType.Kind() != reflect.Slice { panic("Indices is not a slice") } rd.Indices = gl.GenBuffer() rd.Indices.Bind(gl.ELEMENT_ARRAY_BUFFER) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, helpers.ByteSizeOfSlice(indices), indices, gl.STATIC_DRAW) rd.Numverts = reflect.ValueOf(indices).Len() switch indicesType.Elem().Kind() { case reflect.Uint8, reflect.Int8: rd.IndexType = gl.UNSIGNED_BYTE case reflect.Uint16, reflect.Int16: rd.IndexType = gl.UNSIGNED_SHORT case reflect.Uint32, reflect.Int32: rd.IndexType = gl.UNSIGNED_INT default: panic(fmt.Sprint("unsupported index type", indicesType.Elem().Kind())) } } if instanceData := mesh.InstanceData; instanceData != nil { Type := reflect.TypeOf(instanceData) if Type.Kind() != reflect.Slice { panic("InstanceData is not a slice") } rd.InstanceData = gl.GenBuffer() rd.InstanceData.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, helpers.ByteSizeOfSlice(instanceData), instanceData, gl.STATIC_DRAW) helpers.SetAttribPointers(renLoc, reflect.ValueOf(instanceData).Index(0).Addr().Interface(), true) rd.NumInstances = reflect.ValueOf(instanceData).Len() } return }