




已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
文档:教程:中级教程:中级教程六出自Ogre3D开放资源地带跳转到: 导航, 搜索目录隐藏 1 介绍 2 准备开始 3 起始代码 4 投影贴图 o 4.1 平截头体(Frustums) o 4.2 修改材质 o 4.3 调用函数 5 消除反向投影 o 5.1 介绍 o 5.2 修改投影器 o 5.3 修改材质 6 炫耀一下投影 o 6.1 简单的旋转 o 6.2 修改视线范围 7 最后要注意的 编辑 介绍在这一课里,我们将介绍如何为场景中的一个物体添加投影贴图。投影纹理是非常有用的,比如你想要一个类似地面上的选择指示器,或者你正在瞄准的瞄准镜,或者投射在某个物体上的其它贴图。下面的截图是一个大家都喜爱的ogre头像,它被投影了一个瞄准器: 1 你能在这里找到本课的代码。当你学习本课时,你应该逐个地往你的工程里添加代码,编译并观察结果。 编辑 准备开始开始之前,我们需要两张新图。右击这两个链接,并保存到Ogre可以找到的地方:decal.png decal_filter.png 最好放在media/materials/textures目录下(对于大多数人,是在OgreSDK目录里)。 编辑 起始代码用你喜爱的IDE创建一个cpp文件,并添加如下代码: #include ExampleApplication.h / A FrameListener that gets passed our projector node and decal frustum so they can be animated class ProjectiveDecalListener: public ExampleFrameListener public: ProjectiveDecalListener(RenderWindow* win, Camera* cam, SceneNode *proj, Frustum *decal) : ExampleFrameListener(win, cam), mProjectorNode(proj), mDecalFrustum(decal), mAnim(0) bool frameStarted(const FrameEvent& evt) return ExampleFrameListener:frameStarted(evt); protected: SceneNode *mProjectorNode; Frustum *mDecalFrustum; float mAnim; ; class ProjectiveDecalApplication: public ExampleApplication protected: SceneNode *mProjectorNode; Frustum *mDecalFrustum; Frustum *mFilterFrustum; void createScene() / Set ambient light mSceneMgr-setAmbientLight(ColourValue(0.2, 0.2, 0.2); / Create a light Light* l = mSceneMgr-createLight(MainLight); l-setPosition(20,80,50); / Position the camera mCamera-setPosition(60, 200, 70); mCamera-lookAt(0,0,0); / Make 6 ogre heads (named head0, head1, etc.) arranged in a circle Entity *ent; for (int i = 0; i getRootSceneNode()-createChildSceneNode(); ent = mSceneMgr-createEntity(head + StringConverter:toString(i), ogrehead.mesh); headNode-attachObject(ent); Radian angle(i * Math:TWO_PI / 6); headNode-setPosition(75 * Math:Cos(angle), 0, 75 * Math:Sin(angle); / The function to create our decal projector void createProjector() / A function to take an existing material and make it receive the projected decal void makeMaterialReceiveDecal(const String &matName) / Create new frame listener void createFrameListener(void) mFrameListener= new ProjectiveDecalListener(mWindow, mCamera, mProjectorNode, mDecalFrustum); mRoot-addFrameListener(mFrameListener); ; #if OGRE_PLATFORM = OGRE_PLATFORM_WIN32 #define WIN32_LEAN_AND_MEAN #include windows.h #endif #ifdef _cplusplus extern C #endif #if OGRE_PLATFORM = OGRE_PLATFORM_WIN32 INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT) #else int main(int argc, char *argv) #endif / Create application object ProjectiveDecalApplication app; try app.go(); catch(Exception& e) #if OGRE_PLATFORM = OGRE_PLATFORM_WIN32 MessageBoxA(NULL, e.getFullDescription().c_str(), An exception has occurred!, MB_OK | MB_ICONERROR | MB_TASKMODAL); #else std:cerr An exception has occurred: getRootSceneNode()-createChildSceneNode(DecalProjectorNode); mProjectorNode-attachObject(mDecalFrustum); mProjectorNode-setPosition(0,5,0);这样一个投影器就创建好了,当你离得越远时,这个贴图会变得更大,就像电影机一样。若你要创建一个投影器,使得不论多远它总是保持恒定的大小和形状,你就要添加如下代码(但现在不要这样做): / 别把这段加到工程里 mDecalFrustum-setProjectionType(PT_ORTHOGRAPHIC); mDecalFrustum-setNearClipDistance(25);通过设置正射投影的视线范围、横纵比、近截取距离,你决定了这个帖图的大小和形状,使得无论投影器有多远,它总是保持恒定。 继续之前,请先搞清楚我们的平截头体将要把贴图投影到的地点。在这个程序中,有一圈Ogre头颅,而这个平截头体处于它们的正中心(虽然微微向上抬起了5个单位),并指向-Z方向(由于我们没有改变朝向,是一个默认值)。这就意味着,最终我们运行程序时,贴图将投向后面的Ogre人头。 编辑 修改材质为了让贴图最终显示在物体上,它使用的材质必须能够接收贴图。为此我们创建一个新的通路,在常规纹理上面渲染贴图。这个平截头体决定了这个投影贴图的位置、大小和形状。在这个Demo里面,我们将直接修改这个材质来接收贴图,但在实际的应用中,你应该创建这个材质的一个拷贝,再修改它,这样你就可以将材质切换回原来的。 首先获得这个材质,并为它创建一个新的通路。找到makeMaterialReceiveDecal并添加以下代码: MaterialPtr mat = (MaterialPtr)MaterialManager:getSingleton().getByName(matName); Pass *pass = mat-getTechnique(0)-createPass();现在我们创建了通路,我们需要设置混合和光照。我们将添加新的纹理,它必须与当前的纹理正确地混合。为此我们将把场景混合(scene blending)设置成alpha透明,并把深度偏移(depth bias)设置成1(也就是贴图不透明)。最后我们把材质的光照关闭,这样不论场景使用何种光照,它总是显示的。如果你想在程序里让这个贴图受光照的影响,你就不必加上最后的函数调用: pass-setSceneBlending(SBT_TRANSPARENT_ALPHA); pass-setDepthBias(1); pass-setLightingEnabled(false);接下来,新通路需要用我们的decal.png图像来创建一个新的纹理单元状态。第二个函数调用打开了投影纹理,并接收我们创建的平截头体。最后两个调用设置过滤和寻址模式: TextureUnitState *texState = pass-createTextureUnitState(decal.png); texState-setProjectiveTexturing(true, mDecalFrustum); texState-setTextureAddressingMode(TextureUnitState:TAM_CLAMP); texState-setTextureFiltering(FO_POINT, FO_LINEAR, FO_NONE);我们已经把纹理的寻址模式设置成clamp,这样贴图就不会在物体上不停地循环了。对于过滤选项,当对象放大时,使用标准线性滤波,但对于缩小的情况,我们只是关闭过滤,并且完全关闭mip贴图。这样避免了当缩小时,贴图的边缘不能很好地融入纹理的其它部分。如果我们不这样做的话,贴图投影区域的边缘会非常的难看。 对于设置材质,以上是所有你要做的。 编辑 调用函数我们已经建立好了函数,为了设置投影器和材质还必须调用它们。在createScene方法的最后面,加上以下代码: createProjector(); for (unsigned int i = 0; i getNumSubEntities(); i+) makeMaterialReceiveDecal(ent-getSubEntity(i)-getMaterialName();注意,在前面的循环里,ent变量已经保存有了Ogre头颅。由于所有的Ogre头颅使用相同的材质,我们只需要随机选择他们中的一个来获取材质名称。 编辑 消除反向投影编辑 介绍也许你已经注意到了,当运行程序里,存在两个投影贴图。一个是投射在-Z方向,也就是我们的平截头体的朝向,另一个投射在+Z方向,在我们创建的平截头体的后面的Ogre人头上。这个的原因是,当一个贴图从平截头体投影出去时,一个相应的(反向)贴图从它的背面投影出去。 这显然不是我们想要的。为了修正它,我们将引了一个过滤器来除去反向投影。 编辑 修改投影器为了过滤掉反向投影,我们需要一个新的平截头体,让它指向我们想要过滤的方向。在createProjector方法中添加以下代码: mFilterFrustum = new Frustum(); mFilterFrustum-setProjectionType(PT_ORTHOGRAPHIC); SceneNode *filterNode = mProjectorNode-createChildSceneNode(DecalFilterNode); filterNode-attachObject(mFilterFrustum); filterNode-setOrientation(Quaternion(Degree(90),Vector3:UNIT_Y);这应该比较熟悉了。唯一的区别就是我们把这个节点旋转了90度以朝向背面。 编辑 修改材质下面我们添加另一个纹理状态到材质的通路上。把以下代码加到makeMaterialReceiveDecal: texState = pass-createTextureUnitState(decal_filter.png); texState-setProjectiveTexturing(true, mFilterFrustum); texState-setTextureAddressingMode(TextureUnitState:TAM_CLAMP); texState-setTextureFiltering(TFO_NONE);这都是非常熟悉的了。注意,我们正在使用过滤纹理,过滤平截头体,并关闭了过滤。编译并运
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- DB4228T 75-2022 堇叶碎米荠生产技术规程
- DB4210T 60-2023 热防护材料综合隔热性能测试方法
- 江西环境工程职业学院《自然资源管理》2023-2024学年第一学期期末试卷
- 镇江市高等专科学校《纪录片解析》2023-2024学年第一学期期末试卷
- 山西师范大学现代文理学院《工笔花鸟》2023-2024学年第一学期期末试卷
- 2025至2030活性炭过滤器行业产业运行态势及投资规划深度研究报告
- 业主出行活动方案
- 业主相亲活动方案
- 业余钓鱼活动方案
- 士兵突击指挥部活动方案
- 2024年输配电及用电工程职称评审题库-多选、判断
- 急救车药品管理制度
- 2024年职业技能:拍卖师专业知识考试题与答案
- 4.1中国特色社会主义进入新时代+课件-高中政治统编版必修一中国特色社会主义+(36张)
- 围栏网片采购安装投标方案(技术标)
- 浙江省2024年高中化学1月学业水平考试试题
- 2024年吉林省长春市中考英语试卷(含答案与解析)
- 100%股权转让协议书
- 《生命的诗意》大单元学习 教学设计 2024-2025学年统编版高中语文必修上册
- 健康体检医疗服务投标书(范本)
- TDT 1015.2-2024 地籍数据库 第2部分:自然资源(正式版)
评论
0/150
提交评论