mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-11 19:48:54 +01:00
parent
d31b0189a2
commit
3024e07ecc
@ -404,7 +404,6 @@ func main() {
|
|||||||
if x, y, ok := parseWindowPosition(); ok {
|
if x, y, ok := parseWindowPosition(); ok {
|
||||||
ebiten.SetWindowPosition(x, y)
|
ebiten.SetWindowPosition(x, y)
|
||||||
}
|
}
|
||||||
ebiten.SetScreenTransparent(*flagTransparent)
|
|
||||||
|
|
||||||
g := &game{
|
g := &game{
|
||||||
width: initScreenWidth,
|
width: initScreenWidth,
|
||||||
@ -464,6 +463,7 @@ func main() {
|
|||||||
log.Fatalf("unexpected graphics library: %s", *flagGraphicsLibrary)
|
log.Fatalf("unexpected graphics library: %s", *flagGraphicsLibrary)
|
||||||
}
|
}
|
||||||
op.InitUnfocused = !*flagInitFocused
|
op.InitUnfocused = !*flagInitFocused
|
||||||
|
op.ScreenTransparent = *flagTransparent
|
||||||
|
|
||||||
const title = "Window Size (Ebitengine Demo)"
|
const title = "Window Size (Ebitengine Demo)"
|
||||||
ww := int(float64(g.width) * initScreenScale)
|
ww := int(float64(g.width) * initScreenScale)
|
||||||
|
@ -80,11 +80,13 @@ type gameForUI struct {
|
|||||||
screen *Image
|
screen *Image
|
||||||
screenShader *Shader
|
screenShader *Shader
|
||||||
imageDumper imageDumper
|
imageDumper imageDumper
|
||||||
|
transparent bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newGameForUI(game Game) *gameForUI {
|
func newGameForUI(game Game, transparent bool) *gameForUI {
|
||||||
g := &gameForUI{
|
g := &gameForUI{
|
||||||
game: game,
|
game: game,
|
||||||
|
transparent: transparent,
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := NewShader([]byte(screenShaderSrc))
|
s, err := NewShader([]byte(screenShaderSrc))
|
||||||
@ -157,7 +159,7 @@ func (g *gameForUI) Update() error {
|
|||||||
|
|
||||||
func (g *gameForUI) DrawOffscreen() error {
|
func (g *gameForUI) DrawOffscreen() error {
|
||||||
g.game.Draw(g.offscreen)
|
g.game.Draw(g.offscreen)
|
||||||
if err := g.imageDumper.dump(g.offscreen); err != nil {
|
if err := g.imageDumper.dump(g.offscreen, g.transparent); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -31,7 +31,7 @@ func datetimeForFilename() string {
|
|||||||
return now.Format(datetimeFormat)
|
return now.Format(datetimeFormat)
|
||||||
}
|
}
|
||||||
|
|
||||||
func takeScreenshot(screen *Image) error {
|
func takeScreenshot(screen *Image, transparent bool) error {
|
||||||
name := "screenshot_" + datetimeForFilename() + ".png"
|
name := "screenshot_" + datetimeForFilename() + ".png"
|
||||||
// Use the home directory for mobiles as a provisional implementation.
|
// Use the home directory for mobiles as a provisional implementation.
|
||||||
if runtime.GOOS == "android" || runtime.GOOS == "ios" {
|
if runtime.GOOS == "android" || runtime.GOOS == "ios" {
|
||||||
@ -41,8 +41,7 @@ func takeScreenshot(screen *Image) error {
|
|||||||
}
|
}
|
||||||
name = filepath.Join(home, name)
|
name = filepath.Join(home, name)
|
||||||
}
|
}
|
||||||
blackbg := !IsScreenTransparent()
|
dumpedName, err := screen.image.DumpScreenshot(name, !transparent)
|
||||||
dumpedName, err := screen.image.DumpScreenshot(name, blackbg)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -155,10 +154,10 @@ func (i *imageDumper) update() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *imageDumper) dump(screen *Image) error {
|
func (i *imageDumper) dump(screen *Image, transparent bool) error {
|
||||||
if i.toTakeScreenshot {
|
if i.toTakeScreenshot {
|
||||||
i.toTakeScreenshot = false
|
i.toTakeScreenshot = false
|
||||||
if err := takeScreenshot(screen); err != nil {
|
if err := takeScreenshot(screen, transparent); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,7 @@ func (u *UserInterface) dumpImages(dir string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RunOptions struct {
|
type RunOptions struct {
|
||||||
GraphicsLibrary GraphicsLibrary
|
GraphicsLibrary GraphicsLibrary
|
||||||
InitUnfocused bool
|
InitUnfocused bool
|
||||||
|
ScreenTransparent bool
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,6 @@ type userInterfaceImpl struct {
|
|||||||
initWindowHeightInDIP int
|
initWindowHeightInDIP int
|
||||||
initWindowFloating bool
|
initWindowFloating bool
|
||||||
initWindowMaximized bool
|
initWindowMaximized bool
|
||||||
initScreenTransparent bool
|
|
||||||
|
|
||||||
origWindowPosX int
|
origWindowPosX int
|
||||||
origWindowPosY int
|
origWindowPosY int
|
||||||
@ -360,19 +359,6 @@ func (u *userInterfaceImpl) setRunnableOnUnfocused(runnableOnUnfocused bool) {
|
|||||||
u.m.Unlock()
|
u.m.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *userInterfaceImpl) isInitScreenTransparent() bool {
|
|
||||||
u.m.RLock()
|
|
||||||
v := u.initScreenTransparent
|
|
||||||
u.m.RUnlock()
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *userInterfaceImpl) setInitScreenTransparent(transparent bool) {
|
|
||||||
u.m.Lock()
|
|
||||||
u.initScreenTransparent = transparent
|
|
||||||
u.m.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *userInterfaceImpl) getIconImages() []image.Image {
|
func (u *userInterfaceImpl) getIconImages() []image.Image {
|
||||||
u.m.RLock()
|
u.m.RLock()
|
||||||
i := u.iconImages
|
i := u.iconImages
|
||||||
@ -874,21 +860,20 @@ func (u *userInterfaceImpl) init(options *RunOptions) error {
|
|||||||
}
|
}
|
||||||
glfw.WindowHint(glfw.Decorated, decorated)
|
glfw.WindowHint(glfw.Decorated, decorated)
|
||||||
|
|
||||||
transparent := u.isInitScreenTransparent()
|
|
||||||
glfwTransparent := glfw.False
|
glfwTransparent := glfw.False
|
||||||
if transparent {
|
if options.ScreenTransparent {
|
||||||
glfwTransparent = glfw.True
|
glfwTransparent = glfw.True
|
||||||
}
|
}
|
||||||
glfw.WindowHint(glfw.TransparentFramebuffer, glfwTransparent)
|
glfw.WindowHint(glfw.TransparentFramebuffer, glfwTransparent)
|
||||||
|
|
||||||
g, err := newGraphicsDriver(&graphicsDriverCreatorImpl{
|
g, err := newGraphicsDriver(&graphicsDriverCreatorImpl{
|
||||||
transparent: transparent,
|
transparent: options.ScreenTransparent,
|
||||||
}, options.GraphicsLibrary)
|
}, options.GraphicsLibrary)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
u.graphicsDriver = g
|
u.graphicsDriver = g
|
||||||
u.graphicsDriver.SetTransparent(u.isInitScreenTransparent())
|
u.graphicsDriver.SetTransparent(options.ScreenTransparent)
|
||||||
|
|
||||||
if u.graphicsDriver.IsGL() {
|
if u.graphicsDriver.IsGL() {
|
||||||
u.graphicsDriver.(interface{ SetGLFWClientAPI() }).SetGLFWClientAPI()
|
u.graphicsDriver.(interface{ SetGLFWClientAPI() }).SetGLFWClientAPI()
|
||||||
@ -1417,25 +1402,6 @@ func monitorFromWindow(window *glfw.Window) *glfw.Monitor {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *userInterfaceImpl) SetScreenTransparent(transparent bool) {
|
|
||||||
if !u.isRunning() {
|
|
||||||
u.setInitScreenTransparent(transparent)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
panic("ui: SetScreenTransparent can't be called after the main loop starts")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *userInterfaceImpl) IsScreenTransparent() bool {
|
|
||||||
if !u.isRunning() {
|
|
||||||
return u.isInitScreenTransparent()
|
|
||||||
}
|
|
||||||
val := false
|
|
||||||
u.t.Call(func() {
|
|
||||||
val = u.window.GetAttrib(glfw.TransparentFramebuffer) == glfw.True
|
|
||||||
})
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *userInterfaceImpl) resetForTick() {
|
func (u *userInterfaceImpl) resetForTick() {
|
||||||
u.input.resetForTick()
|
u.input.resetForTick()
|
||||||
|
|
||||||
@ -1617,3 +1583,7 @@ func (u *userInterfaceImpl) setOrigWindowPos(x, y int) {
|
|||||||
u.origWindowPosX = x
|
u.origWindowPosX = x
|
||||||
u.origWindowPosY = y
|
u.origWindowPosY = y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsScreenTransparentAvailable() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
@ -652,6 +652,13 @@ func (u *userInterfaceImpl) Run(game Game, options *RunOptions) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
u.graphicsDriver = g
|
u.graphicsDriver = g
|
||||||
|
|
||||||
|
if bodyStyle := document.Get("body").Get("style"); options.ScreenTransparent {
|
||||||
|
bodyStyle.Set("backgroundColor", "transparent")
|
||||||
|
} else {
|
||||||
|
bodyStyle.Set("backgroundColor", "#000")
|
||||||
|
}
|
||||||
|
|
||||||
return <-u.loop(game)
|
return <-u.loop(game)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,17 +677,6 @@ func (u *userInterfaceImpl) SetScreenTransparent(transparent bool) {
|
|||||||
panic("ui: SetScreenTransparent can't be called after the main loop starts")
|
panic("ui: 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 *userInterfaceImpl) IsScreenTransparent() bool {
|
|
||||||
bodyStyle := document.Get("body").Get("style")
|
|
||||||
return bodyStyle.Get("backgroundColor").Equal(stringTransparent)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *userInterfaceImpl) resetForTick() {
|
func (u *userInterfaceImpl) resetForTick() {
|
||||||
@ -700,3 +696,7 @@ func (u *userInterfaceImpl) beginFrame() {
|
|||||||
|
|
||||||
func (u *userInterfaceImpl) endFrame() {
|
func (u *userInterfaceImpl) endFrame() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsScreenTransparentAvailable() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
@ -421,14 +421,6 @@ func (u *userInterfaceImpl) DeviceScaleFactor() float64 {
|
|||||||
return deviceScale()
|
return deviceScale()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *userInterfaceImpl) SetScreenTransparent(transparent bool) {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *userInterfaceImpl) IsScreenTransparent() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *userInterfaceImpl) resetForTick() {
|
func (u *userInterfaceImpl) resetForTick() {
|
||||||
u.input.resetForTick()
|
u.input.resetForTick()
|
||||||
}
|
}
|
||||||
@ -475,3 +467,7 @@ func (u *userInterfaceImpl) beginFrame() {
|
|||||||
|
|
||||||
func (u *userInterfaceImpl) endFrame() {
|
func (u *userInterfaceImpl) endFrame() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsScreenTransparentAvailable() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -126,13 +126,6 @@ func (*userInterfaceImpl) SetFPSMode(mode FPSModeType) {
|
|||||||
func (*userInterfaceImpl) ScheduleFrame() {
|
func (*userInterfaceImpl) ScheduleFrame() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*userInterfaceImpl) IsScreenTransparent() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*userInterfaceImpl) SetScreenTransparent(transparent bool) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*userInterfaceImpl) Input() *Input {
|
func (*userInterfaceImpl) Input() *Input {
|
||||||
return &theUI.input
|
return &theUI.input
|
||||||
}
|
}
|
||||||
@ -146,3 +139,7 @@ func (u *userInterfaceImpl) beginFrame() {
|
|||||||
|
|
||||||
func (u *userInterfaceImpl) endFrame() {
|
func (u *userInterfaceImpl) endFrame() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsScreenTransparentAvailable() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
44
run.go
44
run.go
@ -241,6 +241,12 @@ type RunGameOptions struct {
|
|||||||
//
|
//
|
||||||
// The default (zero) value is false, which means that the window is focused.
|
// The default (zero) value is false, which means that the window is focused.
|
||||||
InitUnfocused bool
|
InitUnfocused bool
|
||||||
|
|
||||||
|
// ScreenTransparent represents whether the window is transparent or not.
|
||||||
|
// ScreenTransparent is valid on desktops and browsers.
|
||||||
|
//
|
||||||
|
// The default (zero) value is false, which means that the window is not transparent.
|
||||||
|
ScreenTransparent bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunGameWithOptions starts the main loop and runs the game with the specified options.
|
// RunGameWithOptions starts the main loop and runs the game with the specified options.
|
||||||
@ -280,8 +286,17 @@ func RunGameWithOptions(game Game, options *RunGameOptions) error {
|
|||||||
defer atomic.StoreInt32(&isRunGameEnded_, 1)
|
defer atomic.StoreInt32(&isRunGameEnded_, 1)
|
||||||
|
|
||||||
initializeWindowPositionIfNeeded(WindowSize())
|
initializeWindowPositionIfNeeded(WindowSize())
|
||||||
g := newGameForUI(game)
|
|
||||||
if err := ui.Get().Run(g, toUIRunOptions(options)); err != nil {
|
op := toUIRunOptions(options)
|
||||||
|
// This is necessary to change the result of IsScreenTransparent.
|
||||||
|
if op.ScreenTransparent {
|
||||||
|
atomic.StoreInt32(&screenTransparent, 1)
|
||||||
|
} else {
|
||||||
|
atomic.StoreInt32(&screenTransparent, 0)
|
||||||
|
}
|
||||||
|
g := newGameForUI(game, op.ScreenTransparent)
|
||||||
|
|
||||||
|
if err := ui.Get().Run(g, op); err != nil {
|
||||||
if errors.Is(err, Termination) {
|
if errors.Is(err, Termination) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -582,8 +597,13 @@ func SetMaxTPS(tps int) {
|
|||||||
// IsScreenTransparent reports whether the window is transparent.
|
// IsScreenTransparent reports whether the window is transparent.
|
||||||
//
|
//
|
||||||
// IsScreenTransparent is concurrent-safe.
|
// IsScreenTransparent is concurrent-safe.
|
||||||
|
//
|
||||||
|
// Deprecated: as of v2.5.
|
||||||
func IsScreenTransparent() bool {
|
func IsScreenTransparent() bool {
|
||||||
return ui.Get().IsScreenTransparent()
|
if !ui.IsScreenTransparentAvailable() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return atomic.LoadInt32(&screenTransparent) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetScreenTransparent sets the state if the window is transparent.
|
// SetScreenTransparent sets the state if the window is transparent.
|
||||||
@ -593,10 +613,18 @@ func IsScreenTransparent() bool {
|
|||||||
// SetScreenTransparent does nothing on mobiles.
|
// SetScreenTransparent does nothing on mobiles.
|
||||||
//
|
//
|
||||||
// SetScreenTransparent is concurrent-safe.
|
// SetScreenTransparent is concurrent-safe.
|
||||||
|
//
|
||||||
|
// Deprecated: as of v2.5. Use RunGameWithOptions instead.
|
||||||
func SetScreenTransparent(transparent bool) {
|
func SetScreenTransparent(transparent bool) {
|
||||||
ui.Get().SetScreenTransparent(transparent)
|
if transparent {
|
||||||
|
atomic.StoreInt32(&screenTransparent, 1)
|
||||||
|
} else {
|
||||||
|
atomic.StoreInt32(&screenTransparent, 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var screenTransparent int32 = 0
|
||||||
|
|
||||||
// SetInitFocused sets whether the application is focused on show.
|
// SetInitFocused sets whether the application is focused on show.
|
||||||
// The default value is true, i.e., the application is focused.
|
// The default value is true, i.e., the application is focused.
|
||||||
//
|
//
|
||||||
@ -620,11 +648,13 @@ var initUnfocused int32 = 0
|
|||||||
func toUIRunOptions(options *RunGameOptions) *ui.RunOptions {
|
func toUIRunOptions(options *RunGameOptions) *ui.RunOptions {
|
||||||
if options == nil {
|
if options == nil {
|
||||||
return &ui.RunOptions{
|
return &ui.RunOptions{
|
||||||
InitUnfocused: atomic.LoadInt32(&initUnfocused) != 0,
|
InitUnfocused: atomic.LoadInt32(&initUnfocused) != 0,
|
||||||
|
ScreenTransparent: atomic.LoadInt32(&screenTransparent) != 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &ui.RunOptions{
|
return &ui.RunOptions{
|
||||||
GraphicsLibrary: ui.GraphicsLibrary(options.GraphicsLibrary),
|
GraphicsLibrary: ui.GraphicsLibrary(options.GraphicsLibrary),
|
||||||
InitUnfocused: options.InitUnfocused,
|
InitUnfocused: options.InitUnfocused,
|
||||||
|
ScreenTransparent: options.ScreenTransparent,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,5 +28,6 @@ import (
|
|||||||
//
|
//
|
||||||
// TODO: Remove this. In order to remove this, the gameForUI should be in another package.
|
// TODO: Remove this. In order to remove this, the gameForUI should be in another package.
|
||||||
func RunGameWithoutMainLoop(game Game, options *RunGameOptions) {
|
func RunGameWithoutMainLoop(game Game, options *RunGameOptions) {
|
||||||
ui.RunWithoutMainLoop(newGameForUI(game), toUIRunOptions(options))
|
op := toUIRunOptions(options)
|
||||||
|
ui.RunWithoutMainLoop(newGameForUI(game, op.ScreenTransparent), op)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user