Just like HLSL.
You didn't say why you want them in the same file. I suppose there is a design reason for that.
A simple solution is to put the shaders in initialized strings. Easy, but does it satisfy your (unspoken) requirements?
Just like HLSL.
class Shader : public object
{
public:
Shader();
virtual ~Shader();
GLuint ID;
void Load(const char* filename);
protected:
private:
GLuint vertexShaderID,
fragmentShaderID;
void Initialize(void);
void CreateShader(GLuint shader_id, std::string shader, GLenum type_shader);
};
void Shader::Load(const char* filename)
{
ifstream in(filename, ios::binary);
if(!in)
{
cerr << "Could open file" << filename << endl; // Lanzamos un mensaje de error
exit(1); // exit(1) usado para abortar el programa
}
std::string glsl_source((std::istreambuf_iterator<char>(in)),
std::istreambuf_iterator<char>());
in.close();
if(glsl_source.length() == 0)
{
exit(1);
}
std::string fs_shader = "#define COMPILING_FS\n" + glsl_source;
std::string vs_shader = "#define COMPILING_VS\n" + glsl_source;
std::cout<<vs_shader<<std::endl;
ID = glCreateProgram();
CreateShader(fragmentShaderID,fs_shader,GL_FRAGMENT_SHADER);
CreateShader(vertexShaderID,vs_shader,GL_VERTEX_SHADER);
Initialize();
}
void Shader::CreateShader(GLuint shader_id, std::string shader, GLenum type_shader)
{
shader_id = glCreateShader(type_shader);
const char* glsl_cstr;
glShaderSource(shader_id, 1, &(glsl_cstr=shader.c_str()),NULL);
glCompileShader(shader_id);
ExitOnGLError("Could compile shader");
}
void Shader::Initialize(void)
{
glAttachShader(ID, fragmentShaderID); // Error in here
ExitOnGLError("Could attach fragmentshader");
glAttachShader(ID, vertexShaderID);
ExitOnGLError("Could attach vertexshader");
glLinkProgram(ID);
ExitOnGLError("Could link program");
}