// Arrays mode uses vertex arrays which involves gl*Pointer calls and // directly passing in the vertex data on every render pass. This is slower // than using VBO's, because the data has to be uploaded to the GPU on every // render pass, but it is useful for older systems where glBufferData is // not available. func (mb *MeshBuffer) renderArrays(mode gl.GLenum, m Mesh, pa, ca, na, ta, ia *Attr) { ps, pc := m[mbPositionKey][0], m[mbPositionKey][1] is, ic := m[mbIndexKey][0], m[mbIndexKey][1] cc := m[mbColorKey][1] nc := m[mbNormalKey][1] tc := m[mbTexCoordKey][1] gl.PushClientAttrib(gl.CLIENT_VERTEX_ARRAY_BIT) defer gl.PopClientAttrib() if pc > 0 { gl.EnableClientState(gl.VERTEX_ARRAY) defer gl.DisableClientState(gl.VERTEX_ARRAY) gl.VertexPointer(pa.size, pa.typ, 0, pa.ptr(0)) } if cc > 0 { gl.EnableClientState(gl.COLOR_ARRAY) defer gl.DisableClientState(gl.COLOR_ARRAY) gl.ColorPointer(ca.size, ca.typ, 0, ca.ptr(0)) } if nc > 0 { gl.EnableClientState(gl.NORMAL_ARRAY) defer gl.DisableClientState(gl.NORMAL_ARRAY) gl.NormalPointer(na.typ, 0, na.ptr(0)) } if tc > 0 { gl.EnableClientState(gl.TEXTURE_COORD_ARRAY) defer gl.DisableClientState(gl.TEXTURE_COORD_ARRAY) gl.TexCoordPointer(ta.size, ta.typ, 0, ta.ptr(0)) } if ic > 0 { gl.EnableClientState(gl.INDEX_ARRAY) defer gl.DisableClientState(gl.INDEX_ARRAY) gl.IndexPointer(ia.typ, 0, ia.ptr(0)) gl.DrawElements(mode, ic, ia.typ, ia.ptr(is*ia.size)) } else { gl.DrawArrays(mode, ps, pc) } }
// 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, pa, ca, na, ta, ia *Attr) { ps, pc := m[mbPositionKey][0], m[mbPositionKey][1] is, ic := m[mbIndexKey][0], m[mbIndexKey][1] cc := m[mbColorKey][1] nc := m[mbNormalKey][1] tc := m[mbTexCoordKey][1] if pc > 0 { gl.EnableClientState(gl.VERTEX_ARRAY) defer gl.DisableClientState(gl.VERTEX_ARRAY) if pa.Invalid() { pa.bind() pa.buffer() gl.VertexPointer(pa.size, pa.typ, 0, uintptr(0)) pa.unbind() } } if cc > 0 { gl.EnableClientState(gl.COLOR_ARRAY) defer gl.DisableClientState(gl.COLOR_ARRAY) if ca.Invalid() { ca.bind() ca.buffer() gl.ColorPointer(ca.size, ca.typ, 0, uintptr(0)) ca.unbind() } } if nc > 0 { gl.EnableClientState(gl.NORMAL_ARRAY) defer gl.DisableClientState(gl.NORMAL_ARRAY) if na.Invalid() { na.bind() na.buffer() gl.NormalPointer(na.typ, 0, uintptr(0)) na.unbind() } } if tc > 0 { gl.EnableClientState(gl.TEXTURE_COORD_ARRAY) defer gl.DisableClientState(gl.TEXTURE_COORD_ARRAY) if ta.Invalid() { ta.bind() ta.buffer() gl.TexCoordPointer(ta.size, ta.typ, 0, uintptr(0)) ta.unbind() } } if ic > 0 { gl.EnableClientState(gl.INDEX_ARRAY) defer gl.DisableClientState(gl.INDEX_ARRAY) ia.bind() if ia.Invalid() { ia.buffer() gl.IndexPointer(ia.typ, 0, uintptr(0)) } gl.PushClientAttrib(gl.CLIENT_VERTEX_ARRAY_BIT) gl.DrawElements(mode, ic, ia.typ, uintptr(is*ia.stride)) gl.PopClientAttrib() ia.unbind() } else { pa.bind() gl.PushClientAttrib(gl.CLIENT_VERTEX_ARRAY_BIT) gl.DrawArrays(mode, ps, pc) gl.PopClientAttrib() pa.unbind() } }