有关D3D模板的使用

re-m2 2018-09-14 02:47:19
在D3D中利用模板绘制镜子中的像,但是书上给的解释不太明白,镜子本身z坐标为3.0f,而解释却说镜子所在平面在z=-3.0f 。
Vertex vertices[] =
{
//箱子的顶点------------------------------------
……

//后面墙
……

//镜子
{ XMFLOAT3(-2.0f, 3.0f, 3.0f), XMFLOAT2(2.0f, 0.0f) },
{ XMFLOAT3(2.0f, 3.0f, 3.0f), XMFLOAT2(0.0f, 0.0f) },
{ XMFLOAT3(-2.0f, -1.0f, 3.0f), XMFLOAT2(2.0f, 3.0f) },

{ XMFLOAT3(-2.0f, -1.0f, 3.0f), XMFLOAT2(2.0f, 3.0f) },
{ XMFLOAT3(2.0f, 3.0f, 3.0f), XMFLOAT2(0.0f, 0.0f) },
{ XMFLOAT3(2.0f, -1.0f, 3.0f), XMFLOAT2(0.0f, 3.0f) },

};
………………………………
………………………………
绘制镜子中的像如下
//----------------------- 2、绘制镜子模版,这里只填充模板不绘制颜色------------------
world = XMMatrixIdentity();
effect->GetVariableByName("World")->AsMatrix()->SetMatrix((float*)&world); //设置世界坐标系
//禁止写入颜色并设置模板缓冲状态
immediateContext->OMSetBlendState(noColorWriteBS,BlendFactor,0xffffffff); //使用NoColorWrite状态,禁止写入颜色
immediateContext->OMSetDepthStencilState(markMirrorDSS,0x1); //设置好相应的模板缓冲区状态

technique->GetPassByIndex(0)->Apply(0,immediateContext);
immediateContext->Draw(6, 54); //绘制镜子,但是这里只填充模板,不绘制镜子

//恢复原来设置
immediateContext->OMSetBlendState(NULL,NULL,0xffffffff);
immediateContext->OMSetDepthStencilState(NULL,0x1);
//----------------------- 2、绘制镜子模版,这里只填充模板不绘制颜色------------------

//----------------------- 3、绘制镜子中的木箱和地板----------------------------------
XMVECTOR refPlane = XMVectorSet(0.f,0.f,-3.f,0.0f); //镜子所在平面:[0,0,-3,0]
XMMATRIX Reflect = XMMatrixReflect(refPlane); //通过镜子反射的坐标

//绘制镜子中的箱子
//由于反射前顺时针顺序的顶点在反射后变为逆时针,因此暂时需要让逆时针为正面来渲染
immediateContext->RSSetState(counterClockFrontRS);
//设置好相应的模板缓冲区状态
immediateContext->OMSetDepthStencilState(drawReflectionDSS,0x1);
world = XMMatrixIdentity();
world = XMMatrixTranslation(0.0f, 0.0f, -6.0f)* Reflect;
effect->GetVariableByName("World")->AsMatrix()->SetMatrix((float*)&world); //设置世界坐标系

//设置箱子的纹理
effect->GetVariableByName("Texture")->AsShaderResource()->SetResource(textureBox);
technique->GetPassByIndex(0)->Apply(0,immediateContext);
immediateContext->Draw( 36, 0); //绘制镜子中的箱子

//绘制镜子中地板
//设置地板的纹理
effect->GetVariableByName("Texture")->AsShaderResource()->SetResource(textureFloor);
technique->GetPassByIndex(0)->Apply(0,immediateContext);
immediateContext->Draw(6, 36); //绘制池子,第二参数表示从顶点数组第36个(从0开始计算)顶点开始绘制

//恢复状态
immediateContext->RSSetState(NULL);
immediateContext->OMSetDepthStencilState(NULL,0x1);
//----------------------- 3、绘制镜子中的木箱和地板----------------------------------

//----------------------- 4、混合镜子,木箱和地板的纹理后绘制镜子--------------------
immediateContext->OMSetBlendState(blendStateAlpha, BlendFactor, 0xffffffff); //开启混合
immediateContext->RSSetState(NoCullRS); //关闭背面消隐
world = XMMatrixIdentity();
effect->GetVariableByName("World")->AsMatrix()->SetMatrix((float*)&world); //设置世界坐标系
effect->GetVariableByName("Texture")->AsShaderResource()->SetResource(textureMirror); //设置镜子的纹理
technique->GetPassByIndex(0)->Apply(0,immediateContext);
immediateContext->Draw(6, 54); //绘制镜子,第二参数表示从顶点数组第36个(从0开始计算)顶点开始绘制
immediateContext->OMSetBlendState(0,0,0xffffffff); //关闭混合,记住最后必须关闭混合
immediateContext->RSSetState(0); //恢复背面消隐
//----------------------- 4、混合镜子,木箱和地板的纹理后绘制镜子--------------------

