mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-11 19:48:54 +01:00
example/piano: Speed up
This commit is contained in:
parent
8c2301e542
commit
9ec7b13f27
@ -103,6 +103,36 @@ func updateInput() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pianoImage *ebiten.Image
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
var err error
|
||||||
|
pianoImage, err = ebiten.NewImage(screenWidth, screenHeight, ebiten.FilterNearest)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
whiteKeys := []string{"A", "S", "D", "F", "G", "H", "J", "K", "L"}
|
||||||
|
width := 24
|
||||||
|
y := 48
|
||||||
|
for i, k := range whiteKeys {
|
||||||
|
x := i*width + 36
|
||||||
|
height := 112
|
||||||
|
pianoImage.DrawFilledRect(x, y, width-1, height, color.White)
|
||||||
|
common.ArcadeFont.DrawText(pianoImage, k, x+8, y+height-16, 1, color.Black)
|
||||||
|
}
|
||||||
|
|
||||||
|
blackKeys := []string{"Q", "W", "", "R", "T", "", "U", "I", "O"}
|
||||||
|
for i, k := range blackKeys {
|
||||||
|
if k == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
x := i*width + 24
|
||||||
|
height := 64
|
||||||
|
pianoImage.DrawFilledRect(x, y, width-1, height, color.Black)
|
||||||
|
common.ArcadeFont.DrawText(pianoImage, k, x+8, y+height-16, 1, color.White)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func update(screen *ebiten.Image) error {
|
func update(screen *ebiten.Image) error {
|
||||||
updateInput()
|
updateInput()
|
||||||
for i, key := range keys {
|
for i, key := range keys {
|
||||||
@ -113,27 +143,7 @@ func update(screen *ebiten.Image) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
screen.Fill(color.RGBA{0x80, 0x80, 0xc0, 0xff})
|
screen.Fill(color.RGBA{0x80, 0x80, 0xc0, 0xff})
|
||||||
|
screen.DrawImage(pianoImage, nil)
|
||||||
whiteKeys := []string{"A", "S", "D", "F", "G", "H", "J", "K", "L"}
|
|
||||||
width := 24
|
|
||||||
y := 48
|
|
||||||
for i, k := range whiteKeys {
|
|
||||||
x := i*width + 36
|
|
||||||
height := 112
|
|
||||||
screen.DrawFilledRect(x, y, width-1, height, color.White)
|
|
||||||
common.ArcadeFont.DrawText(screen, k, x+8, y+height-16, 1, color.Black)
|
|
||||||
}
|
|
||||||
|
|
||||||
blackKeys := []string{"Q", "W", "", "R", "T", "", "U", "I", "O"}
|
|
||||||
for i, k := range blackKeys {
|
|
||||||
if k == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
x := i*width + 24
|
|
||||||
height := 64
|
|
||||||
screen.DrawFilledRect(x, y, width-1, height, color.Black)
|
|
||||||
common.ArcadeFont.DrawText(screen, k, x+8, y+height-16, 1, color.White)
|
|
||||||
}
|
|
||||||
|
|
||||||
ebitenutil.DebugPrint(screen, fmt.Sprintf("FPS: %0.2f", ebiten.CurrentFPS()))
|
ebitenutil.DebugPrint(screen, fmt.Sprintf("FPS: %0.2f", ebiten.CurrentFPS()))
|
||||||
return nil
|
return nil
|
||||||
|
@ -18,8 +18,6 @@ var audioEnabled = false
|
|||||||
|
|
||||||
const SampleRate = 44100
|
const SampleRate = 44100
|
||||||
|
|
||||||
var currentPosition = 0
|
|
||||||
|
|
||||||
type channel struct {
|
type channel struct {
|
||||||
l []int16
|
l []int16
|
||||||
r []int16
|
r []int16
|
||||||
@ -143,10 +141,8 @@ func loadChannelBuffer(channel int, bufferSize int) (l, r []int16) {
|
|||||||
|
|
||||||
ch := channels[channel]
|
ch := channels[channel]
|
||||||
length := min(len(ch.l), bufferSize)
|
length := min(len(ch.l), bufferSize)
|
||||||
inputL := make([]int16, length)
|
inputL := ch.l[:length]
|
||||||
inputR := make([]int16, length)
|
inputR := ch.r[:length]
|
||||||
copy(inputL, ch.l[:length])
|
|
||||||
copy(inputR, ch.r[:length])
|
|
||||||
ch.l = ch.l[length:]
|
ch.l = ch.l[length:]
|
||||||
ch.r = ch.r[length:]
|
ch.r = ch.r[length:]
|
||||||
ch.nextInsertionPosition -= min(bufferSize, ch.nextInsertionPosition)
|
ch.nextInsertionPosition -= min(bufferSize, ch.nextInsertionPosition)
|
||||||
|
@ -33,28 +33,21 @@ var (
|
|||||||
|
|
||||||
const bufferSize = 1024
|
const bufferSize = 1024
|
||||||
|
|
||||||
func audioProcess(channel int) func(e js.Object) {
|
type audioProcessor struct {
|
||||||
return func(e js.Object) {
|
channel int
|
||||||
// Can't use 'go' here. Probably it may cause race conditions.
|
}
|
||||||
defer func() {
|
|
||||||
currentPosition += bufferSize
|
|
||||||
}()
|
|
||||||
|
|
||||||
b := e.Get("outputBuffer")
|
func (a *audioProcessor) Process(e js.Object) {
|
||||||
l := b.Call("getChannelData", 0)
|
// Can't use 'go' here. Probably it may cause race conditions.
|
||||||
r := b.Call("getChannelData", 1)
|
b := e.Get("outputBuffer")
|
||||||
inputL, inputR := loadChannelBuffer(channel, bufferSize)
|
l := b.Call("getChannelData", 0)
|
||||||
const max = 1 << 15
|
r := b.Call("getChannelData", 1)
|
||||||
for i := 0; i < bufferSize; i++ {
|
inputL, inputR := loadChannelBuffer(a.channel, bufferSize)
|
||||||
// TODO: Use copyToChannel?
|
const max = 1 << 15
|
||||||
if len(inputL) <= i {
|
for i := 0; i < len(inputL); i++ {
|
||||||
l.SetIndex(i, 0)
|
// TODO: Use copyToChannel?
|
||||||
r.SetIndex(i, 0)
|
l.SetIndex(i, float64(inputL[i])/max)
|
||||||
continue
|
r.SetIndex(i, float64(inputR[i])/max)
|
||||||
}
|
|
||||||
l.SetIndex(i, float64(inputL[i])/max)
|
|
||||||
r.SetIndex(i, float64(inputR[i])/max)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +62,8 @@ func initialize() {
|
|||||||
// https://developer.mozilla.org/ja/docs/Web/API/ScriptProcessorNode
|
// https://developer.mozilla.org/ja/docs/Web/API/ScriptProcessorNode
|
||||||
for i := 0; i < MaxChannel; i++ {
|
for i := 0; i < MaxChannel; i++ {
|
||||||
node := context.Call("createScriptProcessor", bufferSize, 0, 2)
|
node := context.Call("createScriptProcessor", bufferSize, 0, 2)
|
||||||
node.Call("addEventListener", "audioprocess", audioProcess(i))
|
processor := &audioProcessor{i}
|
||||||
|
node.Call("addEventListener", "audioprocess", processor.Process)
|
||||||
nodes = append(nodes, node)
|
nodes = append(nodes, node)
|
||||||
|
|
||||||
dummy := context.Call("createBufferSource")
|
dummy := context.Call("createBufferSource")
|
||||||
|
@ -53,10 +53,11 @@ func orthoProjectionMatrix(left, right, bottom, top int) *[4][4]float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Framebuffer struct {
|
type Framebuffer struct {
|
||||||
native opengl.Framebuffer
|
native opengl.Framebuffer
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
flipY bool
|
flipY bool
|
||||||
|
proMatrix *[4][4]float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewZeroFramebuffer(c *opengl.Context, width, height int) (*Framebuffer, error) {
|
func NewZeroFramebuffer(c *opengl.Context, width, height int) (*Framebuffer, error) {
|
||||||
@ -100,6 +101,9 @@ func (f *Framebuffer) setAsViewport(c *opengl.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *Framebuffer) projectionMatrix() *[4][4]float64 {
|
func (f *Framebuffer) projectionMatrix() *[4][4]float64 {
|
||||||
|
if f.proMatrix != nil {
|
||||||
|
return f.proMatrix
|
||||||
|
}
|
||||||
width := NextPowerOf2Int(f.width)
|
width := NextPowerOf2Int(f.width)
|
||||||
height := NextPowerOf2Int(f.height)
|
height := NextPowerOf2Int(f.height)
|
||||||
m := orthoProjectionMatrix(0, width, 0, height)
|
m := orthoProjectionMatrix(0, width, 0, height)
|
||||||
@ -107,7 +111,8 @@ func (f *Framebuffer) projectionMatrix() *[4][4]float64 {
|
|||||||
m[1][1] *= -1
|
m[1][1] *= -1
|
||||||
m[1][3] += float64(f.height) / float64(NextPowerOf2Int(f.height)) * 2
|
m[1][3] += float64(f.height) / float64(NextPowerOf2Int(f.height)) * 2
|
||||||
}
|
}
|
||||||
return m
|
f.proMatrix = m
|
||||||
|
return f.proMatrix
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Framebuffer) Fill(c *opengl.Context, clr color.Color) error {
|
func (f *Framebuffer) Fill(c *opengl.Context, clr color.Color) error {
|
||||||
|
Loading…
Reference in New Issue
Block a user