【问题标题】:OpenGL Shader Compilation Errors: unexpected $undefined at token "<undefined>"OpenGL 着色器编译错误:在令牌“<undefined>”处出现意外的 $undefined
【发布时间】:2012-06-08 07:04:36
【问题描述】:

我看到了this 的问题,它确实揭示了一些启示。尽管如此,我似乎无法弄清楚我是如何“不正确地”加载我的着色器的,因为这个已经之前执行过,而最近没有对着色器加载代码进行任何更改,所以我认为这些错误必须来自我的抽奖电话。

尽管如此,为了简洁起见,我仍然会发布着色器文件、用于绘制我要渲染的圆的绘制函数,以及作为字符串加载到着色器文件中的代码。

基本上我需要知道的是为什么我会收到这些错误以及它们到底有什么问题?

来自调试输出

ERROR { 
    OpenGL Says: 
     Vertex info
-----------
0(1) : error C0000: syntax error, unexpected $undefined at token "<undefined>"

Fragment info
-------------
0(1) : error C0000: syntax error, unexpected $undefined at token "<undefined>"

 };

绘制代码

    void Circle::draw( GLuint program )
    {
        const size_t centerMag = mCenter.length();

        glUseProgram( program );

        for( float t = 0; t < mCircumference; t += 0.1 )
        {
            float x = centerMag + glm::cos( 2 * M_PI * t );
            float y = centerMag + glm::sin( 2 * M_PI * t );

            mVertices->push_back( glm::vec4( x, y, 0, 1 ) );
        }

        QListIterator< glm::vec4 > iVertices( *mVertices );

        const size_t size = mVertices->size();

        float** verts = new float*[ size ];

        size_t i = 0;

        glEnableClientState( GL_VERTEX_ARRAY );

        while( iVertices.hasNext() )
        {
            verts[ i ] = new float[ size ];
            verts[ i ] = const_cast< float* >( glm::value_ptr( iVertices.next() ) );

            glVertexPointer( 4, GL_FLOAT, 0, verts[ i ] );

            glDrawArrays( GL_LINES, 0, 4 );

            ++i;
        }

        glDisableClientState( GL_VERTEX_ARRAY );

        for( unsigned iMem = 0; iMem < size; ++iMem )
        {
            delete[] verts[ iMem ];
            verts[ iMem ] = NULL;
        }

        delete[] verts;
        verts = NULL;
    }

文件实用程序

    QString FileUtility::readShader( QString filepath )
    {
        std::ifstream in( filepath.toStdString().c_str() );
        std::stringstream shaderDat;

        shaderDat << in.rdbuf();

        QString shaderFile;

        shaderFile += shaderDat.str().c_str();

        in.close();

        return shaderFile;
    }

GenericColor.frag

#version 330

out vec4 outputColor;

void main()
{
    outputColor = vec4(1.0f, 0, 0, 1.0f);
}

Position.vert

#version 330

layout(location = 0) in vec4 position;

void main()
{
    gl_Position = position;
}

更新

由于请求了我的着色器绑定/编译代码,我想我不妨只发布我的整个着色器处理程序以及引擎类。

-Engine -ShaderHandler.

更新

这里是解析的着色器字符串(Info 是调试输出):

Info { 
    Shader Source #version 330

in uniform mvp;

layout(location = 0) in vec4 position;

void main()
{
    gl_ModelViewProjectionMatrix = mvp;
    gl_Position = position;
}




 };



Info { 
    Shader Source #version 330

out vec4 outputColor;

void main()
{
    outputColor = vec4(1.0f, 0, 0, 1.0f);
}


 };

【问题讨论】:

  • 能否也显示着色器编译/VA 绑定代码?
  • 已更新,我决定将整个源文件粘贴到 bin 中。
  • 您是否有机会发布正在加载到 glShaderSource 的确切 c_str?着色器编译错误应该与程序的其余部分无关(您的绘制代码可能无关紧要)。也许可以通过这种方式发现一些东西。
  • 是的,刚刚更新。我想知道问题是否是因为我为此使用了 Qt...
  • 哦,Qt... QGLWindow 可能不是支持 GL3.1 核心配置文件的东西...不幸的是。您必须稍作修改才能使用纯 WinAPI 创建兼容的上下文。您没有提到 Qt,但这是 GL3 的一个众所周知的问题

标签: c++ opengl error-handling compilation glsl


【解决方案1】:

我的猜测:我在您的代码中看到了 glLoadMatrix() 调用,这基本上意味着您使用的是过时的(3.1 之前的)GL API,并且没有正确初始化 GL3.1 Core Profile 上下文。

这会导致您的上下文不支持 GLSL1.50+ 和“位置”属性(因此着色器编译器出错)。

尝试更改 GL 的初始化,然后检查 glBindAttribLocation 调用。避免使用 glLoadMatrix 的东西 - 改用着色器制服。

查看 opengl.org 的网站:http://www.opengl.org/wiki/Tutorial:_OpenGL_3.1_The_First_Triangle_(C%2B%2B/Win) 以获得 GL 3.1 上下文创建示例。和GL2.0有点不同-

【讨论】:

    【解决方案2】:

    这可能与您当前的问题无关,但很快就会解决:

    verts[ i ] = new float[ size ];
    verts[ i ] = const_cast< float* >( glm::value_ptr( iVertices.next() ) );
    

    第一行分配的内存被泄露了,此外,当你在几行之后调用delete 时,你删除了new 给出的值,但是被转换了。是这个意思吗?

    【讨论】:

      【解决方案3】:

      该错误消息意味着着色器编译器在着色器的第一行看到一个垃圾字符(不是可打印的 ASCII 字符、空格、制表符或换行符)。这很可能意味着您传递给glShaderSource 的字符串是垃圾——可能是一个悬空指针,它曾经指向您的着色器代码,但由于某些东西被破坏而不再这样做。

      编辑

      我从您的链接中看到您的代码如下所示:

      s.Source = shader.toStdString().c_str();
      

      这将设置s.Source 指向一个临时std::string 对象的内部缓冲区,该对象将在此行之后不久被销毁,留下s.Source 一个悬空指针...

      【讨论】:

      • 谢谢。上帝,有时我讨厌我来自 C# 背景。
      • 另一个案例说明:这也发生在我身上,但 末尾缺少 \0 终止符,所以我将其添加到您的声明中说 "on着色器的第一行”.
      • @Wappenull:缺少 NUL 通常会在着色器的 last 行而不是第一行给出错误。错误信息开头括号中的数字是行号(括号前的数字是传递给glShaderSource的数组中的索引)
      【解决方案4】:

      我收到此错误是因为我从网站上剪切并粘贴了一些着色器代码。我认为 LF/CR 的差异导致了问题。使用手动输入的相同代码删除粘贴的文本有效。

      【讨论】:

        【解决方案5】:

        我在标准 C 中遇到了这个错误,因为我忘记将 NUL(\0) 终止符放在我正在读取字符的 malloc'd 内存的末尾。

        我怀疑 GL 在glLinkProgram()(glew) 期间会查找空终止字符以链接着色器。

        如果您没有将const GLint *length 参数传递给glLinkProgram() it assumes NUL termination.,则会出现错误。感谢derhass 指出这一点。

        【讨论】:

        • "我怀疑 GL 会寻找空终止字符" 除非你告诉它。您可以通过glShaderSourcelength 参数指定每个字符串部分的长度,或者对整个length 数组使用负长度或NULL 来告诉它字符串是NUL 终止的。
        • 你完全正确!我的大脑完全忽略了 length** 参数的文档。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-29
        • 1970-01-01
        相关资源
        最近更新 更多