Ver código fonte

improved vbo API

Daniel Salvadori 7 anos atrás
pai
commit
a6090d546d

+ 3 - 3
experimental/physics/debug.go

@@ -33,7 +33,7 @@ func ShowWorldFace(scene *core.Node, face []math32.Vector3, color *math32.Color)
 	vertices.AppendVector3(&face[0])
 
 	geom := geometry.NewGeometry()
-	geom.AddVBO(gls.NewVBO(vertices).AddAttrib(gls.VertexPosition, 3))
+	geom.AddVBO(gls.NewVBO(vertices).AddAttrib(gls.VertexPosition))
 
 	mat := material.NewStandard(color)
 	faceGraphic := graphic.NewLineStrip(geom, mat)
@@ -63,7 +63,7 @@ func ShowPenAxis(scene *core.Node, axis *math32.Vector3) {//}, min, max float32)
 	vertices.AppendVector3(maxPoint)
 
 	geom := geometry.NewGeometry()
-	geom.AddVBO(gls.NewVBO(vertices).AddAttrib(gls.VertexPosition, 3))
+	geom.AddVBO(gls.NewVBO(vertices).AddAttrib(gls.VertexPosition))
 
 	mat := material.NewStandard(&math32.Color{1,1,1})
 	faceGraphic := graphic.NewLines(geom, mat)
@@ -86,7 +86,7 @@ func ShowContact(scene *core.Node, contact *collision.Contact) {
 	vertices.AppendVector3(otherPoint)
 
 	geom := geometry.NewGeometry()
-	geom.AddVBO(gls.NewVBO(vertices).AddAttrib(gls.VertexPosition, 3))
+	geom.AddVBO(gls.NewVBO(vertices).AddAttrib(gls.VertexPosition))
 
 	mat := material.NewStandard(&math32.Color{0,0,1})
 	faceGraphic := graphic.NewLines(geom, mat)

+ 3 - 3
geometry/box.go

@@ -135,9 +135,9 @@ func NewSegmentedBox(width, height, length float32, widthSegments, heightSegment
 	buildPlane("x", "y", -1, -1, box.Width, box.Height, -lHalf, 5) // nz
 
 	box.SetIndices(indices)
-	box.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition, 3))
-	box.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal, 3))
-	box.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord, 2))
+	box.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
+	box.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal))
+	box.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord))
 
 	// Update bounding box
 	box.boundingBox.Min = math32.Vector3{-wHalf, -hHalf, -lHalf}

+ 3 - 3
geometry/circle.go

@@ -82,9 +82,9 @@ func NewCircleSector(radius float64, segments int, thetaStart, thetaLength float
 	}
 
 	circ.SetIndices(indices)
-	circ.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition, 3))
-	circ.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal, 3))
-	circ.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord, 2))
+	circ.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
+	circ.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal))
+	circ.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord))
 
 	// Update volume
 	circ.volume = 0

+ 3 - 3
geometry/cylinder.go

@@ -253,9 +253,9 @@ func NewCylinder(radiusTop, radiusBottom, height float64,
 	}
 
 	c.SetIndices(indices)
-	c.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition, 3))
-	c.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal, 3))
-	c.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord, 2))
+	c.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
+	c.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal))
+	c.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord))
 
 	return c
 }

+ 5 - 1
geometry/geometry.go

@@ -7,6 +7,7 @@ package geometry
 import (
 	"github.com/g3n/engine/gls"
 	"github.com/g3n/engine/math32"
+	"strconv"
 )
 
 // IGeometry is the interface for all geometries.
@@ -159,7 +160,10 @@ func (g *Geometry) AddVBO(vbo *gls.VBO) {
 	for _, existingVbo := range g.vbos {
 		for _, attrib := range vbo.Attributes() {
 			if existingVbo.AttribName(attrib.Name) != nil {
-				panic("Geometry.AddVBO: geometry already has a VBO with attribute named:" + attrib.Name)
+				panic("Geometry.AddVBO: geometry already has a VBO with attribute name:" + attrib.Name)
+			}
+			if existingVbo.Attrib(attrib.Type) != nil {
+				panic("Geometry.AddVBO: geometry already has a VBO with attribute type:" + strconv.Itoa(int(attrib.Type)))
 			}
 		}
 	}

+ 3 - 3
geometry/plane.go

@@ -71,9 +71,9 @@ func NewPlane(width, height float32, widthSegments, heightSegments int) *Plane {
 	}
 
 	plane.SetIndices(indices)
-	plane.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition, 3))
-	plane.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal, 3))
-	plane.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord, 2))
+	plane.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
+	plane.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal))
+	plane.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord))
 
 	// Update area
 	plane.area = width*height

