I am a complete beginner to the Shading Language. I read that there are 3 components to a simple shader, source code for vertex shader, source code for fragment shader, and application code to initialize the 2 shaders. If I want to compile and link the shader program, do I put make a seperate file for vertex code, fragment code, and application code? How do I link the three files together and compile successfully? I am using Linux. Some example lines of code would be nice. Thanks.
This depends on what shading language you’re using and how you’re using it.
With OpenGL you can pass the shader as an ascii string to OpenGL and it will interpret it. Now you have vertex & fragment assembly style shaders and the OpenGL shading language higher level equivalents. Both can be sent as ascii strings to OpenGL at runtime for parsing & compilation giving a handle you can use to load the parsed or compiled shader.
Remember that with shaders a big part of using a shader is setting up the OpenGL state as the input parameters to the various shader registers/inputs. So fixed attributes and per vertex attributes and matrices etc feed the vertex shader program then the output from the vertex shader gets interpolated and is used by the fragment shader which can also use texture and other fixed state.
So with gl shading language, you’d load a program which comprised a vertex and fragment shader by calling:
/* set up & compile vertex shader */ my_vert_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB) glShaderSourceARB(my_vert_shader, nvstrings, vstrings, vlengths); glCompileShaderARB(my_vert_shader); /* set up & compile fragment shader */ my_frag_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB) glShaderSourceARB(my_frag_shader, nfstrings, fstrings, flengths); glCompileShaderARB(my_frag_shader); /* create & link useable shader program */ my_program = glCreateProgramObjectARB(); glAttachObjectARB(my_program, my_vert_shader); glAttachObjectARB(my_program, my_frag_shader); glLinkProgramARB(my_program); glUseProgramObjectARB(my_program);
I’ve laid it out this way for clarity, you can compile the shaders after they’re attached to the program but AFAIK it isn’t essential. You need to link after they’re in the program obviously. It’s early days but maybe it would be more optimal one day to attach then compile but that’s very speculative.
Remember this is all just calling semantics, the big missing part (besides the shader code) is setting up the OpenGL state & traditional fixed function inputs to feed the shader, there are of course more generic calls for this now that aren’t in the traditional pipeline so calls like glUniformARB and glVertexAttribARB or their equivalents are pretty important for shaders.
AFAIK the coupling of vertex and fragment programs with the link stage is unique to glslang. Other approaches you just load the vert and/or frag programs directly and render. I think it’s fast and has the potential for additional optimization & error checking incase you’re doing something redundant or want to reuse a vertex shader but only tap a few of the outputs in a changing fragment shader, I wouldn’t rely on this though.