mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-11 19:48:54 +01:00
graphics: Enable to draw unlimited number of sprites (#245)
This commit is contained in:
parent
d00eb131f4
commit
66f262c80e
@ -98,20 +98,20 @@ func (s Sprites) Src(i int) (x0, y0, x1, y1 int) {
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
MinSprites = 0
|
MinSprites = 0
|
||||||
MaxSprites = 10000
|
MaxSprites = 50000
|
||||||
)
|
)
|
||||||
|
|
||||||
var sprites = &Sprites{make([]*Sprite, MaxSprites), 500}
|
var sprites = &Sprites{make([]*Sprite, MaxSprites), 500}
|
||||||
|
|
||||||
func update(screen *ebiten.Image) error {
|
func update(screen *ebiten.Image) error {
|
||||||
if ebiten.IsKeyPressed(ebiten.KeyLeft) {
|
if ebiten.IsKeyPressed(ebiten.KeyLeft) {
|
||||||
sprites.num -= 20
|
sprites.num -= 100
|
||||||
if sprites.num < MinSprites {
|
if sprites.num < MinSprites {
|
||||||
sprites.num = MinSprites
|
sprites.num = MinSprites
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ebiten.IsKeyPressed(ebiten.KeyRight) {
|
if ebiten.IsKeyPressed(ebiten.KeyRight) {
|
||||||
sprites.num += 20
|
sprites.num += 100
|
||||||
if MaxSprites < sprites.num {
|
if MaxSprites < sprites.num {
|
||||||
sprites.num = MaxSprites
|
sprites.num = MaxSprites
|
||||||
}
|
}
|
||||||
|
@ -58,13 +58,43 @@ func (q *commandQueue) Enqueue(command command) {
|
|||||||
q.commands = append(q.commands, command)
|
q.commands = append(q.commands, command)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (q *commandQueue) commandGroups() [][]command {
|
||||||
|
cs := make([]command, len(q.commands))
|
||||||
|
copy(cs, q.commands)
|
||||||
|
gs := [][]command{}
|
||||||
|
quads := 0
|
||||||
|
for 0 < len(cs) {
|
||||||
|
if len(gs) == 0 {
|
||||||
|
gs = append(gs, []command{})
|
||||||
|
}
|
||||||
|
c := cs[0]
|
||||||
|
switch c := c.(type) {
|
||||||
|
case *drawImageCommand:
|
||||||
|
if maxQuads >= quads+c.quadsNum() {
|
||||||
|
quads += c.quadsNum()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
cc := c.split(maxQuads - quads)
|
||||||
|
gs[len(gs)-1] = append(gs[len(gs)-1], cc[0])
|
||||||
|
cs[0] = cc[1]
|
||||||
|
quads = 0
|
||||||
|
gs = append(gs, []command{})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
gs[len(gs)-1] = append(gs[len(gs)-1], c)
|
||||||
|
cs = cs[1:]
|
||||||
|
}
|
||||||
|
return gs
|
||||||
|
}
|
||||||
|
|
||||||
func (q *commandQueue) Flush(context *opengl.Context) error {
|
func (q *commandQueue) Flush(context *opengl.Context) error {
|
||||||
q.m.Lock()
|
q.m.Lock()
|
||||||
defer q.m.Unlock()
|
defer q.m.Unlock()
|
||||||
// glViewport must be called at least at every frame on iOS.
|
// glViewport must be called at least at every frame on iOS.
|
||||||
context.ResetViewportSize()
|
context.ResetViewportSize()
|
||||||
|
for _, g := range q.commandGroups() {
|
||||||
vertices := []int16{}
|
vertices := []int16{}
|
||||||
for _, c := range q.commands {
|
for _, c := range g {
|
||||||
switch c := c.(type) {
|
switch c := c.(type) {
|
||||||
case *drawImageCommand:
|
case *drawImageCommand:
|
||||||
vertices = append(vertices, c.vertices...)
|
vertices = append(vertices, c.vertices...)
|
||||||
@ -78,9 +108,9 @@ func (q *commandQueue) Flush(context *opengl.Context) error {
|
|||||||
if maxQuads < len(vertices)/16 {
|
if maxQuads < len(vertices)/16 {
|
||||||
return errors.New(fmt.Sprintf("len(quads) must be equal to or less than %d", maxQuads))
|
return errors.New(fmt.Sprintf("len(quads) must be equal to or less than %d", maxQuads))
|
||||||
}
|
}
|
||||||
numc := len(q.commands)
|
numc := len(g)
|
||||||
indexOffsetInBytes := 0
|
indexOffsetInBytes := 0
|
||||||
for _, c := range q.commands {
|
for _, c := range g {
|
||||||
if err := c.Exec(context, indexOffsetInBytes); err != nil {
|
if err := c.Exec(context, indexOffsetInBytes); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -88,11 +118,12 @@ func (q *commandQueue) Flush(context *opengl.Context) error {
|
|||||||
indexOffsetInBytes += 6 * len(c.vertices) / 16 * 2
|
indexOffsetInBytes += 6 * len(c.vertices) / 16 * 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
q.commands = []command{}
|
|
||||||
if 0 < numc {
|
if 0 < numc {
|
||||||
// Call glFlush to prevent black flicking (especially on Android (#226) and iOS).
|
// Call glFlush to prevent black flicking (especially on Android (#226) and iOS).
|
||||||
context.Flush()
|
context.Flush()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
q.commands = []command{}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +164,7 @@ func (c *drawImageCommand) Exec(context *opengl.Context, indexOffsetInBytes int)
|
|||||||
}
|
}
|
||||||
context.BlendFunc(c.mode)
|
context.BlendFunc(c.mode)
|
||||||
|
|
||||||
n := len(c.vertices) / 16
|
n := c.quadsNum()
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -156,6 +187,18 @@ func (c *drawImageCommand) Exec(context *opengl.Context, indexOffsetInBytes int)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *drawImageCommand) split(quadsNum int) [2]*drawImageCommand {
|
||||||
|
c1 := *c
|
||||||
|
c2 := *c
|
||||||
|
c1.vertices = c.vertices[:quadsNum*16]
|
||||||
|
c2.vertices = c.vertices[quadsNum*16:]
|
||||||
|
return [2]*drawImageCommand{&c1, &c2}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *drawImageCommand) quadsNum() int {
|
||||||
|
return len(c.vertices) / 16
|
||||||
|
}
|
||||||
|
|
||||||
type replacePixelsCommand struct {
|
type replacePixelsCommand struct {
|
||||||
dst *Image
|
dst *Image
|
||||||
pixels []uint8
|
pixels []uint8
|
||||||
|
@ -61,7 +61,6 @@ func (p *pixels) fill(clr color.Color) {
|
|||||||
|
|
||||||
func (p *pixels) appendDrawImageHistory(item *drawImageHistoryItem) {
|
func (p *pixels) appendDrawImageHistory(item *drawImageHistoryItem) {
|
||||||
p.drawImageHistory = append(p.drawImageHistory, item)
|
p.drawImageHistory = append(p.drawImageHistory, item)
|
||||||
// TODO: Consider the number of the vertices, which should not exceed the max number (#245).
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pixels) at(image *graphics.Image, idx int, context *opengl.Context) (color.Color, error) {
|
func (p *pixels) at(image *graphics.Image, idx int, context *opengl.Context) (color.Color, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user