+ 3 - 3
geometry/sphere.go

@@ -83,9 +83,9 @@ func NewSphere(radius float64, widthSegments, heightSegments int, phiStart, phiL
 	}
 
 	s.SetIndices(indices)
-	s.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition, 3))
-	s.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal, 3))
-	s.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord, 2))
+	s.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
+	s.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal))
+	s.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord))
 
 	r := float32(radius)
 

+ 3 - 3
geometry/torus.go

@@ -69,9 +69,9 @@ func NewTorus(radius, tube float64, radialSegments, tubularSegments int, arc flo
 	}
 
 	t.SetIndices(indices)
-	t.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition, 3))
-	t.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal, 3))
-	t.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord, 2))
+	t.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
+	t.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal))
+	t.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord))
 
 	return t
 }

+ 54 - 22
gls/vbo.go

@@ -21,9 +21,10 @@ type VBO struct {
 
 // VBOattrib describes one attribute of an OpenGL Vertex Buffer Object.
 type VBOattrib struct {
-	Type     AttribType // Type of the attribute
-	Name     string     // Name of the attribute
-	ItemSize int32      // Number of elements
+	Type       AttribType // Type of the attribute
+	Name       string     // Name of the attribute
+	ItemSize   int32      // Number of components
+	ByteOffset uint32     // Byte offset from the start of the VBO
 }
 
 // AttribType is the functional type of a vbo attribute.
@@ -38,13 +39,23 @@ const (
 )
 
 // Map from attribute type to default attribute name.
-var attribTypeMap = map[AttribType]string{
+var attribTypeNameMap = map[AttribType]string{
 	VertexPosition: "VertexPosition",
 	VertexNormal:   "VertexNormal",
 	VertexColor:    "VertexColor",
 	VertexTexcoord: "VertexTexcoord",
 }
 
+// Map from attribute type to default attribute size.
+var attribTypeSizeMap = map[AttribType]int32{
+	VertexPosition: 3,
+	VertexNormal:   3,
+	VertexColor:    3,
+	VertexTexcoord: 2,
+}
+
+const floatSize = uint32(unsafe.Sizeof(float32(0)))
+
 // NewVBO creates and returns a pointer to a new OpenGL Vertex Buffer Object.
 func NewVBO(buffer math32.ArrayF32) *VBO {
 
@@ -64,24 +75,51 @@ func (vbo *VBO) init() {
 	vbo.attribs = make([]VBOattrib, 0)
 }
 
-// AddAttrib adds a new attribute to the VBO by attribute type.
-func (vbo *VBO) AddAttrib(atype AttribType, itemSize int32) *VBO {
+// AddAttrib adds a new attribute to the VBO with the specified type.
+// The attribute's ByteOffset is computed automatically based on the existing attributes.
+func (vbo *VBO) AddAttrib(atype AttribType) *VBO {
+
+	vbo.attribs = append(vbo.attribs, VBOattrib{
+		Type:       atype,
+		Name:       attribTypeNameMap[atype],
+		ItemSize:   attribTypeSizeMap[atype],
+		ByteOffset: uint32(vbo.StrideSize()),
+	})
+	return vbo
+}
+
+// AddAttribOffset adds a new attribute to the VBO with the specified type and byteOffset.
+func (vbo *VBO) AddAttribOffset(atype AttribType, byteOffset uint32) *VBO {
 
 	vbo.attribs = append(vbo.attribs, VBOattrib{
-		Type:     atype,
-		Name:     attribTypeMap[atype],
-		ItemSize: itemSize,
+		Type:       atype,
+		Name:       attribTypeNameMap[atype],
+		ItemSize:   attribTypeSizeMap[atype],
+		ByteOffset: byteOffset,
 	})
 	return vbo
 }
 
-// AddAttribName adds a new attribute to the VBO by name.
-func (vbo *VBO) AddAttribName(name string, itemSize int32) *VBO {
+// AddCustomAttrib adds a new attribute to the VBO with the specified name and itemSize.
+func (vbo *VBO) AddCustomAttrib(name string, itemSize int32) *VBO {
 
 	vbo.attribs = append(vbo.attribs, VBOattrib{
-		Type:     Undefined,
-		Name:     name,
-		ItemSize: itemSize,
+		Type:       Undefined,
+		Name:       name,
+		ItemSize:   itemSize,
+		ByteOffset: uint32(vbo.StrideSize()),
+	})
+	return vbo
+}
+
+// AddCustomAttribOffset adds a new attribute to the VBO with the specified name, itemSize and byteOffset.
+func (vbo *VBO) AddCustomAttribOffset(name string, itemSize int32, byteOffset uint32) *VBO {
+
+	vbo.attribs = append(vbo.attribs, VBOattrib{
+		Type:       Undefined,
+		Name:       name,
+		ItemSize:   itemSize,
+		ByteOffset: byteOffset,
 	})
 	return vbo
 }
@@ -234,9 +272,6 @@ func (vbo *VBO) Transfer(gs *GLS) {
 		// Calculates stride size
 		strideSize := vbo.StrideSize()
 		// For each attribute
-		var items uint32
-		var offset uint32
-		elsize := int32(unsafe.Sizeof(float32(0)))
 		for _, attrib := range vbo.attribs {
 			// Get attribute location in the current program
 			loc := gs.prog.GetAttribLocation(attrib.Name)
@@ -246,9 +281,7 @@ func (vbo *VBO) Transfer(gs *GLS) {
 			}
 			// Enables attribute and sets its stride and offset in the buffer
 			gs.EnableVertexAttribArray(uint32(loc))
-			gs.VertexAttribPointer(uint32(loc), attrib.ItemSize, FLOAT, false, int32(strideSize), offset)
-			items += uint32(attrib.ItemSize)
-			offset = uint32(elsize) * items
+			gs.VertexAttribPointer(uint32(loc), attrib.ItemSize, FLOAT, false, int32(strideSize), attrib.ByteOffset)
 		}
 		vbo.gs = gs // this indicates that the vbo was initialized
 	}
@@ -307,7 +340,6 @@ func (vbo *VBO) ReadVectors3(attribType AttribType, cb func(vec math32.Vector3)
 	}
 }
 
-
 // Read3Vectors3 iterates over all 3-float32 items (3 items at a time) for the specified attribute
 // and calls the specified callback function with the value of each of the 3 items as Vector3.
 // The callback function returns false to continue or true to break.
@@ -331,4 +363,4 @@ func (vbo *VBO) ReadTripleVectors3(attribType AttribType, cb func(vec1, vec2, ve
 			break
 		}
 	}
-}
+}

+ 2 - 2
graphic/axis_helper.go

@@ -36,8 +36,8 @@ func NewAxisHelper(size float32) *AxisHelper {
 		0, 1, 0, 0.6, 1, 0,
 		0, 0, 1, 0, 0.6, 1,
 	)
-	geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition, 3))
-	geom.AddVBO(gls.NewVBO(colors).AddAttrib(gls.VertexColor, 3))
+	geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
+	geom.AddVBO(gls.NewVBO(colors).AddAttrib(gls.VertexColor))
 
 	// Creates line material
 	mat := material.NewBasic()

