【问题标题】:Why is the glsl '#version' definition giving me an error?为什么 glsl '#version' 定义给我一个错误?
【发布时间】:2020-12-25 22:00:26
【问题描述】:

我有一个简单的着色器创建管道。没什么特别的。着色器源从我所知道的正确读取。最初,我将着色器代码放在后缀为“.glsl”的文件中只是因为我想要,但现在它们是普通的“.txt”文件。

读入着色器代码后,我编译着色器并链接着色器,并检查编译状态和信息日志是否有错误。下面的实际着色器代码在我看来并没有错误,因为它现在基本上不是您可以在网上找到的简单教程的抄本,如果您需要,我会提供链接。

我确实收到了一个错误,即“0(1) : error C0104: Unknown pre-processor directive #version330”。 这对于顶点着色器和片段着色器都是一样的,它们的创建过程几乎相同。

我的驱动程序版本也是[4.6.0 NVIDIA 445.87],所以我应该可以使用#version 330。 我也确实将它们都设置为“#version 330 core”,但我遇到了同样的错误。

这是我的程序和着色器创建过程。


   struct s_Program
   {
       uint32_t program, vert, frag;

       s_Program()
       {
           vert = glCreateShader(GL_VERTEX_SHADER);
           frag = glCreateShader(GL_FRAGMENT_SHADER);
           program = glCreateProgram();
       }

       bool genVert(const char* fpath)
       {
           std::fstream file(fpath);
           if (!file)
           {
               logf("[FILE_ERROR] : Failed to read shader file.");
               return(false);
           }

           logf("Reading vert shader.");
           const char* source;
           std::string newSource, line;
           while (file >> line)
           {
               newSource += line;
           }
           source = newSource.c_str();

           glShaderSource(vert, 1, &source, 0);
           glCompileShader(vert);

           int comp;
           glGetShaderiv(vert, GL_COMPILE_STATUS, &comp);
           if (comp == GL_FALSE)
           {
               int maxLength = 0;
               glGetShaderiv(vert, GL_INFO_LOG_LENGTH, &maxLength);

               std::vector<char> errorLog(maxLength);
               glGetShaderInfoLog(vert, maxLength, &maxLength, &errorLog[0]);

               logf(&errorLog[0]);

               glDeleteShader(vert);
               return(false);
           }

           glAttachShader(program, vert);
           return(true);
       }

       bool genFrag(const char* fpath)
       {
           std::fstream file(fpath);
           if (!file)
           {
               logf("[FILE_ERROR] : Failed to read shader file.");
               return(false);
           }

           const char* source;
           std::string newSource = "", line;
           while (file >> line)
           {
               newSource += line;
           }
           source = newSource.c_str();

           glShaderSource(frag, 1, &source, 0);
           glCompileShader(frag);

           int comp;
           glGetShaderiv(frag, GL_COMPILE_STATUS, &comp);
           if (comp == GL_FALSE)
           {
               int maxLength = 0;
               glGetShaderiv(frag, GL_INFO_LOG_LENGTH, &maxLength);

               std::vector<char> errorLog(maxLength);
               glGetShaderInfoLog(frag, maxLength, &maxLength, &errorLog[0]);

               logf(&errorLog[0]);

               glDeleteShader(frag);
               return(false);
           }

           glAttachShader(program, frag);
           return(true);
       }

       void linkProgram()
       {
           glLinkProgram(program); glDetachShader(program, vert); glDetachShader(program, frag);
           glDeleteShader(vert); glDeleteShader(frag);
       }

       void bindProgram()
       { glUseProgram(program); }

       void unbindProgram()
       { glUseProgram(0); }
   };

这些是我的着色器。


// Vertex
#version 330

in vec4 _pos;

out vec4 aColor;

void main()
{
    _pos = vec4(_pos, 1.0);
    gl_Position = _pos;
}

// Fragment
#version 330

out vec4 FragColor;

in vec4 _color;

void main()
{
    _color = vec4(0.5, 0.5, 0.1, 1.0);
    FragColor = _color;
}

这是主文件中的实现。


    s_Program mainShader;
    if (!mainShader.genVert("data/shaders/standardVert.txt"))
    { logf("[ERR] : Failed to generate Vertex Shader."); }
    if (mainShader.genFrag("data/shaders/standardFrag.txt"))
    { logf("[ERR] : Failed to generate Fragment Shader."); }
    mainShader.linkProgram();

然后我在循环中调用我的函数“bindProgram”,让 GL 使用该程序。

我显然错过了什么,我只想知道什么。

【问题讨论】:

  • 您是否尝试在阅读后打印出着色器,以确保您阅读正确?

标签: c++ opengl glsl shader glew


【解决方案1】:

您的while (file &gt;&gt; line) 循环逐字读取。将每个单词附加到字符串中会有效地从着色器中去除 所有空格

相反,这样做是为了将文件按原样读入std::string

std::stringstream src_ss;
file >> src_ss.rdbuf();
std::string newSource{ src_ss.str() };

【讨论】:

  • 这解释了为什么着色器包含“#version 330”但错误提示“#version330”。我正要问 OP 他们是否正在阅读正确的文件,但这解释了它。不错的收获。
  • 我确实知道 'file >> line' 会这样做,并且感谢您提供字符串方法,但是我使用的方法在此之前一直有效,这让我最困惑。下次有机会我会试试这个方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-22
  • 2018-12-23
  • 2017-12-17
  • 2013-11-14
相关资源
最近更新 更多