查看: 1627|回复: 19

osg在callback中设置shader出错,并且不会更改颜色

[复制链接]

该用户从未签到

发表于 2012-12-6 20:35:12 | 显示全部楼层 |阅读模式
本帖最后由 liu7667715 于 2012-12-10 11:52 编辑

osg在callback中设置shader出错,并且不会更改颜色;
shader代码如下:
  1. //脚本:
  2. const char* ChangeColor::base_vert = {
  3.          "varying vec3 vNormal;\n"
  4.          "varying vec2 vTC;\n"
  5.          "uniform sampler2D Base;\n"
  6.          "void main(void)\n"
  7.          "{\n"
  8.          "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
  9.          "vTC = gl_MultiTexCoord0.st;\n"
  10.          "}\n"
  11. };

  12. const char* ChangeColor::yellow_frag = {
  13.          "//yellow\n"
  14.          "varying vec3 vNormal;\n"
  15.          "varying vec2 vTC;\n"
  16.          "uniform sampler2D Base;\n"
  17.          "void main(void)\n"
  18.          "{\n"
  19.          "gl_FragColor = vec4((texture2D( Base, vTC ).rgb * 0.5f + vec3(0.953f,0.486f,0.015f)*0.5f),1.0f);\n"
  20.          "}\n"
  21. };

  22. const char* ChangeColor::transparent_frag = {
  23.          "//blue\n"
  24.          "varying vec3 vNormal;\n"
  25.          "varying vec2 vTC;\n"
  26.          "uniform sampler2D Base;\n"
  27.          "void main(void)\n"
  28.          "{\n"
  29.          "gl_FragColor = vec4(  vec3(0.0,0.0,0.0), 0.0 );\n"
  30.          "}\n"
  31. };

  32. //更改颜色代码:


  33. void ChangeColor::change(osg::StateSet* stateset)
  34. {
  35.         if(0 == stateset)
  36.                 return;

  37.         osg::ref_ptr<osg::Program> programObject = dynamic_cast<osg::Program*>(stateset->getAttribute(osg::StateAttribute::PROGRAM, 0));
  38.         if(!programObject)
  39.                 programObject=new osg::Program();

  40.         if (programObject->getNumShaders()==0)
  41.         {
  42.                 //Alpha混合开启
  43.                 stateset->setMode(GL_BLEND,osg::StateAttribute::ON);

  44.                 programObject->addShader(new osg::Shader(osg::Shader::VERTEX,base_vert));
  45.                 programObject->addShader(new osg::Shader(osg::Shader::FRAGMENT,yellow_frag));

  46.                 stateset->setAttributeAndModes(programObject,osg::StateAttribute::ON);
  47.         }
  48. }        

  49. //设置透明代码:

  50. void ChangeColor::changeTransparent(osg::StateSet* stateset)
  51. {
  52.         if(0 == stateset)
  53.                 return;

  54.         osg::ref_ptr<osg::Program> programObject = dynamic_cast<osg::Program*>(stateset->getAttribute(osg::StateAttribute::PROGRAM, 0));

  55.         if(!programObject)
  56.                 programObject=new osg::Program();

  57.         if (programObject->getNumShaders()==0)
  58.         {
  59.                 //Alpha混合开启
  60.                 stateset->setMode(GL_BLEND,osg::StateAttribute::ON);

  61.                 programObject->addShader(new osg::Shader(osg::Shader::VERTEX,base_vert));
  62.                 programObject->addShader(new osg::Shader(osg::Shader::FRAGMENT,transparent_frag));

  63.                 stateset->setAttributeAndModes(programObject,osg::StateAttribute::ON);
  64.                 stateset->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
  65.                 // 启用深度检测,使不透明的多边形遮挡它后面的透明物体
  66.                 stateset->setMode( GL_DEPTH_TEST, osg::StateAttribute::ON );

  67.         }
  68. }

  69. //恢复颜色代码:

  70. void ChangeColor::resume(osg::StateSet* stateset)
  71. {        
  72.         if(0 == stateset)
  73.                 return;
  74.         
  75.         osg::ref_ptr<osg::Program> programObject = dynamic_cast<osg::Program*>(stateset->getAttribute(osg::StateAttribute::PROGRAM, 0));

  76.         if(programObject!=NULL&&programObject->getNumShaders()>0)
  77.         {
  78.                 for (int i=programObject->getNumShaders() - 1; i >= 0; --i)
  79.                 {
  80.                         programObject->removeShader(programObject->getShader(i));
  81.                 }
  82.                 stateset->setAttributeAndModes(programObject,osg::StateAttribute::ON);
  83.         }
  84. }
