EXC_BAD_ACCESS с glTexImage2D в GLKViewController
У меня есть EXC_BAD_ACCESS
в последней строке этого кода (этот код запускается несколько раз в секунду), но я не могу понять, в чем проблема:
[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);
При отладке я проверяю, что текстура создана (идентификатор> 0), выходной кадр имеет действительный указатель на данные и является 4-канальной матрицей. Я внутри drawRect
метод GLKViewController. Я думаю, что мне не нужно связывать фреймбуфер, так как это одна из вещей, которые здесь автоматизированы. Это не сбой в первом кадре, но несколько десятков кадров позже.
Кто-нибудь может определить проблему?
ОБНОВИТЬ:
Кажется, это из-за состояния гонки на _outputFrame
обновляется во время чтения glTexImage2D
, Я постараюсь заблокировать его для чтения, затем доложу.
2 ответа
Это было действительно решение (см. ОБНОВЛЕНИЕ), я исправил это с 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];
Я только что разобрался в такой проблеме через несколько дней.
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;