Ошибки сборки шейдера OpenGL: неожиданный $undefined в токене "<undefined>"

Я видел этот вопрос, и это действительно пролило некоторый свет. Несмотря на это, я не могу понять, как я "ненадлежащим образом" загружаю свой шейдер, потому что он выполнялся раньше, без каких-либо изменений в коде загрузки шейдеров, поэтому я предполагаю, что эти ошибки должны исходить из моих обратных вызовов.

Несмотря на это, я все равно буду публиковать файлы шейдеров для краткости, использовать функцию draw, используемую для рисования круга, который я пытаюсь сделать, и код, который загружается в файл шейдера в виде строки.

В принципе, мне нужно знать, почему я получаю эти ошибки и что, черт возьми, с ними не так?

(От выхода отладки)

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;
    }

FileUtility

    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;
}

Обновление

Поскольку мой код привязки/компиляции шейдеров был запрошен, я решил, что могу просто разместить весь мой обработчик шейдеров, а также класс двигателя.

- Двигатель - 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);
}


 };

Ответ 1

Это сообщение об ошибке означает, что компилятор шейдера видит в первой строке шейдера символ мусора (что-то другое, чем печатный символ ASCII, пробел, вкладка или новая строка). Скорее всего, строка, которую вы передаете в glShaderSource, представляет собой мусор - вероятно, висячий указатель, который однажды указал на ваш шейдерный код, но больше не делает из-за чего-то разрушившегося.

изменить

Я вижу по вашей ссылке у вас есть код, который выглядит следующим образом:

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

Это установит s.Source, указывающий на внутренний буфер временного объекта std::string, который будет уничтожен вскоре после этой строки, оставив s.Source висячий указатель...

Ответ 2

Мое предположение: я видел вызовы glLoadMatrix() в вашем коде, что в основном означает, что вы используете устаревший (pre-3.1) GL API и не инициализируете контекст основного профиля GL3.1 правильно.

Это приводит к ситуации, когда ваш контекст не поддерживает атрибуты 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 -

Ответ 3

Это, вероятно, не связано с вашей текущей проблемой, но будет достаточно скоро:

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

Выделена память, выделенная в первой строке, более того, когда вы вызываете delete несколько строк после, вы удаляете значение, указанное new, но выставляемое. Это то, что вы имеете в виду?

Ответ 4

Я получил эту ошибку, потому что я вырезал и вставлял некоторый шейдерный код с веб-сайта. Я предполагаю, что разница в LF/CR вызывала проблему. Удаление вставляемого текста с помощью того же кода, который вводится вручную.