2013-09-03 3 views
1

У меня возникли проблемы с поиском правильного места для настройки шейдера для приложения OpenGLES с использованием GLKView и GLKViewController.Правильное место для настройки шейдеров для GLKView?

Кажется, что viewDidLoad - это естественное место для этого, но создание шейдера терпит неудачу, когда я пытаюсь сделать это здесь. Моя установка что-то вроде этого:

//shader helper method 
int setupShaders(const char* vShader, const char* fShader); //returns a program handle 

//inside GLKViewController subclass 

static int program; 

-(void)viewDidLoad{ 
    [super viewDidLoad]; 
    program = setupShaders(vsh, fsh); //program will be zero indicating setup failure 
} 

Я знаю, что код установки работает, потому что это удастся, если я называю это внутри - (Недействительными) glkView: (GLKView *) вид drawInRect: (CGRect) Прямоугольник.

Так что я предполагаю, что OpenGL не полностью инициализирован, когда вызывается (void) viewDidLoad, или что-то нужно сделать, чтобы установить правильный контекст OpenGL для настройки, которую я пытаюсь сделать, t найти документацию о том, где и как правильно выполнить настройку.

ответ

0

Так получилось, что он отлично работает, если вы инициализируете изнутри - (void) viewDidAppear. Решение Джейкоба прекрасно работает, но мне кажется, что мне немного проще использовать обратный вызов, а не добавлять условие к методу рисования.

2

Вы правы, что самое раннее место, где вы можете легко настроить свои шейдеры, находится в методе drawRect. Это связано с тем, что должен существовать действительный ток контекста GL. Пер в GLKView documentation:

Перед вызовом его DrawRect: метод, вид делает его объект EAGLContext текущий контекст OpenGL ES и связывает его фреймбуфера объект контекста OpenGL ES в качестве цели для рендеринга команд.

Таким образом, проще всего повесить на какую-либо информацию, например, дескриптор program, и только инициализировать, если он отличен от нуля.

if (program == 0) 
    program = setupShaders(vsh, fsh); 

Если вам не нравится этот подход, вы можете рассмотреть инициализации вашего GLKView с контекстом, которую вы предоставляете, или переопределения bindDrawable. Или вы не могли использовать GLKView и делать что-то вручную ...

1

Перед тем, как вы можете позвонить любому API OpenGL ES, должен быть ток EAGLContext, который включает в себя работу по настройке, например, компиляцию шейдеров. GLKView делает свой контекст актуальным перед вызовом метода drawRect: (или glkView:drawInRect:), но вы можете сделать его текущим контекстом в любое время.

Контекст вида является текущим, начиная с viewDidAppear:, потому что этот метод вызывается после того, как первый раз сам вид рисуется. Я не уверен, что в этот момент гарантированно будет актуальным, - нет документального контракта API, что контекст GLKView останется актуальным после окончания чертежа. Поэтому лучше всего позвонить [EAGLContext setCurrentContext:myContext], когда захотите выполнить настройку для своей сцены OpenGL ES (даже если вы решите сделать это в viewDidAppear:).

Смотрите игры шаблон OpenGL ES, когда вы создаете новый проект Xcode для примера установки GLKView/GLKViewController.