独立着色器对象,可以对管线的各个阶段进行动态组合,使得对某一个管线阶段的代码进行复用。
注意的问题:
获取uniform变量和设置uniform变量。设置的是某个程序对象的uniform而不是管线对象的。
例子代码:
创建
createShaderPipelineProgram(GLuint target, const char * src)
{
GLuint object;
GLint status;
const char * shaderPrefix = "#version 440\n";
const GLchar * fullSrc[] = {
shaderPrefix,src
};
object = glCreateShaderProgramv(target, , (const GLchar **)fullSrc);
glGetProgramiv(object, GL_LINK_STATUS, &status);
if (!status)
{
GLint charsWritten, infoLogLength;
glGetProgramiv(object, GL_INFO_LOG_LENGTH, &infoLogLength);
char * infoLog = new char[infoLogLength];
glGetProgramInfoLog(object, infoLogLength, &charsWritten, infoLog);
LOGI("Error compiling %s:\n", GetShaderStageName(target));
LOGI("Log: %s", infoLog);
delete[] infoLog;
glDeleteProgram(object);
object = ;
}
return object;
}
渲染初始化
initRendering(void)
{
//全局初始化
glGenProgramPipelines(, &_tessPipeline);
glBindProgramPipeline(_tessPipeline);
CHECK_GL_ERROR();
std::string tess_vertex = loadShaderSourceWithIncludeTag("",
"shaders/tess_vertex.glsl");
std::string tess_control = loadShaderSourceWithIncludeTag("",
"shaders/tess_control.glsl");
std::string terrain_tessellation = loadShaderSourceWithIncludeTag("",
"shaders/tess_eval.glsl");
std::string tess_frag = loadShaderSourceWithIncludeTag("",
"shaders/tess_frag.glsl");
LOGI("Compiling vertex shader\n");
_tessVertexProg = createShaderPipelineProgram(GL_VERTEX_SHADER, tess_vertex.c_str());
LOGI("Compiling frag shader\n");
_tessFragmentProg = createShaderPipelineProgram(GL_FRAGMENT_SHADER, tess_frag.c_str());
initQuadData();
CHECK_GL_ERROR();
}
绘制
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();
GLuint nmvp = glGetUniformLocation(_tessVertexProg, "mvp");
if (nmvp!=-)
{
glProgramUniformMatrix4fv(_tessVertexProg, nmvp,,GL_FALSE, camera_matrix._array);
CHECK_GL_ERROR();
}
glBindVertexArray(_quad_vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _quad_index_buffer);
glDrawElements(GL_TRIANGLE_STRIP, , GL_UNSIGNED_SHORT, NULL);
CHECK_GL_ERROR();
glBindVertexArray();
glBindProgramPipeline();
}
顶点着色器
layout(location = ) in vec3 vs_in_vertex;
uniform mat4 mvp;
out gl_PerVertex{
vec4 gl_Position;
};
void main() {
gl_Position = mvp*vec4(vs_in_vertex, );
}
片元着色器
layout(location = ) out vec4 fragColor;
void main() {
fragColor = vec4(, , , );
}