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). // nvertices must <= len(vertices).
// vertices is never shrunk since re-extending a vertices buffer is heavy. // vertices is never shrunk since re-extending a vertices buffer is heavy.
nvertices int nvertices int
indices []uint16
} }
// theCommandQueue is the command queue for the current process. // theCommandQueue is the command queue for the current process.
var theCommandQueue = &commandQueue{} 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. // appendVertices appends vertices to the queue.
func (q *commandQueue) appendVertices(vertices []float32) { func (q *commandQueue) appendVertices(vertices []float32) {
if len(q.vertices) < q.nvertices+len(vertices) { 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 // Note that the vertices passed to BufferSubData is not under GC management
// in opengl package due to unsafe-way. // in opengl package due to unsafe-way.
// See BufferSubData in context_mobile.go. // 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 // NOTE: WebGL doesn't seem to have gl.MAX_ELEMENTS_VERTICES or
// gl.MAX_ELEMENTS_INDICES so far. // gl.MAX_ELEMENTS_INDICES so far.

View File

@ -120,8 +120,6 @@ type openGLState struct {
lastColorMatrixTranslation []float32 lastColorMatrixTranslation []float32
lastSourceWidth int lastSourceWidth int
lastSourceHeight int lastSourceHeight int
indices []uint16
} }
var ( var (
@ -229,19 +227,10 @@ func (s *openGLState) reset() error {
s.arrayBuffer = theArrayBufferLayout.newArrayBuffer() 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 // Note that the indices passed to NewElementArrayBuffer is not under GC management
// in opengl package due to unsafe-way. // in opengl package due to unsafe-way.
// See NewElementArrayBuffer in context_mobile.go. // See NewElementArrayBuffer in context_mobile.go.
s.elementArrayBuffer = opengl.GetContext().NewElementArrayBuffer(s.indices) s.elementArrayBuffer = opengl.GetContext().NewElementArrayBuffer(indicesNum * 2)
return nil return nil
} }

View File

@ -58,7 +58,6 @@ func init() {
ArrayBuffer = gl.ARRAY_BUFFER ArrayBuffer = gl.ARRAY_BUFFER
ElementArrayBuffer = gl.ELEMENT_ARRAY_BUFFER ElementArrayBuffer = gl.ELEMENT_ARRAY_BUFFER
DynamicDraw = gl.DYNAMIC_DRAW DynamicDraw = gl.DYNAMIC_DRAW
StaticDraw = gl.STATIC_DRAW
Triangles = gl.TRIANGLES Triangles = gl.TRIANGLES
Lines = gl.LINES Lines = gl.LINES
Short = gl.SHORT Short = gl.SHORT
@ -452,13 +451,13 @@ func (c *Context) NewArrayBuffer(size int) Buffer {
return buffer return buffer
} }
func (c *Context) NewElementArrayBuffer(indices []uint16) Buffer { func (c *Context) NewElementArrayBuffer(size int) Buffer {
var buffer Buffer var buffer Buffer
_ = c.runOnContextThread(func() error { _ = c.runOnContextThread(func() error {
var b uint32 var b uint32
gl.GenBuffers(1, &b) gl.GenBuffers(1, &b)
gl.BindBuffer(uint32(ElementArrayBuffer), 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) buffer = Buffer(b)
return nil 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 { _ = 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 return nil
}) })
} }

View File

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

View File

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