// GS as the abbreviation for Geometry Shader in the following text. //
//////////////////////////////////////////////////////////////////////////////////////////////////////////
1. Transformation can be applied in GS, and usually so.
/***************************************************************************/
/***************************************************************************/
2. About Data Transferring among VS, GS, and FS.
WARNING: "varying " in VS represents INTERPOLATION before transferring to GS!
Usually more than 1 vertex will be processed in one GS process due to the per-primitive process principle of GS. So in order to tell which vertex attribute of this primitive is being processed, data coming from VS should be in the form as an array like “in vec2 v2TexCoord[];”, “in mat4 m4MVPMat;”(but VS output is as usual, “varying vec2 v2TexCoord;” for “#version 120” and previous version of the VS, or “out vec2 v2TexCoord;” for “#version 150” or later), so that we can use “v2TexCoord[i]” (for(int i = 0; i < gl_in.length(); i++), i is a certain index of a vertex) for processing the texcoord of vertex No.i in this primitive.
E.G. :
Vertex Shader:
#version 120
//#extension GL_EXT_geometry_shader4 : enable
varying mat4 m4MVPMat;
void main()
{
gl_Position = gl_Vertex;
m4MVPMat = gl_ModelViewProjectionMatrix;
gl_TexCoord[0].st = gl_MultiTexCoord0.st;
}
///////////////////////////////////////////////////////////////////////////////
Geometry Shader:
#version 330
//#extension GL_EXT_geometry_shader4 : enable
precision highp float;
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
in mat4 m4MVPMat[];
out vec2 v2TC;
void main()
{
int i;
for(i = 0; i < gl_in.length(); i++)
{
gl_Position = m4MVPMat[i]gl_in[i].gl_Position;
v2TC = gl_in[i].gl_TexCoord[0].st;
EmitVertex();
}
EndPrimitive();
}
///////////////////////////////////////////////////////////////////////////////
Fragment Shader:
#version 120
//#extension GL_EXT_geometry_shader4 : enable
uniform sampler2D tex;
varying vec2 v2TC;
void main()
{
gl_FragColor = texture2D(tex, v2TC);
}
Methods of data transferring can be obtained from the example above. Another palpable truth can be inferred is that different version of GLSL can be applied among GS, VS and FS. Also, gl_TexCoord[n] which ought to be deprecated after GLSL1.2 is available in GS.
/***************************************************************************/
/***************************************************************************/
3. Output primitive type can only be strip-type like triangle_strip and line_strip.
/***************************************************************************/
/***************************************************************************/
4. About max_vertex:
E.G.:
layout(max_vertices = 3, triangle_strip) out;
①. EmitVertex() is called for 3 times, a triangle would be the output;
②. EmitVertex() is called for OVER 3 times, a triangle strip would be the output. If it’s called for 4 times, there will be 2 triangles in the form of a triangle strip;
③. EmitVertex() is called LESS THAN 3 times, no primitive outputs. If 2 times, these 2 vertices would also be simply discarded.
E.G. その2:
layout(max_vertices = 4, triangle_strip) out;
①. EmitVertex() just 4 times, 2 triangles in th form of triangle strip;
②. EmitVertex() OVER 4 times, triangle strip is the output.
③. EmitVertex() LESS THAN 4 times, also discard, no primitives output.
So both of max_vertices and output primitive-type are relative to the output of GS.