Is it possible to have a vertex shader and the fragment shader in the same file?

Started by
12 comments, last by Hector San Roman Lanza 11 years, 6 months ago
Just like HLSL.
Advertisement
I don't think so. The [font=courier new,courier,monospace]void main()[/font] functions for the vertex shader and fragment shader would conflict.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
You could always create a wrapper file in a format like XML in which you put both your fragment and vertex shaders. You can then parse the XML file and read the two different sources and compile them as normal.
I think you could also pull this off with some pre-processor magic though

I gets all your texture budgets!


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"]#vertex
main() {
..
}

#fragment
main() {
...
}
[/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 smile.png
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

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.

I gets all your texture budgets!

I used a marker and do a quick string function after I load the file to replace the markers with 0's and save offsets, Then I pass those pointers to the compiler. [vertex shader] [fragment shader] [geometry shader] is what I use. I also have shader definition which allows me to create indexes to attributes and other data opengl needs to index data.


So it ends up looking like this.
[source lang="plain"]
[Shader Definition]

[0] = attribute vPosition
[1] = uniform mModelView
[2] = uniform mProjection

frag fragColor0

[Vertex shader]
#version 150

in 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 150


out vec4 fragColor0;

void main (void)
{
// Save it squared
fragColor0 = vec4(0, 0, 0, 0);
}

[/source]
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.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...
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

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.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...



Yep, that's pretty much what Olof Hedman and I were talking about, should work just fine.

I gets all your texture budgets!

I use Cornstalks' suggestion and it works great; it's nice that glShaderSource takes an array of strings as it's source param because you can just pop in the appropriate #define in the first array slot.

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....

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.


[quote name='Cornstalks' timestamp='1349901383' post='4988845']
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.
[/quote]

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.

This topic is closed to new replies.

Advertisement