间歇性GLSL顶点着色器编译错误

 mobiledu2502927147 发布于 2023-01-20 16:44

我一直在编写一个顶点着色器的间歇性错误,为新创建的OpenGL上下文的第一次渲染做准备.它是通常在同一硬件上工作的相同顶点着色器.失败后,返回的信息日志glGetShaderInfoLog通常显示如下:

Vertex shader failed to compile with the following errors:

是的,这就是全部.它发生在Windows上,包括ATI和NVidia GPU,但我主要是在ATI上进行测试.如果我在Visual Studio调试器下运行,则可能glCompileShader在后续glGetShaderiv调用中或后续调用中检测到访问冲突.

我没有看到Mac上的错误,但由于重现它并不总是很容易,我不能确定它不会发生.

我注意到如果我wglShareLists在创建上下文时没有调用,则错误消失(或者至少我不能轻易地重现它).我认为这意味着一些不良信息正从先前创建的(可能是先前破坏的)OpenGL上下文流向新的.然而,我一直在修剪东西,直到没有太多应该分享的东西:没有纹理对象,显示列表,VBO,PBO.据我所知,剩下的唯一剩下的就是着色器和程序对象.

在为窗口创建OpenGL上下文之后,我大致初始化着色如下:

// Program initialization
GLint vertexShader = glCreateShader( GL_VERTEX_SHADER );
glShaderSource( vertexShader, 1, &vertexShaderSource, NULL );
glCompileShader( vertexShader );
GLint   status;
glGetShaderiv( vertexShader, GL_COMPILE_STATUS, &status );
if (status == GL_TRUE)
{
    GLint fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
    glShaderSource( fragmentShader, 1, &fragShaderSource, NULL );
    glCompileShader( fragmentShader );
    glGetShaderiv( vertexShader, GL_COMPILE_STATUS, &status );
    if (status == GL_TRUE)
    {
        GLint program = glCreateProgram();
        if (program != 0)
        {
            glAttachShader( program, vertexShader );
            glAttachShader( program, fragmentShader );
            glLinkProgram( program );
            glDetachShader( program, fragmentShader );
            glDetachShader( program, vertexShader );
            glDeleteShader( fragmentShader );
            // check for link success...
        }
    }
}
else
{
    char logBuf[1024];
    glGetShaderInfoLog( vertexShader, sizeof(logBuf), NULL, (GLchar*)logBuf );
    LogToFile( (char*)logBuf );
}

然后我渲染多个帧,并在某些时候清理

glDeleteProgram( program );
glDeleteShader( vertexShader );

并破坏OpenGL上下文.稍后,我在同一窗口中创建一个新的OpenGL上下文,以相同的方式初始化它,但顶点着色器无法编译.

如果我不渲染任何几何体,我无法重现错误,但渲染单点就足够了.

它仍然使用简化的顶点着色器:

#version 120
void main()
{
    gl_Position = ftransform();
    gl_FrontColor = gl_Color;
    gl_BackColor = gl_Color;
}

和一个简化的片段着色器:

#version 120
void main()
{
    gl_FragColor = gl_Color;
}

我尝试了AMD的CodeXL OpenGL调试器,将其设置为打破错误.它只是告诉我编译失败,我已经知道了.

失败的OpenGL上下文是在一个窗口上,其中先前创建,成功呈现和销毁了不同的上下文.重新使用这样的窗口没有错,是吗?(我知道,一旦你打电话SetPixelFormat,你就无法改变窗口的像素格式.我确保每次都使用相同的像素格式.)

补充:在修剪渲染代码时,我发现如果我注释掉了这条线

glEnable( GL_VERTEX_PROGRAM_TWO_SIDE );

然后错误就消失了.但随着更多真实世界的渲染(例如,纹理)恢复,它似乎没有什么区别.

添加2014年3月7日:我最终创建了一个独立的Visual C++项目,可以在某些情况下重现该错误,以便任何感兴趣的人都可以尝试: ShaderBugTest项目 为了使错误可重现,您需要拥有Microsoft的"应用程序"验证程序"设置为监视堆错误.随附的Read Me有更详细的步骤来重现.

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有