func (b *VertexBuffer) SetVertices(src []byte, usage Usage) error { gl.VertexArray(0).Bind() b.bind() // set size of buffer and invalidate it gl.BufferData(gl.ARRAY_BUFFER, len(src), nil, usage.gl()) if len(src) > 0 { // if unmap returns false, the buffer we wrote to is no longer valid and we // need to try again. though, this is apparently uncommon in modern // drivers. this means it is not feasible to compute/copy vertices directly // into the mapped buffer. however, it would be nice to provide a // failure-capable API to do this. const maxretries = 5 retries := 0 for ; retries < maxretries; retries++ { ptr := gl.MapBuffer(gl.ARRAY_BUFFER, gl.WRITE_ONLY) slicehdr := reflect.SliceHeader{ Data: uintptr(ptr), Len: len(src), Cap: len(src), } dest := *(*[]byte)(unsafe.Pointer(&slicehdr)) copy(dest, src) if gl.UnmapBuffer(gl.ARRAY_BUFFER) { break } } if retries == maxretries { return errMapBufferFailed } } b.count = len(src) / b.format.Stride() return nil }
func (t *Texture) ReadTextureFromGPU() []byte { t.Bind() b := gl.GenBuffer() b.Bind(gl.PIXEL_UNPACK_BUFFER) gl.BufferData(gl.PIXEL_UNPACK_BUFFER, t.Width()*t.Height()*t.PixelSize(), 0, gl.STREAM_DRAW) //gl.GetTexImage(t.target, 0, t.format, buffer) b.Bind(gl.PIXEL_UNPACK_BUFFER) gl.TexSubImage2D(t.target, 0, 0, 0, t.Width(), t.Height(), t.format, t.typ, unsafe.Pointer(uintptr(0))) b.Bind(gl.PIXEL_UNPACK_BUFFER) l := t.Width() * t.Height() * t.PixelSize() gl.BufferData(gl.PIXEL_UNPACK_BUFFER, t.Width()*t.Height()*t.PixelSize(), 0, gl.STREAM_DRAW) ptr := gl.MapBuffer(gl.PIXEL_UNPACK_BUFFER, gl.WRITE_ONLY) var x []byte s := (*reflect.SliceHeader)(unsafe.Pointer(&x)) s.Data = uintptr(ptr) s.Len = l s.Cap = l gl.UnmapBuffer(gl.PIXEL_UNPACK_BUFFER) return x }
func (b *IndexBuffer) setIndices(copyTo func(unsafe.Pointer), usage Usage, size int) error { gl.VertexArray(0).Bind() b.bind() gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, size, nil, usage.gl()) if size > 0 { const maxretries = 5 retries := 0 for ; retries < maxretries; retries++ { ptr := gl.MapBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.WRITE_ONLY) copyTo(ptr) if gl.UnmapBuffer(gl.ELEMENT_ARRAY_BUFFER) { break } } if retries == maxretries { return errMapBufferFailed } } return nil }