add indices to vertex array
This commit is contained in:
parent
6268c52e77
commit
c87527aa5d
20
graphics.go
20
graphics.go
|
@ -114,9 +114,9 @@ func NewSprite(parent pixelgl.Doer, picture Picture) *Sprite {
|
||||||
s.va, err = pixelgl.NewVertexArray(
|
s.va, err = pixelgl.NewVertexArray(
|
||||||
picture.Texture(),
|
picture.Texture(),
|
||||||
ctx.Shader().VertexFormat(),
|
ctx.Shader().VertexFormat(),
|
||||||
pixelgl.TriangleFanDrawMode,
|
|
||||||
pixelgl.DynamicUsage,
|
pixelgl.DynamicUsage,
|
||||||
4,
|
4,
|
||||||
|
[]int{0, 1, 2, 0, 2, 3},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(errors.Wrap(err, "failed to create sprite"))
|
panic(errors.Wrap(err, "failed to create sprite"))
|
||||||
|
@ -231,9 +231,9 @@ func NewLineColor(parent pixelgl.Doer, c color.Color, a, b Vec, width float64) *
|
||||||
lc.va, err = pixelgl.NewVertexArray(
|
lc.va, err = pixelgl.NewVertexArray(
|
||||||
parent,
|
parent,
|
||||||
ctx.Shader().VertexFormat(),
|
ctx.Shader().VertexFormat(),
|
||||||
pixelgl.TriangleStripDrawMode,
|
|
||||||
pixelgl.DynamicUsage,
|
pixelgl.DynamicUsage,
|
||||||
4,
|
4,
|
||||||
|
[]int{0, 1, 2, 1, 2, 3},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(errors.Wrap(err, "failed to create line"))
|
panic(errors.Wrap(err, "failed to create line"))
|
||||||
|
@ -340,14 +340,19 @@ func NewPolygonColor(parent pixelgl.Doer, c color.Color, points ...Vec) *Polygon
|
||||||
points: points,
|
points: points,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var indices []int
|
||||||
|
for i := 2; i < len(points); i++ {
|
||||||
|
indices = append(indices, 0, i-1, i)
|
||||||
|
}
|
||||||
|
|
||||||
parent.Do(func(ctx pixelgl.Context) {
|
parent.Do(func(ctx pixelgl.Context) {
|
||||||
var err error
|
var err error
|
||||||
pc.va, err = pixelgl.NewVertexArray(
|
pc.va, err = pixelgl.NewVertexArray(
|
||||||
parent,
|
parent,
|
||||||
ctx.Shader().VertexFormat(),
|
ctx.Shader().VertexFormat(),
|
||||||
pixelgl.TriangleFanDrawMode,
|
|
||||||
pixelgl.DynamicUsage,
|
pixelgl.DynamicUsage,
|
||||||
len(points),
|
len(points),
|
||||||
|
indices,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(errors.Wrap(err, "failed to create polygon"))
|
panic(errors.Wrap(err, "failed to create polygon"))
|
||||||
|
@ -448,17 +453,22 @@ func NewEllipseColor(parent pixelgl.Doer, c color.Color, radius Vec, fill float6
|
||||||
fill: fill,
|
fill: fill,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var indices []int
|
||||||
|
for i := 2; i < (n+1)*2; i++ {
|
||||||
|
indices = append(indices, i-2, i-1, i)
|
||||||
|
}
|
||||||
|
|
||||||
parent.Do(func(ctx pixelgl.Context) {
|
parent.Do(func(ctx pixelgl.Context) {
|
||||||
var err error
|
var err error
|
||||||
ec.va, err = pixelgl.NewVertexArray(
|
ec.va, err = pixelgl.NewVertexArray(
|
||||||
parent,
|
parent,
|
||||||
ctx.Shader().VertexFormat(),
|
ctx.Shader().VertexFormat(),
|
||||||
pixelgl.TriangleStripDrawMode,
|
|
||||||
pixelgl.DynamicUsage,
|
pixelgl.DynamicUsage,
|
||||||
(n+1)*2,
|
(n+1)*2,
|
||||||
|
indices,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(errors.Wrap(err, "failed to create circle"))
|
panic(errors.Wrap(err, "failed to create ellipse"))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -40,55 +40,31 @@ const (
|
||||||
StreamUsage VertexUsage = gl.STREAM_DRAW
|
StreamUsage VertexUsage = gl.STREAM_DRAW
|
||||||
)
|
)
|
||||||
|
|
||||||
// VertexDrawMode specifies how should the vertices be drawn.
|
|
||||||
type VertexDrawMode int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// PointsDrawMode just draws individual points
|
|
||||||
PointsDrawMode VertexDrawMode = gl.POINTS
|
|
||||||
|
|
||||||
// LinesDrawMode takes pairs of vertices and draws a line from each pair
|
|
||||||
LinesDrawMode VertexDrawMode = gl.LINES
|
|
||||||
|
|
||||||
// LineStripDrawMode takes each two subsequent vertices and draws a line from each two
|
|
||||||
LineStripDrawMode VertexDrawMode = gl.LINE_STRIP
|
|
||||||
|
|
||||||
// LineLoopDrawMode is same as line strip, but also draws a line between the first and the last vertex
|
|
||||||
LineLoopDrawMode VertexDrawMode = gl.LINE_LOOP
|
|
||||||
|
|
||||||
// TrianglesDrawMode takes triples of vertices and draws a triangle from each triple
|
|
||||||
TrianglesDrawMode VertexDrawMode = gl.TRIANGLES
|
|
||||||
|
|
||||||
// TriangleStripDrawMode takes each three subsequent vertices and draws a triangle from each three
|
|
||||||
TriangleStripDrawMode VertexDrawMode = gl.TRIANGLE_STRIP
|
|
||||||
|
|
||||||
// TriangleFanDrawMode draws triangles from the first vertex and each two subsequent: {0, 1, 2, 3} -> {0, 1, 2}, {0, 2, 3}.
|
|
||||||
TriangleFanDrawMode VertexDrawMode = gl.TRIANGLE_FAN
|
|
||||||
)
|
|
||||||
|
|
||||||
// VertexArray is an OpenGL vertex array object that also holds it's own vertex buffer object.
|
// VertexArray is an OpenGL vertex array object that also holds it's own vertex buffer object.
|
||||||
// From the user's points of view, VertexArray is an array of vertices that can be drawn.
|
// From the user's points of view, VertexArray is an array of vertices that can be drawn.
|
||||||
type VertexArray struct {
|
type VertexArray struct {
|
||||||
enabled bool
|
enabled bool
|
||||||
parent Doer
|
parent Doer
|
||||||
vao uint32
|
vao, vbo, ebo uint32
|
||||||
vbo uint32
|
vertexNum, indexNum int
|
||||||
format VertexFormat
|
format VertexFormat
|
||||||
stride int
|
usage VertexUsage
|
||||||
count int
|
stride int
|
||||||
attrs map[Attr]int
|
attrs map[Attr]int
|
||||||
mode VertexDrawMode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewVertexArray creates a new empty vertex array and wraps another Doer around it.
|
// NewVertexArray creates a new empty vertex array and wraps another Doer around it.
|
||||||
func NewVertexArray(parent Doer, format VertexFormat, mode VertexDrawMode, usage VertexUsage, count int) (*VertexArray, error) {
|
//
|
||||||
|
// You cannot specify vertex attributes in this constructor, only their count. Use SetVertexAttribute* methods to
|
||||||
|
// set the vertex attributes. Use indices to specify how you want to combine vertices into triangles.
|
||||||
|
func NewVertexArray(parent Doer, format VertexFormat, usage VertexUsage, vertexNum int, indices []int) (*VertexArray, error) {
|
||||||
va := &VertexArray{
|
va := &VertexArray{
|
||||||
parent: parent,
|
parent: parent,
|
||||||
format: format,
|
format: format,
|
||||||
count: count,
|
usage: usage,
|
||||||
stride: format.Size(),
|
vertexNum: vertexNum,
|
||||||
attrs: make(map[Attr]int),
|
stride: format.Size(),
|
||||||
mode: mode,
|
attrs: make(map[Attr]int),
|
||||||
}
|
}
|
||||||
|
|
||||||
offset := 0
|
offset := 0
|
||||||
|
@ -105,18 +81,19 @@ func NewVertexArray(parent Doer, format VertexFormat, mode VertexDrawMode, usage
|
||||||
offset += attr.Type.Size()
|
offset += attr.Type.Size()
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
|
||||||
parent.Do(func(ctx Context) {
|
parent.Do(func(ctx Context) {
|
||||||
err = DoErr(func() error {
|
Do(func() {
|
||||||
gl.GenVertexArrays(1, &va.vao)
|
gl.GenVertexArrays(1, &va.vao)
|
||||||
gl.BindVertexArray(va.vao)
|
gl.BindVertexArray(va.vao)
|
||||||
|
|
||||||
gl.GenBuffers(1, &va.vbo)
|
gl.GenBuffers(1, &va.vbo)
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, va.vbo)
|
gl.BindBuffer(gl.ARRAY_BUFFER, va.vbo)
|
||||||
|
|
||||||
emptyData := make([]byte, count*va.stride)
|
emptyData := make([]byte, vertexNum*va.stride)
|
||||||
gl.BufferData(gl.ARRAY_BUFFER, len(emptyData), gl.Ptr(emptyData), uint32(usage))
|
gl.BufferData(gl.ARRAY_BUFFER, len(emptyData), gl.Ptr(emptyData), uint32(usage))
|
||||||
|
|
||||||
|
gl.GenBuffers(1, &va.ebo)
|
||||||
|
|
||||||
offset := 0
|
offset := 0
|
||||||
for i, attr := range format {
|
for i, attr := range format {
|
||||||
var size int32
|
var size int32
|
||||||
|
@ -143,15 +120,16 @@ func NewVertexArray(parent Doer, format VertexFormat, mode VertexDrawMode, usage
|
||||||
offset += attr.Type.Size()
|
offset += attr.Type.Size()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, va.ebo) // need to bind EBO, so that VAO registers it
|
||||||
|
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
||||||
gl.BindVertexArray(0)
|
gl.BindVertexArray(0)
|
||||||
|
|
||||||
return nil
|
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to create vertex array")
|
va.SetIndices(indices)
|
||||||
}
|
|
||||||
|
|
||||||
return va, nil
|
return va, nil
|
||||||
}
|
}
|
||||||
|
@ -173,7 +151,7 @@ func (va *VertexArray) ID() uint32 {
|
||||||
|
|
||||||
// Count returns the number of vertices in a vertex array.
|
// Count returns the number of vertices in a vertex array.
|
||||||
func (va *VertexArray) Count() int {
|
func (va *VertexArray) Count() int {
|
||||||
return va.count
|
return va.vertexNum
|
||||||
}
|
}
|
||||||
|
|
||||||
// VertexFormat returns the format of the vertices inside a vertex array.
|
// VertexFormat returns the format of the vertices inside a vertex array.
|
||||||
|
@ -183,19 +161,9 @@ func (va *VertexArray) VertexFormat() VertexFormat {
|
||||||
return va.format
|
return va.format
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDrawMode sets the draw mode of a vertex array. Subsequent calls to Draw will use this draw mode.
|
// VertexUsage returns the usage of the verteices inside a vertex array.
|
||||||
func (va *VertexArray) SetDrawMode(mode VertexDrawMode) {
|
func (va *VertexArray) VertexUsage() VertexUsage {
|
||||||
DoNoBlock(func() {
|
return va.usage
|
||||||
va.mode = mode
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// DrawMode returns the most recently set draw mode of a vertex array.
|
|
||||||
func (va *VertexArray) DrawMode() VertexDrawMode {
|
|
||||||
mode := DoVal(func() interface{} {
|
|
||||||
return va.mode
|
|
||||||
})
|
|
||||||
return mode.(VertexDrawMode)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw draws a vertex array.
|
// Draw draws a vertex array.
|
||||||
|
@ -203,10 +171,29 @@ func (va *VertexArray) Draw() {
|
||||||
va.Do(func(Context) {})
|
va.Do(func(Context) {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetIndices sets the indices of triangles to be drawn. Triangles will be formed from the vertices of the array
|
||||||
|
// as defined by these indices. The first drawn triangle is specified by the first three indices, the second by
|
||||||
|
// the fourth through sixth and so on.
|
||||||
|
func (va *VertexArray) SetIndices(indices []int) {
|
||||||
|
if len(indices)%3 != 0 {
|
||||||
|
panic("vertex array set indices: number of indices not divisible by 3")
|
||||||
|
}
|
||||||
|
indices32 := make([]uint32, len(indices))
|
||||||
|
for i := range indices32 {
|
||||||
|
indices32[i] = uint32(indices[i])
|
||||||
|
}
|
||||||
|
va.indexNum = len(indices32)
|
||||||
|
DoNoBlock(func() {
|
||||||
|
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, va.ebo)
|
||||||
|
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, 4*len(indices32), gl.Ptr(indices32), uint32(va.usage))
|
||||||
|
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// SetVertex sets the value of all attributes of a vertex.
|
// SetVertex sets the value of all attributes of a vertex.
|
||||||
// Argument data must be a slice/array containing the new vertex data.
|
// Argument data must be a slice/array containing the new vertex data.
|
||||||
func (va *VertexArray) SetVertex(vertex int, data interface{}) {
|
func (va *VertexArray) SetVertex(vertex int, data interface{}) {
|
||||||
if vertex < 0 || vertex >= va.count {
|
if vertex < 0 || vertex >= va.vertexNum {
|
||||||
panic("set vertex error: invalid vertex index")
|
panic("set vertex error: invalid vertex index")
|
||||||
}
|
}
|
||||||
DoNoBlock(func() {
|
DoNoBlock(func() {
|
||||||
|
@ -220,7 +207,7 @@ func (va *VertexArray) SetVertex(vertex int, data interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (va *VertexArray) checkVertex(vertex int) {
|
func (va *VertexArray) checkVertex(vertex int) {
|
||||||
if vertex < 0 || vertex >= va.count {
|
if vertex < 0 || vertex >= va.vertexNum {
|
||||||
panic("invalid vertex index")
|
panic("invalid vertex index")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,14 +309,12 @@ func (va *VertexArray) Do(sub func(Context)) {
|
||||||
}
|
}
|
||||||
DoNoBlock(func() {
|
DoNoBlock(func() {
|
||||||
gl.BindVertexArray(va.vao)
|
gl.BindVertexArray(va.vao)
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, va.vbo)
|
|
||||||
})
|
})
|
||||||
va.enabled = true
|
va.enabled = true
|
||||||
sub(ctx)
|
sub(ctx)
|
||||||
va.enabled = false
|
va.enabled = false
|
||||||
DoNoBlock(func() {
|
DoNoBlock(func() {
|
||||||
gl.DrawArrays(uint32(va.mode), 0, int32(va.count))
|
gl.DrawElements(gl.TRIANGLES, int32(va.indexNum), gl.UNSIGNED_INT, gl.PtrOffset(0))
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
|
||||||
gl.BindVertexArray(0)
|
gl.BindVertexArray(0)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
21
window.go
21
window.go
|
@ -53,6 +53,7 @@ type WindowConfig struct {
|
||||||
|
|
||||||
// Window is a window handler. Use this type to manipulate a window (input, drawing, ...).
|
// Window is a window handler. Use this type to manipulate a window (input, drawing, ...).
|
||||||
type Window struct {
|
type Window struct {
|
||||||
|
enabled bool
|
||||||
window *glfw.Window
|
window *glfw.Window
|
||||||
config WindowConfig
|
config WindowConfig
|
||||||
contextHolder pixelgl.ContextHolder
|
contextHolder pixelgl.ContextHolder
|
||||||
|
@ -314,22 +315,26 @@ var currentWindow struct {
|
||||||
|
|
||||||
// Do makes the context of this window current, if it's not already, and executes sub.
|
// Do makes the context of this window current, if it's not already, and executes sub.
|
||||||
func (w *Window) Do(sub func(pixelgl.Context)) {
|
func (w *Window) Do(sub func(pixelgl.Context)) {
|
||||||
currentWindow.Lock()
|
if !w.enabled {
|
||||||
defer currentWindow.Unlock()
|
currentWindow.Lock()
|
||||||
|
defer currentWindow.Unlock()
|
||||||
|
|
||||||
if currentWindow.handler != w {
|
if currentWindow.handler != w {
|
||||||
pixelgl.Do(func() {
|
pixelgl.Do(func() {
|
||||||
w.window.MakeContextCurrent()
|
w.window.MakeContextCurrent()
|
||||||
pixelgl.Init()
|
pixelgl.Init()
|
||||||
})
|
})
|
||||||
currentWindow.handler = w
|
currentWindow.handler = w
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
w.enabled = true
|
||||||
if w.defaultShader != nil {
|
if w.defaultShader != nil {
|
||||||
w.defaultShader.Do(sub)
|
w.defaultShader.Do(sub)
|
||||||
} else {
|
} else {
|
||||||
w.contextHolder.Do(sub)
|
w.contextHolder.Do(sub)
|
||||||
}
|
}
|
||||||
|
w.enabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultVertexFormat = pixelgl.VertexFormat{
|
var defaultVertexFormat = pixelgl.VertexFormat{
|
||||||
|
|
Loading…
Reference in New Issue