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