Reputation: 35
I am following the tutorials at learnopengl.com and their shaders have been put directly into a const char*. When I try to put the same code into a shader file, later reading it into a const char*, with all the code the same, glGetShaderiv() generates a syntax error.
This is the error: ERROR: 0:1: '' syntax error: illegal extended ASCII character (0xdd).
However, this error does not come up when the code is put directly into a const char*
here is the const char* code vs my code
const char* :
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";
my vertex file:
#version 330 core
layout (location = 0) in vec3 position;
void main() {
gl_Position = vec4(position.x, position.y, position.z, 1.0);
}
my yellow fragment shader:
#version 430 core
out vec4 colour;
void main() {
colour = vec4(1.0f, 1.0f, 0.0f, 1.0f);
}
my orange fragment shader:
#version 430 core
out vec4 colour;
void main() {
colour = vec4(1.0f, 1.0f, 0.0f, 1.0f);
}
and also, here is the code that i use to convert my shaders to strings:
std::ifstream shaderFile(filePath);
std::stringstream tmp;
std::string fileContents = "";
std::string line = "";
while (std::getline(shaderFile, line)) fileContents += line + "\n";
return fileContents + "\0";
and here is another method that I have tried to read from my file
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>());
my shader compilation code:
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();
glShaderSource(vertexShaderID, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShaderID);
glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &success);
glShaderSource(yellowFragmentShaderID, 1, &yellowFragmentShaderSource, NULL);
glCompileShader(yellowFragmentShaderID);
glGetShaderiv(yellowFragmentShaderID, GL_COMPILE_STATUS, &success);
glShaderSource(orangeFragmentShaderID, 1, &orangeFragmentShaderSource, NULL);
glCompileShader(orangeFragmentShaderID);
glGetShaderiv(orangeFragmentShaderID, GL_COMPILE_STATUS, &success);
I have no idea why my string does not work It all looks the same when I outputted the string to console. Can someone pls help me?
Upvotes: 1
Views: 1869
Reputation: 6766
When you call tmp.c_str() you receive a pointer to the string owned by tmp.
When you then call tmp = something_else; a new chunk of memory is allocated to hold the new string, and the pointer (e.g. vertexShaderSource) is now invalid. It's known as a dangling pointer.
A simple fix would be to change:
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();
to:
tmp = convertShaders("VertexShader.vert");
const GLchar *vertexShaderSource = tmp.c_str();
std::cout << vertexShaderSource << std::endl;
std::string tmp2 = convertShaders("FragmentShaderYellow.frag");
const GLchar *yellowFragmentShaderSource = tmp2.c_str();
std::string tmp3 = convertShaders("FragmentShaderOrange.frag");
const GLchar *orangeFragmentShaderSource = tmp3.c_str();
By using 3 different tmp std::string you avoid the problem of the old contents getting invalidated.
Upvotes: 2