go - 使用闪亮的驱动程序将更改发布到窗口
问题描述
我需要显示image.RGBA
我正在运行的模拟生成的一系列帧,并且我正在尝试使用闪亮来这样做。在熟悉包的同时,我尝试运行一个简单的示例,与提供的示例非常相似,但我不明白背后的逻辑Window.Publish
,以及更改何时显示在屏幕上。
根据and的文档,Upload
Fill
填充 Window 时,在调用 Publish 之前不会有任何可见的效果。
但是,当我w.Publish
在上传缓冲区或填充窗口后调用时,我只看到一个黑色窗口。
奇怪的是,如果我在事件循环中使用相同的行上传或填充窗口,则窗口会更新:移动鼠标时我看到背景颜色发生变化,并且在调整窗口大小时绘制了正方形,即使我没有调用w.Publish
在事件循环内。
// create a Window
winSize := image.Point{900, 600}
w, err := s.NewWindow(&screen.NewWindowOptions{
Width: winSize.X,
Height: winSize.Y,
Title: "Viewer",
})
if err != nil {
log.Fatalf("s.NewWindow: %+v", err)
}
defer w.Release()
// create a Buffer
size0 := image.Point{30, 30}
b, err := s.NewBuffer(size0)
if err != nil {
log.Fatalf("s.NewBuffer: %+v", err)
}
defer b.Release()
// fill the buffer with a color
white := color.RGBA{255, 255, 255, 255}
draw.Draw(b.RGBA(), b.RGBA().Bounds(), &image.Uniform{white}, image.Point{0, 0}, draw.Src)
// draw the buffer on the window
w.Upload(image.Point{40, 40}, b, b.Bounds())
// publish the changes
w.Publish()
// at this point I see a black window
var sz size.Event
for {
e := w.NextEvent()
switch e := e.(type) {
default:
case key.Event:
if e.Code == key.CodeEscape {
return
}
case mouse.Event:
// this works, the background changes and the square is drawn
v := uint8(rand.Intn(255))
w.Fill(image.Rectangle{image.Point{}, winSize}, color.RGBA{v, v, v, 255}, draw.Src)
w.Upload(image.Point{30, 30}, b, b.Bounds())
case size.Event:
// this works, the background changes and the square is drawn
sz = e
w.Fill(sz.Bounds(), color.RGBA{80, 80, 80, 255}, draw.Src)
w.Upload(image.Point{30, 30}, b, b.Bounds())
case paint.Event:
log.Printf("paint.Event: %T %+v", e, e)
}
}
- 为什么调用发布时窗口没有更新?
- 为什么即使没有调用发布,窗口也会在循环内更新?
- 为什么一个
size
事件会产生一个paint
事件?我留下的那条日志行是在大小事件之后打印的,但不是mouse
事件。
如果使用纹理,将缓冲区上传到纹理,然后将纹理复制到窗口,也会发生同样的事情。
我只需要一个具有快速绘图和基本事件处理功能的最小 UI,而且这个包看起来非常易于使用,但如果有其他简单的选项,我可以接受。
编辑:
当我在 Ubuntu 20.04 上运行它时,我相信使用的驱动程序是 X11,所以我查看了 Publish的实现,并且有一条评论可以解释为什么调用 publish 不需要实际绘制,但对同步很有用:
func (w *windowImpl) Publish() screen.PublishResult {
// This sync isn't needed to flush the outgoing X11 requests. Instead, it
// acts as a form of flow control. Outgoing requests can be quite small on
// the wire, e.g. draw this texture ID (an integer) to this rectangle (four
// more integers), but much more expensive on the server (blending a
// million source and destination pixels). Without this sync, the Go X11
// client could easily end up sending work at a faster rate than the X11
// server can serve.
w.s.xc.Sync()
return screen.PublishResult{}
}
但我仍然不明白为什么即使使用显式发布调用,在循环外绘图也不起作用。
干杯!
解决方案
推荐阅读
- excel - 公式与显示结果不一致
- reactjs - 使用流星调用 API 资源
- angular - 如何在 TypeScript 或 Angular 类中使用 formElement.selectionStart 和 formElement.selectionEnd
- report - 如何在 IIS 上构建和托管 jsreport 服务器
- python-3.x - ModuleNotFoundError:尽管下载了硒,但没有名为“硒”的模块消息
- smartgit - 在 Smartgit 中启用“压缩更改显示”
- javascript - 新日期() - angular2+
- wordpress - 什么是带有可定制灯箱的好的 wordpress Gallery 插件?
- javascript - 将文件输入转换为 Base 64 后返回错误
- agora.io - 最低频道号是多少?agora web 支持吗?