+ 2 - 2
graphic/grid_helper.go

@@ -37,8 +37,8 @@ func NewGridHelper(size, step float32, color *math32.Color) *GridHelper {
 	geom := geometry.NewGeometry()
 	geom.AddVBO(
 		gls.NewVBO(positions).
-			AddAttrib(gls.VertexPosition, 3).
-			AddAttrib(gls.VertexColor, 3),
+			AddAttrib(gls.VertexPosition).
+			AddAttrib(gls.VertexColor),
 	)
 
 	// Creates material

+ 1 - 1
graphic/normals_helper.go

@@ -41,7 +41,7 @@ func NewNormalsHelper(ig IGraphic, size float32, color *math32.Color, lineWidth
 	// Creates this helper geometry
 	geom := geometry.NewGeometry()
 	positions := math32.NewArrayF32(n, n)
-	geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition, 3))
+	geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
 
 	// Creates this helper material
 	mat := material.NewStandard(color)

+ 2 - 2
graphic/sprite.go

@@ -44,8 +44,8 @@ func NewSprite(width, height float32, imat material.IMaterial) *Sprite {
 	geom.SetIndices(indices)
 	geom.AddVBO(
 		gls.NewVBO(positions).
-			AddAttrib(gls.VertexPosition, 3).
-			AddAttrib(gls.VertexTexcoord, 2),
+			AddAttrib(gls.VertexPosition).
+			AddAttrib(gls.VertexTexcoord),
 	)
 
 	s.Graphic.Init(geom, gls.TRIANGLES)

+ 3 - 3
gui/chart.go

@@ -476,7 +476,7 @@ func newChartScaleX(chart *Chart, lines int, color *math32.Color) *chartScaleX {
 
 	// Creates geometry and adds VBO
 	geom := geometry.NewGeometry()
-	geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition, 3))
+	geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
 
 	// Initializes the panel graphic
 	gr := graphic.NewGraphic(geom, gls.LINES)
