go-gl / gl

Go bindings for OpenGL (generated via glow)
MIT License
1.06k stars 72 forks source link

gl.ClearColor alpha channel parameter not affecting transparency. #118

Closed drakbar closed 5 years ago

drakbar commented 5 years ago

gl.ClearColor(1, 0, 0, 0)

I would expect to not see anything, however it is coming through as red. background

gl.Viewport(0, 0, int32(width), int32(height))
gl.Clear(gl.COLOR_BUFFER_BIT)
gl.ClearColor(1, 0, 0, 0)
win.GLSwap()

Can you have a transparent background?

Noofbiz commented 5 years ago

You need a window that has a transparent background behind the opengl surface. If you're using glfw there's a window hint you need to use for that, but last I checked it only works on windows and X11.

drakbar commented 5 years ago

You were right. In order to get it to work I had to make calls to the windows API using syscall. Using this stack overflow as a guide, and lxn's win api on how to write the calls I was able to get it working.

demo

var ( 
  // Library
  libuser32     uintptr

  // Functions
  getWindowLong uintptr
  setWindowLong uintptr

  setLayeredWindowAttributes uintptr
)

const (
  GWL_EXSTYLE    = -20
  WS_EX_LAYERED  = 0X00080000
  LWA_COLORKEY   = 0x00000001
  BLACK          = 0x00000000
)

func init() {

  // Library
  libuser32 = MustLoadLibrary("user32.dll")

  // functions
  setWindowLong = MustGetProcAddress(libuser32, "SetWindowLongW")
  getWindowLong = MustGetProcAddress(libuser32, "GetWindowLongW")

  setLayeredWindowAttributes = MustGetProcAddress(libuser32, "SetLayeredWindowAttributes")
}

func main() {
  SetWindowLong(HWnd, GWL_EXSTYLE, GetWindowLong(HWnd, GWL_EXSTYLE) | WS_EX_LAYERED)
  SetLayeredWindowAttributes(HWnd, BLACK, 0, LWA_COLORKEY)
}

func SetWindowLong(hWnd unsafe.Pointer, index, value int32) int32 {
  ret, _, _ := syscall.Syscall(setWindowLong, 3,
    uintptr(hWnd),
    uintptr(index),
    uintptr(value))

  return int32(ret)
}

func GetWindowLong(hWnd unsafe.Pointer, index int32) int32 {
  ret, _, _ := syscall.Syscall(getWindowLong, 2,
    uintptr(hWnd),
    uintptr(index),
    0)

  return int32(ret)
}

func SetLayeredWindowAttributes(hWnd unsafe.Pointer, rgb int32, alpha uint8, dwflags int32) int32 {
  ret, _, _ := syscall.Syscall6(setLayeredWindowAttributes, 4,
    uintptr(hWnd),
    uintptr(rgb),
    uintptr(alpha),
    uintptr(dwflags),
    0,0)

  return int32(ret)
}

func MustLoadLibrary(name string) uintptr {
  lib, err := syscall.LoadLibrary(name)
  if err != nil {
    panic(err)
  }

  return uintptr(lib)
}

func MustGetProcAddress(lib uintptr, name string) uintptr {
  addr, err := syscall.GetProcAddress(syscall.Handle(lib), name)
  if err != nil {
    panic(err)
  }

  return uintptr(addr)
}