Хобрук: Ваш путь к мастерству в программировании

Как отображать очень большие текстуры на основе металла в NSScrollView?

У меня есть программа, которая отображает изображение внутри NSScrollView. Я использую Metal для рендеринга изображения, поэтому NSClipView documentView - это MTKView. Я поддерживаю возможность увеличения / уменьшения изображения. Последние шаги конвейера рендеринга заключают мою текстуру Metal в CIImage, где я применяю фильтр CIAffineTransform для масштабирования. Я визуализирую изображение в drawRect в графическом виде следующим образом:

CIImage *image = ...;
CIRenderDestination *renderDest = [[CIRenderDestination alloc] initWithWidth:image.extent.size.width
                                                                      height:image.extent.size.height
                                                                 pixelFormat:self.colorPixelFormat
                                                               commandBuffer:commandBuffer
                                                          mtlTextureProvider:^id<MTLTexture> _Nonnull{
    return drawable.texture;
}];

[self.ciContext startTaskToRender:image
                    toDestination:renderDest
                            error:&error];

Когда размер представления документа изменяется, я обновляю свойство представления drawableSize. Это отлично работает, и полосы прокрутки и полосы прокрутки работают должным образом. Проблема в том, что когда коэффициент увеличения становится слишком большим, базовая текстура отрисовываемого объекта превышает объем памяти графического процессора:

validateTextureDimensions, line 1081: error 'MTLTextureDescriptor has width (18798) greater than the maximum allowed size of 16384.'
validateTextureDimensions:1081: failed assertion `MTLTextureDescriptor has width (18798) greater than the maximum allowed size of 16384.'

поэтому рисование обрезанного изображения в части чертежа не сработает (не то, чтобы я знал, как это сделать из CIImage). Это происходит, даже если я не рисую изображение в представлении (т.е. просто устанавливаю ожидаемый размер для рисования), что предполагает, что проблема в MTKView. Конечно, рисовать полное изображение мне не нужно; только та часть, которая видна в виде клипа. Я мог бы ограничить просмотр drawableSize / документа, но тогда мне пришлось бы эффективно реализовать прокрутку вручную и потерять полосы прокрутки.

Каков наилучший путь для стандартного режима прокрутки при отображении очень больших изображений? В качестве альтернативы, есть ли способ использовать что-то вроде CATiledLayer с Metal?


  • Я все еще на любительском уровне с металлом, но кажется, что было бы проще просто устранить посредника (CIImage) и самому нарисовать металл. Вы бы просто нарисовали два треугольника, чтобы покрыть прямоугольную область всей (без обрезки) текстуры, и ваш фрагментный шейдер будет просто сэмплировать из вашей текстуры. Таким образом, масштабирование будет происходить на графическом процессоре. Учитывая, что у вас уже есть MTLTexture и MTKView, это будет довольно просто (если вы осмотрите детали архитектуры рендеринга Metal). 24.06.2020
  • Я действительно хочу использовать фильтры Core Image, но более серьезная проблема заключается в том, что мне все еще нужна функциональность NSScroll (системная прокрутка и полосы прокрутки). 25.06.2020
  • Мне кажется, что при таком подходе вы получите стандартную функциональность NSScroll бесплатно. MTKView будет полным размером вашей увеличенной текстуры и будет встроен в представление прокрутки. Если вы правильно написали код, рисунок Metal вашей текстуры будет автоматически переведен и обрезан. Но да, если вы хотите использовать фильтры CI, очевидно, что CI должен быть задействован. Однако мне интересно: если вы хотите, чтобы CI изменил ваш имидж, нужно ли вам вообще задействовать Metal? Почему бы не отобразить изображение CI, возможно, преобразовав его в изображение CG? 25.06.2020
  • Я обнаружил, что MTKView не обрезался, отсюда и ошибка памяти. Metal и AppKit на самом деле не общаются друг с другом. Я ценю предложения! 01.07.2020

Ответы:


1

Я получил предложение от инженера Apple на форумах разработчиков, которое должно было разместить MTKView внутри представления документа NSScrollView, то есть:

NSScrollView
  NSClipView
    NSView <-- document view
      MTKView

Это имеет смысл, поскольку Metal и AppKit на самом деле не общаются друг с другом. С помощью этой схемы можно управлять размером представления документа, чтобы полосы прокрутки отображались правильно, и вручную установить MTKView не больше, чем то, что отображается в представлении клипа. Не идеальное решение, поскольку здесь задействовано много NSRect-математики, но, безусловно, выполнимое. (У меня еще не было времени реализовать его, но я обновлю этот ответ любой полезной информацией, если она появится.)

В ответе на форуме предлагается посмотреть на код, который синхронизирует два режима прокрутки в качестве хорошей отправной точки.

30.06.2020
Новые материалы

Создание кнопочного меню с использованием HTML, CSS и JavaScript
Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

Внедрите OAuth в свои веб-приложения для повышения безопасности
OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

Классы в JavaScript
class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

Как свинг-трейдеры могут использовать ИИ для больших выигрышей
По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

Как построить любой стол
Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...

Обзор: Машинное обучение: классификация
Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

Разработка расширений Qlik Sense с qExt
Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..