replace UpdateData with more convenient SetVertexAttribute

This commit is contained in:
faiface 2016-11-26 22:42:26 +01:00
parent 4421c7dbef
commit c6e2d67aba
1 changed files with 38 additions and 12 deletions

View File

@ -92,10 +92,12 @@ const (
type VertexArray struct { type VertexArray struct {
parent Doer parent Doer
format VertexFormat format VertexFormat
stride int
count int
attrs map[VertexAttribute]int
vao uint32 vao uint32
vbo uint32 vbo uint32
mode VertexDrawMode mode VertexDrawMode
count int
} }
// NewVertexArray creates a new vertex array and wraps another Doer around it. // 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{ va := &VertexArray{
parent: parent, parent: parent,
format: format, format: format,
stride: format.Size(),
count: len(data) / format.Size(),
attrs: make(map[VertexAttribute]int),
mode: mode, 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 var err error
parent.Do(func() { parent.Do(func() {
err = DoGLErr(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.BindBuffer(gl.ARRAY_BUFFER, va.vbo)
gl.BufferData(gl.ARRAY_BUFFER, 8*len(data), gl.Ptr(data), uint32(usage)) gl.BufferData(gl.ARRAY_BUFFER, 8*len(data), gl.Ptr(data), uint32(usage))
stride := format.Size()
va.count = len(data) / stride
offset := 0 offset := 0
for i, attr := range format { for i, attr := range format {
gl.VertexAttribPointer( gl.VertexAttribPointer(
@ -126,7 +141,7 @@ func NewVertexArray(parent Doer, format VertexFormat, mode VertexDrawMode, usage
int32(attr.Size), int32(attr.Size),
gl.DOUBLE, gl.DOUBLE,
false, false,
int32(8*stride), int32(8*va.stride),
gl.PtrOffset(8*offset), gl.PtrOffset(8*offset),
) )
gl.EnableVertexAttribArray(uint32(i)) gl.EnableVertexAttribArray(uint32(i))
@ -192,17 +207,28 @@ func (va *VertexArray) Data() []float64 {
return data return data
} }
// UpdateData overwrites the current vertex array data starting at the index offset. // SetVertexAttribute sets the value of the specified vertex attribute of the specified vertex.
// func (va *VertexArray) SetVertexAttribute(vertex int, attr VertexAttribute, data []float64) {
// Offset is not a number of bytes, instead, it's an index in the array. if len(data) != attr.Size {
// If offset is negative or offset+len(data)>len(originaldata) the program panics. panic("set vertex attribute error: invalid data length")
func (va *VertexArray) UpdateData(offset int, data []float64) { }
if vertex < 0 || vertex >= va.count {
panic("set vertex attribute error: invalid vertex index")
}
DoNoBlock(func() { DoNoBlock(func() {
gl.BindBuffer(gl.ARRAY_BUFFER, va.vbo) 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) gl.BindBuffer(gl.ARRAY_BUFFER, 0)
if err := getLastGLErr(); err != nil { if err := getLastGLErr(); err != nil {
panic(errors.Wrap(err, "failed to update vertex array")) panic(errors.Wrap(err, "set attribute vertex error"))
} }
}) })
} }