复制代码



错误出现在 设置为透明后,恢复不透明状态,然后在callback函数中执行更改颜色就会出错;

请大神予以解答,谢谢!

错误3

错误3


错误2

错误2


错误1

错误1


ChangeColor.h (1.11 KB, 下载次数: 0)

该用户从未签到

发表于 2012-12-7 07:50:29 | 显示全部楼层
语法都错误了,还执行什么

该用户从未签到

 楼主| 发表于 2012-12-10 11:29:31 | 显示全部楼层
liuzhiyu123 发表于 2012-12-7 07:50
语法都错误了,还执行什么

哪个地方错了,给点提示好吗,对shader脚本不熟

该用户从未签到

发表于 2012-12-10 11:45:35 | 显示全部楼层
"gl_FragColor = vec4((texture2D( Base, vTC ).rgb * 0.5f + vec3(0.953f,0.486f,0.015f)*0.5f),1.0f);\n"
没有后面的f  , 0.5f  0.953f······

该用户从未签到

发表于 2012-12-10 11:48:57 | 显示全部楼层
sorry 说错了

该用户从未签到

发表于 2012-12-10 11:58:47 | 显示全部楼层
这边跑没问题啊

该用户从未签到

 楼主| 发表于 2012-12-10 12:25:26 | 显示全部楼层
huidian200803 发表于 2012-12-10 11:58
这边跑没问题啊

错误出现在 设置为透明后,恢复不透明状态,然后在callback函数中执行更改颜色就会出错;

该用户从未签到

发表于 2012-12-11 10:59:37 | 显示全部楼层
shader中的确不应该有0.f这样的东西存在,shader编译都没有通过

该用户从未签到

 楼主| 发表于 2012-12-11 18:45:23 | 显示全部楼层
array 发表于 2012-12-11 10:59
shader中的确不应该有0.f这样的东西存在,shader编译都没有通过

程序修改过来了,但依然会有问题,我做过一个简单的Test,如果用键盘事件调用changeTransparent,change以及resume函数的话,快速切换颜色(每次切换前调用resume),依然会出现错误;
测试代码,以及修改后的shader脚本如下:
  1. const char* ChangeColor::base_vert = {
  2.          "varying vec3 vNormal;\n"
  3.          "varying vec2 vTC;\n"
  4.          "uniform sampler2D Base;\n"
  5.          "\n"
  6.          "void main(void)\n"
  7.          "{\n"
  8.          "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
  9.          "vTC = gl_MultiTexCoord0.st;\n"
  10.          "}\n"
  11. };

  12. const char* ChangeColor::halfTransparent_frag = {
  13.          "//blue\n"
  14.          "varying vec3 vNormal;\n"
  15.          "varying vec2 vTC;\n"
  16.          "uniform sampler2D Base;\n"
  17.          "void main(void)\n"
  18.          "{\n"
  19.          "gl_FragColor = vec4(texture2D( Base, vTC ).rgb * 0.5, 0.2 );\n"
  20.          "}\n"
  21. };


  22. const char* ChangeColor::transparent_frag = {
  23.          "//blue\n"
  24.          "varying vec3 vNormal;\n"
  25.          "varying vec2 vTC;\n"
  26.          "uniform sampler2D Base;\n"
  27.          "void main(void)\n"
  28.          "{\n"
  29.          "gl_FragColor = vec4(texture2D( Base, vTC ).rgb * 0.5, 0.0 );\n"
  30.          "}\n"
  31. };


  32. const char* ChangeColor::yellow_frag = {
  33.          "//yellow\n"
  34.          "varying vec3 vNormal;\n"
  35.          "varying vec2 vTC;\n"
  36.          "uniform sampler2D Base;\n"
  37.          "void main(void)\n"
  38.          "{\n"
  39.          "gl_FragColor = vec4((texture2D( Base, vTC ).rgb * 0.5 + vec3(0.953,0.486,0.015)*0.5),1.0);\n"
  40.          "}\n"
  41. };
