Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当我的着色器文件的所有信息都正确地读入字符串并且语法正确时,为什么OpenGL会给出语法错误_C++_String_Opengl - Fatal编程技术网

C++ 当我的着色器文件的所有信息都正确地读入字符串并且语法正确时,为什么OpenGL会给出语法错误

C++ 当我的着色器文件的所有信息都正确地读入字符串并且语法正确时,为什么OpenGL会给出语法错误,c++,string,opengl,C++,String,Opengl,我正在学习learnopengl.com上的教程,它们的着色器已直接放入const char*中。当我尝试将相同的代码放入着色器文件,然后将其读入常量char*,并且所有代码都相同时,glGetShaderiv()会生成语法错误 这是错误:错误:0:1:“”语法错误:非法扩展ASCII字符(0xdd) 但是,当代码直接放入常量字符中时,不会出现此错误* 这是常量字符*代码与我的代码 常量字符*: const GLchar* vertexShaderSource = "#version 3

我正在学习learnopengl.com上的教程,它们的着色器已直接放入const char*中。当我尝试将相同的代码放入着色器文件,然后将其读入常量char*,并且所有代码都相同时,glGetShaderiv()会生成语法错误

这是错误:错误:0:1:“”语法错误:非法扩展ASCII字符(0xdd)

但是,当代码直接放入常量字符中时,不会出现此错误*

这是常量字符*代码与我的代码

常量字符*:

    const GLchar* vertexShaderSource = "#version 330 core\n"
    "layout (location = 0) in vec3 position;\n"
    "void main()\n"
    "{\n"
    "gl_Position = vec4(position.x, position.y, position.z, 1.0);\n"
    "}\0";

const GLchar* orangeFragmentShaderSource = "#version 330 core\n"
    "out vec4 color;\n"
    "void main()\n"
    "{\n"
    "color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
    "}\n\0";

const GLchar* yellowFragmentShaderSource = "#version 330 core\n"
    "out vec4 color;\n"
    "void main()\n"
    "{\n"
    "color = vec4(1.0f, 1.0f, 0.0f, 1.0f); // The color yellow \n"
    "}\n\0";
我的顶点文件:

      #version 330 core

      layout (location = 0) in vec3 position;

      void main() {

      gl_Position = vec4(position.x, position.y, position.z, 1.0);

   }
我的黄色片段着色器:

      #version 430 core

      out vec4 colour;

      void main() {

      colour = vec4(1.0f, 1.0f, 0.0f, 1.0f);

  }
     #version 430 core

    out vec4 colour;

    void main() {

    colour = vec4(1.0f, 1.0f, 0.0f, 1.0f);

 }
我的橙色片段着色器:

      #version 430 core

      out vec4 colour;

      void main() {

      colour = vec4(1.0f, 1.0f, 0.0f, 1.0f);

  }
     #version 430 core

    out vec4 colour;

    void main() {

    colour = vec4(1.0f, 1.0f, 0.0f, 1.0f);

 }
此外,下面是我用来将着色器转换为字符串的代码:

      std::ifstream shaderFile(filePath);
      std::stringstream tmp;

      std::string fileContents = "";
      std::string line = "";

      while (std::getline(shaderFile, line)) fileContents += line + "\n";

      return fileContents + "\0";
这里是另一个我试图从我的文件中读取的方法

   std::ifstream shaderFile(filePath);

   if (!shaderFile.good()) {
       std::cout << "File failed to load..." << filePath << std::endl;
       std::system("PAUSE");
       std::exit(1);
   }

  return std::string(std::istreambuf_iterator<char>(shaderFile), std::istreambuf_iterator<char>());
std::ifstream着色器文件(filePath);
如果(!shaderFile.good()){
std::cout当调用tmp.c_str()时,您将收到一个指向tmp拥有的字符串的指针

然后调用tmp=something_other时,会分配一块新内存来保存新字符串,指针(例如vertexShaderSource)现在无效。它被称为悬挂指针

一个简单的解决办法是改变:

tmp = convertShaders("VertexShader.vert");
const GLchar *vertexShaderSource = tmp.c_str();
std::cout << vertexShaderSource << std::endl;

tmp = convertShaders("FragmentShaderYellow.frag");
const GLchar *yellowFragmentShaderSource = tmp.c_str();

tmp = convertShaders("FragmentShaderOrange.frag");
const GLchar *orangeFragmentShaderSource = tmp.c_str();
tmp=convertshader(“VertexShader.vert”);
const GLchar*vertexShaderSource=tmp.c_str();

std::cout如何将std::string传递给
glShaderSource
?在字符串的字符上循环。它们是否包含任何非ASCII字符?检查值小于0的字节(对于有符号的字符,或对于无符号的字符,>127)。如果您从网站复制文本,它可能包含看起来完全有效的非ASCII字符,例如,有时它们会使用奇特的双向引号。FWIW,0xdd是Microsoft(可能还有其他人)使用的字节模式要指示已释放的内存块。BDL是正确的,您需要在调用glShaderSource的位置发布代码,您几乎肯定是错误地传入了字符串。每当覆盖
tmp
时,字符串内存就会被释放。因此
vertexShaderSource
yellowFragmentShaderSource
指向无效d地址。@GallifreyDW:了解指针是如何工作的。在您的例子中,
vertexShaderSource
yellowFragmentShaderSource
都是无效的,因为它们指向的内存不是有效的,因为它们指向的缓冲区是由在获取指针后修改的
tmp
对象管理的。