关于shader的概念,可以参见我的另一篇博客《opengl版本发展史及各种概念的厘清》,这里列举一个例子,用来实现一个特效,屏幕的左半部显示为红色。首先我们准备好两个shader程序:


static const char* gl3_VertexShader = {"#version 330 core\n""in vec4 osg_Vertex;\n""in vec4 osg_Color;\n""in vec4 osg_MultiTexCoord0;\n""uniform mat4 osg_ModelViewProjectionMatrix;\n""out vec2 texCoord;\n""out vec4 vertexColor;\n""void main(void)\n""{\n""    gl_Position = osg_ModelViewProjectionMatrix * osg_Vertex;\n""    texCoord = osg_MultiTexCoord0.xy;\n""    vertexColor = osg_Color; \n""}\n"
};static const char* gl3_FragmentShader = {"#version 330 core\n""uniform sampler2D baseTexture;\n""in vec2 texCoord;\n""in vec4 vertexColor;\n""out vec4 color;\n""void main(void)\n""{\n""    color = vertexColor * texture(baseTexture, texCoord);\n""}\n"
};

这两段代码是OSG提供的默认的shader功能,从stateset中摘抄过来的。为了实现屏幕的左半部显示为红色的特效,我们重新定义一个fragment shader


static const char* sh1 = {"#version 330 core\n""uniform sampler2D baseTexture;\n""in vec2 texCoord;\n""in vec4 vertexColor;\n""out vec4 color;\n""void main(void)\n""{\n""    color = vertexColor * texture(baseTexture, texCoord);\n""    if(texCoord.x < 0.5){\n""        color = vec4(1,0,0,1);\n""    }\n""}\n"
};

OSG中与shader相关的有两个类:osg::Program 和 osg::Shader.  osg::shader与具体的顶点shader或fragment shader 相关,而Program类封装了shader的编译链接等工作。使用这两个类的方法特别简单

        /*set default shaders*/osg::ref_ptr<osg::Program> program = new osg::Program;program->addShader(new osg::Shader(osg::Shader::VERTEX, gl3_VertexShader));program->addShader(new osg::Shader(osg::Shader::FRAGMENT, sh1));stateset->setAttribute(program.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);stateset->setTextureAttributeAndModes(0, _texture2D, osg::StateAttribute::ON);stateset->setTextureAttributeAndModes(1, _depthTexture, osg::StateAttribute::ON);

上面的代码段使用了两种shader,vertex shader 与 fragment shader总是成对出现。stateset是某个node的状态集,我门对上篇博客《osg中实现HUD(OSG初级篇1)》的代码进行修改,验证本article的结论,完整代码如下:

