在SDL Go程序中复制纹理时运行时出现恐慌

huangapple go评论82阅读模式
英文:

Runtime panic when copying texture in SDL Go program

问题

我有一个使用SDL2的Go程序,试图将像素数组写入屏幕。当我尝试使用新的像素更新纹理时,程序会出现运行时错误:

fatal error: unexpected signal during runtime execution

不幸的是,我几乎找不到关于如何在Go中传递不安全指针的文档,而且我不确定我是否正确处理了这个问题。下面是一个展示了这个问题的示例代码:

func main() {
    window := sdl.CreateWindow("test", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
        800, 600, sdl.WINDOW_SHOWN)
    renderer := sdl.CreateRenderer(window, -1, 0)
    texture := sdl.CreateTexture(renderer, sdl.PIXELFORMAT_ARGB8888,
        sdl.TEXTUREACCESS_STATIC, 800, 600)

    defer renderer.Destroy()
    defer texture.Destroy()
    defer window.Destroy()

    for {
        pixels := make([]uint32, 800*600)

        texture.Update(nil, unsafe.Pointer(&pixels), int(800*unsafe.Sizeof(pixels)))
        window.UpdateSurface()

        renderer.Clear()
        renderer.Copy(texture, nil, nil)
        renderer.Present()
    }

    sdl.Delay(1000)
    sdl.Quit()
}

这段代码可以编译通过,但运行时会产生一个恐慌错误,但我无法在这段代码中看到导致错误的原因。

我正在使用这些SDL2 Go绑定:https://github.com/veandco/go-sdl2

英文:

I have an SDL2 go program which tries to write a pixel array to the screen. When I try and update the texture with the new pixels the program panics with a runtime error:

fatal error: unexpected signal during runtime execution

Unfortunately I can find little to no documentation about how to pass around unsafe pointers in Go and I'm not sure if I'm approaching this correctly, here is some example code that exhibits the problem:

func main() {
	window := sdl.CreateWindow("test", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
		800, 600, sdl.WINDOW_SHOWN)
	renderer := sdl.CreateRenderer(window, -1, 0)
	texture := sdl.CreateTexture(renderer, sdl.PIXELFORMAT_ARGB8888,
		sdl.TEXTUREACCESS_STATIC, 800, 600)

	defer renderer.Destroy()
	defer texture.Destroy()
	defer window.Destroy()

	for {
		pixels := make([]uint32, 800*600)

		texture.Update(nil, unsafe.Pointer(&pixels), int(800*unsafe.Sizeof(pixels)))
		window.UpdateSurface()

		renderer.Clear()
		renderer.Copy(texture, nil, nil)
		renderer.Present()
	}

	sdl.Delay(1000)
	sdl.Quit()
}

This code will compile with no errors, but when ran it will produce a runtime panic, but I can't see what would cause that in this code.

I am using these SDL2 Go bindings: https://github.com/veandco/go-sdl2

答案1

得分: 2

pitch参数预计接受表面的宽度* sizeof(int32),就我所知,此代码可以工作并在每个循环中打印随机像素:

func main() {
    window, err := sdl.CreateWindow("test", sdl.WINDOWPOS_UNDEFINED,
        sdl.WINDOWPOS_UNDEFINED, 800, 600, sdl.WINDOW_SHOWN)
    if err != nil {
        log.Fatal(err)
    }
    defer window.Destroy()

    renderer, err := sdl.CreateRenderer(window, -1, 0)
    if err != nil {
        log.Fatal(err)
    }
    defer renderer.Destroy()

    texture, err := renderer.CreateTexture(sdl.PIXELFORMAT_ARGB8888,
        sdl.TEXTUREACCESS_STATIC, 800, 600)

    if err != nil {
        log.Fatal(err)
    }
    defer texture.Destroy()

    pixels := make([]uint32, 800*600)
L:
    for {
        for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
            if _, ok := event.(*sdl.QuitEvent); ok {
                break L
            }
        }
        for i := range pixels {
            pixels[i] = 0x00777777 + uint32(rand.Intn(0x00AAAAAA))
        }
        //4 == sizeof(int32), unsafe.Sizeof(pixels) returns the actual size of
        //the slice header which is 24
        texture.Update(nil, unsafe.Pointer(&pixels[0]), 800*4)
        window.UpdateSurface()

        renderer.Clear()
        renderer.Copy(texture, nil, nil)
        renderer.Present()
    }

    sdl.Delay(1000)
    sdl.Quit()
}

//编辑应该是unsafe.Pointer(&pixels[0])而不是unsafe.Pointer(&pixels)

英文:

The pitch parameter expects the surface's width * sizeof(int32) as far as I can, this code works and prints random pixels every loop:

func main() {
window, err := sdl.CreateWindow("test", sdl.WINDOWPOS_UNDEFINED,
sdl.WINDOWPOS_UNDEFINED, 800, 600, sdl.WINDOW_SHOWN)
if err != nil {
log.Fatal(err)
}
defer window.Destroy()
renderer, err := sdl.CreateRenderer(window, -1, 0)
if err != nil {
log.Fatal(err)
}
defer renderer.Destroy()
texture, err := renderer.CreateTexture(sdl.PIXELFORMAT_ARGB8888,
sdl.TEXTUREACCESS_STATIC, 800, 600)
if err != nil {
log.Fatal(err)
}
defer texture.Destroy()
pixels := make([]uint32, 800*600)
L:
for {
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
if _, ok := event.(*sdl.QuitEvent); ok {
break L
}
}
for i := range pixels {
pixels[i] = 0x00777777 + uint32(rand.Intn(0x00AAAAAA))
}
//4 == sizeof(int32), unsafe.Sizeof(pixels) returns the actual size of
//the slice header which is 24
texture.Update(nil, unsafe.Pointer(&pixels[0]), 800*4)
window.UpdateSurface()
renderer.Clear()
renderer.Copy(texture, nil, nil)
renderer.Present()
}
sdl.Delay(1000)
sdl.Quit()
}

//edit it should be unsafe.Pointer(&pixels[0]) not unsafe.Pointer(&pixels).

huangapple
  • 本文由 发表于 2014年8月15日 18:54:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/25325229.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定