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