复制代码
  1. if (ea.getKey() == 'r')
  2.                         {
  3.                                 //ChangeColor::instance()->resume(m_mtTestChangeColor->getChild(0)->getOrCreateStateSet());
  4.                                 ChangeColor::instance()->change(m_mtTestChangeColor->getChild(0)->getOrCreateStateSet());
  5.                                 std::cout<<"change"<<std::endl;
  6.                         }
  7.                         if (ea.getKey() == 't')
  8.                         {
  9.                                 //ChangeColor::instance()->resume(m_mtTestChangeColor->getChild(0)->getOrCreateStateSet());
  10.                                 ChangeColor::instance()->changeTransparent(m_mtTestChangeColor->getChild(0)->getOrCreateStateSet());
  11.                                 std::cout<<"changeTransparent"<<std::endl;
  12.                         }
  13.                         if (ea.getKey() == 'y')
  14.                         {
  15.                                 //ChangeColor::instance()->resume(m_mtTestChangeColor->getChild(0)->getOrCreateStateSet());
  16.                                 ChangeColor::instance()->changeHalfTransparent(m_mtTestChangeColor->getChild(0)->getOrCreateStateSet());
  17.                                 std::cout<<"changeHalfTransparent"<<std::endl;
  18.                         }
  19.                         if (ea.getKey() == 'u')
  20.                         {
  21.                                 ChangeColor::instance()->resume(m_mtTestChangeColor->getChild(0)->getOrCreateStateSet());
  22.                                 std::cout<<"resume"<<std::endl;
  23.                         }
复制代码
osganimate.cpp (6.23 KB, 下载次数: 5)

该用户从未签到

发表于 2012-12-17 09:44:46 | 显示全部楼层
您所谓的出现错误指得是什么,您是否存在一些不安全的线程操作?

该用户从未签到

 楼主| 发表于 2012-12-21 15:10:45 | 显示全部楼层
array 发表于 2012-12-17 09:44
您所谓的出现错误指得是什么,您是否存在一些不安全的线程操作?

没有线程操作啊,只是简单的按键切换,错误如图所示
1.png

该用户从未签到

 楼主| 发表于 2012-12-21 15:11:39 | 显示全部楼层
liu7667715 发表于 2012-12-21 15:10
没有线程操作啊,只是简单的按键切换,错误如图所示

当然只是在切换很快的时候才会出现,慢慢的按键切换时不会出错

该用户从未签到

发表于 2012-12-21 16:02:10 | 显示全部楼层
慢慢来

该用户从未签到

 楼主| 发表于 2012-12-24 17:23:30 | 显示全部楼层
liuzhiyu123 发表于 2012-12-21 16:02
慢慢来

我的真正程序中用法是放到回调中,所以没办法慢啊,那个程序仅仅是一个测试用例,不是最终的程序效果

该用户从未签到

发表于 2012-12-25 09:50:24 | 显示全部楼层
很明显您的shader还是没有编译通过,依然存在错误

该用户从未签到

 楼主| 发表于 2013-5-8 14:50:39 | 显示全部楼层
array 发表于 2012-12-25 09:50
很明显您的shader还是没有编译通过,依然存在错误

亲,能不能告诉错误在哪里,或者给我修改一下?

该用户从未签到

发表于 2013-5-13 09:22:20 | 显示全部楼层
一个最直接的可能性就是您每次切换的时候都是直接往Program对象里面addShader,但是从没有去除掉之前的shader

该用户从未签到

 楼主| 发表于 2013-5-21 10:28:16 | 显示全部楼层
array 发表于 2013-5-13 09:22
一个最直接的可能性就是您每次切换的时候都是直接往Program对象里面addShader,但是从没有去除掉之前的shad ...

您可以先看一下代码嘛?

该用户从未签到

发表于 2013-5-21 16:35:40 | 显示全部楼层
我的回答就是一个很大的可能性,否则错误提示中不会有main重复定义。请您先排查这一点

该用户从未签到

 楼主| 发表于 2013-5-22 09:37:15 | 显示全部楼层
array 发表于 2013-5-21 16:35
我的回答就是一个很大的可能性,否则错误提示中不会有main重复定义。请您先排查这一点

但是我每次改变颜色时,都会执行resume()函数,这个函数就是用来执行移除shader操作的,代码如下:
  1. osg::ref_ptr<osg::Program> programObject = dynamic_cast<osg::Program*>(stateset->getAttribute(osg::StateAttribute::PROGRAM, 0));

  2.         if(programObject!=NULL&&programObject->getNumShaders()>0)
  3.         {
  4.                 for (int i=programObject->getNumShaders()-1; i >=0; i--)
  5.                 {
  6.                         programObject->removeShader(programObject->getShader(i));
  7.                 }
  8.                 stateset->setAttributeAndModes(programObject,osg::StateAttribute::ON);
  9.         }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表