OpenGL(八)使用 subroutine 切换可编程管线
2017-04-14 13:57
183 查看
Subroutine 功能是在OpenGL 4.0 版本里才增加的,因此对于各种Android手机,这个功能基本跪了。如果你发现你的程序报错:ARB_shader_subroutine,那就说明当前显卡不支持。不过大体思路可以了解一下,因为思路类似的功能有其他的实现方式。
subroutine uniform SurfaceColor U_SurfaceColor;
subroutine (SurfaceColor) vec4 Ambient()
{
//...
}
subroutine (SurfaceColor) vec4 Diffuse()
{
//...
}
subroutine (SurfaceColor) vec4 Specular()
{
//...
}
void main()
{
gl_FragColor = U_SurfaceColor();
}在shader中,每一个函数中的代码段代表一种处理函数。另一方面在GL指令中,绑定这个函数指针,并为其指定实现函数的索引值,即可实现效果的控制。surfaceColorLocation = glGetSubroutineUniformLocation(program,GL_FRAGMENT_SHADER,"U_SurfaceColor");
GLuint ambientLightIndex = glGetSubroutineIndex(program,GL_FRAGMENT_SHADER,"Ambient");
GLuint diffuseLightIndex = glGetSubroutineIndex(program,GL_FRAGMENT_SHADER,"Diffuse");
GLuint specularLightIndex = glGetSubroutineIndex(program,GL_FRAGMENT_SHADER,"Specular");
//draw
glUniformMatrix4fv(MLocation, 1, GL_FALSE, glm::value_ptr(model));
glUniformSubroutinesuiv(GL_FRAGMENT_SHADER,1,&ambientLightIndex);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibo);
glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
关注我的微信公众号,获取更多优质内容
原理
在shader中声明一个函数变量,然后定义它的指针,并将其作为一个uniform变量公开出去。最后定义很多复写函数即可。实现
由于版本限制,使用 subroutine 要注意在shader中加入版本的编译宏:#version 400 core在shader中编写:subroutine vec4 SurfaceColor();subroutine uniform SurfaceColor U_SurfaceColor;
subroutine (SurfaceColor) vec4 Ambient()
{
//...
}
subroutine (SurfaceColor) vec4 Diffuse()
{
//...
}
subroutine (SurfaceColor) vec4 Specular()
{
//...
}
void main()
{
gl_FragColor = U_SurfaceColor();
}在shader中,每一个函数中的代码段代表一种处理函数。另一方面在GL指令中,绑定这个函数指针,并为其指定实现函数的索引值,即可实现效果的控制。surfaceColorLocation = glGetSubroutineUniformLocation(program,GL_FRAGMENT_SHADER,"U_SurfaceColor");
GLuint ambientLightIndex = glGetSubroutineIndex(program,GL_FRAGMENT_SHADER,"Ambient");
GLuint diffuseLightIndex = glGetSubroutineIndex(program,GL_FRAGMENT_SHADER,"Diffuse");
GLuint specularLightIndex = glGetSubroutineIndex(program,GL_FRAGMENT_SHADER,"Specular");
//draw
glUniformMatrix4fv(MLocation, 1, GL_FALSE, glm::value_ptr(model));
glUniformSubroutinesuiv(GL_FRAGMENT_SHADER,1,&ambientLightIndex);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibo);
glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
总结
本文介绍了OpenGL中的 subroutine 机制,通过它可以切换shader的内容。在Unity3d中使用Shader.maximumLOD技术可以达到类似的效果,相关内容可以参考官方文档
关注我的微信公众号,获取更多优质内容
相关文章推荐
- OpenGL(八)使用 subroutine 切换可编程管线
- VC中使用OpenGL编程的初步
- 使用MFC开始openGL编程
- OpenGLShader 编程系列- glUniform*的使用
- OpenGL(一) OpenGL管线 与 可编程管线流程
- Android编程实现两个Activity相互切换而不使用onCreate()的方法
- 使用Win32API开始openGL编程
- OpenGL(十一) 可编程管线 基础光照 的实现
- 使用glew和glfw进行opengl编程
- Android编程心得-使用ActionBar+Fragment+ViewPager实现动态切换Menu效果
- 从OpenGL 1.x 到 2.x的迁移(即从固定管线到可编程管线的迁移)
- 在C++ Builder中使用OpenGL编程的优化框架
- .NET数据库编程求索之路--7.使用ADO.NET实现(工厂模式-实现多数据库切换)(4)
- .NET数据库编程求索之路--7.使用ADO.NET实现(工厂模式-实现多数据库切换)(2)
- opengl从固定渲染管线到可编程渲染管线
- OpenGL基础图形编程 - OpenGL辅助库的基本使用
- .NET数据库编程求索之路--7.使用ADO.NET实现(工厂模式-实现多数据库切换)(1)
- 使用Qt进行OpenGL编程OpenGL programming withQt [1]
- OpenGL基础图形编程(六)OpenGL辅组库的基本使用
- 现代3D图形编程学习--opengl使用不同的缓存对象(译者添加)