mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
parent
b8a099e354
commit
0ec447e0d0
@ -37,7 +37,8 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
flagWindowPosition = flag.String("windowposition", "", "window position (e.g., 100,200)")
|
||||
flagWindowPosition = flag.String("windowposition", "", "window position (e.g., 100,200)")
|
||||
flagScreenTransparent = flag.Bool("screentransparent", false, "screen transparent")
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -86,6 +87,7 @@ func update(screen *ebiten.Image) error {
|
||||
tps := ebiten.MaxTPS()
|
||||
decorated := ebiten.IsWindowDecorated()
|
||||
positionX, positionY := ebiten.WindowPosition()
|
||||
transparent := ebiten.IsScreenTransparent()
|
||||
|
||||
if ebiten.IsKeyPressed(ebiten.KeyShift) {
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyUp) {
|
||||
@ -182,7 +184,9 @@ func update(screen *ebiten.Image) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
screen.Fill(color.RGBA{0x80, 0x80, 0xc0, 0xff})
|
||||
if !transparent {
|
||||
screen.Fill(color.RGBA{0x80, 0x80, 0xc0, 0xff})
|
||||
}
|
||||
w, h := gophersImage.Size()
|
||||
w2, h2 := screen.Size()
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
@ -261,6 +265,7 @@ func main() {
|
||||
if x, y, ok := parseWindowPosition(); ok {
|
||||
ebiten.SetWindowPosition(x, y)
|
||||
}
|
||||
ebiten.SetScreenTransparent(*flagScreenTransparent)
|
||||
|
||||
if err := ebiten.Run(update, initScreenWidth, initScreenHeight, initScreenScale, "Window Size (Ebiten Demo)"); err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -26,6 +26,7 @@ type Graphics interface {
|
||||
Begin()
|
||||
End()
|
||||
SetWindow(window unsafe.Pointer)
|
||||
SetTransparent(transparent bool)
|
||||
SetVertices(vertices []float32, indices []uint16)
|
||||
Flush()
|
||||
NewImage(width, height int) (Image, error)
|
||||
|
@ -46,6 +46,7 @@ type UI interface {
|
||||
ScreenScale() float64
|
||||
ScreenSizeInFullscreen() (int, int)
|
||||
WindowPosition() (int, int)
|
||||
IsScreenTransparent() bool
|
||||
|
||||
SetCursorVisible(visible bool)
|
||||
SetFullscreen(fullscreen bool)
|
||||
@ -58,6 +59,7 @@ type UI interface {
|
||||
SetWindowResizable(resizable bool)
|
||||
SetWindowTitle(title string)
|
||||
SetWindowPosition(x, y int)
|
||||
SetScreenTransparent(transparent bool)
|
||||
|
||||
Input() Input
|
||||
}
|
||||
|
@ -73,13 +73,14 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
ClientAPI = Hint(0x00022001)
|
||||
ContextVersionMajor = Hint(0x00022002)
|
||||
ContextVersionMinor = Hint(0x00022003)
|
||||
Decorated = Hint(0x00020005)
|
||||
Focused = Hint(0x00020001)
|
||||
Resizable = Hint(0x00020003)
|
||||
Visible = Hint(0x00020004)
|
||||
ClientAPI = Hint(0x00022001)
|
||||
ContextVersionMajor = Hint(0x00022002)
|
||||
ContextVersionMinor = Hint(0x00022003)
|
||||
Decorated = Hint(0x00020005)
|
||||
Focused = Hint(0x00020001)
|
||||
Resizable = Hint(0x00020003)
|
||||
TransparentFramebuffer = Hint(0x0002000A)
|
||||
Visible = Hint(0x00020004)
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -78,6 +78,15 @@ func (ml MetalLayer) SetDevice(device mtl.Device) {
|
||||
C.MetalLayer_SetDevice(ml.metalLayer, device.Device())
|
||||
}
|
||||
|
||||
// SetOpaque a Boolean value indicating whether the layer contains completely opaque content.
|
||||
func (ml MetalLayer) SetOpaque(opaque bool) {
|
||||
if opaque {
|
||||
C.MetalLayer_SetOpaque(ml.metalLayer, 1)
|
||||
} else {
|
||||
C.MetalLayer_SetOpaque(ml.metalLayer, 0)
|
||||
}
|
||||
}
|
||||
|
||||
// SetPixelFormat controls the pixel format of textures for rendering layer content.
|
||||
//
|
||||
// The pixel format for a Metal layer must be PixelFormatBGRA8UNorm, PixelFormatBGRA8UNormSRGB,
|
||||
|
@ -16,12 +16,14 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef signed char BOOL;
|
||||
typedef unsigned long uint_t;
|
||||
|
||||
void *MakeMetalLayer();
|
||||
|
||||
uint16_t MetalLayer_PixelFormat(void *metalLayer);
|
||||
void MetalLayer_SetDevice(void *metalLayer, void *device);
|
||||
void MetalLayer_SetOpaque(void *metalLayer, BOOL opaque);
|
||||
const char *MetalLayer_SetPixelFormat(void *metalLayer, uint16_t pixelFormat);
|
||||
const char *MetalLayer_SetMaximumDrawableCount(void *metalLayer,
|
||||
uint_t maximumDrawableCount);
|
||||
|
@ -38,6 +38,10 @@ void MetalLayer_SetDevice(void *metalLayer, void *device) {
|
||||
((CAMetalLayer *)metalLayer).device = (id<MTLDevice>)device;
|
||||
}
|
||||
|
||||
void MetalLayer_SetOpaque(void *metalLayer, BOOL opaque) {
|
||||
((CAMetalLayer *)metalLayer).opaque = opaque;
|
||||
}
|
||||
|
||||
const char *MetalLayer_SetPixelFormat(void *metalLayer, uint16_t pixelFormat) {
|
||||
@try {
|
||||
((CAMetalLayer *)metalLayer).pixelFormat = (MTLPixelFormat)pixelFormat;
|
||||
|
@ -293,15 +293,14 @@ type Driver struct {
|
||||
|
||||
screenDrawable ca.MetalDrawable
|
||||
|
||||
vb mtl.Buffer
|
||||
ib mtl.Buffer
|
||||
|
||||
vb mtl.Buffer
|
||||
ib mtl.Buffer
|
||||
src *Image
|
||||
dst *Image
|
||||
|
||||
drawCalled bool
|
||||
|
||||
transparent bool
|
||||
maxImageSize int
|
||||
drawCalled bool
|
||||
|
||||
t *thread.Thread
|
||||
|
||||
@ -440,6 +439,10 @@ func (d *Driver) NewScreenFramebufferImage(width, height int) (driver.Image, err
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *Driver) SetTransparent(transparent bool) {
|
||||
d.transparent = transparent
|
||||
}
|
||||
|
||||
func (d *Driver) Reset() error {
|
||||
if err := d.t.Call(func() error {
|
||||
if d.cq != (mtl.CommandQueue{}) {
|
||||
@ -455,6 +458,9 @@ func (d *Driver) Reset() error {
|
||||
if err := d.view.reset(); err != nil {
|
||||
return err
|
||||
}
|
||||
if d.transparent {
|
||||
d.view.ml.SetOpaque(false)
|
||||
}
|
||||
|
||||
replaces := map[string]string{
|
||||
"{{.FilterNearest}}": fmt.Sprintf("%d", driver.FilterNearest),
|
||||
|
@ -54,6 +54,10 @@ func (d *Driver) SetWindow(window unsafe.Pointer) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
func (d *Driver) SetTransparent(transparent bool) {
|
||||
// Do nothings.
|
||||
}
|
||||
|
||||
func (d *Driver) checkSize(width, height int) {
|
||||
if width < 1 {
|
||||
panic(fmt.Sprintf("opengl: width (%d) must be equal or more than %d", width, 1))
|
||||
|
@ -53,16 +53,17 @@ type UserInterface struct {
|
||||
|
||||
lastActualScale float64
|
||||
|
||||
initMonitor *glfw.Monitor
|
||||
initFullscreenWidth int
|
||||
initFullscreenHeight int
|
||||
initFullscreen bool
|
||||
initCursorVisible bool
|
||||
initWindowDecorated bool
|
||||
initWindowResizable bool
|
||||
initWindowPositionX int
|
||||
initWindowPositionY int
|
||||
initIconImages []image.Image
|
||||
initMonitor *glfw.Monitor
|
||||
initFullscreenWidth int
|
||||
initFullscreenHeight int
|
||||
initFullscreen bool
|
||||
initCursorVisible bool
|
||||
initWindowDecorated bool
|
||||
initWindowResizable bool
|
||||
initWindowPositionX int
|
||||
initWindowPositionY int
|
||||
initScreenTransparent bool
|
||||
initIconImages []image.Image
|
||||
|
||||
reqWidth int
|
||||
reqHeight int
|
||||
@ -260,6 +261,19 @@ func (u *UserInterface) setInitWindowResizable(resizable bool) {
|
||||
u.m.Unlock()
|
||||
}
|
||||
|
||||
func (u *UserInterface) isInitScreenTransparent() bool {
|
||||
u.m.RLock()
|
||||
v := u.initScreenTransparent
|
||||
u.m.RUnlock()
|
||||
return v
|
||||
}
|
||||
|
||||
func (u *UserInterface) setInitScreenTransparent(transparent bool) {
|
||||
u.m.RLock()
|
||||
u.initScreenTransparent = transparent
|
||||
u.m.RUnlock()
|
||||
}
|
||||
|
||||
func (u *UserInterface) getInitIconImages() []image.Image {
|
||||
u.m.RLock()
|
||||
i := u.initIconImages
|
||||
@ -617,13 +631,19 @@ func (u *UserInterface) run(width, height int, scale float64, title string, cont
|
||||
glfw.WindowHint(glfw.ClientAPI, glfw.NoAPI)
|
||||
}
|
||||
|
||||
// 'decorated' must be solved before creating a window (#556).
|
||||
decorated := glfw.False
|
||||
if u.isInitWindowDecorated() {
|
||||
decorated = glfw.True
|
||||
}
|
||||
glfw.WindowHint(glfw.Decorated, decorated)
|
||||
|
||||
transparent := glfw.False
|
||||
if u.isInitScreenTransparent() {
|
||||
transparent = glfw.True
|
||||
}
|
||||
glfw.WindowHint(glfw.TransparentFramebuffer, transparent)
|
||||
u.graphics.SetTransparent(u.isInitScreenTransparent())
|
||||
|
||||
resizable := glfw.False
|
||||
if u.isInitWindowResizable() {
|
||||
resizable = glfw.True
|
||||
@ -1050,6 +1070,26 @@ func (u *UserInterface) WindowPosition() (int, int) {
|
||||
return x, y
|
||||
}
|
||||
|
||||
func (u *UserInterface) SetScreenTransparent(transparent bool) {
|
||||
if !u.isRunning() {
|
||||
u.setInitScreenTransparent(transparent)
|
||||
return
|
||||
}
|
||||
panic("ui: SetScreenTransparent can't be called after Run.")
|
||||
}
|
||||
|
||||
func (u *UserInterface) IsScreenTransparent() bool {
|
||||
if !u.isRunning() {
|
||||
return u.isInitScreenTransparent()
|
||||
}
|
||||
val := false
|
||||
_ = u.t.Call(func() error {
|
||||
val = u.window.GetAttrib(glfw.TransparentFramebuffer) == glfw.True
|
||||
return nil
|
||||
})
|
||||
return val
|
||||
}
|
||||
|
||||
func (u *UserInterface) Input() driver.Input {
|
||||
return &u.input
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ type UserInterface struct {
|
||||
scale float64
|
||||
runnableInBackground bool
|
||||
vsync bool
|
||||
running bool
|
||||
|
||||
sizeChanged bool
|
||||
contextLost bool
|
||||
@ -156,6 +157,9 @@ func (u *UserInterface) IsWindowResizable() bool {
|
||||
|
||||
func (u *UserInterface) SetWindowResizable(decorated bool) {
|
||||
// Do nothing
|
||||
if u.running {
|
||||
panic("js: SetWindowResizable can't be called after the main loop starts")
|
||||
}
|
||||
}
|
||||
|
||||
func (u *UserInterface) DeviceScaleFactor() float64 {
|
||||
@ -426,6 +430,7 @@ func (u *UserInterface) Run(width, height int, scale float64, title string, cont
|
||||
u.setScreenSize(width, height)
|
||||
u.pseudoScale = scale
|
||||
canvas.Call("focus")
|
||||
u.running = true
|
||||
ch := u.loop(context)
|
||||
if runtime.GOARCH == "wasm" {
|
||||
return <-ch
|
||||
@ -434,6 +439,9 @@ func (u *UserInterface) Run(width, height int, scale float64, title string, cont
|
||||
// On GopherJS, the main goroutine cannot be blocked due to the bug (gopherjs/gopherjs#826).
|
||||
// Return immediately.
|
||||
go func() {
|
||||
defer func() {
|
||||
u.running = false
|
||||
}()
|
||||
if err := <-ch; err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@ -484,9 +492,30 @@ func (u *UserInterface) SetWindowPosition(x, y int) {
|
||||
}
|
||||
|
||||
func (u *UserInterface) WindowPosition() (int, int) {
|
||||
if !u.running {
|
||||
panic("js: WindowPosition can't be called before the main loop starts")
|
||||
}
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
func (u *UserInterface) SetScreenTransparent(transparent bool) {
|
||||
if u.running {
|
||||
panic("js: SetScreenTransparent can't be called after the main loop starts")
|
||||
}
|
||||
|
||||
bodyStyle := document.Get("body").Get("style")
|
||||
if transparent {
|
||||
bodyStyle.Set("backgroundColor", "transparent")
|
||||
} else {
|
||||
bodyStyle.Set("backgroundColor", "#000")
|
||||
}
|
||||
}
|
||||
|
||||
func (u *UserInterface) IsScreenTransparent() bool {
|
||||
bodyStyle := document.Get("body").Get("style")
|
||||
return bodyStyle.Get("backgroundColor").String() == "transparent"
|
||||
}
|
||||
|
||||
func (u *UserInterface) Input() driver.Input {
|
||||
return &u.input
|
||||
}
|
||||
|
@ -451,6 +451,14 @@ func (u *UserInterface) WindowPosition() (int, int) {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
func (u *UserInterface) SetScreenTransparent(transparent bool) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
func (u *UserInterface) IsScreenTransparent() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (u *UserInterface) Input() driver.Input {
|
||||
return &u.input
|
||||
}
|
||||
|
14
run.go
14
run.go
@ -411,3 +411,17 @@ func SetMaxTPS(tps int) {
|
||||
}
|
||||
atomic.StoreInt32(¤tMaxTPS, int32(tps))
|
||||
}
|
||||
|
||||
// IsScreenTransparent reports whether the window is transparent.
|
||||
func IsScreenTransparent() bool {
|
||||
return uiDriver().IsScreenTransparent()
|
||||
}
|
||||
|
||||
// SetScreenTransparent sets the state if the window is transparent.
|
||||
//
|
||||
// SetScreenTransparent panics if SetScreenTransparent is called after Run.
|
||||
//
|
||||
// SetScreenTransparent does nothing on mobiles.
|
||||
func SetScreenTransparent(transparent bool) {
|
||||
uiDriver().SetScreenTransparent(transparent)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user