Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 43 additions & 6 deletions DeltaCore/UI/Game/GameView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public enum SamplerMode
{
case linear
case nearestNeighbor
case pixelPerfect
}

public class GameView: UIView
Expand Down Expand Up @@ -75,7 +76,7 @@ public class GameView: UIView
switch self.samplerMode
{
case .linear: image = inputImage.samplingLinear()
case .nearestNeighbor: image = inputImage.samplingNearest()
case .nearestNeighbor, .pixelPerfect: image = inputImage.samplingNearest()
}

if let filter = self.filter
Expand Down Expand Up @@ -125,6 +126,8 @@ public class GameView: UIView
private var didLayoutSubviews = false
private var didRenderInitialFrame = false
private var isRenderingInitialFrame = false
private var pixelAlignmentOffset = CGPointZero
private var lastGLKOffset = CGPointZero

private var isUsingMetal: Bool {
let isUsingMetal = (self.eaglContext == nil)
Expand Down Expand Up @@ -154,7 +157,7 @@ public class GameView: UIView
}

private func initialize()
{
{
self.glkView.frame = self.bounds
self.glkView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.glkView.delegate = self.glkViewDelegate
Expand Down Expand Up @@ -187,6 +190,8 @@ public class GameView: UIView
public override func layoutSubviews()
{
super.layoutSubviews()
self.pixelAlignmentOffset.y = ceil(self.frame.minY) - self.frame.minY
self.pixelAlignmentOffset.x = ceil(self.frame.minX) - self.frame.minX

if self.outputImage != nil
{
Expand Down Expand Up @@ -348,7 +353,26 @@ private extension GameView

if let outputImage = self.outputImage
{
let bounds = CGRect(x: 0, y: 0, width: self.glkView.drawableWidth, height: self.glkView.drawableHeight)
let x, y, width, height: CGFloat
switch samplerMode {
case .pixelPerfect:
width = floor(CGFloat(self.glkView.drawableWidth) / outputImage.extent.width) * outputImage.extent.width
height = floor(CGFloat(self.glkView.drawableHeight) / outputImage.extent.height) * outputImage.extent.height
x = floor((CGFloat(self.glkView.drawableWidth) - width) / 2)
y = floor((CGFloat(self.glkView.drawableHeight) - height) / 2)
if lastGLKOffset != pixelAlignmentOffset {
DispatchQueue.main.async {
self.glkView.frame.origin = self.pixelAlignmentOffset
self.lastGLKOffset = self.glkView.frame.origin
}
}
default:
width = CGFloat(self.glkView.drawableWidth)
height = CGFloat(self.glkView.drawableHeight)
x = 0
y = 0
}
let bounds = CGRect(x: x, y: y, width: width, height: height)
self.openGLESContext.draw(outputImage, in: bounds, from: outputImage.extent)
}
}
Expand All @@ -368,8 +392,21 @@ extension GameView: MTKViewDelegate
let currentDrawable = self.metalLayer?.nextDrawable()
else { return }

let scaleX = view.drawableSize.width / image.extent.width
let scaleY = view.drawableSize.height / image.extent.height
let scaleX, scaleY, offsetX, offsetY: CGFloat

switch samplerMode {
case .pixelPerfect:
scaleX = floor(view.drawableSize.width / image.extent.width)
scaleY = floor(view.drawableSize.height / image.extent.height)
offsetX = floor((view.drawableSize.width - image.extent.width * scaleX) / 2)
offsetY = floor((view.drawableSize.height - image.extent.height * scaleY) / 2)
self.metalLayer?.frame.origin = self.pixelAlignmentOffset
default:
scaleX = view.drawableSize.width / image.extent.width
scaleY = view.drawableSize.height / image.extent.height
offsetX = 0
offsetY = 0
}
let outputImage = image.transformed(by: CGAffineTransform(scaleX: scaleX, y: scaleY))

do
Expand All @@ -383,7 +420,7 @@ extension GameView: MTKViewDelegate
return texture
}

try self.metalContext.startTask(toRender: outputImage, from: outputImage.extent, to: destination, at: .zero)
try self.metalContext.startTask(toRender: outputImage, from: outputImage.extent, to: destination, at: CGPoint(x: offsetX, y: offsetY))

commandBuffer.present(currentDrawable)
commandBuffer.commit()
Expand Down