在 Golang 中绘制像素缓冲区到框架的跨平台方式?

假设我有一个内存位图/像素网格,我想在某种窗口中将它们全部写到屏幕上。例如:


[

 [255,0,0],[200,100,100]...

 [255,0,100],[155,200,100]...

 ...

]

有没有一种简单而高效的方法来做到这一点?我很乐意使用 OpenGL 或 Vulkan,但它们在这里似乎有点矫枉过正。任何仍然允许我捕获鼠标/键盘输入的东西的奖励积分,但如果它使事情复杂化,我很乐意自己管理这部分。我个人在 Linux 上工作,如果它不能移植到 Windows,我也可以接受,但这会很好。


编辑:只是根据 Ben Hoyt 的评论对此进行了更新 - 我的目标是提供令人耳目一新的框架,将用例想象成编写 GIF 播放器。给定一组这些帧,我想按顺序显示它们,并在它们之间显示一个相当低的显示。


白猪掌柜的
浏览 99回答 2
2回答

暮色呼如

如果您的目标只是将图像加载到屏幕上,这里有一种使用 OpenGL 和 GLFW 的直接方法。您可以使用像 Fyne 这样的库来执行此操作,但它已经在内部使用了 OpenGL 和 GLFW(以及许多其他依赖项),因此您最好去掉中间人。这是我的样板程序,它使用 OpenGL 纹理和帧缓冲区将图像 blits 到屏幕。package mainimport (    "image"    "runtime"    "github.com/go-gl/gl/all-core/gl"    "github.com/go-gl/glfw/v3.3/glfw")func init() {    // GLFW: This is needed to arrange that main() runs on main thread.    // See documentation for functions that are only allowed to be called from the main thread.    runtime.LockOSThread()}func main() {    err := glfw.Init()    if err != nil {        panic(err)    }    defer glfw.Terminate()    window, err := glfw.CreateWindow(640, 480, "My Window", nil, nil)    if err != nil {        panic(err)    }    window.MakeContextCurrent()    err = gl.Init()    if err != nil {        panic(err)    }    var texture uint32    {        gl.GenTextures(1, &texture)        gl.BindTexture(gl.TEXTURE_2D, texture)        gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)        gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)        gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)        gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)        gl.BindImageTexture(0, texture, 0, false, 0, gl.WRITE_ONLY, gl.RGBA8)    }    var framebuffer uint32    {        gl.GenFramebuffers(1, &framebuffer)        gl.BindFramebuffer(gl.FRAMEBUFFER, framebuffer)        gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0)        gl.BindFramebuffer(gl.READ_FRAMEBUFFER, framebuffer)        gl.BindFramebuffer(gl.DRAW_FRAMEBUFFER, 0)    }    for !window.ShouldClose() {        var w, h = window.GetSize()        var img = image.NewRGBA(image.Rect(0, 0, w, h))        // -------------------------        // MODIFY OR LOAD IMAGE HERE        // -------------------------        gl.BindTexture(gl.TEXTURE_2D, texture)        gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, int32(w), int32(h), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(img.Pix))        gl.BlitFramebuffer(0, 0, int32(w), int32(h), 0, 0, int32(w), int32(h), gl.COLOR_BUFFER_BIT, gl.LINEAR)        window.SwapBuffers()        glfw.PollEvents()    }}

隔江千里

我最终为此使用了 Fyne,以支持跨平台和支持快速刷新的目标。如果有人知道在屏幕上放置像素缓冲区的本机方法,请随时在这里发表评论,但这看起来非常轻量级并且本机适用于 Go。关于如何正确执行此操作的我的 GHI 可以在这里看到:https ://github.com/fyne-io/fyne/issues/3052以 60 FPS 播放大量连续光栅帧:https://i.stack.imgur.com/YkcFW.gif
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go