From c6e2d67aba52fecf5a5c579a21f1781c56d9b44e Mon Sep 17 00:00:00 2001 From: faiface Date: Sat, 26 Nov 2016 22:42:26 +0100 Subject: [PATCH] replace UpdateData with more convenient SetVertexAttribute --- pixelgl/vertex.go | 50 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/pixelgl/vertex.go b/pixelgl/vertex.go index 3a0e5c8..92092ef 100644 --- a/pixelgl/vertex.go +++ b/pixelgl/vertex.go @@ -92,10 +92,12 @@ const ( type VertexArray struct { parent Doer format VertexFormat + stride int + count int + attrs map[VertexAttribute]int vao uint32 vbo uint32 mode VertexDrawMode - count int } // NewVertexArray creates a new vertex array and wraps another Doer around it. @@ -103,9 +105,25 @@ func NewVertexArray(parent Doer, format VertexFormat, mode VertexDrawMode, usage va := &VertexArray{ parent: parent, format: format, + stride: format.Size(), + count: len(data) / format.Size(), + attrs: make(map[VertexAttribute]int), mode: mode, } + if len(data)%format.Size() != 0 { + return nil, errors.New("failed to create vertex array: data length not divisable by format size") + } + + offset := 0 + for _, attr := range format { + if _, ok := va.attrs[attr]; ok { + return nil, errors.New("failed to create vertex array: invalid vertex format: duplicate vertex attribute") + } + va.attrs[attr] = offset + offset += attr.Size + } + var err error parent.Do(func() { err = DoGLErr(func() { @@ -116,9 +134,6 @@ func NewVertexArray(parent Doer, format VertexFormat, mode VertexDrawMode, usage gl.BindBuffer(gl.ARRAY_BUFFER, va.vbo) gl.BufferData(gl.ARRAY_BUFFER, 8*len(data), gl.Ptr(data), uint32(usage)) - stride := format.Size() - va.count = len(data) / stride - offset := 0 for i, attr := range format { gl.VertexAttribPointer( @@ -126,7 +141,7 @@ func NewVertexArray(parent Doer, format VertexFormat, mode VertexDrawMode, usage int32(attr.Size), gl.DOUBLE, false, - int32(8*stride), + int32(8*va.stride), gl.PtrOffset(8*offset), ) gl.EnableVertexAttribArray(uint32(i)) @@ -192,17 +207,28 @@ func (va *VertexArray) Data() []float64 { return data } -// UpdateData overwrites the current vertex array data starting at the index offset. -// -// Offset is not a number of bytes, instead, it's an index in the array. -// If offset is negative or offset+len(data)>len(originaldata) the program panics. -func (va *VertexArray) UpdateData(offset int, data []float64) { +// SetVertexAttribute sets the value of the specified vertex attribute of the specified vertex. +func (va *VertexArray) SetVertexAttribute(vertex int, attr VertexAttribute, data []float64) { + if len(data) != attr.Size { + panic("set vertex attribute error: invalid data length") + } + if vertex < 0 || vertex >= va.count { + panic("set vertex attribute error: invalid vertex index") + } DoNoBlock(func() { gl.BindBuffer(gl.ARRAY_BUFFER, va.vbo) - gl.BufferSubData(gl.ARRAY_BUFFER, 8*offset, 8*len(data), gl.Ptr(data)) + + attrOffset, ok := va.attrs[attr] + if !ok { + panic("set vertex attribute error: invalid vertex attribute") + } + offset := 8*va.stride*vertex + 8*attrOffset + gl.BufferSubData(gl.ARRAY_BUFFER, offset, 8*len(data), gl.Ptr(data)) + gl.BindBuffer(gl.ARRAY_BUFFER, 0) + if err := getLastGLErr(); err != nil { - panic(errors.Wrap(err, "failed to update vertex array")) + panic(errors.Wrap(err, "set attribute vertex error")) } }) }