EXC_BAD_ACCESS 与 GLKViewController 中的 glTexImage2D
Posted
技术标签:
【中文标题】EXC_BAD_ACCESS 与 GLKViewController 中的 glTexImage2D【英文标题】:EXC_BAD_ACCESS with glTexImage2D in GLKViewController 【发布时间】:2014-09-28 06:26:36 【问题描述】:我在这段代码的最后一行有一个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);
在调试时,我确保创建了纹理(id > 0),输出帧有一个指向数据的有效指针,并且是一个 4 通道矩阵。我在 GLKViewController 的 drawRect
方法中。我认为我不应该绑定帧缓冲区,因为它是这里自动化的事情之一。 它不会在第一帧崩溃,而是在几十帧之后崩溃。
有人能发现问题吗?
更新:
似乎是因为_outputFrame
上的竞争条件,它正在被glTexImage2D
读取时更新。我会尝试锁定它以供阅读,然后再报告。
【问题讨论】:
如果您能发布您的解决方案,那就太好了,这样如果其他人遇到类似问题,他们也可以从中受益。 我贴出来了,不知道对大家有没有用,因为很具体... 【参考方案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];
【讨论】:
【参考方案2】:几天后我才发现这样的问题。
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;
【讨论】:
我编辑了您的帖子的语法和布局。感谢您的反馈,但我不知道您为什么建议不要使用多线程,因为它确实取决于具体情况,而且我使用的是自定义着色器,而不是 GLKBaseEffect。以上是关于EXC_BAD_ACCESS 与 GLKViewController 中的 glTexImage2D的主要内容,如果未能解决你的问题,请参考以下文章
UIButton 导致 (lldb) 错误与 EXC_BAD_ACCESS
程序接收信号:带有Core Data的“EXC_BAD_ACCESS”