static const char* gl3_VertexShader = {"#version 330 core\n""in vec4 osg_Vertex;\n""in vec4 osg_Color;\n""in vec4 osg_MultiTexCoord0;\n""uniform mat4 osg_ModelViewProjectionMatrix;\n""out vec2 texCoord;\n""out vec4 vertexColor;\n""void main(void)\n""{\n""    gl_Position = osg_ModelViewProjectionMatrix * osg_Vertex;\n""    texCoord = osg_MultiTexCoord0.xy;\n""    vertexColor = osg_Color; \n""}\n"
};static const char* gl3_FragmentShader = {"#version 330 core\n""uniform sampler2D baseTexture;\n""in vec2 texCoord;\n""in vec4 vertexColor;\n""out vec4 color;\n""void main(void)\n""{\n""    color = vertexColor * texture(baseTexture, texCoord);\n""}\n"
};static const char* sh1 = {"#version 330 core\n""uniform sampler2D baseTexture;\n""in vec2 texCoord;\n""in vec4 vertexColor;\n""out vec4 color;\n""void main(void)\n""{\n""    color = vertexColor * texture(baseTexture, texCoord);\n""    if(texCoord.x < 0.5){\n""        color = vec4(1,0,0,1);\n""    }\n""}\n"
};osg::Geometry* createQuad(int screen_width, int screen_heigh, float z) {osg::Geometry* polyGeom = new osg::Geometry();polyGeom->setSupportsDisplayList(false);osg::Vec3Array* vertices = new osg::Vec3Array;osg::Vec2Array* texcoords = new osg::Vec2Array;osg::Vec4Array* colors = new osg::Vec4Array;/*four vertex*/vertices->push_back(osg::Vec3d(0, 0, z));texcoords->push_back(osg::Vec2f(0, 0));vertices->push_back(osg::Vec3d(screen_width, 0, z));texcoords->push_back(osg::Vec2f(1, 0));vertices->push_back(osg::Vec3d(screen_width, screen_heigh, z));texcoords->push_back(osg::Vec2f(1, 1));vertices->push_back(osg::Vec3d(0, screen_heigh, z));texcoords->push_back(osg::Vec2f(0, 1));/*four vertex*/colors->push_back(osg::Vec4f(1.0,1.0,1.0,1.0));colors->setBinding(osg::Array::BIND_OVERALL);/*set vertex array and tex coord array*/polyGeom->setVertexArray(vertices);polyGeom->setTexCoordArray(0, texcoords);polyGeom->setColorArray(colors);polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN, 0, vertices->size()));return polyGeom;
}int
main(int argc, char** argv)
{// initialize a viewer:osgViewer::Viewer viewer;///*create effect*/viewer.setUpViewAcrossAllScreens();osgViewer::Viewer::Windows windows;viewer.getWindows(windows);int screen_width = windows[0]->getTraits()->width;int screen_heigh = windows[0]->getTraits()->height;osg::Camera* camera = new osg::Camera;camera->setName("Hud Camera");// set the projection matrixcamera->setProjectionMatrixAsOrtho2D(0, screen_width, 0, screen_heigh);camera->setViewport(0, 0, screen_width, screen_heigh);// set the view matrixcamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);camera->setViewMatrix(osg::Matrix::identity());camera->setClearColor(osg::Vec4(1, 0.5, 0.5, 0.5));/*create quad */osg::Geode* _geode = new osg::Geode();_geode->setName("GeodeOfHUD");osg::Geometry* polyGeom = createQuad(screen_width, screen_heigh, -100);polyGeom->setName("PolyGeomOfHUD_");_geode->addDrawable(polyGeom);osg::StateSet* stateset = _geode->getOrCreateStateSet();stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);/*set default shaders*/osg::ref_ptr<osg::Program> program = new osg::Program;program->addShader(new osg::Shader(osg::Shader::VERTEX, gl3_VertexShader));program->addShader(new osg::Shader(osg::Shader::FRAGMENT, sh1));stateset->setAttribute(program.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);camera->addChild(_geode);viewer.setSceneData(camera);int r = viewer.run();return r;
}

