4

在过去的常规 OpenGL 中,确定纹理上传是否成功是相当容易的——在调用 glTexImage2D 之后,您可以使用带有 GL_TEXTURE_WIDTH 和 GL_TEXTURE_HEIGHT 作为参数的 glGetTexLevelParameteriv。然而,GLES 似乎不允许这样做,据我所知,它没有机制来确定纹理是否实际上已成功提供给卡(例如,glGetError 仅针对不会成功的事情设置,与没有成功的事情相反)。

我正在处理的应用程序总是跨越是否有足够的 VRAM 可用(并且经常有很多动态分配的 FBO 等飞来飞去,使事情进一步复杂化),如果重要的纹理上传失败,我需要知道我是否需要清除不重要的纹理并重试。

4

1 回答 1

4

我担心目前这是不可能的。现在删除了包含纹理大小的整个 OpenGL 状态(根据 GLES 2.0.25 规范)。正如您正确陈述的那样,纹理上传出错时不会产生错误(可悲的是设计使然)。代理纹理已被删除,人们报告称它们在 PC 级 GPU 上通常不受支持/损坏。所以现在怎么办?

您可以尝试通过帧缓冲区对象读取纹理内容(可能不是整个纹理,但只有角点/每 32 个像素/...)。它不会很快,但它应该可以工作。也许您也可以使用附加纹理的帧缓冲区完整性测试(但这似乎仅限于图像内部格式,如果由于内存不足而导致纹理上传失败,可能会或可能不会设置 - 您必须进行测试) .

您可以(理论上)通过创建渲染缓冲区对象来确定可用内存量,规范指出 glRenderbufferStorage() 将因 GL_OUT_OF_MEMORY 而失败,因此应该非常可靠。

在分配纹理之前测试可用空间非常容易,然后删除渲染缓冲区(如果成功),然后分配纹理本身。请记住,使用 mipmap 时,基本级别的纹理将占用 1.33 倍多一点的存储空间。

更好的是在应用程序启动时确定可用内存(可能在编译着色器并分配其他不容易估计内存占用的对象之后)并跟踪对象分配以查看剩余多少内存。看起来很复杂,但是如果将 OpenGL 对象包装在类中,那应该很容易。

于 2012-01-11T15:59:10.753 回答