@@ -561,7 +561,7 @@ func newChartScaleY(chart *Chart, lines int, color *math32.Color) *chartScaleY {
 
 	// Creates geometry and adds VBO
 	geom := geometry.NewGeometry()
-	geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition, 3))
+	geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
 
 	// Initializes the panel with this graphic
 	gr := graphic.NewGraphic(geom, gls.LINES)
@@ -630,7 +630,7 @@ func newGraph(chart *Chart, color *math32.Color, data []float32) *Graph {
 	// Creates geometry and adds VBO with positions
 	geom := geometry.NewGeometry()
 	lg.positions = math32.NewArrayF32(0, 0)
-	lg.vbo = gls.NewVBO(lg.positions).AddAttrib(gls.VertexPosition, 3)
+	lg.vbo = gls.NewVBO(lg.positions).AddAttrib(gls.VertexPosition)
 	geom.AddVBO(lg.vbo)
 
 	// Initializes the panel with this graphic

+ 2 - 2
gui/panel.go

@@ -153,8 +153,8 @@ func (p *Panel) Initialize(width, height float32) {
 		geom := geometry.NewGeometry()
 		geom.SetIndices(indices)
 		geom.AddVBO(gls.NewVBO(positions).
-			AddAttrib(gls.VertexPosition, 3).
-			AddAttrib(gls.VertexTexcoord, 2),
+			AddAttrib(gls.VertexPosition).
+			AddAttrib(gls.VertexTexcoord),
 		)
 		panelQuadGeometry = geom
 	}

+ 5 - 5
loader/collada/geometry.go

@@ -285,16 +285,16 @@ func newMeshPolylist(m *Mesh, pels []interface{}) (*geometry.Geometry, uint32, e
 	geom := geometry.NewGeometry()
 
 	// Creates VBO with vertex positions
-	geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition, 3))
+	geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
 
 	// Creates VBO with vertex normals
 	if normals.Size() > 0 {
-		geom.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal, 3))
+		geom.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal))
 	}
 
 	// Creates VBO with uv coordinates
 	if uvs.Size() > 0 {
-		geom.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord, 2))
+		geom.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord))
 	}
 
 	// Sets the geometry indices buffer
@@ -383,7 +383,7 @@ func newMeshLines(m *Mesh, ln *Lines) (*geometry.Geometry, uint32, error) {
 	geom := geometry.NewGeometry()
 
 	// Creates VBO with vertex positions
-	geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition, 3))
+	geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
 
 	// Sets the geometry indices buffer
 	geom.SetIndices(indices)
@@ -436,7 +436,7 @@ func newMeshPoints(m *Mesh) (*geometry.Geometry, uint32, error) {
 
 	// Creates geometry and add VBO with vertex positions
 	geom := geometry.NewGeometry()
-	geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition, 3))
+	geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
 	return geom, gls.POINTS, nil
 }
 

+ 3 - 3
loader/obj/obj.go

@@ -259,9 +259,9 @@ func (dec *Decoder) NewGeometry(obj *Object) (*geometry.Geometry, error) {
 	}
 
 	geom.SetIndices(indices)
-	geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition, 3))
-	geom.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal, 3))
-	geom.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord, 2))
+	geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
+	geom.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal))
+	geom.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord))
 
 	return geom, nil
 }