设置GL_TEXTURE_MAX_ANISOTROPY_EXT会导致下一帧崩溃

Setting GL_TEXTURE_MAX_ANISOTROPY_EXT causes crash on next frame

本文关键字:崩溃 一帧 TEXTURE GL MAX ANISOTROPY EXT 设置      更新时间:2023-10-16

我使用OpenGL 3.3和延迟着色。

当我在帧之间为采样器设置各向异性值时,下一帧会导致glClear下一帧崩溃。

以下是我如何设置各向异性值:

bool OpenGLRenderer::SetAnisotropicFiltering(const float newAnisoLevel)
{
    if (newAnisoLevel < 0.0f || newAnisoLevel > GetMaxAnisotropicFiltering())
        return false;
    mCurrentAnisotropy = newAnisoLevel;
    // the sampler used for geometry pass
    GLCALL(glSamplerParameterf(mTextureSampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, mCurrentAnisotropy));
    // the sampler used in shading pass
    GLCALL(glSamplerParameterf(mGBuffer.mTextureSampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, mCurrentAnisotropy));
    return true;
}

几何体过程具有以下漫反射/法线纹理,设置如下:

    GLCALL(glUseProgram(mGeometryProgram.mProgramHandle));
    GLCALL(glGenSamplers(1, &mTextureSampler));
    GLCALL(glSamplerParameteri(mTextureSampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
    GLCALL(glSamplerParameteri(mTextureSampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR));
    GLCALL(glSamplerParameteri(mTextureSampler, GL_TEXTURE_WRAP_S, GL_REPEAT));
    GLCALL(glSamplerParameteri(mTextureSampler, GL_TEXTURE_WRAP_T, GL_REPEAT));
    GLCALL(glUniform1i(glGetUniformLocation(mGeometryProgram.mProgramHandle, "unifDiffuseTexture"), OpenGLTexture::TEXTURE_UNIT_DIFFUSE));
    GLCALL(glUniform1i(glGetUniformLocation(mGeometryProgram.mProgramHandle, "unifNormalTexture"), OpenGLTexture::TEXTURE_UNIT_NORMAL));
    GLCALL(glBindSampler(OpenGLTexture::TEXTURE_UNIT_DIFFUSE, mTextureSampler));
    GLCALL(glBindSampler(OpenGLTexture::TEXTURE_UNIT_NORMAL, mTextureSampler));
    GLCALL(glUseProgram(0));

着色过程具有用于照明计算的以下纹理:

    GLCALL(glUseProgram(shadingProgramID));
    GLCALL(glGenSamplers(1, &mTextureSampler));
    GLCALL(glSamplerParameteri(mTextureSampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
    GLCALL(glSamplerParameteri(mTextureSampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
    GLCALL(glSamplerParameteri(mTextureSampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
    GLCALL(glSamplerParameteri(mTextureSampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
    GLCALL(glUniform1i(glGetUniformLocation(shadingProgramID, "unifPositionTexture"), GBuffer::GBUFFER_TEXTURE_POSITION));
    GLCALL(glUniform1i(glGetUniformLocation(shadingProgramID, "unifNormalTexture"), GBuffer::GBUFFER_TEXTURE_NORMAL));
    GLCALL(glUniform1i(glGetUniformLocation(shadingProgramID, "unifDiffuseTexture"), GBuffer::GBUFFER_TEXTURE_DIFFUSE));
    GLCALL(glBindSampler(GBuffer::GBUFFER_TEXTURE_POSITION, mTextureSampler));
    GLCALL(glBindSampler(GBuffer::GBUFFER_TEXTURE_NORMAL, mTextureSampler));
    GLCALL(glBindSampler(GBuffer::GBUFFER_TEXTURE_DIFFUSE, mTextureSampler));
    GLCALL(glUseProgram(0));

然后在下一帧中,当进行几何传递时,它会立即在glClear函数上崩溃

void OpenGLRenderer::GeometryPass(const RenderQueue& renderQueue)
{
    GLCALL(glUseProgram(mGeometryProgram.mProgramHandle));
    GLCALL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mGBuffer.mFramebuffer));
    GLCALL(glDepthMask(GL_TRUE));
    GLCALL(glEnable(GL_DEPTH_TEST));
    // clear GBuffer fbo
    GLCALL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));    // <----- crash!
    // both containers are assumed to be sorted by MeshID ascending
    auto meshIterator = mMeshes.begin();
    for (const Renderable& renderable : renderQueue)
    {
         // lots of draw code.....
    }
    GLCALL(glDisable(GL_DEPTH_TEST));
    GLCALL(glDepthMask(GL_FALSE));
    GLCALL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
    GLCALL(glUseProgram(0));
}

这里可能有什么问题?

您的范围验证是错误的。各向异性的最小可接受值为1.0f10fem>off(各向同性)。

老实说,当各向异性设置在可接受范围以上或以下时,我不会返回false,也不做任何其他操作,而是考虑将值钳制为[1.0,MAX]。稍后,通过在函数返回后检查mCurrentAnisotropy的值,您总是可以发现您的请求是不可接受的。如果将各向异性级别作为选项存储在配置文件中,并且硬件发生更改,则此选项非常有用。尽管16.0几乎是目前普遍的最大值,但一些真正旧的硬件只支持8.0。您仍然可以返回false、报告警告或其他任何信息,但我个人总是将对实现无法支持的各向异性级别过高的请求解释为:"我想要尽可能高的各向异性。"