2014-09-28 2 views
1

У меня есть EXC_BAD_ACCESS в последней строке этого кода (этот код обжигают несколько раз в секунду), но я не могу понять, в чем проблема:EXC_BAD_ACCESS с glTexImage2D в GLKViewController

[EAGLContext setCurrentContext:_context]; 
glActiveTexture(GL_TEXTURE0); 
glPixelStorei(GL_PACK_ALIGNMENT, 1); 
glBindTexture(GL_TEXTURE_2D, _backgroundTexture); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _outputFrame.cols, _outputFrame.rows, 0, GL_BGRA, GL_UNSIGNED_BYTE, _outputFrame.data); 

При отладке я убедитесь, что текстура создана (id> 0), выходной кадр имеет действительный указатель на данные и представляет собой 4-канальную матрицу. Я внутри метода drawRect GLKViewController. Я думаю, мне не нужно было привязывать фреймбуфер, так как это одна из вещей, которые автоматизированы здесь. Это не сбой при первом кадре, а несколько десятков кадров позже.

Может ли кто-нибудь обнаружить проблему?

UPDATE:

Кажется, это из-за состояния гонки на _outputFrame, она обновляется в то же время читать glTexImage2D. Я попытаюсь заблокировать его для чтения, а затем отчитаюсь.

+0

Было бы неплохо, если бы вы могли опубликовать свое решение, чтобы другие могли извлечь выгоду из него, если у них возникнет аналогичная проблема. – Unheilig

+0

Я разместил его, но не знаю, может ли он быть полезным кому угодно, поскольку он очень специфичен ... – aledalgrande

ответ

1

Это решение действительно (см UPDATE), я установил его с NSLock. Во-первых, я сменил переменную экземпляра _outputFrame с временным тот, который обновляется из другого потока и использовать блокировку, чтобы обновить переменную экземпляра:

[_frameLock lock]; 
_outputFrame = temp; 
[_frameLock unlock]; 

Затем используется замок, когда я хотел прочитать из переменной экземпляра:

glActiveTexture(GL_TEXTURE0); 
glPixelStorei(GL_PACK_ALIGNMENT, 1); 
glBindTexture(GL_TEXTURE_2D, _backgroundTexture); 
[_frameLock lock]; 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _outputFrame.cols, _outputFrame.rows, 0, GL_BGRA, GL_UNSIGNED_BYTE, _outputFrame.data); 
[_frameLock unlock]; 
0

Я как раз понял некоторые проблемы, подобные этому через несколько дней.

1. better avoid rendering in multi-thread 
2. better render in GLKView with base affect, and don't manually manage framebuffer& render buffer by yourself 
3. base effect render raw pixel data like this 

Мое решение:

glTexImage2D(...); 
self.baseEffect.texture2d0.envMode = GLKTextureEnvModeReplace; 
self.baseEffect.texture2d0.target = GLKTextureTarget2D; 
self.baseEffect.texture2d0.name = texture; 
self.baseEffect.texture2d0.enabled = YES; 
self.baseEffect.useConstantColor = YES; 
+0

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