【问题标题】:glGenerateMipmap fails if not followed by a glGetError... wait, what?如果后面没有 glGetError,glGenerateMipmap 会失败……等等,什么?
【发布时间】:2014-08-16 19:17:35
【问题描述】:

我在项目的纹理生成方面遇到了一个非常奇怪的问题。第一个 mipmapped 纹理完美无缺,但下一个仅绘制第一级。在调试时,我突然想到了一个修复它的技巧:

glGenTextures(1, &texture->textureID);
glBindTexture(GL_TEXTURE_2D, texture->textureID);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

glTexStorage2D(GL_TEXTURE_2D, 10, GL_RGBA8, width, height);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
glGenerateMipmap(GL_TEXTURE_2D);
assert(glGetError() == GL_NO_ERROR);    // Mipmapping fails if glGetError is not here

glBindTexture(GL_TEXTURE_2D, 0);

为什么只有在 glGenerateMimap 之后调用 glGetError(正如您在此断言中看到的那样,总是返回 GL_NO_ERROR)函数时才有效?为什么和它有关系?

我目前正在使用带有最新 GeForce 340.52 驱动程序的 GeForce GTX 670

编辑:几张图片可能会有所帮助

使用 glGetError():

没有 glGetError():

【问题讨论】:

  • “宽度”和“高度”的值是多少?无论如何,我同意这看起来令人费解。最可能的解释是驱动程序错误。
  • 如果这是你的问题,它们不是二的幂,尽管我的显卡支持它们。尽管如此,我还是会尝试使用 POT 图像,看看是否有什么不同。
  • 我实际上想检查它们是否至少为 512,否则为 glTexStorage2D() 指定 10 个级别将是一个错误。但既然你没有收到错误,我认为参数一定没问题。
  • 啊,我明白了。是的,他们是。我现在刚刚尝试了几张 1024x1024 图像,同样的事情发生了。我现在假设这是一个驱动程序错误,并在它们再次更新时重新检查。还是谢谢

标签: opengl mipmaps


【解决方案1】:

参考Is iOS glGenerateMipmap synchronous, or is it possibly asynchronous?,glGenerateMipmaps 似乎是异步工作的。我的项目使用共享上下文来创建着色器、纹理和网格(抱歉,如果我没有提到这一点,我认为这无关紧要)。

问题是,每当纹理生成完成时,“纹理生成”标志就会上升并且共享上下文将被破坏,因此似乎最后一个 glGenerateMipmap 没有通过管道刷新。对 glGetError 的调用需要从管道中刷新操作,以查看是否有任何错误需要报告,这正是它使一切工作完美无缺的原因。

因此,换句话说,如果您在单独的共享上下文中执行某项操作,则需要在终止该线程之前显式调用 glFinish,否则某些操作将被撤消。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-22
    • 2020-01-23
    • 2014-02-08
    • 1970-01-01
    • 2023-03-03
    • 2022-06-10
    • 2016-06-08
    • 2016-07-10
    相关资源
    最近更新 更多