MTKView - изменение размера текстуры для заполнения вида

Я новичок в Metal, но прилежно работаю над образцом проекта AVCamFilter от Apple. . Проект демонстрирует использование MTKView в качестве предварительного просмотра для AVCaptureSession.

Мне не удалось выяснить, как сделать мой MTKView рендерингом «в полноэкранном режиме» (особенно на iPhone X, XS и iPad Pro 3-го поколения). Хотя мои ограничения правильно установлены в раскадровке, предварительный просмотр моей камеры масштабируется до другого соотношения сторон, а не в полноэкранном режиме.

В качестве теста поставил;

self.clearColor = MTLClearColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)

в моем MTKView init, подтверждающем, что MTKView имеет правильный размер (я вижу красный фон в проблемных областях, но предварительный просмотр моей камеры не растягивается, чтобы заполнить экран).

Я считаю, что моя проблема существует в этом расчете;

// Calculate scale.
if textureWidth > 0 && textureHeight > 0 {
  switch textureRotation {
    case .rotate0Degrees, .rotate180Degrees:
      scaleX = Float(internalBounds.width / CGFloat(textureWidth))
      scaleY = Float(internalBounds.height / CGFloat(textureHeight))

    case .rotate90Degrees, .rotate270Degrees:
      scaleX = Float(internalBounds.width / CGFloat(textureHeight))
      scaleY = Float(internalBounds.height / CGFloat(textureWidth))
   }
}

// Resize aspect ratio.
resizeAspect = min(scaleX, scaleY)
if scaleX < scaleY {
  scaleY = scaleX / scaleY
  scaleX = 1.0
} else {
  scaleX = scaleY / scaleX
  scaleY = 1.0
}

В моей тестовой среде размер моей текстуры составляет 2400x1800, а мои внутренние границы - 834x1194. Хотя я осознаю разницу в соотношении сторон, я пытаюсь вычислить правильную математику, чтобы текстура заполняла весь дисплей (даже если это означает, что она немного меньше масштабируется, и я теряю часть текстуры по бокам).

Может кто-нибудь посоветовать? Спасибо!


person ZbadhabitZ    schedule 21.02.2019    source источник
comment
Где-то будет область просмотра, которую необходимо обновить с учетом нового размера представления. Это окно просмотра будет установлено на MTLRenderCommandEncoder во время рендеринга. Это то, что влияет на размер визуализированного вывода.   -  person trojanfoe    schedule 22.02.2019
comment
Спасибо за ответ @trojanfoe. Я проверил свой файл MTLView и предоставленную документацию, но, похоже, ничего в файле не ссылается на область просмотра. В частности, этот файл является один, над которым я работаю, и функция draw(), как я полагаю, - это то место, где будет установлено окно просмотра, хотя рабочий образец от Apple не имеет такой ссылки.   -  person ZbadhabitZ    schedule 22.02.2019
comment
Это в методе MTKView делегата MTKView:drawableSizeWillChange:.   -  person trojanfoe    schedule 22.02.2019
comment
Спасибо за комментарий, @trojanfoe. К сожалению, я не думаю, что у меня есть MTKViewDelegate в этом проекте. Я просмотрел весь образец и нигде не нашел drawableSizeWillChange метода.   -  person ZbadhabitZ    schedule 22.02.2019
comment
Хорошо, я действительно загрузил и посмотрел образец, и, похоже, он получает размер от internalPixelBuffer, размер которого равен self.bounds, и поэтому он должен работать независимо от размера представления (как и следовало ожидать). Вы, вероятно, должны подозревать свою конфигурацию ограничений. Извините за потраченное время на предположения по поводу реализации,   -  person trojanfoe    schedule 23.02.2019
comment
Нет проблем, @trojanfoe. Спасибо, что изучили это! Что любопытно, если я установил цвет фона на моем MTKView, пустые области будут правильно отображать цвет фона. Это наводит меня на мысль, что мои ограничения верны, но масштабирование предварительного просмотра камеры не принимает во внимание обновленные размеры экрана на новых устройствах. На самом деле я нашел еще один образец проекта Apple, в котором есть похожий предварительный просмотр Metal, но он работает так, как я ожидал, и я работаю над прочесыванием кода, чтобы найти разницу. Я обновлю вопрос, если смогу разобраться!   -  person ZbadhabitZ    schedule 23.02.2019
comment
Есть обновления? сталкивается с той же проблемой @ZbadhabitZ   -  person Kevin    schedule 28.06.2020


Ответы (2)


// Resize aspect ratio.
resizeAspect = min(scaleX, scaleY)

if scaleX < scaleY {
  scaleY = scaleX / scaleY
  scaleX = 1.0
} else {
  scaleX = scaleY / scaleX
  scaleY = 1.0
}

Заменить

// Resize aspect ratio.
// For AspectFill Screen scaleX > scaleY
// For AspectFit Screen scaleX < scaleY
    
resizeAspect = min(scaleX, scaleY)
if scaleX > scaleY {
   scaleY = scaleX / scaleY
   scaleX = 1.0
} else {
   scaleX = scaleY / scaleX
  scaleY = 1.0
}
person Urmit Chauhan    schedule 01.03.2021

person    schedule
comment
Добро пожаловать в SO, ваш ответ может решить проблему, но он также должен объяснить ваше решение, по крайней мере, в нескольких предложениях. это помогает сделать ваш ответ более читабельным. пожалуйста, попробуйте добавить его, отредактировав свой ответ. - person Saeed Zhiany; 15.10.2019
comment
Захваченное изображение не будет таким же, как PreviewView. Вам не кажется, что это важно здесь упомянуть? - person Abhishek Dave; 22.10.2020