我要发帖 回复

高级会员

109

主题

1366

积分

0

专家分

OSG-VR-GIS

忠于职守杰出贡献

:

私信
发表时间 : 2007-12-21 14:15:52 | 浏览 : 1760    评论 : 0
Navy14.2 - 向着色器传递变量数据
目的:
2.jpg
使用OpenGL着色语言,实现从调用程序向着色器传递所需的参数。
-----------------------------

概述:


着色器有两种类型的参数:一致变量(Uniform variables)指得是在一帧当中保持恒定的数值,典型的参数包括视口的方向和灯光的方向。而易变变量(Varying variables)对于每一个执行单元(包括顶点着色器中的顶点,以及片元着色器中的片元)都是变化的。
一致变量用于从渲染程序向着色器传递参数。在《OpenGL着色语言》一书中,凹凸贴图着色器的例子使用了三个一致变量参数:三维向量LightPosition,以及两个2D材质变量baseTexture和normalMap。OSG类提供了一种直截了当的机制,使得osg/' target = '_blank' style = 'color: #666; padding-right: 16px; background: url(static/image/admincp/newwin.gif) no-repeat right;'>OpenSceneGraph程序可以向着色器直接传递数据。

  

代码:
以下所述为osg/' target = '_blank' style = 'color: #666; padding-right: 16px; background: url(static/image/admincp/newwin.gif) no-repeat right;'>OpenSceneGraph程序向凹凸贴图着色器传递参数的方法。其代码使用了Program对象类的方法addUniform,此方法有两个输入参数:一个用于声明着色器一致变量的字符串,以及一个用于记录参数值的变量。声明2D材质一致变量的方法与此类似,其输入参数为2D材质变量名称的字符串,以及所用材质单元的整数值。用于向凹凸贴图着色器传递所需变量的代码如下:

bool loadShaderSource(osg::Shader* obj, const std::string& fileName );

int main( int argc, char **argv )
{
   osg::Group* rootNode = new osg::Group();
   osg::Node* tankNode = NULL;
   osg::Node* terrainNode = NULL;
   osg::PositionAttitudeTransform* tankXform =
      new osg::PositionAttitudeTransform();

   osgDB::FilePathList pathList = osgDB::getDataFilePathList();
   pathList.push_back
      ("C:\\Projects\\OpenSceneGraph\\OpenSceneGraph-Data\\NPSData\\Models\\T72-Tank\\");
   pathList.push_back
      ("C:\\Projects\\OpenSceneGraph\\OpenSceneGraph-Data\\NPSData\\Models\\JoeDirt\\");
   osgDB::setDataFilePathList(pathList);

   tankNode = osgDB::readNodeFile("T72-tank_des.flt");
   terrainNode = osgDB::readNodeFile("JoeDirt.flt");
   if (! (tankNode && terrainNode))
   {
      std::cout << "Couldn't load models, quitting." << std::endl;
      return -1;
   }
   rootNode->addChild(terrainNode);
   rootNode->addChild(tankXform);
   tankXform->addChild(tankNode);

   tankXform->setPosition( osg::Vec3(10,10,8) );
   tankXform->setAttitude(
      osg::Quat(osg::DegreesToRadians(-45.0), osg::Vec3(0,0,1) ) );

   // 将一个“空”Program对象关联到rootNode,它相当于定义了一个缺省的
   // StateAttribute属性。“空”Program对象(不与任何Shader对象关联)是一种
   // 特殊情形,它表示程序将使用OpenGL 1.x固化功能的渲染管道。
   osg::StateSet* rootState = rootNode->getOrCreateStateSet();
   osg::Program* defaultProgramObject = new osg::Program;
   rootState->setAttributeAndModes(defaultProgramObject, osg::StateAttribute::ON);
   osg::StateSet* bumpMapState = tankNode->getOrCreateStateSet();

   osg::Program* bumpMapProgramObject = new osg::Program;

   osg::Shader* brickVertexObject =
      new osg::Shader( osg::Shader::VERTEX );
   osg::Shader* brickFragmentObject =
      new osg::Shader( osg::Shader::FRAGMENT );

   bool ok =
      loadShaderSource( brickVertexObject, "shaders/bumpmap.vert" )
      &&
      loadShaderSource( brickFragmentObject, "shaders/bumpmap.frag" ) ;

   if(!ok)
   {
      std::cout << "Couldn't load shaders" << std::endl;
      return -1;
   }

   bumpMapProgramObject->addShader( brickFragmentObject );
   bumpMapProgramObject->addShader( brickVertexObject );

   osg::Uniform* lightPosU = new osg::Uniform("LightPosition",osg::Vec3(0,0,1));
   osg::Uniform* normalMapU = new osg::Uniform("normalMap",1);
   osg::Uniform* baseTextureU = new osg::Uniform("baseTexture",0);
   bumpMapState->addUniform(lightPosU);
   bumpMapState->addUniform(normalMapU);
   bumpMapState->addUniform(baseTextureU);
   bumpMapState->setAttributeAndModes(bumpMapProgramObject, osg::StateAttribute::ON);

   osg::Texture2D* tankBodyNormalMap = new osg::Texture2D;
   // 避免在优化过程中静态量出错。
   tankBodyNormalMap->setDataVariance(osg::Object::DYNAMIC);
   osg::Image* tankBody = osgDB::readImageFile("TankBump.png");
   if (!tankBody)
   {
      std::cout << " couldn't find texture, quiting." << std::endl;
      return -1;
   }

   tankBodyNormalMap->setImage(tankBody);
   bumpMapState->setTextureAttributeAndModes(1,tankBodyNormalMap,osg::StateAttribute::ON);

   osgViewer::Viewer viewer;
   viewer.setCameraManipulator(new osgGA::TrackballManipulator());
   viewer.setSceneData( rootNode );
   viewer.realize();

   while( !viewer.done() )
   {
      viewer.frame();
   }
   return 0;
}

编程愉快!

最近VR访客


OSG中国官方网站:http://www.osgChina.org
OSG中国官方讨论区:http://bbs.osgChina.org

OSG专业群-OSG地形研究者 49668412
      OSG地形专业研究 45763709

手机版|VR开发网 统计 津ICP备18009691号
网安备12019202000257

GMT+8, 2021-9-18 01:06 AM

返回顶部