// LayoutGeometry builds a vertex array object holding vertex attribute locations and // buffer pointers for the given geometry. func LayoutGeometry(s *Shader, geom *Geometry) *GeometryLayout { vertices := geom.VertexBuffer if s.vertexFormat != vertices.Format() { panic("moo") } vao := gl.GenVertexArray() vao.Bind() var attrib gl.AttribLocation vertices.bind() var i VertexFormat offset := 0 stride := s.vertexFormat.Stride() for i = 1; i <= MaxVertexFormat; i <<= 1 { if s.vertexFormat&i == 0 { continue } name, ok := s.vertexAttrs[i] if !ok { // TODO: return error or something? break } attrib = s.prog.GetAttribLocation(name) if attrib >= 0 { attrib.AttribPointer(i.attribElems(), i.attribType(), i.attribNormalized(), stride, uintptr(offset)) attrib.EnableArray() } offset += i.AttribBytes() } geom.IndexBuffer.bind() layout := &GeometryLayout{ vao: vao, idxbuf: &geom.IndexBuffer, shader: s, } return layout }
// renderBuffered uses VBO's. This is the preferred mode for systems // where shader support is not present or deemed necessary. func (mb *MeshBuffer) renderBuffered(mode gl.GLenum, m Mesh, program gl.Program) { is, ic := m[mbIndexKey][0], m[mbIndexKey][1] program.Use() var attribLocation gl.AttribLocation for _, value := range mb.attr { if value.name == "index" { continue } value.bind() if value.Invalid() { value.buffer() } attribLocation = program.GetAttribLocation(value.name) attribLocation.EnableArray() attribLocation.AttribPointer(value.size, value.typ, false, 0, uintptr(0)) value.unbind() } ia := mb.find(mbIndexKey) ia.bind() if ia.Invalid() { ia.buffer() } gl.DrawElements(mode, ic, ia.typ, uintptr(is*ia.stride)) ia.unbind() for _, value := range mb.attr { if value.name == "index" { continue } attribLocation := program.GetAttribLocation(value.name) attribLocation.DisableArray() } }