faiface / pixel

A hand-crafted 2D game library in Go
MIT License
4.46k stars 246 forks source link

Creating a layered Window #232

Open qb-0 opened 4 years ago

qb-0 commented 4 years ago

Im trying to create a layered (fully transparent Window) on Windows and I'm facing two issues:

  1. Is there some way to get the Pixel Window hwnd?
  2. If I use the hwnd manually it won't get layered aswell. Are my parameters correct?

Is there maybe something already build in to draw on a transparent Window?


package main

import (
    "github.com/Sann0/w32"
    "github.com/faiface/pixel"
    "github.com/faiface/pixel/pixelgl"
    "golang.org/x/image/colornames"
    "syscall"
)

var (
    moduser32                      = syscall.NewLazyDLL("user32.dll")
    procSetLayeredWindowAttributes = moduser32.NewProc("SetLayeredWindowAttributes")
)

func SetLayeredAttributes(hwnd w32.HWND, cr w32.COLORREF, alpha byte, flags uint32) bool {
    r0, _, _ := syscall.Syscall6(procSetLayeredWindowAttributes.Addr(), 4, uintptr(hwnd), uintptr(cr), uintptr(alpha), uintptr(flags), 0, 0)
    return r0 != 0
}

func initWindow() {
    cfg := pixelgl.WindowConfig{
        Title:  "Pixel",
        Bounds: pixel.R(0, 0, 1024, 768),
        VSync:  true,
        // Undecorated: true,
        // AlwaysOnTop: true,
    }
    win, err := pixelgl.NewWindow(cfg)
    if err != nil {
        panic(err)
    }
    // win.SetCursorDisabled()
    /*
    result := w32.SetWindowLong(w32.HWND(handle), w32.GWL_EXSTYLE, uint32(w32.GetWindowLong(w32.HWND(handle), w32.GWL_EXSTYLE)) | 0x00080000)
    fmt.Println(result)
    // (135, 206, 345) colornames.Skyblue
    result2 := SetLayeredAttributes(w32.HWND(handle), w32.COLORREF(uint32(135) | uint32(206) | uint32(235)), 0, 0x00000001)
    fmt.Println(result2)
    */
    mainLoop(win)
}

func mainLoop(win *pixelgl.Window) {
    for !win.Closed() {
        win.Clear(colornames.Skyblue)
        win.Update()
    }
}

func main() {
    pixelgl.Run(initWindow)
}
qb-0 commented 4 years ago

I got it finally running with calling EnumWindows from the win32 api. Anyway I would prefer a native pixel way.

delp commented 4 years ago

I'm not sure what would be involved in doing this but I'll tag it as a feature request :)

fgrosse commented 4 years ago

I think #234 implements the requested feature. At least it allows you to make the window fully (or partially) transparent which I think it what you want?

delp commented 4 years ago

@Sann0 could you take a look at https://github.com/faiface/pixel/pull/234 and see if it resolves your issue?

qb-0 commented 4 years ago

234 is great and works how it should be but a win32 layered window lets you interact through the window itself. Example

Not sure if thats something which glfw supports aswell.

delp commented 4 years ago

You could make a pretty good Bonzi Buddy with that

delp commented 4 years ago

@Sann0 so check this out.

Try making a window with these settings. You should see the effect you're looking for. This could be animated obviously. I'm going to close this issue because the feature is implemented now. You can follow up if you like.

    cfg := pixelgl.WindowConfig{
        Title:                  "Pixel Rocks!",
        Bounds:                 pixel.R(0, 0, 1024, 768),
        VSync:                  true,
        TransparentFramebuffer: true,
        Undecorated:            true,
    }
delp commented 4 years ago

Oh wait...I see what you mean. You can click on things through the window. I'm not sure if that's possible right now. That requires more investigation.