Проблемы с необычной настройкой NSOpenGLView
Я пытаюсь установить подкласс NSOpenGLView
необычным образом, и я сталкиваюсь с некоторыми проблемами. По сути, я пишу программу для моделирования биоинженерии для моего доктора наук, и мне нужно иметь возможность скомпилировать ее как под MacOSX, так и под Unix (моя машина - Mac, но сим в конечном итоге будет работать на более мощной машине Unix). Поскольку в течение следующих полутора лет код будет становиться все длиннее и длиннее, я бы не стал отслеживать две совершенно разные версии программы. Итак, я надеюсь, что смогу скомпилировать код ObjectiveC под Unix, избегая ObjectiveC-2.0 и оставляя интерфейс необязательным (он в основном будет там для выполнения настройки перед долгим моделированием и мониторинга вещей для коротких во время разработки).
Текущая версия хорошо работает без интерфейса - симуляция выполняется правильно, и программа способна рендерить кадры OpenGL и экспортировать их в графические и видеофайлы без каких-либо проблем. Так как я сейчас добавляю интерфейс (прямо сейчас просто окно с подклассом NSOpenGLView и кнопкой "Пуск") поверх этого (чтобы я мог запустить код с альтернативной версией main() без него), я приходится "соединять" OpenGL странным образом, поскольку код рисования находится не в функции drawRect или даже где-либо в подклассовом представлении, а вместо этого в "базовой" программе.
Что я сделал до сих пор это:
Основная программа (с использованием объекта "Решетка") выполняет все симуляции и рендеринг, корректно выводя изображения и видео в файлы. Это также содержит
NSOpenGLContext
и звонки[renderContext flushBuffer];
Подкласс NSOpenGLView с именем PottsView содержит экземпляр решетки, которая инициализируется вместе с представлением, подобным этому:
- (id)initWithFrame:(NSRect)frame { if(![super initWithFrame:frame]) return nil; // code frameSize.width = WIN_WIDTH; frameSize.height = WIN_HEIGHT; [self setFrameSize:frameSize]; init_genrand64(time(0)); latt = [Lattice alloc]; if (SEED_TYPE) { [latt initWithRandomSites]; } else { [latt initWithEllipse]; } [[latt context] makeCurrentContext]; return self; }
drawRect()
пустой.
- PottsController - это объект, созданный в InterfaceBuilder, который соединяет кнопку запуска с представлением. Кнопка "Пуск" просто говорит решетке выполнить несколько шагов.
Теперь нажатие кнопки start приводит к правильной работе симуляции (т.е. выводу в файлы и на терминал), но PottsView работает неправильно. Он остается белым, но если я cmd+tab частей, если он меняется на разделы визуализированного кадра. То же самое, если я нажимаю Expose (F3).
Я пробовал несколько комбинаций промывки, setNeedsDisplay
и т. д., но, честно говоря, я потерян. До апреля этого года я не занимался программированием, и, поскольку, насколько я могу судить, это совершенно обратный способ использования NSOpenGLView. У меня нет идей. Я надеюсь, что кто-то может подсказать, как я могу заставить работать текущую настройку или как полностью переписать программу (при этом оставляя интерфейс необязательным).
1 ответ
Непонятно, как вы думаете, что вы "связали" контекст и представление вместе. У вас может быть столько openglContexts, сколько вам нужно - просто рисование в одном из них не приведет к тому, что его содержимое отобразится в случайном NSOpenGLView. Извинения, если я что-то пропустил.
NSOpenGLView - это довольно простой подкласс NSView, который создает контекст и формат пикселей. Поскольку у вас уже есть такие, вы можете покончить с NSOpenGLView и использовать пользовательский подкласс NSView.
Вам следует взглянуть на эту инструкцию. Http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_drawing/opengl_drawing.html
Чтобы нарисовать на экране, вы должны очистить графический контекст от -drawRect:
Это заблокирует основной поток, пока gpu обрабатывает ваши инструкции, это может быть проблемой, если у вас много инструкций. Это также не может произойти более 50 кадров в секунду.
Если вы уже визуализируете свои фреймы в файлы, не лучше ли вам наблюдать за выходным каталогом и рисовать изображение каждый раз, когда добавляется новый, opengl не требуется?