Как разделить текстуры между NSOpenGLView и полноэкранным контекстом в Mac OS? - PullRequest
3 голосов
/ 28 февраля 2011

Я работаю над приложением, которое использует 2D текстуры для создания анимированных калейдоскопов. Он начинает отображаться в NSOpenGLView. Я добавляю опцию для переключения в полноэкранный режим.

Я бы предпочел использовать подход OS 10.5 для полноэкранного режима, чтобы я мог поддерживать 10.5, но я думаю, что столкнулся бы с той же проблемой, если бы я использовал подход, описанный в документации в разделе «Создание полноэкранного приложения в Mac» OS X v10.6 ".

Метод инициализации NSOpenGLContext initWithFormat: shareContext: принимает необязательный указатель на «Другой графический контекст OpenGL, чье пространство имен текстуры и списки отображения, которые вы хотите передать получателю».

Код, который я использую для создания полноэкранного контекста OpenGL, прост:

NSOpenGLPixelFormatAttribute myAttributes[] =               // Pixel Format Attributes for the FullScreen NSOpenGLContext
{
    NSOpenGLPFAFullScreen,                                  // specify full-screen OpenGL context
    NSOpenGLPFAScreenMask,
    CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay),   // specify main display
    NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute) 32,
    NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute) 0,
    NSOpenGLPFAStencilSize, 0,
    NSOpenGLPFADoubleBuffer,
    NSOpenGLPFAAccelerated,
    0
};

NSOpenGLPixelFormat *myPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:myAttributes];  // Create FullScreen NSOpenGLContext with these attributes


NSOpenGLContext *fullScreenContext = [[NSOpenGLContext alloc] initWithFormat:myPixelFormat shareContext: myContext]; // Create an NSOpenGLContext with the FullScreen pixel format.

Однако, похоже, это не работает.

Мое приложение использует только одну текстуру, поэтому я начал с использования glGenTextures и glBindTexture. Вместо этого я просто использовал текущую текстуру для контекста.

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

Я не получаю никаких ошибок, но рисование с текстурой ничего не делает.

Я вынужден пересоздавать свою текстуру каждый раз, когда я переключаюсь в полноэкранный режим. Это плохо, потому что текстуры потенциально очень большие (в зависимости от размера изображения, загружаемого пользователем, вплоть до максимального размера текстуры). Это заставляет меня загружать две копии очень большого объекта в VRAM. Хуже того, в некоторых случаях мне приходится выполнять обход байтов, чтобы получить правильный порядок байтов. На большую текстуру уходит несколько секунд, что делает «беременную паузу» при входе в полноэкранный режим.

Есть ли какая-то хитрость, которой мне не хватает для совместного использования текстур между NSOpenGLView и полноэкранным контекстом OpenGL?

1 Ответ

0 голосов
/ 25 мая 2017

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

Совет: работа с API рисования, таким как DirectX и OpenGL, без правильного инструмента проверки (см. Khronos или NVidia для веб-сайта разработчика) может быть очень болезненной. Правильный инструмент - это первое, что вам нужно.

  1. Вы создали новый NSOpenGLContext, инициализируя его в том же формате пикселей и обозначая другой контекст в качестве источника для совместного использования ресурсов. Отлично!
  2. Вы должны присвоить его своему NSOpenGLView, используя метод setOpenGLContext. (нет необходимости в update, setview или других вещах, которые я видел в Интернете в очень старом посте)
    • если вы создали свое окно с использованием файлов xib, вы можете использовать метод awakeFromNib класса NSOpenGLView, чтобы изменить контекст по умолчанию на новый только что созданный
    • старый контекст, прикрепленный к представлению, будет автоматически уничтожен
    • любой ранее существующий ресурс в общем контексте будет «импортирован» и в новый.
  3. вызов [your_new_Context makeCurrentContext] - я сделал это в методе awakeFormNib
  4. (И здесь я думаю, что проблема @Duncan), вам нужно установить все необходимое состояние рендеринга. Состояние рендеринга не передается через контекст! Только ресурсы. Вот некоторые состояния рендеринга, которые вы хотите установить (измените их в соответствии с вашими потребностями):

    * +1032 * glEnableVertexAttribArray (pgmImagePosition_); glEnableVertexAttribArray (pgmImageTextureCoord_); glEnable (GL_TEXTURE_2D); glDisable (GL_DITHER); glDisable (GL_ALPHA_TEST); glDisable (GL_BLEND); glDisable (GL_STENCIL_TEST); glDisable (GL_FOG); glDisable (GL_DEPTH_TEST); glPixelZoom (1.0,1.0); glClearColor (0,1, 0,1, 0,1, 1,0);

Надеюсь, это поможет. Значение https://developer.apple.com/library/content/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_contexts/opengl_contexts.html все еще предлагается.

...