博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Ogre 2011-12-4 合成器框架
阅读量:6408 次
发布时间:2019-06-23

本文共 9555 字,大约阅读时间需要 31 分钟。

合成器框架Compositor

合成器框架脚本**.compositior

工作原理:合成器框架是在场景已被渲染后来改变场景的显示,是一种后处理技术。

1.合成器框架将已经渲染的场景渲染到一个texture上去。

2.然后根据需要改变这个texture的内容。

3.为了渲染texture中的改变后的场景,需要创建一个quad用来cover the monitor。

4. 将texture渲染到quad中去(也即是渲染到屏幕上去)。

 

调用流程:

1. 代码中加入合成器框架。

2. 合成器脚本中定义被渲染到的纹理和输出目标quad。

3. 被渲染到的纹理在mayerial文件夹下面的*.material文件。

4. *.material中定义了用到的fragment_program_ref。

1 compositor compositor1  2 {
3 technique 4 {
5 // 定义场景被渲染到的纹理 6 texture scene target_width target_height PF_R8G8B8 7 // 定义纹理的内容 8 target scene 9 {
10 // 内容是当前被渲染的场景 11 input previous 12 } 13 14 //定义合成器的输出。合成器不需要输入,并将其结果输出到quad。 15 //quad需要用到材质mymaterial18,并需要我们的scene target作为纹理输入 16 target_output 17 {
18 // quad有一个输入参数 19 input one 20 pass render_quad 21 {
22 //quad需要用到材质mymaterial18 23 material mymaterial18 24 // quad用该合成器的渲染目标:secene作为其输入 25 input 0 secene 26 } 27 } 28 } 29 }

1 material mymaterial18  2 {
3 technique 4 {
5 pass 6 {
7 fragment_program_ref myfragmentshader5 8 {
9 } 10 11 texture_unit 12 {
13 } 14 } 15 } 16 } 17 18 19 fragment_program myfragmentshader5 cg 20 {
21 source Ogre3DBeginnersGuideShaders.cg 22 entry_point myfragmentshader5 23 profiles ps_1_1 arbfp1 24 }
1 void myfragmentshader5(  2                         float2 uv: TEXCOORD0,  3                         out float4 color : COLOR,  4                         uniform sampler2D texture  5                        )  6 {
7 float4 tmp_color = tex2D(texture, uv); 8 float grey_value = tmp_color.r * 0.3 + tmp_color.g * 0.59 + 9 tmp_color.b * 0.11; 10 color = float4(grey_value, grey_value, grey_value, 0); 11 }

 

可以将2个合成器组合到一起用,此时在合成器脚本中需要创建2个纹理,一个用来保存场景,一个用来保存中间结果。

compositor compositor2 {
technique {
texture scene target_width target_height PF_R8G8B8 texture tmp target_width target_height PF_R8G8B8 target scene {
input previous } // 1.合成器将场景内容render到scene; // 2.利用mymaterial18(材质定义中调用fragment_program)对scene的内容进行处理后保存到tmp // 3.利用mymaterial19(材质定义中调用fragment_program)对tmp的内容处理后输出到quad target tmp {
pass render_quad {
material mymaterial18 input 0 scene } } target_output {
input one pass render_quad {
material mymaterial19 input 0 tmp } } } }

也可以只用一个纹理而不需要2个纹理:

compositor compositor3 {
technique {
texture scene target_width target_height PF_R8G8B8 target scene {
input previous } target scene {
pass render_quad {
material mymaterial18 input 0 scene } } target_output {
input one pass render_quad {
material mymaterial19 input 0 scene } } } }

 

将2个合成器组合到一起用时也可以不用重新写一个合成器脚本,只需要在代码里加入2个合成器即可,得到一个合成器链,最终结果就是这个链上的每个合成器的结果的累加。

Ogre::CompositorManager::getSingleton().addCompositor(mCamera->getViewport(), "compositor1");         Ogre::CompositorManager::getSingleton().setCompositorEnabled(mCamera->getViewport(), "compositor1", true);         Ogre::CompositorManager::getSingleton().addCompositor(mCamera->getViewport(), "compositor2");         Ogre::CompositorManager::getSingleton().setCompositorEnabled(mCamera->getViewport(), "compositor2", true);

也可以不在材质脚本或者合成器脚本中修改场景

而通过程序修改:

// 合成器的listener class CompositorListener1 : public Ogre::CompositorInstance::Listener {
public: // 当材质创建时会调用该函数 void notifyMaterialSetup(uint32 pass_id, MaterialPtr& mat) {
// 修改材质的像素参数 mat->getBestTechnique()->getPass(pass_id)->getFragmentProgramParameters() ->setNamedConstant("numPixels", 125.0f); } private: }; class MyApplication :public ExampleApplication {
public: MyApplication() {compositorListener_ = 0;} ~MyApplication() {
if (compositorListener_) {
delete compositorListener_; } } void createScene() {
Ogre::Entity* ent1 = mSceneMgr->createEntity("entity1", "Sinbad.mesh"); ent1->setMaterial(Ogre::MaterialManager::getSingleton().getByName("mymaterial11")); Ogre::SceneNode* node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode("node1", Ogre::Vector3(0, 0, 450)); node1->attachObject(ent1); // 加入和启用合成器 Ogre::CompositorManager::getSingleton().addCompositor(mCamera->getViewport(), "compositor8"); Ogre::CompositorManager::getSingleton().setCompositorEnabled(mCamera->getViewport(), "compositor8", true); // 取得合成器的指针 Ogre::CompositorInstance* comp = Ogre::CompositorManager::getSingleton().getCompositorChain(mCamera->getViewport())->getCompositor("compositor8"); // 创建合成器监听器,并将其加入到合成器中去 compositorListener_ = new CompositorListener1; comp->addListener(compositorListener_); } private: CompositorListener1* compositorListener_; };

 

当程序运行的时候通过用户的输入来改变像素数目:

1 // 合成器的listener   2 class CompositorListener1 : public Ogre::CompositorInstance::Listener   3 {
4 public: 5 CompositorListener1(){number_ = 125.0;} 6 7 8 // 当材质渲染时会调用该函数 9 void notifyMaterialRender(uint32 pass_id, MaterialPtr& mat) 10 {
11 // 修改材质的像素参数 12 mat->getBestTechnique()->getPass(pass_id)->getFragmentProgramParameters() 13 ->setNamedConstant("numPixels", number_); 14 } 15 16 void setNumber(float num) 17 {
18 number_ = num; 19 } 20 21 float getNumber() 22 {
23 return number_; 24 } 25 26 private: 27 float number_; 28 }; 29 30 31 class MyFrameListener : public Ogre::FrameListener 32 {
33 public: 34 MyFrameListener(RenderWindow* win, CompositorListener1* listener) 35 {
36 compListener_ = listener; 37 size_t windHnd = 0; 38 std::stringstream winHndStr; 39 win->getCustomAttribute("WINDOW", &windHnd); 40 winHndStr << windHnd; 41 42 OIS::ParamList pl; 43 pl.insert(std::make_pair(std::string("WINDOW"), winHndStr.str())); 44 inputmgr_ = OIS::InputManager::createInputSystem(pl); 45 keyboard_ = static_cast
(inputmgr_->createInputObject(OIS::OISKeyboard, false)); 46 } 47 48 ~MyFrameListener() 49 {
50 inputmgr_->destroyInputObject(keyboard_); 51 OIS::InputManager::destroyInputSystem(inputmgr_); 52 } 53 54 bool frameStarted(const Ogre::FrameEvent& evt) 55 {
56 keyboard_->capture(); 57 if (keyboard_->isKeyDown(OIS::KC_ESCAPE)) 58 {
59 return false; 60 } 61 62 if (keyboard_->isKeyDown(OIS::KC_UP)) 63 {
64 float num = compListener_->getNumber(); 65 ++num; 66 compListener_->setNumber(num); 67 } 68 69 if (keyboard_->isKeyDown(OIS::KC_DOWN)) 70 {
71 float num = compListener_->getNumber(); 72 --num; 73 compListener_->setNumber(num); 74 } 75 76 return true; 77 } 78 79 private: 80 OIS::InputManager* inputmgr_; 81 OIS::Keyboard* keyboard_; 82 CompositorListener1* compListener_; 83 }; 84 85 class MyApplication :public ExampleApplication 86 {
87 public: 88 MyApplication() {compositorListener_ = 0; listener_ = 0;} 89 ~MyApplication() 90 {
91 if (compositorListener_) 92 delete compositorListener_; 93 if (listener_) 94 delete listener_; 95 } 96 97 void createFrameListener() 98 {
99 listener_ = new MyFrameListener(mWindow, compositorListener_); 100 mRoot->addFrameListener(listener_); 101 } 102 103 void createScene() 104 {
105 Ogre::Entity* ent1 = mSceneMgr->createEntity("entity1", "Sinbad.mesh"); 106 ent1->setMaterial(Ogre::MaterialManager::getSingleton().getByName("mymaterial1")); 107 108 Ogre::SceneNode* node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode("node1", Ogre::Vector3(0, 0, 450)); 109 node1->attachObject(ent1); 110 111 // 加入和启用合成器 112 Ogre::CompositorManager::getSingleton().addCompositor(mCamera->getViewport(), "compositor8"); 113 Ogre::CompositorManager::getSingleton().setCompositorEnabled(mCamera->getViewport(), "compositor8", true); 114 115 // 取得合成器的指针 116 Ogre::CompositorInstance* comp 117 = Ogre::CompositorManager::getSingleton().getCompositorChain(mCamera->getViewport())->getCompositor("compositor8"); 118 119 // 创建合成器监听器,并将其加入到合成器中去 120 compositorListener_ = new CompositorListener1; 121 comp->addListener(compositorListener_); 122 } 123 124 private: 125 CompositorListener1* compositorListener_; 126 Ogre::FrameListener* listener_; 127 }; 128 129 130 int main() 131 {
132 MyApplication app; 133 app.go(); 134 return 0; 135 }

 

转载地址:http://nxqea.baihongyu.com/

你可能感兴趣的文章
iOS key value coding kvc在接收json数据与 model封装中的使用
查看>>
Android 滑动效果入门篇(二)—— Gallery
查看>>
Revit二次开发示例:DesignOptions
查看>>
Entity Framework 系统约定配置
查看>>
优秀设计:纹理在网页设计中的20个应用示例
查看>>
C++ 关键字 explicit, export, mutable
查看>>
生成指定范围的一组随机数并求平均值
查看>>
android语音识别方法
查看>>
File Operations in Android NDK(转)
查看>>
如何将kux格式的视频转换成我们常用的MP4格式
查看>>
[sublime系列文章] sublime text 3插件配置说明
查看>>
学习 PixiJS — 碰撞检测
查看>>
Vue 基础篇
查看>>
JavaScript:函数防抖与函数节流
查看>>
关于区间贪心的补全
查看>>
架构设计步骤
查看>>
自定义元素探秘及构建可复用组件最佳实践
查看>>
区块链是一个公共数据库,要放在一个块内
查看>>
Jenkins 用户文档(目录)
查看>>
系统常见指标
查看>>