mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
parent
d31b0189a2
commit
3024e07ecc
@ -404,7 +404,6 @@ func main() {
|
||||
if x, y, ok := parseWindowPosition(); ok {
|
||||
ebiten.SetWindowPosition(x, y)
|
||||
}
|
||||
ebiten.SetScreenTransparent(*flagTransparent)
|
||||
|
||||
g := &game{
|
||||
width: initScreenWidth,
|
||||
@ -464,6 +463,7 @@ func main() {
|
||||
log.Fatalf("unexpected graphics library: %s", *flagGraphicsLibrary)
|
||||
}
|
||||
op.InitUnfocused = !*flagInitFocused
|
||||
op.ScreenTransparent = *flagTransparent
|
||||
|
||||
const title = "Window Size (Ebitengine Demo)"
|
||||
ww := int(float64(g.width) * initScreenScale)
|
||||
|
@ -80,11 +80,13 @@ type gameForUI struct {
|
||||
screen *Image
|
||||
screenShader *Shader
|
||||
imageDumper imageDumper
|
||||
transparent bool
|
||||
}
|
||||
|
||||
func newGameForUI(game Game) *gameForUI {
|
||||
func newGameForUI(game Game, transparent bool) *gameForUI {
|
||||
g := &gameForUI{
|
||||
game: game,
|
||||
game: game,
|
||||
transparent: transparent,
|
||||
}
|
||||
|
||||
s, err := NewShader([]byte(screenShaderSrc))
|
||||
@ -157,7 +159,7 @@ func (g *gameForUI) Update() error {
|
||||
|
||||
func (g *gameForUI) DrawOffscreen() error {
|
||||
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 nil
|
||||
|
@ -31,7 +31,7 @@ func datetimeForFilename() string {
|
||||
return now.Format(datetimeFormat)
|
||||
}
|
||||
|
||||
func takeScreenshot(screen *Image) error {
|
||||
func takeScreenshot(screen *Image, transparent bool) error {
|
||||
name := "screenshot_" + datetimeForFilename() + ".png"
|
||||
// Use the home directory for mobiles as a provisional implementation.
|
||||
if runtime.GOOS == "android" || runtime.GOOS == "ios" {
|
||||
@ -41,8 +41,7 @@ func takeScreenshot(screen *Image) error {
|
||||
}
|
||||
name = filepath.Join(home, name)
|
||||
}
|
||||
blackbg := !IsScreenTransparent()
|
||||
dumpedName, err := screen.image.DumpScreenshot(name, blackbg)
|
||||
dumpedName, err := screen.image.DumpScreenshot(name, !transparent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -155,10 +154,10 @@ func (i *imageDumper) update() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *imageDumper) dump(screen *Image) error {
|
||||
func (i *imageDumper) dump(screen *Image, transparent bool) error {
|
||||
if i.toTakeScreenshot {
|
||||
i.toTakeScreenshot = false
|
||||
if err := takeScreenshot(screen); err != nil {
|
||||
if err := takeScreenshot(screen, transparent); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +97,7 @@ func (u *UserInterface) dumpImages(dir string) (string, error) {
|
||||
}
|
||||
|
||||
type RunOptions struct {
|
||||
GraphicsLibrary GraphicsLibrary
|
||||
InitUnfocused bool
|
||||
GraphicsLibrary GraphicsLibrary
|
||||
InitUnfocused bool
|
||||
ScreenTransparent bool
|
||||
}
|
||||
|
@ -92,7 +92,6 @@ type userInterfaceImpl struct {
|
||||
initWindowHeightInDIP int
|
||||
initWindowFloating bool
|
||||
initWindowMaximized bool
|
||||
initScreenTransparent bool
|
||||
|
||||
origWindowPosX int
|
||||
origWindowPosY int
|
||||
@ -360,19 +359,6 @@ func (u *userInterfaceImpl) setRunnableOnUnfocused(runnableOnUnfocused bool) {
|
||||
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 {
|
||||
u.m.RLock()
|
||||
i := u.iconImages
|
||||
@ -874,21 +860,20 @@ func (u *userInterfaceImpl) init(options *RunOptions) error {
|
||||
}
|
||||
glfw.WindowHint(glfw.Decorated, decorated)
|
||||
|
||||
transparent := u.isInitScreenTransparent()
|
||||
glfwTransparent := glfw.False
|
||||
if transparent {
|
||||
if options.ScreenTransparent {
|
||||
glfwTransparent = glfw.True
|
||||
}
|
||||
glfw.WindowHint(glfw.TransparentFramebuffer, glfwTransparent)
|
||||
|
||||
g, err := newGraphicsDriver(&graphicsDriverCreatorImpl{
|
||||
transparent: transparent,
|
||||
transparent: options.ScreenTransparent,
|
||||
}, options.GraphicsLibrary)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.graphicsDriver = g
|
||||
u.graphicsDriver.SetTransparent(u.isInitScreenTransparent())
|
||||
u.graphicsDriver.SetTransparent(options.ScreenTransparent)
|
||||
|
||||
if u.graphicsDriver.IsGL() {
|
||||
u.graphicsDriver.(interface{ SetGLFWClientAPI() }).SetGLFWClientAPI()
|
||||
@ -1417,25 +1402,6 @@ func monitorFromWindow(window *glfw.Window) *glfw.Monitor {
|
||||
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() {
|
||||
u.input.resetForTick()
|
||||
|
||||
@ -1617,3 +1583,7 @@ func (u *userInterfaceImpl) setOrigWindowPos(x, y int) {
|
||||
u.origWindowPosX = x
|
||||
u.origWindowPosY = y
|
||||
}
|
||||
|
||||
func IsScreenTransparentAvailable() bool {
|
||||
return true
|
||||
}
|
||||
|
@ -652,6 +652,13 @@ func (u *userInterfaceImpl) Run(game Game, options *RunOptions) error {
|
||||
return err
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
@ -670,17 +677,6 @@ func (u *userInterfaceImpl) SetScreenTransparent(transparent bool) {
|
||||
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() {
|
||||
@ -700,3 +696,7 @@ func (u *userInterfaceImpl) beginFrame() {
|
||||
|
||||
func (u *userInterfaceImpl) endFrame() {
|
||||
}
|
||||
|
||||
func IsScreenTransparentAvailable() bool {
|
||||
return true
|
||||
}
|
||||
|
@ -421,14 +421,6 @@ func (u *userInterfaceImpl) DeviceScaleFactor() float64 {
|
||||
return deviceScale()
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) SetScreenTransparent(transparent bool) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) IsScreenTransparent() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) resetForTick() {
|
||||
u.input.resetForTick()
|
||||
}
|
||||
@ -475,3 +467,7 @@ func (u *userInterfaceImpl) beginFrame() {
|
||||
|
||||
func (u *userInterfaceImpl) endFrame() {
|
||||
}
|
||||
|
||||
func IsScreenTransparentAvailable() bool {
|
||||
return false
|
||||
}
|
||||
|
@ -126,13 +126,6 @@ func (*userInterfaceImpl) SetFPSMode(mode FPSModeType) {
|
||||
func (*userInterfaceImpl) ScheduleFrame() {
|
||||
}
|
||||
|
||||
func (*userInterfaceImpl) IsScreenTransparent() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (*userInterfaceImpl) SetScreenTransparent(transparent bool) {
|
||||
}
|
||||
|
||||
func (*userInterfaceImpl) Input() *Input {
|
||||
return &theUI.input
|
||||
}
|
||||
@ -146,3 +139,7 @@ func (u *userInterfaceImpl) beginFrame() {
|
||||
|
||||
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.
|
||||
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.
|
||||
@ -280,8 +286,17 @@ func RunGameWithOptions(game Game, options *RunGameOptions) error {
|
||||
defer atomic.StoreInt32(&isRunGameEnded_, 1)
|
||||
|
||||
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) {
|
||||
return nil
|
||||
}
|
||||
@ -582,8 +597,13 @@ func SetMaxTPS(tps int) {
|
||||
// IsScreenTransparent reports whether the window is transparent.
|
||||
//
|
||||
// IsScreenTransparent is concurrent-safe.
|
||||
//
|
||||
// Deprecated: as of v2.5.
|
||||
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.
|
||||
@ -593,10 +613,18 @@ func IsScreenTransparent() bool {
|
||||
// SetScreenTransparent does nothing on mobiles.
|
||||
//
|
||||
// SetScreenTransparent is concurrent-safe.
|
||||
//
|
||||
// Deprecated: as of v2.5. Use RunGameWithOptions instead.
|
||||
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.
|
||||
// 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 {
|
||||
if options == nil {
|
||||
return &ui.RunOptions{
|
||||
InitUnfocused: atomic.LoadInt32(&initUnfocused) != 0,
|
||||
InitUnfocused: atomic.LoadInt32(&initUnfocused) != 0,
|
||||
ScreenTransparent: atomic.LoadInt32(&screenTransparent) != 0,
|
||||
}
|
||||
}
|
||||
return &ui.RunOptions{
|
||||
GraphicsLibrary: ui.GraphicsLibrary(options.GraphicsLibrary),
|
||||
InitUnfocused: options.InitUnfocused,
|
||||
GraphicsLibrary: ui.GraphicsLibrary(options.GraphicsLibrary),
|
||||
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.
|
||||
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