graphics: Bug fix: fullscreen rendering was wrong

After fad65f2f5d, the viewport size
is always same as the framebuffer size. The 'screen' image size
was the actual rendering region size, and padding was not
considered in the size. The padding is added on the fullscreen
mode.

This fix adds the extra padding values to the 'screen' image size
so that the 'screen' framebuffer will be same size as the monitor
size.

Fixes #693
This commit is contained in:
Hajime Hoshi 2018-09-29 21:47:39 +09:00
parent fad65f2f5d
commit 15260537a2
2 changed files with 32 additions and 22 deletions

View File

@ -15,8 +15,9 @@
package ebiten package ebiten
import ( import (
"math"
"github.com/hajimehoshi/ebiten/internal/clock" "github.com/hajimehoshi/ebiten/internal/clock"
"github.com/hajimehoshi/ebiten/internal/graphics"
"github.com/hajimehoshi/ebiten/internal/hooks" "github.com/hajimehoshi/ebiten/internal/hooks"
"github.com/hajimehoshi/ebiten/internal/shareable" "github.com/hajimehoshi/ebiten/internal/shareable"
"github.com/hajimehoshi/ebiten/internal/ui" "github.com/hajimehoshi/ebiten/internal/ui"
@ -30,14 +31,16 @@ func newGraphicsContext(f func(*Image) error) *graphicsContext {
} }
type graphicsContext struct { type graphicsContext struct {
f func(*Image) error f func(*Image) error
offscreen *Image offscreen *Image
screen *Image screen *Image
screenScale float64 screenWidth int
initialized bool screenHeight int
invalidated bool // browser only screenScale float64
offsetX float64 initialized bool
offsetY float64 invalidated bool // browser only
offsetX float64
offsetY float64
} }
func (c *graphicsContext) Invalidate() { func (c *graphicsContext) Invalidate() {
@ -61,8 +64,10 @@ func (c *graphicsContext) SetSize(screenWidth, screenHeight int, screenScale flo
w := int(float64(screenWidth) * screenScale) w := int(float64(screenWidth) * screenScale)
h := int(float64(screenHeight) * screenScale) h := int(float64(screenHeight) * screenScale)
px0, py0, _, _ := ui.ScreenPadding() px0, py0, px1, py1 := ui.ScreenPadding()
c.screen = newImageWithScreenFramebuffer(w, h) c.screen = newImageWithScreenFramebuffer(w+int(math.Ceil(px0+px1)), h+int(math.Ceil(py0+py1)))
c.screenWidth = w
c.screenHeight = h
c.offsetX = px0 c.offsetX = px0
c.offsetY = py0 c.offsetY = py0
@ -110,20 +115,18 @@ func (c *graphicsContext) Update(afterFrameUpdate func()) error {
if c.offsetX > 0 || c.offsetY > 0 { if c.offsetX > 0 || c.offsetY > 0 {
op := &DrawImageOptions{} op := &DrawImageOptions{}
w, h := emptyImage.Size() w, h := emptyImage.Size()
s := float64(graphics.MaxImageSize()) sw, sh := c.screen.Size()
op.GeoM.Scale(s/float64(w), s/float64(h)) op.GeoM.Scale(float64(sw)/float64(w), float64(sh)/float64(h))
op.CompositeMode = CompositeModeCopy op.CompositeMode = CompositeModeCopy
c.screen.DrawImage(emptyImage, op) c.screen.DrawImage(emptyImage, op)
} }
_, dh := c.screen.Size()
op := &DrawImageOptions{} op := &DrawImageOptions{}
// c.screen is special: its Y axis is down to up, // c.screen is special: its Y axis is down to up,
// and the origin point is lower left. // and the origin point is lower left.
op.GeoM.Scale(c.screenScale, -c.screenScale) op.GeoM.Scale(c.screenScale, -c.screenScale)
// Make dh an even number to fit the upper side of the screen (#662). // Make the screen height an even number to fit the upper side of the screen (#662).
op.GeoM.Translate(0, float64((dh+1)/2*2)) op.GeoM.Translate(0, float64((c.screenHeight+1)/2*2))
op.GeoM.Translate(c.offsetX, c.offsetY) op.GeoM.Translate(c.offsetX, c.offsetY)
op.CompositeMode = CompositeModeCopy op.CompositeMode = CompositeModeCopy

View File

@ -380,17 +380,24 @@ func ScreenPadding() (x0, y0, x1, y1 float64) {
ox := (float64(u.windowWidth)*u.actualScreenScale() - float64(u.width)*u.actualScreenScale()) / 2 ox := (float64(u.windowWidth)*u.actualScreenScale() - float64(u.width)*u.actualScreenScale()) / 2
return ox, 0, ox, 0 return ox, 0, ox, 0
} }
ox := 0.0
oy := 0.0
m := glfw.GetPrimaryMonitor() m := glfw.GetPrimaryMonitor()
v := m.GetVideoMode() v := m.GetVideoMode()
d := devicescale.DeviceScale() d := devicescale.DeviceScale()
mx := float64(v.Width) * d / glfwScale()
my := float64(v.Height) * d / glfwScale()
sx := 0.0
sy := 0.0
_ = u.runOnMainThread(func() error { _ = u.runOnMainThread(func() error {
ox = (float64(v.Width)*d/glfwScale() - float64(u.width)*u.actualScreenScale()) / 2 sx = float64(u.width) * u.actualScreenScale()
oy = (float64(v.Height)*d/glfwScale() - float64(u.height)*u.actualScreenScale()) / 2 sy = float64(u.height) * u.actualScreenScale()
return nil return nil
}) })
return ox, oy, ox, oy ox := (mx - sx) / 2
oy := (my - sy) / 2
return ox, oy, (mx - sx) - ox, (my - sy) - oy
} }
func AdjustedCursorPosition() (x, y int) { func AdjustedCursorPosition() (x, y int) {