幾何着色器的作用是:
1.增強多頂點的訪問屬性。
2.控制輸出數據的數量。
3.在管線中改變幾何體類型。
4.將頂點數據流切分爲多個子數據流。
使用方法:
設置輸入圖元類型,輸出圖元類型,以及輸出的頂點數量。
layout(triangles) in;
layout(triangle_strip,max_vertices = 3) out;
幾何着色器的輸出只能爲條帶。
points lines triangles line_adjacency triangles_adjacency
EmitVertex()
EndPrimitive()
注意問題:
1.當啓用了幾何着色器,在固定管線中設置裁剪面或是設置正反面將被幾何着色器覆蓋也就是不起作用。
2.幾何着色器中的頂點來源可以是頂點着色器,也可以是細分着色器。
這裏採用獨立的着色器程序,來驗證注意問題2.
vs-fs
vs-gs-fs
vs-tcs-tes-fs
draw(nv::matrix4f & camera_matrix)
{
glBindProgramPipeline(_tessPipeline);
CHECK_GL_ERROR();
glUseProgramStages(_tessPipeline,GL_VERTEX_SHADER_BIT, _tessVertexProg);
CHECK_GL_ERROR();
glUseProgramStages(_tessPipeline, GL_FRAGMENT_SHADER_BIT, _tessFragmentProg);
CHECK_GL_ERROR();
if (_mPipelineMode == 0)
{
// glEnable(GL_CULL_FACE);
// glCullFace(GL_BACK);
// glFrontFace(GL_CW);
glUseProgramStages(_tessPipeline, GL_TESS_CONTROL_SHADER_BIT, 0);
CHECK_GL_ERROR();
glUseProgramStages(_tessPipeline, GL_TESS_EVALUATION_SHADER_BIT, 0);
CHECK_GL_ERROR();
glUseProgramStages(_tessPipeline, GL_GEOMETRY_SHADER_BIT, 0);
CHECK_GL_ERROR();
glBindVertexArray(_quad_vao);
CHECK_GL_ERROR();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _quad_index_buffer);
CHECK_GL_ERROR();
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (const GLvoid *)0);
CHECK_GL_ERROR();
// glDisable(GL_CULL_FACE);
}
else if(_mPipelineMode == 1)
{
glUseProgramStages(_tessPipeline, GL_TESS_CONTROL_SHADER_BIT, _tessControlProg);
CHECK_GL_ERROR();
glUseProgramStages(_tessPipeline, GL_TESS_EVALUATION_SHADER_BIT, _tessEvalProg);
CHECK_GL_ERROR();
glUseProgramStages(_tessPipeline, GL_GEOMETRY_SHADER_BIT, 0);
CHECK_GL_ERROR();
glPatchParameteri(GL_PATCH_VERTICES, 4);
glBindVertexArray(_quad_vao);
CHECK_GL_ERROR();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _tess_quad_index_buffer);
CHECK_GL_ERROR();
glDrawElements(GL_PATCHES, 4, GL_UNSIGNED_SHORT, (const GLvoid *)0);
}
else if (_mPipelineMode == 2)
{
glUseProgramStages(_tessPipeline, GL_TESS_CONTROL_SHADER_BIT, _tessControlProg);
CHECK_GL_ERROR();
glUseProgramStages(_tessPipeline, GL_TESS_EVALUATION_SHADER_BIT, _tessEvalProg);
CHECK_GL_ERROR();
glUseProgramStages(_tessPipeline, GL_GEOMETRY_SHADER_BIT, _tessGeomWireframeProg);
CHECK_GL_ERROR();
glPatchParameteri(GL_PATCH_VERTICES, 4);
glBindVertexArray(_quad_vao);
CHECK_GL_ERROR();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _tess_quad_index_buffer);
CHECK_GL_ERROR();
glDrawElements(GL_PATCHES, 4, GL_UNSIGNED_SHORT, (const GLvoid *)0);
}
else if (_mPipelineMode == 3)
{
// glEnable(GL_CULL_FACE);
// glCullFace(GL_BACK);
// glFrontFace(GL_CW);
glUseProgramStages(_tessPipeline, GL_TESS_CONTROL_SHADER_BIT, 0);
CHECK_GL_ERROR();
glUseProgramStages(_tessPipeline, GL_TESS_EVALUATION_SHADER_BIT, 0);
CHECK_GL_ERROR();
glUseProgramStages(_tessPipeline, GL_GEOMETRY_SHADER_BIT, _tessGeomWireframeProg);
CHECK_GL_ERROR();
glBindVertexArray(_quad_vao);
CHECK_GL_ERROR();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _quad_index_buffer);
CHECK_GL_ERROR();
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (const GLvoid *)0);
//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (const GLvoid *)0);
//glDisable(GL_CULL_FACE);
}
CHECK_GL_ERROR();
glBindVertexArray(0);
glBindProgramPipeline(0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
着色器
//vs
layout(location = 0) in vec3 vs_in_vertex;
out gl_PerVertex{
vec4 gl_Position;
};
void main() {
if(iMode.x == 0)
{
gl_Position = mvp*vec4(vs_in_vertex, 1.0);
}else
{
gl_Position = vec4(vs_in_vertex, 1.0);
}
}
//tcs
//設置輸出每個面片的控制點數目
layout (vertices = 4) out;
in gl_PerVertex
{
vec4 gl_Position;
}gl_in[];
out gl_PerVertex
{
vec4 gl_Position;
} gl_out[];
void main() {
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
gl_TessLevelOuter[0] = outerTessFactor.x;
gl_TessLevelOuter[1] = outerTessFactor.y;
gl_TessLevelOuter[2] = outerTessFactor.z;
gl_TessLevelOuter[3] = outerTessFactor.w;
gl_TessLevelInner[0] = innerTessFactor.x;
gl_TessLevelInner[1] = innerTessFactor.y;
}
//tes
layout(quads, equal_spacing, ccw) in;
in gl_PerVertex
{
vec4 gl_Position;
}gl_in[];
out gl_PerVertex
{
vec4 gl_Position;
};
void main()
{
float u = gl_TessCoord.x;
float omu = 1 - u;
float v = gl_TessCoord.y;
float omv = 1 - v;
gl_Position = mvp*(omu*omv*gl_in[0].gl_Position +
u*omv*gl_in[1].gl_Position+
u*v*gl_in[2].gl_Position+
omu*v*gl_in[3].gl_Position);
}
//gs
layout (triangles) in;
layout (line_strip, max_vertices = 3) out;
//layout(triangle_strip, max_vertices = 3) out;
in gl_PerVertex {
vec4 gl_Position;
}gl_in[];
out gl_PerVertex
{
vec4 gl_Position;
};
void main()
{
mat4 tmvp = mat4(1.0);
if(iMode.x == 3)
{
tmvp = mvp;
}
gl_Position = tmvp*gl_in[0].gl_Position;
EmitVertex();
gl_Position = tmvp*gl_in[1].gl_Position;
EmitVertex();
gl_Position = tmvp*gl_in[2].gl_Position;
EmitVertex();
EndPrimitive();
}