osg中运用Shader(osg初级篇2)相关推荐

  1. android在主程序中调用图片,009android初级篇之APP中使用系统相机相册等集成应用...

    009android初级篇之APP中使用系统相机相册等集成应用 android应用中使用相机功能,大致有两种方式实现: 直接调用系统内部的相机程序,显示的也是系统预设的界面(简单,只有简单的拍照功能) ...

  2. shader forge初级篇|反射材质的运用

    反射效果在制作游戏场景时是经常需要的,特别是在大理石.陶瓷类材质上有助于提升场景质感与氛围. 说道反射,游戏中常见做法就是利用当前场景cubemap作为反射源 而cubemap又是当前场景+Skybo ...

  3. osg中实现HUD(OSG初级篇1)

    HEAD-UP DISPLAY, 即是抬头显示功能,在opengl编程中,我们有时需要一种屏幕区域,这个区域并不会随着三维场景视角表换而发生改变,也可以讲,是在三维场景中实现了一个二维子场景,故常用来 ...

  4. 《Unity Shader入门精要》笔记:初级篇(2)

    本篇博客主要为个人学习所编写读书笔记,不用于任何商业用途,以及不允许任何人以任何形式进行转载. 本篇博客会补充一些扩展内容(例如其他博客链接). 本篇博客还会提供一些边读边做的效果截图.文章内所有数学 ...

  5. 《Unity Shader入门精要》笔记:初级篇(1)

    本篇博客主要为个人学习所编写读书笔记,不用于任何商业用途,以及不允许任何人以任何形式进行转载. 本篇博客会补充一些扩展内容(例如其他博客链接). 本篇博客还会提供一些边读边做的效果截图.文章内所有数学 ...

  6. 初探OSG+Opencascade在qt上的实践值获取模型颜色并在OSG中显示

    很久没有正式写过一篇博客,之前因为工作原因,致使个人项目一直停滞,在出差回来后,决定利用晚上的空闲时间重新对之前的知识进行梳理和补充,前版本中实现了如何利用opencascade读取stp模型,并显示 ...

  7. osg中三维模型的位置变换

    对模型的平移和旋转等操作是我们在做三维软件开发时必然会解决的事情.但是由于基本变换默认是以世界坐标系的原点为变换中心,所以我们在进行平移旋转等操作时往往会发现其并非如我们想象的那样去执行.举个简单的例 ...

  8. 在Eclipse中使用JUnit4进行单元测试(初级篇)

    转载自   在Eclipse中使用JUnit4进行单元测试(初级篇) 本文绝大部分内容引自这篇文章: http://www.devx.com/Java/Article/31983/0/page/1 我 ...

  9. cacheinterceptor第二次访问没被调用_访问者设计模式在OSG中的应用

    为什么要谈谈访问者设计模式呢?因为OSG整个引擎就是用访问者设计模式建立起来的,不论是遍历节点图,还是做各种实用的功能,都需要大量的用到访问者设计模式. 先谈谈访问者设计模式的定义. 1:什么是访问者 ...

最新文章

  1. 微软将发布5月安全漏洞补丁 修补PPT
  2. php 操作数组 (合并,拆分,追加,查找,删除等)
  3. C语言函数strstr()分析及实现
  4. linux停止nodejs,node.js – 在linux重启后,nodejs消失了
  5. android 打包报错,android 打包报错,请问有没有好的解决办法
  6. php cdi_DI / CDI –基础
  7. 电信计算机知识考试,2020中国电信考试试题——专业知识一
  8. ios fixed定位后内容不显示_记录CSS中 position:fixed 踩的坑
  9. 6-7Pytorch搭建cifar10训练脚本(下)
  10. 给Execl样式添加配置文件.
  11. 可执行文件的 MD5 碰撞
  12. 洛谷入门5——口算练习题
  13. 浅谈车联网与大数据分析
  14. Problem F - Football Free Kick(数组1e9的插入和删除)
  15. XJNU CTF 2018
  16. 键盘符号中英文名称大全
  17. PS 2020一些使用技巧
  18. word2007表格计算机,电脑员好做吗?使用word2007表格?
  19. 64匹马,8个赛道,通过比赛,决出前四名,最少需要比赛次数
  20. 统计学在中国的发展与就业前景

热门文章

  1. 笔记:2016-06-03
  2. 【Web】Rest API 验证授权如何做?
  3. 轻松学HTML+CSS网站开发
  4. 网络系统管理之静态路由配置
  5. 硬盘突然变慢的原因,系统突然变慢的原因
  6. 京东裁员杀红眼了!说要给n+1,员工签字后,公司又反悔了!
  7. 和产品争论MySQL底层如何实现order by的,惨败!
  8. 这款笔记本写代码真爽,包邮送一台!
  9. 【高并发】高并发环境下构建缓存服务需要注意哪些问题?我和阿里P9聊了很久!...
  10. 字节跳动的敌人,只有时间