OpenGL渲染带鱼眼校正的相机画面时白屏闪烁问题求助
分析与解决方案
首先,先帮你拆解这个问题:错误代码NCGSYS_FrameMemAlloc : AllocateAnyMemoryRegion (Kernel) failed - 138本质是GPU显存或系统内存分配失败,结合你的代码来看,最可能的根源是纹理资源泄漏,再加上一些小的代码逻辑问题,共同导致了偶尔的白屏闪烁。
核心问题:重复创建纹理导致显存泄漏
你的代码里每次处理相机帧时都调用glGenTextures(1, &textureID),这会在GPU上不断生成新的纹理对象,但从来没有销毁旧的。随着运行时间增加,显存会被这些废弃的纹理占满,最终触发内存分配失败,出现白屏。
修复方案:
把纹理的创建移到初始化阶段(只执行一次),在渲染循环里只用glTexSubImage2D更新纹理数据,而不是每次都生成新纹理:
// 初始化阶段(只跑一次) glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); // 设置纹理参数(只需要设置一次) glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // 先分配一个空纹理占位 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 600, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); // 渲染循环(每帧执行) // 从共享内存获取buf后,更新纹理数据 glBindTexture(GL_TEXTURE_2D, textureID); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1024, 600, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)buf); // 后续的顶点属性、绘制逻辑... glVertexAttribPointer ( positionLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vVertices ); glVertexAttribPointer ( texCoordLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &vVertices[3] ); glEnableVertexAttribArray ( positionLoc ); glEnableVertexAttribArray ( texCoordLoc ); // 注意:先设置清屏颜色,再执行清屏 glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D,textureID); glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices ); eglSwapBuffers();
其他需要修正的细节
- 清屏顺序错误:你现在是先调用
glClear再设置glClearColor,这会导致第一帧之后的清屏颜色可能不是你预期的黑色,虽然不是白闪的直接原因,但会导致画面异常,调整顺序为先设颜色再清屏。 - 冗余的
glEnable(GL_TEXTURE_2D):如果你用的是现代OpenGL(核心模式),这个调用是多余的;如果是固定管线模式,它也只需要在初始化时调用一次,不需要每帧都执行。
额外排查方向
如果修复纹理泄漏后仍然出现问题,需要检查:
- 共享内存的
buf是否每次使用后都正确释放,避免系统内存耗尽间接影响GPU内存分配; - 鱼眼校正的片段着色器是否有异常逻辑(比如过度的内存占用、非法访问),导致驱动层面的内存分配异常;
- 显卡驱动是否为最新版本,旧驱动可能存在内存管理的bug。
内容的提问来源于stack exchange,提问作者senthil
相关产品推荐
相关产品推荐

