more complicated viewport resizing logic to make sure viewport offset works

This commit is contained in:
a dinosaur 2024-09-21 22:06:48 +10:00
parent 86316ee42c
commit e6690c3e2b
4 changed files with 57 additions and 14 deletions

View File

@ -133,7 +133,7 @@ public class Application {
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
let backBufferSize = Size(Int(event.window.data1), Int(event.window.data2))
self.renderer!.resize(size: backBufferSize)
self.del.resize(backBufferSize)
self.del.resize(.init(origin: .zero, size: backBufferSize))
return .running
default:

View File

@ -3,13 +3,13 @@ public protocol GameDelegate {
func fixedUpdate(_ time: GameTime)
func update(_ time: GameTime)
func draw(_ renderer: Renderer, _ time: GameTime)
func resize(_ size: Size<Int>)
func resize(_ frame: Rect<Int>)
}
public extension GameDelegate {
func fixedUpdate(_ time: GameTime) {}
func update(_ time: GameTime) {}
func resize(_ size: Size<Int>) {}
func resize(_ frame: Rect<Int>) {}
}
public struct GameTime {

View File

@ -6,6 +6,7 @@ public class Keyboard {
case leftBracket
case right, left, up, down
case space, tab
case enter
}
public static func down(_ key: Keys) -> Bool {
@ -93,6 +94,7 @@ internal extension Keyboard.Keys {
case .down: SDLK_DOWN
case .space: SDLK_SPACE
case .tab: SDLK_TAB
case .enter: SDLK_RETURN
}
}
@ -131,6 +133,7 @@ internal extension Keyboard.Keys {
case .down: SDL_SCANCODE_DOWN
case .space: SDL_SCANCODE_SPACE
case .tab: SDL_SCANCODE_TAB
case .enter: SDL_SCANCODE_RETURN
}
}
}

View File

@ -3,13 +3,25 @@ import simd
internal class SpriteTestGame: GameDelegate {
private var spriteBatch: SpriteBatch!
private var player = TestPlayer(position: .one * 10)
private var player = TestPlayer(position: .one * 100)
private var texture: RendererTexture2D!
private var wireShark: RendererTexture2D!
private var level = TestLevel()
private var frame: Size<Float>!
var worldMousePosition: SIMD2<Float> {
var mpos = Mouse.position
if self.spriteBatch.viewport != .init(origin: .zero, size: self.frame) {
mpos /= SIMD2(self.frame)
mpos *= SIMD2(self.spriteBatch.viewport.size)
mpos += SIMD2(self.spriteBatch.viewport.origin)
}
return mpos
}
func create(_ renderer: Renderer) {
self.spriteBatch = renderer.createSpriteBatch()
self.resize(renderer.frame)
renderer.clearColor = .init(hue: 301.2, saturation: 0.357, value: 0.488).linear // .magenta.mix(.white, 0.4).mix(.black, 0.8)
self.texture = renderer.loadTexture(resourcePath: "test.png")
self.wireShark = renderer.loadTexture(resourcePath: "wireshark.png")
@ -22,7 +34,8 @@ internal class SpriteTestGame: GameDelegate {
if let pad = GameController.current?.state {
self.player.velocity.x = pad.leftStick.x.axisDeadzone(0.1, 0.8) * 660
if pad.pressed(.start) {
self.player.position = .one * 10
self.player.position = .one * 100
self.player.velocity = .zero
}
if pad.pressed(.east) && player.onGround {
self.player.velocity.y = -1000
@ -30,6 +43,10 @@ internal class SpriteTestGame: GameDelegate {
self.player.velocity.y = -550
}
}
if Keyboard.pressed(.enter) {
self.player.position = .one * 100
self.player.velocity = .zero
}
if Keyboard.down(.left) {
self.player.velocity.x = -660
} else if Keyboard.down(.right) {
@ -41,10 +58,11 @@ internal class SpriteTestGame: GameDelegate {
self.player.velocity.y = -550
}
let mpos = self.worldMousePosition
if Mouse.down(.left) {
self.level.set(SIMD2(Mouse.position / TestLevel.cellScale, rounding: .down), true)
self.level.set(SIMD2(mpos / TestLevel.cellScale, rounding: .down), true)
} else if Mouse.down(.right) {
self.level.set(SIMD2(Mouse.position / TestLevel.cellScale, rounding: .down), false)
self.level.set(SIMD2(mpos / TestLevel.cellScale, rounding: .down), false)
}
self.player.update(deltaTime: dt, level: self.level)
@ -93,11 +111,7 @@ internal class SpriteTestGame: GameDelegate {
position: doorPosition, transform: doorAffine, color: .red.mix(.white, 0.3))
// Draw mouse cursor
var mpos = Mouse.position
if self.spriteBatch.viewport.size != Size<Float>(renderer.frame.size) {
mpos /= SIMD2(Size<Float>(renderer.frame.size))
mpos *= SIMD2(self.spriteBatch.viewport.size)
}
let mpos = self.worldMousePosition
let inter = 0.5 + sin(Float(time.total) * 10) * 0.5
let color = Color<Float>.green.mix(.white, 0.3)
let mesh = Mesh<VertexPosition2DTexcoordColor, UInt16>.init(vertices: [
@ -115,8 +129,34 @@ internal class SpriteTestGame: GameDelegate {
self.spriteBatch.end()
}
func resize(_ size: Size<Int>) {
self.spriteBatch.viewport.size = Size<Float>(size)
func resize(_ frame: Rect<Int>) {
let viewport = Rect<Float>(frame)
self.frame = viewport.size
let rect = Rect<Float>(origin: .zero, size: .init(2560, 1440))
if viewport == rect {
self.spriteBatch.viewport = rect
return
}
let viewportRatio = viewport.w / viewport.h
let rectRatio = rect.w / rect.h
if abs(viewportRatio - rectRatio) <= .ulpOfOne * 10 { self.spriteBatch.viewport = rect }
else if viewportRatio > rectRatio {
let width = rect.h * viewportRatio
self.spriteBatch.viewport = .init(
x: (rect.w - width) * 0.5,
y: 0,
width: width,
height: rect.h)
} else {
let height = rect.w / viewportRatio
self.spriteBatch.viewport = .init(
x: 0,
y: (rect.h - height) * 0.5,
width: rect.w,
height: height)
}
}
}