Is it possible to have a vertex shader and the fragment shader in the same file?
#2 Moderator* - Reputation: 5387
Posted 10 October 2012 - 09:43 AM
#3 Members - Reputation: 2045
Posted 10 October 2012 - 09:55 AM
I think you could also pull this off with some pre-processor magic though
#4 Members - Reputation: 1226
Posted 10 October 2012 - 10:48 AM
I think you could also pull this off with some pre-processor magic though
The opengl api requires you to split them before loading, so I don't think the preprocessor will help you?
But maybe just a simple marker in the file you can look for?
[source lang="cpp"]#vertexmain() {..}#fragmentmain() {...}[/source]
Should be simple to write some loader code that finds and split the file on the markers
Edit:
I realized how to do it with preprocessor, should also work
Just have a vertex_main and a fragment_main that you patch in a #define for at the top of the file at load.
Interesting concept, might be useful
Edited by Olof Hedman, 10 October 2012 - 10:53 AM.
#5 Members - Reputation: 2045
Posted 10 October 2012 - 10:55 AM
I realized how to do it with preprocessor, should also work
Just have a vertex_main and a fragment_main that you patch in a #define for at the top of the file at load.
Interesting concept, might be useful
Yeah that's what I was thinking as well, haven't tested it though but I believe this should work.
#6 Members - Reputation: 114
Posted 10 October 2012 - 02:09 PM
So it ends up looking like this.
[source lang="plain"][Shader Definition][0] = attribute vPosition[1] = uniform mModelView[2] = uniform mProjectionfrag fragColor0[Vertex shader]#version 150in vec3 vPosition;uniform mat4 mModelView;uniform mat4 mProjection;void main(void){ vec4 posTemp = mModelView * vec4(vPosition, 1.0); gl_Position = mProjection * posTemp;}[Fragment shader]#version 150out vec4 fragColor0;void main (void){ // Save it squared fragColor0 = vec4(0, 0, 0, 0); }[/source]
Edited by RevenantBob, 10 October 2012 - 02:09 PM.
#7 Moderator* - Reputation: 5387
Posted 10 October 2012 - 02:36 PM
Shader.glsl
#ifdef COMPILING_VERTEX_SHADER
// vertex shader
void main()
{}
#endif
#ifdef COMPILING_FRAGMENT_SHADER
// fragment shader
void main()
{}
#endif
Source File.cpp
std::string fileContents = fileToString("Shader.glsl"); // load it as a string
std::string compilingString = "#define COMPILNG_VERTEX_SHADER\n" + fileContents;
// load vertex shader...
compilingString = "#define COMPILING_FRAGMENT_SHADER\n" + fileContents;
// load fragment shader...
#8 Members - Reputation: 2045
Posted 10 October 2012 - 04:16 PM
A different way to do with with macro magic is something like:
Shader.glsl#ifdef COMPILING_VERTEX_SHADER // vertex shader void main() {} #endif #ifdef COMPILING_FRAGMENT_SHADER // fragment shader void main() {} #endif
Source File.cppstd::string fileContents = fileToString("Shader.glsl"); // load it as a string std::string compilingString = "#define COMPILNG_VERTEX_SHADER\n" + fileContents; // load vertex shader... compilingString = "#define COMPILING_FRAGMENT_SHADER\n" + fileContents; // load fragment shader...
Yep, that's pretty much what Olof Hedman and I were talking about, should work just fine.
#9 Members - Reputation: 3827
Posted 10 October 2012 - 07:29 PM
It's also be possible to extend that to support multiple shaders of the same type in a single file, and all other combinations with another #define such as:
#define MyVertexShaderEntryPointName main
void MyVertexShaderEntryPointName ()
{
// do stuff....
It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.
#10 Members - Reputation: 1226
Posted 11 October 2012 - 01:06 AM
A different way to do with with macro magic is something like:
Yep, that's pretty much what Olof Hedman and I were talking about, should work just fine.
Yep. I like my suggestion (and mhagain's) better though, that is to re-define the main function name.
That way you don't have to clutter your source file with #ifdefs, and the other main should be removed at link time.
Edited by Olof Hedman, 11 October 2012 - 01:06 AM.
#13 Members - Reputation: 146
Posted 12 October 2012 - 08:51 AM
Shader.hpp
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);
};
Shader.cpp
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");
}






