graphics: Call glBufferSubData for element array buffer every frame

This is a preparation for more flexible drawing commands.
This commit is contained in:
Hajime Hoshi 2018-05-31 00:53:02 +09:00
parent f7072d7ee5
commit 03e3f0f5f7
5 changed files with 67 additions and 47 deletions

View File

@ -47,11 +47,27 @@ type commandQueue struct {
// nvertices must <= len(vertices).
// vertices is never shrunk since re-extending a vertices buffer is heavy.
nvertices int
indices []uint16
}
// theCommandQueue is the command queue for the current process.
var theCommandQueue = &commandQueue{}
func init() {
q := theCommandQueue
// Initialize indices for drawImageCommand.
q.indices = make([]uint16, 6*maxQuads)
for i := uint16(0); i < maxQuads; i++ {
q.indices[6*i+0] = 4*i + 0
q.indices[6*i+1] = 4*i + 1
q.indices[6*i+2] = 4*i + 2
q.indices[6*i+3] = 4*i + 1
q.indices[6*i+4] = 4*i + 2
q.indices[6*i+5] = 4*i + 3
}
}
// appendVertices appends vertices to the queue.
func (q *commandQueue) appendVertices(vertices []float32) {
if len(q.vertices) < q.nvertices+len(vertices) {
@ -140,7 +156,8 @@ func (q *commandQueue) Flush() error {
// Note that the vertices passed to BufferSubData is not under GC management
// in opengl package due to unsafe-way.
// See BufferSubData in context_mobile.go.
opengl.GetContext().BufferSubData(opengl.ArrayBuffer, q.vertices[lastN:n])
opengl.GetContext().ElementArrayBufferSubData(q.indices)
opengl.GetContext().ArrayBufferSubData(q.vertices[lastN:n])
}
// NOTE: WebGL doesn't seem to have gl.MAX_ELEMENTS_VERTICES or
// gl.MAX_ELEMENTS_INDICES so far.

View File

@ -120,8 +120,6 @@ type openGLState struct {
lastColorMatrixTranslation []float32
lastSourceWidth int
lastSourceHeight int
indices []uint16
}
var (
@ -229,19 +227,10 @@ func (s *openGLState) reset() error {
s.arrayBuffer = theArrayBufferLayout.newArrayBuffer()
s.indices = make([]uint16, 6*maxQuads)
for i := uint16(0); i < maxQuads; i++ {
s.indices[6*i+0] = 4*i + 0
s.indices[6*i+1] = 4*i + 1
s.indices[6*i+2] = 4*i + 2
s.indices[6*i+3] = 4*i + 1
s.indices[6*i+4] = 4*i + 2
s.indices[6*i+5] = 4*i + 3
}
// Note that the indices passed to NewElementArrayBuffer is not under GC management
// in opengl package due to unsafe-way.
// See NewElementArrayBuffer in context_mobile.go.
s.elementArrayBuffer = opengl.GetContext().NewElementArrayBuffer(s.indices)
s.elementArrayBuffer = opengl.GetContext().NewElementArrayBuffer(indicesNum * 2)
return nil
}

View File

@ -58,7 +58,6 @@ func init() {
ArrayBuffer = gl.ARRAY_BUFFER
ElementArrayBuffer = gl.ELEMENT_ARRAY_BUFFER
DynamicDraw = gl.DYNAMIC_DRAW
StaticDraw = gl.STATIC_DRAW
Triangles = gl.TRIANGLES
Lines = gl.LINES
Short = gl.SHORT
@ -452,13 +451,13 @@ func (c *Context) NewArrayBuffer(size int) Buffer {
return buffer
}
func (c *Context) NewElementArrayBuffer(indices []uint16) Buffer {
func (c *Context) NewElementArrayBuffer(size int) Buffer {
var buffer Buffer
_ = c.runOnContextThread(func() error {
var b uint32
gl.GenBuffers(1, &b)
gl.BindBuffer(uint32(ElementArrayBuffer), b)
gl.BufferData(uint32(ElementArrayBuffer), 2*len(indices), gl.Ptr(indices), uint32(StaticDraw))
gl.BufferData(uint32(ElementArrayBuffer), size, nil, uint32(DynamicDraw))
buffer = Buffer(b)
return nil
})
@ -472,9 +471,16 @@ func (c *Context) BindBuffer(bufferType BufferType, b Buffer) {
})
}
func (c *Context) BufferSubData(bufferType BufferType, data []float32) {
func (c *Context) ArrayBufferSubData(data []float32) {
_ = c.runOnContextThread(func() error {
gl.BufferSubData(uint32(bufferType), 0, len(data)*4, gl.Ptr(data))
gl.BufferSubData(uint32(ArrayBuffer), 0, len(data)*4, gl.Ptr(data))
return nil
})
}
func (c *Context) ElementArrayBufferSubData(data []uint16) {
_ = c.runOnContextThread(func() error {
gl.BufferSubData(uint32(ElementArrayBuffer), 0, len(data)*2, gl.Ptr(data))
return nil
})
}

View File

@ -55,7 +55,6 @@ func init() {
ArrayBuffer = BufferType(c.Get("ARRAY_BUFFER").Int())
ElementArrayBuffer = BufferType(c.Get("ELEMENT_ARRAY_BUFFER").Int())
DynamicDraw = BufferUsage(c.Get("DYNAMIC_DRAW").Int())
StaticDraw = BufferUsage(c.Get("STATIC_DRAW").Int())
Triangles = Mode(c.Get("TRIANGLES").Int())
Lines = Mode(c.Get("LINES").Int())
Short = DataType(c.Get("SHORT").Int())
@ -358,11 +357,11 @@ func (c *Context) NewArrayBuffer(size int) Buffer {
return b
}
func (c *Context) NewElementArrayBuffer(indices []uint16) Buffer {
func (c *Context) NewElementArrayBuffer(size int) Buffer {
gl := c.gl
b := gl.Call("createBuffer")
gl.Call("bindBuffer", int(ElementArrayBuffer), b)
gl.Call("bufferData", int(ElementArrayBuffer), indices, int(StaticDraw))
gl.Call("bufferData", int(ElementArrayBuffer), size, int(DynamicDraw))
return b
}
@ -371,9 +370,14 @@ func (c *Context) BindBuffer(bufferType BufferType, b Buffer) {
gl.Call("bindBuffer", int(bufferType), b)
}
func (c *Context) BufferSubData(bufferType BufferType, data []float32) {
func (c *Context) ArrayBufferSubData(data []float32) {
gl := c.gl
gl.Call("bufferSubData", int(bufferType), 0, data)
gl.Call("bufferSubData", int(ArrayBuffer), 0, data)
}
func (c *Context) ElementArrayBufferSubData(data []uint16) {
gl := c.gl
gl.Call("bufferSubData", int(ElementArrayBuffer), 0, data)
}
func (c *Context) DeleteBuffer(b Buffer) {

View File

@ -57,7 +57,6 @@ func init() {
ArrayBuffer = mgl.ARRAY_BUFFER
ElementArrayBuffer = mgl.ELEMENT_ARRAY_BUFFER
DynamicDraw = mgl.DYNAMIC_DRAW
StaticDraw = mgl.STATIC_DRAW
Triangles = mgl.TRIANGLES
Lines = mgl.LINES
Short = mgl.SHORT
@ -353,6 +352,27 @@ func (c *Context) DisableVertexAttribArray(p Program, location string) {
gl.DisableVertexAttribArray(mgl.Attrib(l))
}
func (c *Context) NewArrayBuffer(size int) Buffer {
gl := c.gl
b := gl.CreateBuffer()
gl.BindBuffer(mgl.Enum(ArrayBuffer), b)
gl.BufferInit(mgl.Enum(ArrayBuffer), size, mgl.Enum(DynamicDraw))
return Buffer(b)
}
func (c *Context) NewElementArrayBuffer(size int) Buffer {
gl := c.gl
b := gl.CreateBuffer()
gl.BindBuffer(mgl.Enum(ElementArrayBuffer), b)
gl.BufferInit(mgl.Enum(ElementArrayBuffer), size, mgl.Enum(DynamicDraw))
return Buffer(b)
}
func (c *Context) BindBuffer(bufferType BufferType, b Buffer) {
gl := c.gl
gl.BindBuffer(mgl.Enum(bufferType), mgl.Buffer(b))
}
func uint16ToBytes(v []uint16) []byte {
u16h := (*reflect.SliceHeader)(unsafe.Pointer(&v))
@ -364,27 +384,6 @@ func uint16ToBytes(v []uint16) []byte {
return b
}
func (c *Context) NewArrayBuffer(size int) Buffer {
gl := c.gl
b := gl.CreateBuffer()
gl.BindBuffer(mgl.Enum(ArrayBuffer), b)
gl.BufferInit(mgl.Enum(ArrayBuffer), size, mgl.Enum(DynamicDraw))
return Buffer(b)
}
func (c *Context) NewElementArrayBuffer(indices []uint16) Buffer {
gl := c.gl
b := gl.CreateBuffer()
gl.BindBuffer(mgl.Enum(ElementArrayBuffer), b)
gl.BufferData(mgl.Enum(ElementArrayBuffer), uint16ToBytes(indices), mgl.Enum(StaticDraw))
return Buffer(b)
}
func (c *Context) BindBuffer(bufferType BufferType, b Buffer) {
gl := c.gl
gl.BindBuffer(mgl.Enum(bufferType), mgl.Buffer(b))
}
func float32ToBytes(v []float32) []byte {
f32h := (*reflect.SliceHeader)(unsafe.Pointer(&v))
@ -396,9 +395,14 @@ func float32ToBytes(v []float32) []byte {
return b
}
func (c *Context) BufferSubData(bufferType BufferType, data []float32) {
func (c *Context) ArrayBufferSubData(data []float32) {
gl := c.gl
gl.BufferSubData(mgl.Enum(bufferType), 0, float32ToBytes(data))
gl.BufferSubData(mgl.Enum(ArrayBuffer), 0, float32ToBytes(data))
}
func (c *Context) ElementArrayBufferSubData(data []uint16) {
gl := c.gl
gl.BufferSubData(mgl.Enum(ElementArrayBuffer), 0, uint16ToBytes(data))
}
func (c *Context) DeleteBuffer(b Buffer) {