目的:
使用OpenGL着色语言中的顶点和片元着色器,替代原有的固化函数管道的光照和材质计算,用于场景图形中的节点选择。(砖块着色器程序来自3DLabs)
------------------------------------
概述:
OpenGL着色语言允许程序员编写自己的像素和顶点着色器。有关着色语言的更多信息,包括最低的硬件和软件需求,请参阅:
http://developer.3dlabs.com/openGL2/
OSG的osg::Program和osg::Shader类允许用户将着色器作为StateSet的一部分加入选定的场景图形子树。如果要在OpenSceneGraph中使用自定义的顶点和片元着色器,则需要使用下面的基类:
osg::Program - 在应用层级上封装了OpenGL着色语言的glProgramObject函数。Program类的对象继承自osg::StateAttribute类。即osg::Program类的实例可以关联到StateSet,并使用setAttributeAndModes()方法来许可自身的使用。开启Program渲染状态之后,与此渲染状态相关联的几何体均会使用该Program的着色器进行渲染。
osg::Shader - 在应用层级上封装了OpenGL着色语言的glShaderObject函数。这个类用于管理着色器源代码的加载和编译。osg::Shader类的实例可以与一个或多个osg::Program的实例相关联。Shader对象有两种类型:osg::Shader::FRAGMENT和osg::Shader::VERTEX。
代码:
要创建一个使用OpenGL像素和片元着色器的程序,可以按照下面的步骤:
- 创建一个osg::Program实例;
- 创建一个osg::Shader类的顶点(VERTEX)或片元(FRAGMENT)着色器实例;
- 加载并编译着色器代码;
- 将着色器添加到osg::Program实例;
- 将osg::Program实例关联给StateSet类,并将其激活;
下面的代码用于加载和应用基本的顶点和片元着色器:
osg::StateSet* brickState = tankNode->getOrCreateStateSet();
osg::Program* brickProgramObject = new osg::Program;
osg::Shader* brickVertexObject =
new osg::Shader( osg::Shader::VERTEX );
osg::Shader* brickFragmentObject =
new osg::Shader( osg::Shader::FRAGMENT );
brickProgramObject->addShader( brickFragmentObject );
brickProgramObject->addShader( brickVertexObject );
loadShaderSource( brickVertexObject, "shaders/brick.vert" );
loadShaderSource( brickFragmentObject, "shaders/brick.frag" );
brickState->setAttributeAndModes(brickProgramObject, osg::StateAttribute::ON);
下面的函数可以方便地加载着色器代码,并将编译后的代码关联给着色器对象:
bool loadShaderSource(osg::Shader* obj, const std::string& fileName )
{
std::string fqFileName = osgDB::findDataFile(fileName);
if( fqFileName.length() == 0 )
{
std::cout << "File /"" << fileName << "/" not found." << std::endl;
return false;
}
bool success = obj->loadShaderSourceFromFile( fqFileName.c_str());
if ( !success )
{
std::cout << "Couldn't load file: " << fileName << std::endl;
return false;
}
else
{
return true;
}
}
祝你好运!