还要加上之后的平移矩阵才能得到效果,如代码上的红色字体标出,我不明白为什么这样变,求解
...全文
235 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
mach 2018-09-21
  • 打赏
  • 举报
回复
因为你的镜子在(0,0,3,0),所以如果以你的镜子为摄像机,原来的原点就变换为(0,0,-3,0)了。
MagicTools引擎,包括3d场景,材质,d3d与opengles两个渲染器,max导出插件,集成了cocos2d作为ui。 引擎架构如下: 1.MtFoundation:底层数学库、字符串处理、操作系统和编译器宏定义等底层封装库。这些功能放在了MtFoundation.dll中,这个库可以以后单独提取出来提供其他项目使用。 2.MtKernel:提供资源管理器、文件系统、场景树管理。所以资源均提供引用计数、加载卸载计数、资源可以按组进行预加载。同一资源可以属于多个资源组,资源组在做rpg游戏切换房间的时候比较有用,可将一个房间的资源列表做一个组进行加载,若已存在的资源会增加其加载计数,而不用重新加载。 3.MtSceneQuery:场景查询模块。场景查询是一个相对独立的模块,可以替换掉。主要做一些算法的工作,比如射线查询、视锥剔除。把它独立处理就是希望这些cpu计算工作可以与渲染分离,便于放到一个独立的线程中。 4.MtGraphic:3d引擎模块,提供网格定义、材质定义,骨骼动画和蒙皮、贴图资源、渲染设备封装等。此处对渲染设备功能做了抽象,将具体渲染调用放到了d3d9renderer和glesrenderer中去。这里的材质在d3d下直接使用d3dxeffect,并使用宏控制编译。gles下使用固定管线控制。 d3d环境下定义了自己的材质和材质模板格式,材质模板主要用于定义effect中可用的宏,这些宏的可选取值,effect代码本身等。材质文件则引用材质模板文件,并定义宏的取值,还有uniform参数值。图形模块提供effect的uniform参数与场景中光源和物体本身材质参数的绑定。 gles环境下定了一个简单的脚本,控制固定功能渲染中的diffuse、specular和第一层纹理的参数 自定义了模型网格、骨骼、动画、材质、渲染实体等文件格式,这些文件格式说明放在了fileformats目录下。 渲染实体(Model)定义了网格与材质的组合关系,目前一个子网格只能有一个材质,但能扩展成一个子网格绑定多个材质。这样可以方便制作材质的过渡效果。 5.MtGraphic2d:这个模块是将cocos2dx0.99.4的底层替换成自己封装的渲染器实现的。cocos2dx原本是使用opengles1.0作为渲染api,在windows系统下使用powervr的模拟器运行。现在可以在d3d下或是opengles下运行。并将其更新流程合并到MtGraphic中,使得cocos2d可以正常的渲染在3d场景的前方。cocos2d的大部分功能已测试完成。可以在d3d下正常运行。 6.MtEngine:对上面几个模块的统一封装,这里负责动态的加载上面的几个模块,这里可以选择使用d3d还是gles进行渲染。还提供了建议场景逻辑控制,支持加载一个xml定义的场景脚本文件。直接使用EgnObject(EngineObject的简写)对场景模型进行控制可以省去操作底层场景树和模型材质创建的流程。 7.sampler:测试项目,用于测试上述功能。加载一个xml场景(里面全是茶壶。。。等编辑器出来就可以摆场景了),cocos2d界面渲染。鼠标键盘的输入控制。(wasd控制移动、鼠标控制方向) 材质文件说明: efm(effect material):d3d专用,里面会引用mtpl(material template)文件。 mtpl:材质模板文件,里面定义可选的宏和可选取值,还有d3dxeffect的代码。 ffm(fixed function material):d3d和gles通用,固定渲染管线材质。gles下只能用这个。 工程里带的导出插件目前只能导出网格,材质需要自己动手配置.(材质的编辑打算放到编辑器里做,然后在编辑器中绑定网格和材质,这也是cryengine和《古域》的做法,这样可以保证编辑的材质和游戏最终运行时的效果一样。)编译max导出插件需要max2010的sdk,安装插件后就可以导出单个模型。一次导出一个模型,做好一个mesh后选择max的export菜单,然后选择导出成“MtEngine Mesh File”(*.mmesh)就可以。 写了这么最后解释下为啥做这个东西吧。之前在做了两年多ogre引擎的开发,ogre确实很牛x,它的代码风格、封装程度、还有大量的算法工具都很不错,降低了3d开发的门槛,在用过的引擎中它门槛是最低的,说明他的封装做的好,但其内部结构过于复杂,不适合做灵活的修改。比如一个entity只能给一个材质,材质缺乏层的概念,不利于叠加临时效果。渲染与场景管理的代码结合得太紧,不能分离。比如没渲染一次场景都得做一次renderable排序加一次八叉树遍历,一帧里的多次渲染按理这些流程应该有所优化,但ogre

456

社区成员

发帖
与我相关
我的任务
社区描述
其它游戏引擎
社区管理员
  • 其它游戏引擎社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