[Feature Request] support integration with go-sdl2 binding?
Related problem
No response
Your request
I know that giu can work with sdl2 backend, but it goes with sdl2 cgo, right? Is it possible to integrate giu with go-sdl2 ((https://github.com/veandco/go-sdl2) ? I mean, seamlessly. yesterday I gave it a try and it seems they two have their owen deps, and work independently.
Alternative solution
No response
Additional context
No response
you can deffinitly integrate cimgui-go with go-sdl if you want (however idk why would you need this as ther is an sdl backend already - I'm not a big fan of it but iirc @AllenDang had some reasons to do this with CGO for glfw and I did similar thing for sdl).
In case of giu - Technically its 100% possible to make giu use sdl instead of glfw, but it wan't tested yet :smile:. You can be the first one who tries.
(I think laud here): Technically you need to override giu.Context.backend with sdlbackend from cimgui-go. The problem is that backdne.Backend is a generic type so this might be difficult to write this variable in giu :thinking: if you change
// before
type GIUContext struct {
backend backend.Backend[glfwbackend.GLFWWindowFlags]
// after
type GIUContext[FLAGST ~int] struct {
backend backend.Backend[FLAGST]
Now it will be difficutl to define giu.Context variable's type
This might require some cimgui-go refactor as well
Here's my scenario: I've been working on a go-sdl2 project for a couple of days, it goes well, then I want to add a gui toolset for it, so I found giu. the demo was pretty cute, exactly what I'm looking for. I think there should be more gl-sdl2 users thinking about the same thing.
unfortunately, once I introduce giu into the project, my go-sdl2 program keeps throwing unknown errors. I mean, some of the go-sdl2 api stop working and give me an empty error. those errors are all gone if I eliminate giu code.
After some debugging, I realized that the two projects were not working the way I expected.
Thanks for you suggestion. giu is quite a new thing to me, I'll dig for a while see if I can make it~
@shellohunter as far as I see, the thing you're looking for is rather cimgui-go, not giu. We try to keep giu as simple as possible. Especially we want users don't need to care about so called backend (opengl/glfw/sdl things) so giu is really top-level. We can ofc consider adding some features to change backend (as long as it is fully optional)
Generally first of all you need to implement your use-case with cimgui-go
yes, you would be right. I thought cimgui-go was a auto-generated binding, so i post it here since giu is more active, :-) actually I also tried cimgui-go with go-sdl2, and I got the same errors. so, the situation is pretty much the same. hopefully replacing the backend could be the way out.
yes, you need to implement backend almost from scratch as contexts and other things must match your sdl and opengl instnce.
I thought cimgui-go was a auto-generated binding
cimgui-go/backend is 100% manually-writen :smile:
btw, if you like discord we've started a server:
Yesterday, I gave another try. Taking ebiten backend as a reference I made some progress on go-sdl2 backend, and here's what i got:
i think something went wrong with the color conversion. but the most obvious issue is the texture .... I tracked the calls from imgui, it's quite weird that it created only 1 texture, and all following draw cmd uses the only 1 texture. haven't figured it out yet. any advice?
CreateWindow(Hello from cimgui-go,1200x900)
CreateTextureRgba(256,256) -> 1
draw cmd: textureID=1, clipRect={0 0 1200 900}
draw cmd: textureID=1, clipRect={0 0 1200 900}
draw cmd: textureID=1, clipRect={61 79 359 359}
draw cmd: textureID=1, clipRect={0 0 1200 900}
draw cmd: textureID=1, clipRect={401 79 899 359}
draw cmd: textureID=1, clipRect={444 115 881 323}
draw cmd: textureID=1, clipRect={408 87 891 351}
draw cmd: textureID=1, clipRect={454 125 505 161}
draw cmd: textureID=1, clipRect={401 79 899 359}
draw cmd: textureID=1, clipRect={0 0 1200 900}
draw cmd: textureID=1, clipRect={801 279 1049 659}
draw cmd: textureID=1, clipRect={808 287 1042 652}
draw cmd: textureID=1, clipRect={0 0 1200 900}
draw cmd: textureID=1, clipRect={0 0 1200 900}
draw cmd: textureID=1, clipRect={61 79 359 359}
here's my backend.Run code:
func (backend *MyBackend) Run(loop func()) {
running := true
for running {
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
switch e := event.(type) {
case *sdl.QuitEvent:
running = false
case *sdl.KeyboardEvent:
if e.Keysym.Sym == sdl.K_ESCAPE {
running = false
}
}
}
if backend.beforeRender != nil {
backend.beforeRender()
}
io := imgui.CurrentIO()
w, h := backend.window.GetSize()
io.SetDisplaySize(imgui.Vec2{X: float32(w), Y: float32(h)})
backend.renderer.SetDrawColor(backend.clearColor.R, backend.clearColor.G, backend.clearColor.B, backend.clearColor.A)
backend.renderer.Clear()
imgui.NewFrame()
loop()
imgui.EndFrame()
imgui.Render()
drawdata := imgui.CurrentDrawData()
for _, drawList := range drawdata.CommandLists() {
for _, cmd := range drawList.Commands() {
clipRect := cmd.ClipRect()
textureID := cmd.TextureId()
println(fmt.Sprintf("draw cmd: textureID=%d, clipRect=%v", textureID, clipRect))
w, h := backend.window.GetSize()
if clipRect.X == 0 &&
clipRect.Y == 0 &&
clipRect.Z == float32(w) &&
clipRect.W == float32(h) {
// TODO: draw triangle?
} else {
if tx, ok := backend.textureCache.Load(textureID); ok {
backend.renderer.Copy(tx.(*sdl.Texture), nil, &sdl.Rect{
X: int32(clipRect.X),
Y: int32(clipRect.Y),
W: int32(clipRect.Z - clipRect.X),
H: int32(clipRect.W - clipRect.Y),
})
}
}
}
}
backend.renderer.Present()
if backend.afterRender != nil {
backend.afterRender()
}
}
}
well, it turns out the ebiten backend received the same draw cmds and texture ids just as my backend got. but it displays various of widgets as expected.
ok, I'm confused.
according to my understanding, imgui takes in charge of widget logics, like creation and organization of widgets, figures out where to draw them, etc. and my backend is responsible for actual rendering. so the imgui lib should create a bunch of textures using the API provided by my backend, then in every loop it should tell my backend to draw each texture at its specific position. that's how they two work together, am i right?
@gucio321 hoping for some advice, if it's not bothering.
according to my understanding, imgui takes in charge of widget logics, like creation and organization of widgets, figures out where to draw them, etc. and my backend is responsible for actual rendering. so the imgui lib should create a bunch of textures using the API provided by my backend, then in every loop it should tell my backend to draw each texture at its specific position. that's how they two work together, am i right?
As far as I understand that - yes.
Generally I think I'm not the right person to ask about that sa I've actually never worked with this low-level logic to be honest. Maybe @damntourists has any idea bout that?
Also, let me note that what you're doing is actually already done inside of Dear ImGui in backends/ directory so it might be worth checking if modifying cimgui-go so that it generates wrappers for that stuff wouldn't be the better idea in fact. (by better I mean easier to do :smile:)
