在常规OpenGL的旧时代,确定纹理上传是否成功相当容易 - 在调用glTexImage2D之后,您可以使用glGetTexLevelParameteriv将GL_TEXTURE_WIDTH和GL_TEXTURE_HEIGHT作为参数。然而,GLES似乎不允许这样做,据我所知,没有机制来确定纹理是否实际上已成功提供给卡(例如,glGetError仅设置为将会不成功,而不是没有成功的事情。)
我正在研究的应用程序总是跨越障碍,在有足够的VRAM可用之间(而且经常有很多动态分配的FBO等飞来飞去,使问题更加复杂),如果重要的纹理上传失败我需要知道是否需要清除不重要的纹理并重试。
答案 0 :(得分:4)
我担心目前这是不可能的。现在删除了包含纹理大小的整个OpenGL状态(根据GLES 2.0.25规范)。正如您所说的那样,纹理上传出错时没有产生错误(遗憾的是设计)。代理纹理被删除,人们报告说它们在PC级GPU上经常得不到支持/破坏。那么现在呢?
您可以尝试通过framebuffer对象读取纹理内容(可能不是整个纹理,但只有角点/每隔32个像素/ ...)。它不会很快,但它应该工作。也许你也可以使用附加纹理的帧缓冲完整性测试(但这似乎仅限于图像内部格式,如果由于内存不足导致纹理上传失败,可能会也可能不会设置 - 你必须测试它)
你可以(理论上)通过创建一个renderbuffer对象来确定可用内存量,规范说明glRenderbufferStorage()会因GL_OUT_OF_MEMORY而失败,所以它应该非常可靠。
在分配纹理之前测试自由空间,然后删除渲染缓冲区(如果成功)然后分配纹理本身将非常容易。请记住,使用mipmap时,纹理对于基本级别来说需要多于1.33倍的存储空间。
更好的方法是在应用程序启动时确定可用内存(可能在编译着色器并分配其他不容易估计内存占用的对象之后)并跟踪对象分配以查看剩余的内存量。这似乎很复杂,但如果OpenGL对象包含在类中,那应该很容易。