func (m *Map) Draw() { gl.PushMatrix() gl.PushAttrib(gl.CURRENT_BIT | gl.ENABLE_BIT | gl.LIGHTING_BIT | gl.POLYGON_BIT | gl.LINE_BIT) gl.EnableClientState(gl.VERTEX_ARRAY) gl.VertexPointer(3, gl.FLOAT, 0, m.vertices) gl.EnableClientState(gl.NORMAL_ARRAY) gl.NormalPointer(gl.FLOAT, 0, m.normals) // gl.EnableClientState(gl.TEXTURE_COORD_ARRAY) // gl.TexCoordPointer(2, gl.FLOAT, 0, m.texcoords) gl.EnableClientState(gl.COLOR_ARRAY) gl.ColorPointer(3, gl.FLOAT, 0, m.colors) // draw solids gl.Enable(gl.COLOR_MATERIAL) // gl.DrawArrays(gl.TRIANGLE_STRIP, 0, len(m.vertices)/3) gl.PolygonMode(gl.FRONT_AND_BACK, gl.LINE) gl.LineWidth(1.0) gl.Color4f(1, 1, 1, 1) gl.DrawArrays(gl.TRIANGLE_STRIP, 0, len(m.vertices)/3) gl.PopAttrib() gl.PopMatrix() }
// 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) pa.bind() if pa.Invalid() { 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) ca.bind() if ca.Invalid() { 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) na.bind() if na.Invalid() { 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) ta.bind() if ta.Invalid() { ta.buffer() } gl.TexCoordPointer(ta.size, ta.typ, 0, uintptr(0)) ta.unbind() } if ic > 0 { ia.bind() if ia.Invalid() { ia.buffer() } 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() } }