??xml version="1.0" encoding="utf-8" standalone="yes"?>国内精品久久久久久久涩爱,很黄很污的网站久久mimi色 ,色综合久久无码五十路人妻http://www.shnenglu.com/Leaf/category/14535.html~~zh-cnFri, 14 Jun 2013 21:22:53 GMTFri, 14 Jun 2013 21:22:53 GMT60镜面反射矩阵推导http://www.shnenglu.com/Leaf/archive/2013/06/15/201017.htmlRender DonkeyRender DonkeyFri, 14 Jun 2013 16:48:00 GMThttp://www.shnenglu.com/Leaf/archive/2013/06/15/201017.htmlhttp://www.shnenglu.com/Leaf/comments/201017.htmlhttp://www.shnenglu.com/Leaf/archive/2013/06/15/201017.html#Feedback0http://www.shnenglu.com/Leaf/comments/commentRss/201017.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/201017.html最q公司游戏正在准备上U,所以FlasCC也就没有研究?jin),偶尔有闲功夫Q也是玩?DMAX和UNITY3D?感觉不会(x)3DMAXQ是一U局限?/p>

回到主题Q记录一下镜面反矩늚推导?/p>

在用Irrlicht和RTT做镜面效果的时候,用到?jin)反矩c(din)?是需要把摄相机镜像,渲染一个RTQ脓(chung)到镜面模型上。这个其实还U结?jin)许久,因?f)之前做水面渲染的时候,水面是^的,很好计算摄相机在水面以下的位|?但是换成镜面Q就不一样了(jin)Q因为镜面可能是L面?于是需要一个通用的反矩c(din)?/p>

反射矩阵的计是Zq面的,因ؓ(f)QQ何反,都需要一个反面?/p>

所以,我们先给出^面表C?Plane(nx,ny,nz,d); 其中(nx,ny,nz)已经单位化?/p>

然后Q我们假讄间中有Q意一点P(x,y,z,1)

设这个点P以Plane为反面的镜像点为P1(x1,y1,z1,w)?/p>

 

Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q?/p>

Ҏ(gu)定理Q我们知道, 若两个点以某一点ؓ(f)镜像Q则两个点的坐标之和除以2Q就刚好是中炏V?

q个理论我们用到q里的话Q?那这个中点就刚好是^面上的一个点?q面上的q个点就?P(x,y,z,1) - (nx,ny,nz,0)*D .  其中D是点P到^面的距离

而D=Plane dot P = (x*nx+y*ny+z*nz+d);

׃面的描述Q我们马上想刎ͼ那么要求点P1的话Q就是这?nbsp;

(P+P1)/2 = P(x,y,z,1) - (nx,ny,nz,0)*D

=> P1 = P(x,y,z,1) - 2(nx,ny,nz,0)*D

=>P1 = P(x,y,z,1) - 2(nx,ny,nz,0)*(x*nx+y*ny+z*nz+d)

 

换成矩阵形式则ؓ(f)

                            ?-2*nx*nx   -2*nx*ny         -2*nx*nz         0  |

                             | -2*ny*nx     1 - 2*ny*ny     -2*ny*nz         0  |

P1 = {x,y,z,1}   x   | -2*nz*nx     -2*nz*ny         1-2*nz*nz        0  |

                             | -2*d*nx      -2*d*ny           -2*d*nz           1  |

 

大功告成

btw:q是行主矩阵表示?/p>

Render Donkey 2013-06-15 00:48 发表评论
]]>
一路风雨走q来Q那些我亲密接触q的目http://www.shnenglu.com/Leaf/archive/2013/04/11/199332.htmlRender DonkeyRender DonkeyWed, 10 Apr 2013 17:51:00 GMThttp://www.shnenglu.com/Leaf/archive/2013/04/11/199332.htmlhttp://www.shnenglu.com/Leaf/comments/199332.htmlhttp://www.shnenglu.com/Leaf/archive/2013/04/11/199332.html#Feedback2http://www.shnenglu.com/Leaf/comments/commentRss/199332.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/199332.html一旉Q又不知道说什么了(jin)?贴几张这一路走来,和我有关的项目截囑֐?nbsp; 旉是由新到?/p>

 

目前在正研发中的目 《帝国来?jin)?/p>

http://v.ku6.com/show/1zMrlsOx0nwpQw3JMoNAjw...html

image

image

 

l爹妈d员(sh)后的W二个?《大话修仙?Q天地劫WEB)

http://xx.sjgame.cn/

image

image

 

处女?《爹妈d员?哎,W一ơ,l了(jin)它?

http://www.87kd.com/game/dmzdy/

 

公司让我们学?fn)实战经验,临时参与了(jin)两个月的《五虎上?/p>

http://whsj.sjgame.cn/

 

W一个FALSH技术DEMO KINGDOM RUSH

http://www.shnenglu.com/Leaf/archive/2013/02/22/198012.html

image

 

HALO 3D引擎DEMO演示

http://www.shnenglu.com/Leaf/archive/2013/02/22/198011.html

wps_clip_image-26198

 

2部的《天地劫?/p>

http://tdj.sjgame.cn/main.html

 

在游戏开发的道\上,我想我依然会(x)l箋(hu)努力、奋斗?生生不息Q不M弃。。。?/p>

Render Donkey 2013-04-11 01:51 发表评论
]]>
irrlicht引擎Q镜子效?/title><link>http://www.shnenglu.com/Leaf/archive/2013/04/05/199111.html</link><dc:creator>Render Donkey</dc:creator><author>Render Donkey</author><pubDate>Thu, 04 Apr 2013 16:53:00 GMT</pubDate><guid>http://www.shnenglu.com/Leaf/archive/2013/04/05/199111.html</guid><wfw:comment>http://www.shnenglu.com/Leaf/comments/199111.html</wfw:comment><comments>http://www.shnenglu.com/Leaf/archive/2013/04/05/199111.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Leaf/comments/commentRss/199111.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Leaf/services/trackbacks/199111.html</trackback:ping><description><![CDATA[<p> </p> <p>最q在用irrlicht做一?D试衣间的项目,Z(jin)l项目增ȝ花样Q于是想实现一面镜子?/p> <p>我记得D3D龙书上有一个用模板缓冲区实现的例子。网上也有OPENGL实现的例子?但这一ơ,我想用irrlicht的RTT实现一面镜子效果?/p> <p>其实原理和水面反原理是一L(fng)Q?只是没有加扰动而已</p> <p> </p> <p>W一步:(x)渲染反射贴图</p> <blockquote> <p>反射贴图的渲染,其实是摄相机通过镜面镜像卛_Qirrlicht中我找了(jin)半天Q没有发现镜像矩늚法Q倒是在网上搜C(jin)一个?很是不错?/p></blockquote> <p>同时Q也阅?jin)一下先前公司引擎项目的代码Q发现其实就是那个公式?有兴的朋友可以参看q里</p> <p> </p> <p><a title="http://www.cnblogs.com/glshader/archive/2010/11/02/1866971.html" >http://www.cnblogs.com/glshader/archive/2010/11/02/1866971.html</a></p> <p> </p> <p>通过q个镜面反射矩阵Q我们可以将摄相机镜像, 相当于是从镜子里向外看,渲染Z个世界?在渲染的时候,要记得设|裁剪面?在我的测试中我没有设|?/p> <p>W二步:(x)重新渲染世界</p> <blockquote> <p>重新渲染世界的时候,镜子需要一个特D的U理来进行反脓(chung)图。(镜像摄相机空间的投媄(jing)U理映射Q?q个贴图方式Q就是指忽略镜子的纹理坐标,而通过</p></blockquote> <p>镜像摄相机来计算出投影坐标,然后贴在镜子上。在我的试中,是用SHADER来实现的?为镜子做?jin)一个特D的U理?/p> <p> </p> <p>下面Q我贴一下SHADERQ很单,如果实在不清楚的Q可以参考一些投q理相关的资料?/p> <p> </p> <p>点着色器代码 HLSL</p> <p>float4x4    WorldViewProj;<br>float4x4    MirrorWorldViewProj;<br>struct VS_OUTPUT<br>{<br>    float4 position    :POSITION; </p> <p>    float3 uv: TEXCOORD0;<br>}; </p> <p>struct VS_INPUT<br>{<br>    float4 position        : POSITION;<br>    float4 color        : COLOR0;<br>    float2 texCoord0    : TEXCOORD0;<br>}; <p>VS_OUTPUT main(VS_INPUT input)<br>{<br>    VS_OUTPUT output; <br>    float4 pos = mul(input.position, WorldViewProj);<br>    output.position = pos;</p> <p>    //计算反射U理的坐?</p> <p>    pos = mul(input.position,MirrorWorldViewProj);<br>    output.uv.x = 0.5 * (pos.w + pos.x);<br>    output.uv.y = 0.5 * (pos.w - pos.y);<br>    output.uv.z = pos.w;<br>    return output;<br>} <p>  <p>像素着色器代码 HLSL <p>sampler2D colorMap;<br>struct PS_OUTPUT<br>{<br>    float4 color : COLOR0;   <br>}; <p>struct PS_INPUT<br>{<br>    float4 position    : POSITION;<br>    float3 uv: TEXCOORD0;<br>};<br>PS_OUTPUT main( PS_INPUT input )<br>{ <br>    PS_OUTPUT output;<br>    float2 uv = saturate(input.uv.xy / input.uv.z);<br>    output.color = tex2D(colorMap,uv);<br>    return output;<br>} <p> </p> <p> </p> <p>RTT相关的操作,irrlicht的RenderToTexture已经很明白了(jin)Q再此不在敷q?/p> <p> </p> <p>上图Q收?/p> <p> </p> <p><a href="http://www.shnenglu.com/images/cppblog_com/Leaf/WindowsLiveWriter/irrlicht_C6B/2000_2.jpg"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="2000" border="0" alt="2000" src="http://www.shnenglu.com/images/cppblog_com/Leaf/WindowsLiveWriter/irrlicht_C6B/2000_thumb.jpg" width="539" height="405"></a></p><img src ="http://www.shnenglu.com/Leaf/aggbug/199111.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Leaf/" target="_blank">Render Donkey</a> 2013-04-05 00:53 <a href="http://www.shnenglu.com/Leaf/archive/2013/04/05/199111.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>irrlicht引擎Q真实的水面渲染http://www.shnenglu.com/Leaf/archive/2013/04/04/199101.htmlRender DonkeyRender DonkeyThu, 04 Apr 2013 10:16:00 GMThttp://www.shnenglu.com/Leaf/archive/2013/04/04/199101.htmlhttp://www.shnenglu.com/Leaf/comments/199101.htmlhttp://www.shnenglu.com/Leaf/archive/2013/04/04/199101.html#Feedback0http://www.shnenglu.com/Leaf/comments/commentRss/199101.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/199101.html先上?/p>

image

 

image

本来说是做镜子效果的Q结果手工计的镜面反射矩阵应用在irrlicht相机上的时候,始终无法出现效果Q只能去|上搜烦(ch)

在irrlicht official wiki上发C(jin)q个扩展的WaterNodeQ下载下来,改了(jin)点BUGQ整合进?jin)Terrain Demo里, 是上图的效果?/p>

在我的机器上,HLSL版本是没有问题的QGL版本貌似RTT有点问题?/p>

 

点击此处下蝲源代?/a>



Render Donkey 2013-04-04 18:16 发表评论
]]>
irrlicht引擎Q硬件蒙皮骨骼动?/title><link>http://www.shnenglu.com/Leaf/archive/2013/03/26/198823.html</link><dc:creator>Render Donkey</dc:creator><author>Render Donkey</author><pubDate>Mon, 25 Mar 2013 16:08:00 GMT</pubDate><guid>http://www.shnenglu.com/Leaf/archive/2013/03/26/198823.html</guid><wfw:comment>http://www.shnenglu.com/Leaf/comments/198823.html</wfw:comment><comments>http://www.shnenglu.com/Leaf/archive/2013/03/26/198823.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Leaf/comments/commentRss/198823.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Leaf/services/trackbacks/198823.html</trackback:ping><description><![CDATA[<p>q个东西很顺利,仅用?jin)半时找C(jin)Ҏ(gu)Q最应该感谢的还是Super TuxKart(USTKQ下面就都用q三字母?. 如果不明白STKQ同时又对它感兴的童鞋Q可以访问这?/p> <p><a title="http://supertuxkart.sourceforge.net/" >http://supertuxkart.sourceforge.net/</a></p> <p>׃墙的原因Q需要各位搭梯子?/p> <p> </p> <p>上周末,在弄换装的时候,发现irrlicht引擎本n是不支持g蒙皮的,多少令h有些失望??j)里׃直寻思着怎么扩展一下,它弄出来?/p> <p>值得说明的是STK对irrlicht引擎的用法是很简单的Q基本上可以说是裸用Qƈ未在irrlicht接口上做修改?而是对外q行?jin)一些必要的扩展?/p> <p>当然QSTK也对外开放了(jin)一个irrlicht.dllQ说是修改了(jin)其中的BUG?但直接用irrlicht是可以的?/p> <p> </p> <p>废话不多_(d)来说说如何不修改irrlicht一行代码,通过外部扩展来实现硬仉骼动d</p> <p> </p> <p>首先Q能够我们不修改irrlicht代码的原因,是因为ISkinnedMesh提供?jin)一个setHardwareSkinning接口Q默认ؓ(f)false.</p> <p>虽然q个接口的说明是"(This feature is not implemented in irrlicht yet)”Q但q不代表Q设|与不设|无差别?</p> <p>查看代码可以发现Q当你设|了(jin)q个为true以后Qirrlicht完全不你的动M(jin)?意思就是,要是你非要让我干我不q不?jin)的事,那就只有?zhn)另请高明了(jin)?/p> <p>irrlichtqCPU计算都不?x)参与?q正好让我们有机可乘Q完全用GPU接管?/p> <p> </p> <p>而要让一个顶点参与骨D,那骨骼烦(ch)引则是少不了(jin)的。所以,我们需要想办法让顶Ҏ(gu)据能够将骨骼索引代入SHADER中?/p> <p>在STK中用?jin)一Uy妙的Ҏ(gu)Q?是使用?jin)顶点的颜色数据Q?虽然q样一来,点颜色q不了(jin)?jin)?但在模型渲染Ӟ点颜色很少被用到的?也就是说Q顶炚w色在STK的动L型中Q被用作?jin)骨骼?ch)引?/p> <p>初始化骨骼烦(ch)引的Ҏ(gu)很简单,用下面的代码遍历卛_?/p> <p>设:(x)我们有一个骨骼动L型是 ISkinnedMesh* pSkinnedMesh = …</p> <p>那么Q初始化代码如下</p> <p>for(u32 i = 0;i < pSkinnedMesh ->getMeshBuffers().size();++i)<br>{<br>    for(u32 g = 0;g < pSkinnedMesh ->getMeshBuffers()[i]->getVertexCount();++g)<br>    {<br>        pSkinnedMesh ->getMeshBuffers()[i]->getVertex(g)->Color = video::SColor(0,0,0,0);<br>    }<br>}</p> <p>//初始化完毕以后,是需要真正的索引赋g(jin)Q通过以下代码可以完成</p> <p>const core::array<scene::ISkinnedMesh::SJoint*>& joints = pSkinnedMesh ->getAllJoints();<br>for(u32 i = 0;i < joints.size();++i)<br>{<br>    const core::array<scene::ISkinnedMesh::SWeight>&    weights = joints[i]->Weights;<br>    for(u32 j = 0;j < weights.size();++j)<br>    {<br>        int buffId = weights[j].buffer_id; <p>        int vertexId = pSkinedMesh->getAllJoints()[i]->Weights[j].vertex_id;<br>        video::SColor* vColor = &pSkinedMesh->getMeshBuffers()[buffId]->getVertex(vertexId)->Color; <p>        if(vColor->getRed() == 0)<br>            vColor->setRed(i + 1);<br>        else if(vColor->getGreen() == 0)<br>            vColor->setGreen(i + 1);<br>        else if(vColor->getBlue() == 0)<br>            vColor->setBlue(i + 1);<br>        else if(vColor->getAlpha() == 0)<br>            vColor->setAlpha(i + 1);<br>    }<br>} <p> </p> <p>//l过以上两个步骤Q顶Ҏ(gu)据改造完成?值得注意的是Q?在这里, 索引 0 是被认ؓ(f)是无效的</p> <p> </p> <p>然后Q我们来创徏一个SHADER作ؓ(f)渲染?/p> <p>假设 我们这个pSkinnedMeshl定?jin)到了(jin)一个IAnimatedSceneNode* node 上?/p> <p>那,我们个结点创Z个材?在创建材质前Q我们需要准备一个SHADER回调?SHADER回调?yu)像下面一样就可以?jin)?/p> <p>class HWSkinCallBack:public video::IShaderConstantSetCallBack<br>{<br>    scene::IAnimatedMeshSceneNode* m_pNode;<br>public:<br>    HWSkinCallBack(scene::IAnimatedMeshSceneNode* node):m_pNode(node)<br>    { <p>    }<br>    virtual void OnSetConstants(video::IMaterialRendererServices* services,<br>        s32 userData)<br>    {<br>        scene::ISkinnedMesh* mesh = (scene::ISkinnedMesh*)m_pNode->getMesh();<br>        f32 joints_data[55 * 16];<br>        int copyIncrement = 0; <p>        const core::array<scene::ISkinnedMesh::SJoint*> joints = mesh->getAllJoints();<br>        for(u32 i = 0;i < joints.size();++i)<br>        {<br>            core::matrix4 joint_vertex_pull(core::matrix4::EM4CONST_NOTHING);<br>            joint_vertex_pull.setbyproduct(joints[i]->GlobalAnimatedMatrix, joints[i]->GlobalInversedMatrix); <p>            f32* pointer = joints_data + copyIncrement;<br>            for(int i = 0;i < 16;++i)<br>                *pointer++ = joint_vertex_pull[i]; <p>            copyIncrement += 16;<br>        } <p>        services->setVertexShaderConstant("JointTransform", joints_data, mesh->getAllJoints().size() * 16);<br>    }<br>}; <p> </p> <p>好了(jin)Q现在我们来创徏一个材?/p> <p>s32 hwskm = gpu->addHighLevelShaderMaterialFromFiles(<br>        "../../skinning.vert","main",video::EVST_VS_2_0,<br>        "","main",video::EPST_PS_2_0,&hwc,video::EMT_SOLID);</p> <p>//用新创徏出来的材质赋值给q个l点</p> <p>node->setMaterialType((video::E_MATERIAL_TYPE)hwskm );</p> <p> </p> <p>//到此Q设|完毕?/p> <p> //最后,是skinning.vert本n的内容了(jin)?贴出来即可,没有太多技巧,是一个普通的蒙皮?/p> <p>// skinning.vert <p>#define MAX_JOINT_NUM 36<br>#define MAX_LIGHT_NUM 8 <p>uniform mat4 JointTransform[MAX_JOINT_NUM]; <p>void main() <br>{<br>    int index;<br>    vec4 ecPos;<br>    vec3 normal;<br>    vec3 light_dir;<br>    float n_dot_l;<br>    float dist; <p>    mat4 ModelTransform = gl_ModelViewProjectionMatrix;<br>    index = int(gl_Color.r * 255.99);<br>    mat4 vertTran = JointTransform[index - 1];<br>    index = int(gl_Color.g * 255.99);<br>    if(index > 0)<br>        vertTran += JointTransform[index - 1]; <p>    index = int(gl_Color.b * 255.99);<br>    if(index > 0)<br>        vertTran += JointTransform[index - 1];<br>    index = int(gl_Color.a * 255.99);<br>    if(index > 0)<br>        vertTran += JointTransform[index - 1];<br>    ecPos = gl_ModelViewMatrix * vertTran * gl_Vertex;<br>    normal = normalize(gl_NormalMatrix * mat3(vertTran) * gl_Normal);<br>    gl_FrontColor = vec4(0,0,0,0);<br>    for(int i = 0;i < MAX_LIGHT_NUM;i++)<br>    {<br>        light_dir = vec3(gl_LightSource[i].position-ecPos);<br>        n_dot_l = max(dot(normal, normalize(light_dir)), 0.0);<br>        dist = length(light_dir);<br>        n_dot_l *= 1.0 / (gl_LightSource[0].constantAttenuation + gl_LightSource[0].linearAttenuation * dist);<br>        gl_FrontColor += gl_LightSource[i].diffuse * n_dot_l;<br>    }<br>    gl_FrontColor = clamp(gl_FrontColor,0.3,1.0); <p>    ModelTransform *= vertTran;<br>    gl_Position = ModelTransform * gl_Vertex;<br>    gl_TexCoord[0] = gl_MultiTexCoord0;<br>    gl_TexCoord[1] = gl_MultiTexCoord1;<br>    /* <br>    // Reflections.<br>    vec3 r = reflect( ecPos.xyz , normal );<br>    float m = 2.0 * sqrt( r.x*r.x + r.y*r.y + (r.z+1.0)*(r.z+1.0) );<br>    gl_TexCoord[1].s = r.x/m + 0.5;<br>    gl_TexCoord[1].t = r.y/m + 0.5;<br>    */<br>} <p> </p> <p> </p> <p>//注:(x)q是GLSL 2.0Q?在用IRR做测试的时候,要选GL驱动方式?/p> <p> </p> <p>q是上个囑֐Q不上图感觉没有真像?虽然囄不出来什么动?/p> <p><a href="http://www.shnenglu.com/images/cppblog_com/Leaf/WindowsLiveWriter/irrlicht_14DD5/image_2.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.shnenglu.com/images/cppblog_com/Leaf/WindowsLiveWriter/irrlicht_14DD5/image_thumb.png" width="526" height="410"></a> </p> <p>Z(jin)说明它真的在动,不得不上W二张?</p> <p> </p> <p><a href="http://www.shnenglu.com/images/cppblog_com/Leaf/WindowsLiveWriter/irrlicht_14DD5/image_4.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.shnenglu.com/images/cppblog_com/Leaf/WindowsLiveWriter/irrlicht_14DD5/image_thumb_1.png" width="523" height="417"></a> </p> <p> </p> <p>在此Q十分感谢Super Tux Kart. 提供?jin)一个学?fn)和扩展irrlicht的榜?</p> <img src ="http://www.shnenglu.com/Leaf/aggbug/198823.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Leaf/" target="_blank">Render Donkey</a> 2013-03-26 00:08 <a href="http://www.shnenglu.com/Leaf/archive/2013/03/26/198823.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>irrlicht引擎Q实现天龙八部的RPG角色换装http://www.shnenglu.com/Leaf/archive/2013/03/24/198762.htmlRender DonkeyRender DonkeySat, 23 Mar 2013 20:08:00 GMThttp://www.shnenglu.com/Leaf/archive/2013/03/24/198762.htmlhttp://www.shnenglu.com/Leaf/comments/198762.htmlhttp://www.shnenglu.com/Leaf/archive/2013/03/24/198762.html#Feedback0http://www.shnenglu.com/Leaf/comments/commentRss/198762.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/198762.html看了(jin)看时_(d)已经3点过?jin),H然惛_点什么,却又不知从何说v?/p>

那就从今天这个用irrlicht做天龙八部的模型换装说v吧?/p>

 

也不知道是ؓ(f)什么,最q又捣鼓起了(jin)OGRE和irrlicht. q且QL用irrlicht实现一些OGRE中的东西?/p>

当然Q这不是商业目Q也没有商业目的Q纯属蛋D已?/p>

 

一切行动的由来Q都来自于vczh那天晚上的D动?/p>

记得有一天晚上在里聊天Q大伙就U赞各位?qing)苣是多么的厉害?/p>

最后vc发了(jin)一个自q桌面截图_(d)(x)让你们看看菊(qing)苣是如何l成的(q不是原话,和话的字眼有出入Q在此不惌M责QQ如果真有想看的Q去ȝ的聊天记录)(j)

那天晚上Q我想了(jin)很久。想惌p从{做页总后,是如何虚渡光阴的?/p>

l于忍不住了(jin)Q翻开?jin)自qUd盘Q看看自己曾l做q的东ѝ?0%是徏好工E就没理?jin)?/p>

q才明白Q我花在思考上的时间远q大于了(jin)行动?于是Q我军_改变自己Q找回那个真的我?/p>

 

3D游戏是我的真爱, 真爱到就画面差一点,只要?DQ我也会(x)很喜Ƣ?/p>

于是Q我觉得自己q是应该接着先前的\C厅R?什么服务器Q什?AS3. 都是云Q?不喜Ƣ就是不喜欢?/p>

U下又开始研Iirrlicht?jin)?/p>

猛地一发现Q自己是多么的搞W, ?9q到11q_(d)一直在做引擎开发, 也翻qirrlicht和ogre无数遍?却从来就没有写完q一个完整的DEMO?/p>

q功能测试用例都没有写过。突然觉得之前的一些设计似乎有些脱M(jin)实际。没有真正用过Q又怎知如何是好Q如何是坏呢Q?/p>

 

q一ơ是真的玩irrlicht?jin)?中间也纠l过是不是OGRE更适合?但在目前q个旉有限的空间下Q我更愿意玩irrlicht.yQ轻ѝ?当然Q意味着更多东西要自己实现?不过对于一个代码控来说Q也反而更自得其乐?正好可以在短路的时候,d考一下其它引擎,用来扩充irrlicht.

我要做的不是把irrlicht整得牛BQ而是惌己弄弄,加上Udq_的崛P我觉得irrlicht更加适合吧?据说gameloft也有使用Q仅是据_(d)(j)?/p>

 

可能很多兄弟?x)说我这讲的东西Q其实就是一坨屎?jin)?不过Q我觉得再坏的评论,也表CZU关注?批评好过于无视啊~~~~

----------------------------------------------------------下面说说我遇上的U结------------------------------------------------

U结1:换装需要场景节炚w?/strong>

  在irrlicht中,q没有提供普通引擎中的submesh或者bodypartq种东西Q用于直接支持换装?在irrlicht中,如果惌换装Q最直接的方法就是依赖于场景l点

比如,在我的示例中Q可以更换头发,帽子Q衣服,护腕Q靴子,面容?那就需?个场景节点,1个作为根节点Q用于控制整个角色的世界坐标Q^U,~放Q旋转等属性。另?个场景节点则分别l有各个部g的模?/p>

贴一下我的角色类的代码,行数不多

class CCharactor
{
    IrrlichtDevice* m_pDevice;
    IAnimatedMeshSceneNode* m_pBodyParts[eCBPT_Num];
    ISceneNode* m_pRoot;
public:
    CCharactor(IrrlichtDevice* pDevice)
        :m_pDevice(pDevice)
    {
        memset(m_pBodyParts,0,sizeof(m_pBodyParts));
        m_pRoot = pDevice->getSceneManager()->addEmptySceneNode(NULL,12345);
    }
    void changeBodyPart(ECharactorBodyPartType ePartType,stringw& meshPath,stringw& metrialPath)
    {
        ISceneManager* smgr = m_pDevice->getSceneManager();

        IAnimatedMeshSceneNode* pBpNode = m_pBodyParts[ePartType];
        IAnimatedMesh* pMesh = smgr->getMesh(meshPath.c_str());
        if(pMesh==NULL)
            return;

        if(pBpNode==NULL)
        {
            pBpNode = smgr->addAnimatedMeshSceneNode(pMesh,m_pRoot);
            m_pBodyParts[ePartType] = pBpNode;
        }
        else
        {
            pBpNode->setMesh(pMesh);
        }
        ITexture* pTexture = m_pDevice->getVideoDriver()->getTexture(metrialPath.c_str());
        if(pTexture)
            pBpNode->setMaterialTexture(0,pTexture);
    }
};

 

//然后Q我用了(jin)一个结构体来构建部件信?/p>

struct SBodyPartInfo
{
    stringw Desc;
    ECharactorBodyPartType Type;
    stringw MeshPath;
    stringw MeterialPath;
};

 

U结2Q共享骨?/strong>

首先Qirrlicht 1.8中对OGRE模型的格式支持在代码中,最高只看到?.40版本的解析,更高的就?x)被无视?天龙八部的模型有几个?.30的,而用于换装和主角的,都是1.40的?可能是解析不全的原因Q导?.40的骨骼动L法正常播放?q个问题整了(jin)几个时Q没有解冻I明天l箋(hu)

其次Q多个模型共享骨骼只能通过场景节点的useAnimationFrom来完成,q且传入的是一个Mesh参数。这点让| 天龙八部的角色动作是分开?jin)的Q不同的d动作是一个skeleton文g?惌实现׃nQ有炚w?ch)?/p>

 

U结3Q模型文件格?/strong>

irrlicht不像OGRE那样有一个强大且成熟的模型文件格?虽然提供?irr格式Q但仅是用于irrEdit的场景信息输出。先看一张图

image

q张图是irrlicht samples中的MeshViewer的提C框内容?上面列出?jin)可以支持的模型文gcd?大家可以看看Q又有多模型格式是可以直接拿来攑ֈ目上用的呢Q?mdl和ms3d可以考虑Qdae的话Q我在开源游? A.D. 中见C用过?其它的话Q就完全不熟(zhn)了(jin)?OGRE?.mesh支持也不完全?N真要自己整一个?

我能惛_的,是选一个插件完整和模型和动L式都比较好的作ؓ(f)与美术工具交互的格式?自己再写一个工P转换成自q格式?/p>

 

U结4Q硬件蒙?/strong>

我以为像NIKO那样的技术狂Q怎么?x)放掉这一个特性?很高兴地在场景节点上发现?jin)硬件蒙皮的函数接口。但一看注释,把我咽着?jin)?/p>

//! (This feature is not implemented in irrlicht yet)
virtual bool setHardwareSkinning(bool on);

 

其它地方Q还没有LQ就先不发表aZ(jin)?l箋(hu)着q个很傻B,很天真的捣鼓之\?

上个图,U念一下我的irrlicht产物?/p>

 

布衣

image

 

换了(jin)w盔?/p>

image

 

换了(jin)帽子和靴?/p>

image

 

PS:头发没有U理Q所以是白的?/p>

Render Donkey 2013-03-24 04:08 发表评论
]]>
WOW渲染中的U理压羃http://www.shnenglu.com/Leaf/archive/2011/01/23/139183.htmlRender DonkeyRender DonkeySun, 23 Jan 2011 12:00:00 GMThttp://www.shnenglu.com/Leaf/archive/2011/01/23/139183.htmlhttp://www.shnenglu.com/Leaf/comments/139183.htmlhttp://www.shnenglu.com/Leaf/archive/2011/01/23/139183.html#Feedback0http://www.shnenglu.com/Leaf/comments/commentRss/139183.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/139183.html一直没玩台服,国服也停留在72U。 成都的天气一天天严峻Q更是不惛_?jin),于是用NVPerfHUD挂了(jin)下WOWQ看看它到底啥样?/p>

用NVPerfHUD挂程序需要被挂的E序自n支持Q但是网上有一个老兄写的一个NVPerfHUD AnyE序可以帮你完成q个功能。对大多数D9的都有效。除非本w做?jin)破解?/p>

l大家这个链接,自己去解决个人问题?/p>

http://www.thecodeway.com/blog/?p=433

 

完美时空的引擎很不错Q依然坚挺地用着D8。其实挺x(chng)来看看的Q可惜市(jng)面上L的工具都不支持D8Q只有D9以及(qing)以后的版本?/p>

 

WOW在CTM的版本中升?jin)它的渲染引擎,光从水面和火焰就看得出来。 但WOW一向是以负载和畅度ؓ(f)主,q且WOW本n卖的不是画面。所以若不能帮助提升游戏性的渲染损耗基本上被无视了(jin)。 其实吧,个h觉得Q做游戏无非׃U了(jin)。 一U是q求画面Q这一Ҏ(gu)子很有心(j)得。二是追求可玩性,q一Ҏ(gu)想WOW应该遥遥领先?jin)吧。 另外一U追求就昑־很单U了(jin)Q-Q钱。 q一点国内许多游戏做得很好,在此׃列名字了(jin)Q因为比较多?/p>

 

׃上星期在公司试新写好的材质和资源管理时Q发现ALPHA试的草丛效果很不理惻I于是草的ALPHA混合开启了(jin)Q一旉Q感觉世界被颠倒了(jin)。因是按画的,排序也只能是按簇排序Q当开启了(jin)ALPHA混合后,草丛与草丛之间没有太多问题,只是草丛本n出现?jin)像素渲染错误。 不管是Z写和Z试如何选择开启和关闭。都?x)有问题?/p>

H然发现草这个东西很特别?/p>

草丛的徏模和GPU GEMS 1上的建模方式一P 三个矩Ş交叉的方式?/p>

Q、它需要用ALPHA混合来实现效?/p>

用ALPHA混合的效果是很不错的。因为可以边缘柔和。毕竟ALPHA试?x)因为图片ALPHA值采样引L(fng)误差D严重的钜ѝ其ơ就是对术要求太高?sh)(jin),需要严格控制ALPHA与非ALPHA交界处?/font>

Q、但它的行ؓ(f)属性却是一个非透明物体。 

q是因ؓ(f)它必L深度关系Q必需写Z。 因ؓ(f)只有写了(jin)ZQ才能够正确CҎ(gu){透明物؜合,q且也只有写?jin)ZQ同一草中的多个面片才能够正常混合?/font>

在忽略其它情况下Q我试过?jin)Z试和Z写的四种l合Q也未能辑ֈ草丛本n和单草都同时达到正的效果?/p>

 

q是多看看别人怎么做的吧,所以上来就比较兛_(j)WOW的植被渲染了(jin)。 当看C面这L(fng)U理的时候,我笑?jin)。没惛_BLZ的美术资源节U到?jin)这L(fng)E度Q真是细致入微啊Q这不是拍马屁,试问有多美术资源是q样做的Q。 可以看出Q若不采用这L(fng)半张Q而用整张Q那么就?28X128的大?/p>

左边为原图,双为ALPHA通道查看?/p>

 

image image

 

而对于树(wi)的渲染,则很普通了(jin)。设|好U理Q设|好数据和渲染状态,提交l制卛_?/p>

image image

Z(jin)看到ALPHA混合的效果,我强忍着把WOW在我7300的显卡上开完了(jin)效果。以Z(x)咋的Q结果啥也没发生?/p>

WOW的植被的没有用到ALPHA混合。我失望?jin)?/p>

可能许多得,把多张纹理整合在一张上更好吧。 当然?jin),q是自然的。 下面是WOW中经怸起出现的植被的纹理打包图?/p>

大家可以看到Q右边的囑ƈ没有被裁剪,其原因不a而谕Q因为想以非对称营造感觉,q且g物体U理本n比较?yu)。)(j)?/p>

image image

 

image

image

发现q草用的是两片,q且大小q(sh)一栗 不知是否真的有此必要?/p>

 

 

我最后要说明的是Q这文章q完了(jin)。没有结论,也没有感a。因为那样太俗套Q?/p>

Render Donkey 2011-01-23 20:00 发表评论
]]>
OGRE3D 渲染pȝU程?/title><link>http://www.shnenglu.com/Leaf/archive/2010/12/20/137076.html</link><dc:creator>Render Donkey</dc:creator><author>Render Donkey</author><pubDate>Mon, 20 Dec 2010 15:14:00 GMT</pubDate><guid>http://www.shnenglu.com/Leaf/archive/2010/12/20/137076.html</guid><wfw:comment>http://www.shnenglu.com/Leaf/comments/137076.html</wfw:comment><comments>http://www.shnenglu.com/Leaf/archive/2010/12/20/137076.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Leaf/comments/commentRss/137076.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Leaf/services/trackbacks/137076.html</trackback:ping><description><![CDATA[     摘要: 先前研究渲染pȝU程化的时候翻C(jin)q篇文章Q于是一边看一边写Z(jin)汉语?文中写多地方译得很不通顺Q见谅?<br> <br> <br> <br>译者序Q偶然在|上看到q篇文章Q自己很想仔l研I一下。但搜寻半天不见中文版。于是自己斗胆翻译了(jin)一下。文中不免有漏洞癑ևQ甚臛_以说有些地方不及(qing)Google译得好。但q样ȝ来说是出?jin)一个中文版Q而我自己在翻译过E中也会(x)停下来仔l思考?<br> <br>OGREq个U程化的文章很老了(jin)。因为OGRE目前已经支持多线E渲染?q篇文章貌似是某些h研究出来的三个线E化Ҏ(gu)Qƈl出?jin)测试结果。以向OGREC֌证明U程化方案的可行性?对于许多想研I渲染线E化的h来说Q是一值得参考的文章。文中提Z(jin)许多在不同情况下U程化时遇到的问题,以及(qing)需要注意的问题。值得一? <br> <br>  <a href='http://www.shnenglu.com/Leaf/archive/2010/12/20/137076.html'>阅读全文</a><img src ="http://www.shnenglu.com/Leaf/aggbug/137076.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Leaf/" target="_blank">Render Donkey</a> 2010-12-20 23:14 <a href="http://www.shnenglu.com/Leaf/archive/2010/12/20/137076.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用控制台写图形程序-Q贪食蛇http://www.shnenglu.com/Leaf/archive/2010/08/20/124043.htmlRender DonkeyRender DonkeyThu, 19 Aug 2010 17:02:00 GMThttp://www.shnenglu.com/Leaf/archive/2010/08/20/124043.htmlhttp://www.shnenglu.com/Leaf/comments/124043.htmlhttp://www.shnenglu.com/Leaf/archive/2010/08/20/124043.html#Feedback7http://www.shnenglu.com/Leaf/comments/commentRss/124043.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/124043.html新版源码下蝲地址. 点击q里 (SnakeGame 0.0.1 ) 链接已修正,h?j)用?
--------------------------------------------------------------------------------------------------------------------------------
先前的版本会(x)闪屏,于是新徏?jin)一个缓冲来解决,q将Ҏ(gu)制台?囑Ş"操作抽象?jin)出?使我们用的时候就像在使用普通的囑Ş讑֤一?br>
        1 讄清屏?br>        2 指定像素位置,讄要绘制的内容
        3 提交~冲区内?

新版源码已完成了(jin)游戏的基本功?br>   输入控制
   食物(g)?br>   障碍(g)?br>另外,q收录了(jin)部分用于方便讄控制台属性的函数.如窗口图?H口句柄{?
Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q?br>Windows下的控制台是可以讄前景Q背景色的。这l了(jin)我一个很不错的想法,用他写图形?br>
说好开工,用了(jin)一个小时写?jin)一个贪食蛇?br>
完成功能Q?br>有一个简单的l制框架?br>一个简单的UI?br>除了(jin)食物没有处理外,其余都OK?br>
能自动更斎ͼ(g)碰撞等。。?br>二话不说Q有图有真相?br>
蛋疼的朋友可以试试,挺爽的。。。?/div>
PicturePicture Picture

下蝲地址Q?a >源码加执行程?/a>

Render Donkey 2010-08-20 01:02 发表评论
]]>
[原]译:(x)一个游戏引擎所应具有的元素http://www.shnenglu.com/Leaf/archive/2010/04/26/113660.htmlRender DonkeyRender DonkeyMon, 26 Apr 2010 15:34:00 GMThttp://www.shnenglu.com/Leaf/archive/2010/04/26/113660.htmlhttp://www.shnenglu.com/Leaf/comments/113660.htmlhttp://www.shnenglu.com/Leaf/archive/2010/04/26/113660.html#Feedback11http://www.shnenglu.com/Leaf/comments/commentRss/113660.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/113660.html阅读全文

Render Donkey 2010-04-26 23:34 发表评论
]]>
[原]irrlicht v1.6 中文例程18 Splitscreenhttp://www.shnenglu.com/Leaf/archive/2010/04/26/113563.htmlRender DonkeyRender DonkeyMon, 26 Apr 2010 01:50:00 GMThttp://www.shnenglu.com/Leaf/archive/2010/04/26/113563.htmlhttp://www.shnenglu.com/Leaf/comments/113563.htmlhttp://www.shnenglu.com/Leaf/archive/2010/04/26/113563.html#Feedback0http://www.shnenglu.com/Leaf/comments/commentRss/113563.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/113563.html我们创Z个被分ؓ(f)4个部分的视口Q有3个固定摄相机和一个用户可以控制的摄相机好Q让们从头文件开始吧Q我x(chng)有再多说的必要了(jin)Q?nbsp; 阅读全文

Render Donkey 2010-04-26 09:50 发表评论
]]>
游戏开发历E之材质pȝhttp://www.shnenglu.com/Leaf/archive/2010/04/24/113443.htmlRender DonkeyRender DonkeySat, 24 Apr 2010 08:13:00 GMThttp://www.shnenglu.com/Leaf/archive/2010/04/24/113443.htmlhttp://www.shnenglu.com/Leaf/comments/113443.htmlhttp://www.shnenglu.com/Leaf/archive/2010/04/24/113443.html#Feedback2http://www.shnenglu.com/Leaf/comments/commentRss/113443.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/113443.html材质Q这个词有各行各业都有自q解释?/p>

工把物体脓(chung)囑֒物体颜色Q高光等l称为材质。D3D和OPENGLq样的图形接口则把物体表面脓(chung)囑֍独叫做纹理,而把漫反,高光{叫做材质?/p>

 

而在游戏引擎或图形引擎中提到的材质,则与此不同?引擎中提到的材质不仅上面的的内容?引擎中所谓的材质Q是指物体在渲染时一pd的状态控制?如,ALPHA混合开关以?qing)ALPHA混合因子、纹理过虑方式,U理通道状态、纹理矩c(din)裁剪模式等Q在D3D中,是SetRenderState,SetTextureStageState,SetSamplerStateState{所控制的。在OPENGL中,则大多数由glEnable所控制?/p>

 

我们所提到的材质系l,则是以此为基展开的?上面提到的这些因子,l成?jin)我们的材质?也是我们在渲染一个物体的时候,提交到设备的状态控制倹{?一个物体的一ơ渲染,我们UC一个PASS。于是我们顺其自然地这个渲染时的材质控制的最单位命名ؓ(f)Pass,则:(x)

 

struct TextureState

{

    void* Texture;

    int ColorOp;

    int ColorAgr1;

    int ColorAgr2;

    int AlphaOp;

    int AlphaAgr1;

    int AlphaAgr2;

.....//更多内容

};

 

class CPass

{

   CColor mAmbient;

   CColor mDiffuse;

   ....更多内容

 

    bool mAlphaEnable;

    int mScrBlend;

    int mDstBlend;

    int mCullMode;

   TextureState[4] mTextureStates;

  ...更多内容

};

 

当我们渲染一个物体的时候,只需要将q个c里面的状态应用到讑֤Q即可完成对物体的绘制?/p>

 

材质pȝ的基本内容就是这些,q也是最Ҏ(gu)做到的事情?/p>

但是Q我们都知道Q像D3D或OPENGLq样的图形接口每讄一ơGPU状态的时候,都会(x)有一定的开销Q通过查看相关文档可以看到某些函数的具体开销|(j)。而ؓ(f)?jin)保证我们的渲染畅Q我们不得不减少q样的开销?/p>

 

很自然地Q我们会(x)惛_Q尽量减切换。而如何减切换呢。我们可以记录下自己的硬件状态,在设|下一个的时候,先判断当前硬件状态是否相同,如果相同。则不用再设|?虽然某些囑Ş接口在其层底做了(jin)cM的功能。但我们外部判断一下,也未不可。从D3D上来Ԍ外部判断比让其内部判断效率更佟뀂需要注意的是,׃我们在自qE序里做?jin)相同判断。因此,当有另一个程序也修改讑֤状态的时候,׃(x)产生意想不到的效果。所以,我们应该适当的查询一下设备状态,q更新自q状态记录表。至于这个查询间隔,pҎ(gu)自己的实际情冉|试?jin)?/p>

 

 

通过记录状态的Ҏ(gu)来提升的效率是很不明昄Q因此,我们需要对材质q行排序Q至于怎么排序Q这法上的问题Q在此先不作q多解释?MQ我们将怼的材质排在一赗由于材质很怼Q绘完一个再l(sh)一个的时候,减少?jin)切换,从而大大提升了(jin)效率?/p>

 

既然已经是涉?qing)到讑֤了(jin),我们d考虑一下设备问题?如果讑֤不支持我们当前给定的材质状态,怎么办? q回FALSE不渲染。还是让E序DOWN掉?  对于一些重要的性能Q设备不支持让程序DOWN掉是最好的做法Q但是,对于像纹理؜合通道不的情况,让其DOWN掉就昑־划不来了(jin)。毕竟我们设计的游戏E序是想让更多的玩家能玩不是Q?q样׃(x)涉及(qing)到PASS的拆分问题?/p>

 

对于PASS的拆分,OGRE已经做得很好?jin)。根据用L(fng)讑֤性能Q如果不满Q就一直拆分,拆到用户满为止Q最后让一个物体渲染多ơ,来实现多个纹理通道混合的效果?而多PASS则是在渲染的时候不得不考虑的地方,毕竟有些物殊效果非得用多PASS不可?/p>

 

对于多PASS的设计,我们可以参考OGRE的材质方法或是D3DX的效果框架。我们把完成一个最l效果的Ҏ(gu)UC一个渲染技?Technique Q一个技术可由多个Pass来完成?/p>

 

class Technique

{

...更多内容

 vector<CPass*> mPasses;

};

 

q样满了(jin)我们的需求?nbsp; 对于同一U效果,我们可以提供多种Technique供程序选择?而这个选择的条件则可以是根据硬件性能Q或是玩家手动选择的配|来实现?/p>

最后结构如下:(x)

class CMaterial

{

public:

...更多内容

vector<CTechnique*> mRenderTechs

};

 

 

 

׃八糟地说?jin)一通,希望没晕MhQ!Q?/p>

Render Donkey 2010-04-24 16:13 发表评论
]]>
监听器在游戏开发中的应?---消息回调http://www.shnenglu.com/Leaf/archive/2010/04/24/113430.htmlRender DonkeyRender DonkeySat, 24 Apr 2010 06:39:00 GMThttp://www.shnenglu.com/Leaf/archive/2010/04/24/113430.htmlhttp://www.shnenglu.com/Leaf/comments/113430.htmlhttp://www.shnenglu.com/Leaf/archive/2010/04/24/113430.html#Feedback5http://www.shnenglu.com/Leaf/comments/commentRss/113430.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/113430.html我一向是不太喜欢l一些东西强加上个名字。但Z(jin)随L逐流Q我q是q样做了(jin)?/p>

 

在我们的游戏开发中Q通常?x)遇C个模块之间的通信?回调估计是最常用的方式了(jin)?回调的设计思想很简单,是两个对象怺注册Q然后在需要的时候调用对方的函数?/p>

如下Q?/p>

 

 

q样Q当A执行自己的某些动作的时候,p用B的函敎ͼq样B׃(x)q行自己的更新或是一些处理?/p>

 

但是Q由于两个对象的直接回调Q导致了(jin)许多不方便之处。特别是当A和B的功能需要扩展的时候。例如:(x)现在A在执行过E中Q需要调用B中其它的功能函数。这时候就不得不修改A和B的接口。然后大安重新~译Q连接,执行?/p>

 

于是Q我们就?x)想会(x)不会(x)有一U更好的Ҏ(gu)来解册一问题?大家可以x(chng)QW(xu)INDOWS中的通信机制Q通过解析消息cd来进行处理。是的,消息回调的好处就是方便扩展?当然我们q里要讲的不是像WINDOWS中那L(fng)消息通信机制Q对于我们来_(d)那种做法q繁琐?/p>

假设现在是想让A通知B一些事情。那么,我们可以把B的void DoB();函数作一点点修改Q?/p>

 

同理Q当B要通知A的时候,也这样做p?jin)?/p>

 

但是Q这样也很麻?ch),关键在于Q如果现在写cA的hq不知道cB的h?x)怎么写,或者说Q类B不知道什么时候要写。另外,如果我们强制cB要实现这L(fng)接口Q会(x)有点不现实?

 

此时Q我们决定用一个中间对象来q接他们?/p>

 


q就是我们传说中的监听器?jin)?在OGRE或是一些广泛采用面向对象思想的源E序中,随处可见q样的模式?/p>

 

q是假设是A需要通知B一些事情。那么,可以在A中注册这个对象,然后调用它的Ҏ(gu)可以了(jin)?/p>

 

而我们在实现B的时候,除了(jin)要实现B自己的东西以外,q需要将ICallBackzq实?void Do(int Msg)函数Q?/p>

 

q样Q双方便很自然地通了(jin)信。而写cA的hҎ(gu)不需要理?x)类B的h?x)怎么写,也不用去类B?x)是什么样的类名。只要告诉写cB的hQ你需要实现这个Callback接口Qƈ且对应的MsgID是干什么用的就O(jin)K?jin)?/p>

 

也许初初的一看,q是吃力不讨好的工作。毕竟一个写A的hQ会(x)L那么多事情?而一个写B的hQ还要去实现一个CallbackcR但是,从可扩展性,和降低耦合上来Ԍ的确?x)v不少的作用?

 

而上面的void Do(int MsgID);函数Q可以做得更强大一炏V?/p>

写成void Do(void* pData); 而这个pData怎么使用Q就要看A和B通信的具体内容了(jin)?

 

 

 

我正力地试着把自己想要说的讲清楚Q谢谢!

 



Render Donkey 2010-04-24 14:39 发表评论
]]>
改进后的 3D贪食?/title><link>http://www.shnenglu.com/Leaf/archive/2009/06/04/86732.html</link><dc:creator>Render Donkey</dc:creator><author>Render Donkey</author><pubDate>Thu, 04 Jun 2009 03:46:00 GMT</pubDate><guid>http://www.shnenglu.com/Leaf/archive/2009/06/04/86732.html</guid><wfw:comment>http://www.shnenglu.com/Leaf/comments/86732.html</wfw:comment><comments>http://www.shnenglu.com/Leaf/archive/2009/06/04/86732.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.shnenglu.com/Leaf/comments/commentRss/86732.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Leaf/services/trackbacks/86732.html</trackback:ping><description><![CDATA[一开始老是觉得哪里不对Ԍ后来发现是自q光照没有讄好?br>如图的效果就好多?jin)。哈?br><br>q是没有看到哪里加附Ӟ于是我把两个游戏的代码和执行文件发?#8220;文g”里面?jin),可以去那里下?br>有什么新x(chng)的,大家可以交流。特别是q个贪食蛇的场景?br><img border=0 alt="" src="http://www.shnenglu.com/images/cppblog_com/leaf/3DSnake.jpg" width=1024 height=768> <img src ="http://www.shnenglu.com/Leaf/aggbug/86732.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Leaf/" target="_blank">Render Donkey</a> 2009-06-04 11:46 <a href="http://www.shnenglu.com/Leaf/archive/2009/06/04/86732.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自己做的游戏:(x)墙中公主http://www.shnenglu.com/Leaf/archive/2009/06/01/86340.htmlRender DonkeyRender DonkeySun, 31 May 2009 18:21:00 GMThttp://www.shnenglu.com/Leaf/archive/2009/06/01/86340.htmlhttp://www.shnenglu.com/Leaf/comments/86340.htmlhttp://www.shnenglu.com/Leaf/archive/2009/06/01/86340.html#Feedback9http://www.shnenglu.com/Leaf/comments/commentRss/86340.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/86340.html手机Q联惻I(j)上有一个游戏叫墙中公主Q就是移动光标,如果光标周围有三个以上颜色相同的方块。则可以消去?br>玩着玩着想自己写一个来试试。当然不是手机版。而是PC版的。游戏很单。代码就不粘?sh)来了(jin)。发张效果图。呵?br>



我想发上来呀。但是传到文仉?jin),不知道怎么插到q里来。?br>
游戏q有一Ҏ(gu)完。没有记分系l。还有就是游戏提C那里少?jin)?nbsp;  I格Q消除方?

Render Donkey 2009-06-01 02:21 发表评论
]]>
HGE中的游戏GUI代码阅读http://www.shnenglu.com/Leaf/archive/2009/05/18/83270.htmlRender DonkeyRender DonkeyMon, 18 May 2009 04:47:00 GMThttp://www.shnenglu.com/Leaf/archive/2009/05/18/83270.htmlhttp://www.shnenglu.com/Leaf/comments/83270.htmlhttp://www.shnenglu.com/Leaf/archive/2009/05/18/83270.html#Feedback0http://www.shnenglu.com/Leaf/comments/commentRss/83270.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/83270.html作?: Kevin Lynx
BLOG: http://blog.csdn.net/kevinlynx


W一部分Q?br>
HGE helpercM的GUIQ?br>
引擎版本Q?.60release?br>


文gQhgegui.h , hgegui.cpp, hgeguictrls.h , hgeguictrls.cpp

大致cdQ?br>


其中QhgeGUIObject是抽象基c,具体的控件类如按钮,文本标签Q都是从它派生而来。HgeGUI属于整个GUIpȝ的managerQ它?x)保存所有的控g?br>
关于hgeGUIObject?个成员变量,文档里已l有所描述Q?br>
int id; //控gID

bool bStatic; //是否可以接受键盘焦点

bool bVisible; //是否可见

bool bEnabled; //是否有效

hgeRect rect; //控g大小



hgeGUI *gui; //其属于的 manager Q相当于父对?br>
hgeGUIObject *next; //用于双向链表Q把所有控件连接在一?br>
hgeGUIObject *prev;

static HGE *hge; //方便使用HGE接口

关于光分接口的描述Q?br>
Render: 用于渲染控g到屏q上

Update: 用于更新其动?br>
Enter: 控g刚显C时的动?br>
Leave: 控g要消失时的动?br>
IsDone: 控g刚显C和消失时的状态查询函?br>


该类也就是提供了(jin)一个抽象而已Q利用C++语言的多态机制来方便hgeGUI理所有的控g。其他具体的控gl承?jin)hgeGUIObject后,必须实现构造函数和Render函数?br>


关于hgeGUIQ?br>
q个cd该属于manager。它负责理所有的控g?br>
其数据成员:(x)

hgeGUIObject *ctrls; //保存所有控?br>
hgeGUIObject *ctrlLock; //可能是用来保存当前被鼠标操作的控?br>
hgeGUIObject *ctrlFocus; //保存焦点控g

hgeGUIObject *ctrlOver; //用来保存鼠标指针所指的控g



int navmode;

int nEnterLeave;

hgeSprite *sprCursor; //渲染鼠标指针用的



float mx,my; //鼠标坐标

int nWheel; //滚轮偏移?br>
bool bLPressed, bLLastPressed;//本左键状态,上一帧的左键状?br>
bool bRPressed, bRLastPressed;

其UpdateҎ(gu)?x)负责控件的q入和离开动画Q还?sh)(x)负责整体的状态设|?--哪些控g拥有焦点Q哪些控件被鼠标正在操作Q哪些控件正被鼠标指针指着Q这些控件它都会(x)保存h。(也就是说Q我们还是可以通过(g)查控件的状态来讄当鼠标指针在其上时的新动甅R)(j)



M而言Q该引擎的GUIq是很简单的。一个managerQ负责管理所有的控gQ然后一个抽象基c,用来协助manager理---其他具体的控仉必须从那个抽象基cL生?br>


下面具体看一个Button控gQ?br>
Buttoncȝ定义如下Q?br>
class hgeGUIButton : public hgeGUIObject

{

public:

hgeGUIButton(int id, float x, float y, float w, float h, HTEXTURE tex, float tx, float ty);

virtual ~hgeGUIButton();



void SetMode(bool _bTrigger) { bTrigger=_bTrigger; }

void SetState(bool _bPressed) { bPressed=_bPressed; }

bool GetState() const { return bPressed; }



virtual void Render();

virtual bool MouseLButton(bool bDown);



private:

bool bTrigger;

bool bPressed;

bool bOldState;

hgeSprite *sprUp, *sprDown;

};

其中bTrigger表示该按钮的行ؓ(f)是否象一个RadioButtonQbPressed表示当前按钮是否被按下,bOldState表示上一ơ按钮状态,特别用来实现bTrigger的,sprUp,sprDown分别用来l制弹v和按下时的按钮外观。这两个_的创建都是从构造函数的tex上创来的,它要求两个状态必M存在一q纹理上Q且序Z左至叟?br>
按钮的实C码也很简单:(x)

void hgeGUIButton::Render()

{

if(bPressed) sprDown->Render(rect.x1, rect.y1);

else sprUp->Render(rect.x1, rect.y1);

}



bool hgeGUIButton::MouseLButton(bool bDown)

{

if(bDown)

{

bOldState=bPressed; bPressed=true;

return false;

}

else

{

if(bTrigger) bPressed=!bOldState;

else bPressed=false;

return true;

}

}



联系hQ当hgeGUI::Update里处理ProcessCtrlӞ如果鼠标左键按下且其指针在按钮范围内Q那么就调用hgeGUIButton::MouseLButton( true )Q这个时候button的bPressed=true,那么在渲染的时候,自然p现出被按下时的状态?br>
事实上对于这U类型的按钮---如同windows下的H体按钮Q我们一般不(g)查其是否被按下,而是(g)查其是否发生?jin)clicked q个事gQ而这个事件是在先按下在弹L(fng)情况下发生的。因此,判断该事件发生的条g׃ؓ(f)Q上一帧状态被按下Q这一帧没被按下?br>


虽然HGE引擎的GUI很简单,但是其扩展性很好。因为hgeGUI::Update基本上派发了(jin)所有控仉要的消息---键盘操作Q以?qing)鼠标操作;而hgeGUIObject基类的很多成员函数都?x)处理这些消息,我们只需要派生hgeGUIObjectQ然后重载我们需要的消息处理卛_?br>
W二部分Q?br>
HGE扩展GUI库,从HGE官方论坛下蝲Q作者不明)(j)Q?br>
工程l构Q?br>


其中Qguitest.cpp为测试文件?br>


cȝ构:(x)



整个pȝ的工作原理:(x)

用户l承抽象基类GUIAppQ实现具体的OnEvent函数Q然后该cM(x)理所有的GUIAppWindow对象QGUIAppWindowH口对象?x)管理其上的所有子控g?br>


相应圎ͼGUIAppzcM(x)直接得到鼠标和键盘消息,然后z֏l所有窗口对象,然后H口对象再把消息z֏到具体的控g对象上?br>


q种Parent-Child关系大致为:(x)


GUIAppWindowcM存有其所属的GUIApp对象指针Q每个具体的控g又保存有其所属的GUIAppWindow 的对象指针?br>


当一个控件处理了(jin)某个事g后,例如按钮处理?jin)鼠标单MӞ它就需要告诉外界用户单M(jin)q个按钮。这里采用的Ҏ(gu)是:(x)在基cGUIAppObject里定义了(jin)一个虚函数OnEvent( int id)

Q然后在其派生类GUIAppWindow里把q个函数重蝲为纯虚函敎ͼ函数有一个参敎ͼ那就是控件ID。当一个控件处理了(jin)某个事g后,通过其内部保存的父窗口指针来调用OnEvent函数Q然后GUIAppWindow的派生类---如果该类能生对象,那么其必然实C(jin)OnEvent的具体代码(q就是ؓ(f)什么在GUIAppWindow里要把OnEvent又重载ؓ(f)U虚函数的原因)(j)Q然后在此代码里Q窗口根据传q来的控件ID来得知哪个控件发生了(jin)事gQ?br>


GUIAppWindow里有一个容器,它保存(sh)(jin)所有该H口上的控g?br>


所有控件再创徏Ӟ都是以其父窗口ؓ(f)参考坐标系的,也就是相对坐标,但是其实际保存的坐标却是l对坐标—既相对于整个屏q的坐标Q如果是H口E序Q就相对于整个窗口)(j)。大致过Eؓ(f)Q在GUIAppWindowzcM创徏子控件时Q给子控件指定的坐标为相对坐标,然后?AddCtrl 时就?x)重新把子控件的坐标改变(sh)绝对坐标?br>


GUIApp里直接有?jin)BeginScene和EndScene的渲染代码?br>


要用该扩展库,大致步骤为:(x)

1Q?l承GUIAppWindowc,在这个派生类里重载具体的处理OnEvent的函敎ͼq创建所有该H口上的子控件?br>
2Q?l承GUIAppc,在这个派生类中创建窗口对象,q把H口对象AddCtrlQ在q里可以q行其他的初始化工作

3Q?在FrameFunc里调用GUIApp::FrameFunc函数?br>


M而言Q这个扩展GUI主要是扩展了(jin)GUI Manager以及(qing)GUI ObjectQƈ且加入了(jin)Parent-Child机制。比较经典的部分在于提供?jin)一?OnEvent 函数Q这样就可以让客L(fng)序员能够得知H体上的控g发生的事件?----其实q种Ҏ(gu)的目的就跟Windows中的消息机制QQt中的signal/slot机制一栗?br>

Render Donkey 2009-05-18 12:47 发表评论
]]>
QOGREQOverlay中文昄 http://www.shnenglu.com/Leaf/archive/2009/05/17/83234.htmlRender DonkeyRender DonkeySun, 17 May 2009 15:59:00 GMThttp://www.shnenglu.com/Leaf/archive/2009/05/17/83234.htmlhttp://www.shnenglu.com/Leaf/comments/83234.htmlhttp://www.shnenglu.com/Leaf/archive/2009/05/17/83234.html#Feedback0http://www.shnenglu.com/Leaf/comments/commentRss/83234.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/83234.html

q日很多朋友咨询Overlay中文昄问题Q回{的多了(jin)想烦(ch)性再写个文档了(jin)Q放在网上共享,于是有?jin)本?/span>

       ?span>Ogre1.2.5版本中,通过?span>Ogre官方论坛的开发者讨论实C(jin)Overlay的中文显C,当初的实现非常的怪异Q具体的实现可以参见Ogre官方论坛?/span>

随着Ogre的更斎ͼ现在Ogre已经发布?span>1.4.7Q?span>1.4pd版本有一个重要的改进Q就是加入了(jin)UTFStringQ这?span>Ogre中文昄予以很大的帮助。ؓ(f)?jin)便于演C,我直接?span>Ogre自带?span>OverlayQ也是大家熟?zhn)?span>DebugOverlayQ测试工E我选择Demo_ParticleFXQ选择其他的也没有关系。现在编译它Q运行后得到下图Q?/span>


囄最左下角显C的是英文DebugOverlayQ接下来我们的Q务就是把它编E中文的Q?span>^_^
?/span>

Overlay中文化操作步骤如?/span>

1.      打开OgreSDK\media\packs\ OgreCore.zip?/span>

2.      打开C:\WINDOWS\FontsQ把simhei.ttfd?span>OgreCore.zipQ(什么,没有simhei.ttfq个文gQ那p其他的中?span>ttf字体吧)(j)?/span>

3.      打开OgreCore.zip中的Ogre.fontdefQ里面有BlueHighwayq个字体定义块,在他的下面添加我们的SimHeiQ?span>code_points里面的一大堆数字看不明白没关p,随后文章?x)解释?/span>

SimHei

{

       type             truetype

       source         simhei.ttf

       size              16

       resolution  96

       code_points 33-166 24403-24403 21069-21069 24103-24103 36895-36895 29575-29575 24179-24179 22343-22343 26368-26368 39640-39640 20302-20302 19977-19977 35282-35282 24418-24418 25968-25968 37327-37327 25209-25209 27425-27425

}

4.      打开OgreCore.zip中的OgreDebugPanel.overlayQ把BlueHighway全部替换?span>SimHeiQ我们要使用中文字体?jin),嘿嘿?/span>

5.      修改完成后,保所做的修改已经保存?span>OgreCore.zip?/span>

6.      q入Ogre解决Ҏ(gu)Q打开文gExampleFrameListener.hQ把54-59行的代码替换如下Q?/span>

              static String currFps = "Current FPS: ";

              static String avgFps = "Average FPS: ";

              static String bestFps = "Best FPS: ";

              static String worstFps = "Worst FPS: ";

              static String tris = "Triangle Count: ";

       static String batches = "Batch Count: ";

 

              static DisplayString currFps = L"当前帧速率: ";

              static DisplayString avgFps = L"q_帧速率: ";

              static DisplayString bestFps = L"最高速率: ";

              static DisplayString worstFps = L"最低速率: ";

              static DisplayString tris = L"三角形数?span>: ";

              static DisplayString batches = L"Ҏ(gu): ";

7.      最后重新编译工E,下面是我q行的截图,是不是已l显CZ文了(jin)Q?span>^_^?/span>


现在再来看看SimHei中的code_points是如何生成的Q这个可以参考我上次写的q篇文章http://www.cnblogs.com/gogoplayer/archive/2008/05/09/1189795.htmlQ至此,实现Overlay中文昄?/span>

转蝲h明出处:(x)

作者:(x)gogoplayer

E-mail : gogoplayer@163.com

QQ : 78939328

http://www.gogoplayer.com.cn

Render Donkey 2009-05-17 23:59 发表评论
]]>
OGRE主要渲染程?/title><link>http://www.shnenglu.com/Leaf/archive/2009/05/17/83233.html</link><dc:creator>Render Donkey</dc:creator><author>Render Donkey</author><pubDate>Sun, 17 May 2009 15:56:00 GMT</pubDate><guid>http://www.shnenglu.com/Leaf/archive/2009/05/17/83233.html</guid><wfw:comment>http://www.shnenglu.com/Leaf/comments/83233.html</wfw:comment><comments>http://www.shnenglu.com/Leaf/archive/2009/05/17/83233.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/Leaf/comments/commentRss/83233.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Leaf/services/trackbacks/83233.html</trackback:ping><description><![CDATA[<div id="bvhfr3z" class=postbody><font size=5>OGRE主要渲染程?/font> <p>                                    谢伟?nbsp;      feiyurainy@163.com</p> <p>                               转蝲h明出?/p> <p>    很早以前想写一些关?span>OGRE</span><span>的文章了(jin)Q一直没Z(x)?/span> </p> <p><span>    理解一个渲染引擎,我觉得最重要的是先抓住了(jin)它的L构,它的ȝQ渲染流E,不然的话Q一个引擎几万行Q甚臛_十万行的代码Q光是打开</span><span>solution</span><span>p吓你一跳了(jin)Q?/span><span>OGRE</span><span>也有十几万行的代码量Q我一开始看它的时候也是无从下手,感觉代码太多?jin),不知道从哪开始看好,q个</span><span>class</span><span>看看Q那?/span><span>class</span><span>看看Q由于对整个引擎没有一个清晰的认识Q看q了(jin)也印象不深,所以,最后,q是军_先找出它的主U,?jin)解它的渲染程Q这h能有机地把各个部分联pv来?/span></p> <p><span>    q篇短文也是?/span><span>OGRE</span><span>的主要渲染流E的一个介l,可能对一?/span><span>class</span><span>不会(x)太多地去介绍具体的实现细节。我所用的代码都是取自?/span><span>OGRE</span><span>的最新的</span><span>CVS</span><span>版本?/span></p> <p><span>    读者最好对</span><span>OGRE</span><span>有一定的?jin)解Q至得看懂它的</span><span>example</span><span>Q不然可能一些东西理解v来比较困难。对</span><span>D3D</span><span>Q?/span><span>OPENGL</span><span>有一定了(jin)解更好?/span></p> <p><span>    如果你看q?/span><span>D3D SDK</span><span>中带的例子,你一定知道一个比较简单的</span><span>3D</span><span>E序要运行v来,臛_都会(x)涉及(qing)以下的几部分Q?/span></p> <p><span>    首先是数据的来源Q包括顶Ҏ(gu)据,U理数据{,q些数据可以从文件中dQ也可以在程序运行时生成?/span></p> <p><span>    接下来,我们?x)徏立顶点缓冲区把顶点保存v来,建立</span><span>texture</span><span>对象来表C?/span><span>texture</span><span>Q对点l成的物体设|它在世界坐标系下的坐标Q设|摄像机的位|,视点Q设|?/span><span>viewport</span><span>的位|和大小Q然后就可以在渲染@环中开始调用渲染操作了(jin)Q经q了(jin)</span><span>front buffer</span><span>?/span><span>back buffer</span><span>的交换,我们p在屏q上看到</span><span>3D</span><span>囑Ş?jin),伪代码如下?x)</span></p> <p><span>      setupVertexBuffer</span></p> <p><span>      setWorldTransform</span></p> <p><span>      setCamera</span></p> <p><span>      setProjectionTransform</span></p> <p><span>      setViewport</span></p> <p>       <span>beginFrame</span></p> <p><span>      setTexture</span></p> <p><span>      drawObject</span></p> <p><span>      endFrame</span> </p> <p><span>     以下是渲染一个物体的主要步骤Q在我看来,q就?/span><span>3D</span><span>E序的主U,同样道理Q无Z多复杂的渲染引擎Q都得实Cq的q些步骤Q其他的一些效果如阴媄(jing)Q光照等Q都是附着在这条主U上的,所以,如果你能在你所研究的渲染引擎上也清晰地看到q条ȝQ可能对你深入地研究它会(x)大有帮助Q下面,我们׃h扑ֈ</span><span>OGRE</span><span>中的q条ȝ?/span></p> <p><span>     OGRE</span><span>的渲染@环都是v源于</span><span>Root::renderOneFrame</span><span>Q这个函数在</span><span>OGRE</span><span>自带?/span><span>example</span><span>中是不会(x)昑ּ调用的,因ؓ(f)</span><span>example</span><span>都调用了(jin)</span><span>Root::startRendering</span><span>Q由</span><span>startRendering</span><span>来调?/span><span>renderOneFrame</span><span>Q如果你?/span><span>OGRE</span><span>来写真正的游戏,或者编辑器Q你可能需要在的消息主循环中调?/span><span>renderOneFrame</span><span>?jin),֐思义Q这个函数就是对整个</span><span>OGRE</span><span>q行一帧的更新Q包括动画,渲染状态的改变Q渲?/span><span>api</span><span>的调用等Q在q个函数中,?x)包括?jin)我们上述伪代码的几乎全部内容Q所以是本文的重Ҏ(gu)在?/span></p> <p><span>     q入</span><span>renderOneFrame</span><span>Q可以看到头两?/span><span>fire</span><span>函数Q这U函数在</span><span>OGRE</span><span>中经常出玎ͼ一般都?/span><span>fire…start</span><span>?/span><span>fire…end</span><span>一起出现的Q在q些函数中,可能?x)处理一些用戯定义的操作,?/span><span>_fireFrameStarted</span><span>׃(x)Ҏ(gu)以的</span><span>frameListener</span><span>q行处理Q这?/span><span>fire</span><span>函数可以暂时不用理会(x)Q(h)l看</span><span>_updateAllRenderTargets</span><span>Q在q个函数中,?x)委zֽ前所用的</span><span>renderer</span><span>Ҏ(gu)有创建出来的</span><span>render target</span><span>q行</span><span>update</span><span>Q?/span><span>render target</span><span>也就是渲染的目的圎ͼ一般会(x)有两U,一U是</span><span>render texture</span><span>Q一U是</span><span>render buffer</span><span>Q接着q入</span><span>RenderSystem::_updateAllRenderTargets</span><span>Q可以看到在</span><span>render system</span><span>中,对创建出来的</span><span>render target</span><span>是用</span><span>RenderTargetPriorityMap</span><span>来保存的Q以便按照一定的序来对</span><span>render target</span><span>q行</span><span>update</span><span>Q因为在渲染物体?/span><span>render buffer</span><span>Ӟ一般会(x)用到之前渲染好的</span><span>render texture</span><span>Q所?/span><span>render texture</span><span>形式?/span><span>render target</span><span>需要在</span><span>render buffer</span><span>之前q行更新?/span></p> <p><span>     q入</span><span>render target</span><span>?/span><span>update</span><span>Q可以看刎ͼ它仍然把</span><span>update</span><span>操作l箋(hu)传递下去,调用所有挂在这?/span><span>render target</span><span>上的</span><span>viewport</span><span>?/span><span>update</span><span>?/span></p> <p><span>     Viewport</span><span>其实是定义?/span><span>render target</span><span>上的一块要q行更新的区域,所以一?/span><span>render target</span><span>是可以挂多个</span><span>viewport</span><span>的,以实现多人对战时分屏Q或者是Mȝ效果Q可以把</span><span>OGRE</span><span>中的</span><span>viewport</span><span>看成是保?/span><span>camera</span><span>?/span><span>rendertarget</span><span>q两者的l合Q把</span><span>viewport</span><span>中所定义?/span><span>camera</span><span>所看到的场景内Ҏ(gu)染到</span><span>viewport</span><span>所定义?/span><span>render target</span><span>的区域里?/span></p> <p><span>     Viewport</span><span>q有一个重要信息是</span><span>ZOrder</span><span>Q可以看?/span><span>RenderTarget</span><span>中的</span><span>ViewportList</span><span>带有一个比较函敎ͼ所以在</span><span>RenderTarget::update</span><span>中,</span><span>ZOrder</span><span>小的,先被渲染,所以,如果两个</span><span>viewport</span><span>所定义的区域互盔R叠了(jin)Q而且</span><span>ZOrder</span><span>又不一P最l的效果是</span><span>ZOrder</span><span>的</span><span>viewport</span><span>的内容会(x)?/span><span>ZOrder</span><span>大的</span><span>viewport</span><span>的内Ҏ(gu)覆盖?/span></p> <p><span>     l箋(hu)q入</span><span>Viewport::update</span><span>Q就像前面所_(d)它调用它所引用?/span><span>camera</span><span>来渲染整个场景,而在</span><span>Camera::_renderScene</span><span>中,是调?/span><span>SceneManager::_renderScene(Camera* camera, Viewport* vp, bool includeOverlays)</span><span>?/span><span>SceneManager::_renderScene</span><span>里就是具体的渲染程?jin)。从函数名称q有参数也可以看出来Q这个函数的作用是利用所指定?/span><span>camera</span><span>?/span><span>viewport</span><span>Q来把场景中的内Ҏ(gu)染到</span><span>viewport</span><span>所指定?/span><span>render target</span><span>的某块区域中。根?/span><span>camera</span><span>Q我们可以定?/span><span>view matrix</span><span>Q?/span><span>projection matrix</span><span>Q还可以q行视锥剔除Q只渲染看得见的物体。注意,我们q里只看标准?/span><span>SceneManager</span><span>的方法,不看</span><span>BspSceneManager</span><span>zcȝҎ(gu)Q而且Q我们会(x)抛开跟主U无关的内容Q如?/span><span>shadow</span><span>?/span><span>setup</span><span>Q骨骼动ȝ播放Q?/span><span>shader</span><span>参数的传递等Q因为我们只注重渲染的主程?/span></p> <p><span>     ?/span><span>SceneManager::_renderScene</span><span>中所应看的第一个重要函数是</span><span>_updateSceneGraph</span><span>Q?/span><span>OGRE</span><span>对场景的l织是通过节点?wi)来l织的,一个节点,你可以看成是I间中的某些变换的组合,如位|,~放Q旋转等Q这些变换,?x)作用到挂接在这些节点上的具体的物体的信息,也就是说Q节点保存(sh)(jin)</span><span>world transform</span><span>Q对具体的物体,如一个hQ在I间中的定位Q都是通过操作节点来完成的。同时节点还?sh)存(sh)(jin)一个世界坐标的</span><span>AABB</span><span>Q这?/span><span>AABB</span><span>能容Ux(chng)有它所挂接的物体的大小Q主要是用于视锥裁减的,如果当前摄像机看不见某个节点?/span><span>AABB</span><span>Q那么说明摄像机看不见节Ҏ(gu)挂接的所有物体,所以在渲染时可以对q个节点视而不见?/span></p> <p><span>     _updateSceneGraph</span><span>的内部处理比较繁琐,我们只需知道Q经q了(jin)</span><span>_updateSceneGraph</span><span>Q场景节Ҏ(gu)(wi)中的每个节点都经q了(jin)更新Q包括位|,~放Q和方位Q还有节点的包围盒?/span></p> <p><span>     l箋(hu)回到</span><span>SceneManager::_renderScene</span><span>Q接下来要看的是</span><span>setViewport</span><span>Q它?x)调用具体?/span><span>renderer</span><span>?/span><span>setviewport</span><span>的操作,讄</span><span>viewport</span><span>中所挂接?/span><span>render target</span><span>为当前所要渲染的目标Q?/span><span>viewport</span><span>中的区域为当前所要渲染的目标中的区域?/span></p> <p><span>     接下来要到</span><span>OGRE</span><span>渲染程中的一个重要的概念Q?/span><span>Render Queue</span><span>。这个东西实在内Ҏ(gu)较多Q还是以后有Z(x)单独提出来说吧,你可以简单把它想成是一个容器,里面的元素就?/span><span>renderable</span><span>Q每?/span><span>renderable</span><span>可以看成是每ơ调?/span><span>drawprimitive</span><span>函数所渲染的物体,可以是一个模型,也可以是模型的一部分。在</span><span>RenderQueue</span><span>中,它会(x)按材质来分组q些</span><span>renderable</span><span>Q还?sh)(x)?/span><span>renderable</span><span>q行排序?/span></p> <p><span>     在每一ơ调?/span><span>SceneManager::_renderScene</span><span>Ӟ都会(x)调用</span><span>SceneManager::prepareRenderQueue</span><span>来清?/span><span>RenderQueue</span><span>Q然后再调用</span><span>SceneManager::__findVisibleObjects</span><span>来把当前摄像机所能看见的物体都加入到</span><span>RenderQueue</span><span>中?/span></p> <p><span>     SceneManager::__findVisibleObjects</span><span>是一个递归的处理过E,它从场景的根节点开始,先检查摄像机是否能看见这个节点的包围盒(包围盒在</span><span>_updateSceneGraph</span><span>时已l计好?jin)?j)Q如果看不见Q那么这个节点,q有它的子节炚w不用了(jin)。如果能看见Q再(g)挂在这个节点上的所?/span><span>MovableObject</span><span>Q如果当前所(g)的</span><span>MovableObject</span><span>是可见的Q就?x)调用它?/span><span>_updateRenderQueue</span><span>Ҏ(gu)Q一般在q个Ҏ(gu)里就可以把和q个</span><span>MovableObject</span><span>相关?/span><span>renderable</span><span>送入</span><span>RenderQueue</span><span>?jin)?/span></p> <p><span>     q里要说?/span><span>MovableObject</span><span>Q?/span><span>MovableObject</span><span>主要是用于表C场景中L的物体,?/span><span>Entity</span><span>Q顾名思义Q能Ud的物体,不过它的“能移?#8221;q个能力是要通过</span><span>SceneNode</span><span>来实现的Q所?/span><span>MovableObject</span><span>来能昄出来Q首先得先挂接在某个场景节点上,通过场景节点来定位。你可以控制</span><span>MovableObject</span><span>的一些属性,如某?/span><span>MovableObject</span><span>是否要显C,是否要隐藏,都可以通过</span><span>MovableObject::setVisible</span><span>Ҏ(gu)来实现?/span></p> <p><span>     (g)完该节点上?/span><span>MovableObject</span><span>之后Q就l箋(hu)调用所有子节点?/span><span>_findVisibleObjects</span><span>Ҏ(gu)Q一直递归下去。这Pp把场景中所有要渲染?/span><span>renderable</span><span>所加入?/span><span>RenderQueue</span><span>中了(jin)?/span></p> <p><span>     x(chng)Q我们就拥有?jin)要渲染的物体的信息了(jin),接下来就是对q些物体q行渲染?jin),你?x)发现?/span><span>D3D</span><span>?/span><span>OpenGL</span><span>的代码很cM的调用:(x)</span></p> <p><span><span>       </span>mDestRenderSystem->clearFrameBuffer</span></p> <p><span>      mDestRenderSystem->_beginFrame<span>    </span></span></p> <p><span><span>       </span>mDestRenderSystem->_setProjectionMatrix</span></p> <p><span><span>       </span>mDestRenderSystem->_setViewMatrix </span></p> <p><span><span>       </span>_renderVisibleObjects();</span></p> <p><span>      mDestRenderSystem->_endFrame();</span></p> <p><span>     q些</span><span>api</span><span>的作用和</span><span>D3D</span><span>中的cM调用的作用都差不多,q里再说一?/span><span>_renderVisibleObjects()</span><span>Q在q个函数中,?x)?/span><span>RenderQueue</span><span>中的每个</span><span>renderable</span><span>q行渲染Q用的是</span><span>visitor</span><span>模式来遍历操作每?/span><span>renderable</span><span>Q最l在</span><span>SceneManager::renderSingleObject</span><span>中取出每?/span><span>renderable</span><span>所保存的顶点,索引Q世界矩늭信息Q来q行渲染。这其中q包括了(jin)查找该</span><span>renderable</span><span>最q的光源{操作,比较复杂?/span></p> <p><span>     到这里,</span><span>SceneManager::_renderScene</span><span>的流E基本走完了(jin)Q也是_(d)</span><span>OGRE</span><span>一帧中的渲染流E差不多也结束了(jin)Q你应该也发玎ͼq个程跟你?/span><span>D3D</span><span>写一个简单程序的程基本是一L(fng)Q在q个程的基上,再去看具体的实现Q如怎么栯|纹理,怎么栯用你熟?zhn)?/span><span>D3D</span><span>?/span><span>OpenGL</span><span>?/span><span>API</span><span>来渲染物体,应该?x)简单得多?/span></p> <p><span>     ?/span><span>OGRE</span><span>的渲染流E的大概介绍到这里也l束?jin),很多l节都没涉及(qing)Q以后有Z(x)再写吧?/span></p> </div> <script type=text/javascript> //<![cdata[ Sys.WebForms.PageRequestManager._initialize('AjaxHolder$scriptmanager1', document.getElementById('Form1')); Sys.WebForms.PageRequestManager.getInstance()._updateControls(['tAjaxHolder$UpdatePanel1'], [], [], 90); //]]> </script> <img src ="http://www.shnenglu.com/Leaf/aggbug/83233.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Leaf/" target="_blank">Render Donkey</a> 2009-05-17 23:56 <a href="http://www.shnenglu.com/Leaf/archive/2009/05/17/83233.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>游戏中的资源理――资源高速缓?/title><link>http://www.shnenglu.com/Leaf/archive/2009/05/17/83230.html</link><dc:creator>Render Donkey</dc:creator><author>Render Donkey</author><pubDate>Sun, 17 May 2009 15:48:00 GMT</pubDate><guid>http://www.shnenglu.com/Leaf/archive/2009/05/17/83230.html</guid><wfw:comment>http://www.shnenglu.com/Leaf/comments/83230.html</wfw:comment><comments>http://www.shnenglu.com/Leaf/archive/2009/05/17/83230.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Leaf/comments/commentRss/83230.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Leaf/services/trackbacks/83230.html</trackback:ping><description><![CDATA[<div id="9dfzhxr" class=postbody> <p>《游戏中的资源管理――资源高速缓存?br>转蝲h明出处:(x)<a rel=nofollow target=_blank><u><font color=#800080>http://groups.google.com/group/jianguhan</font></u></a> <br><br><br>1.什么是资源高速缓?<br>    资源高速缓存的原理与其它内存高速缓存的工作原理是相似的。在游戏的状态{换过E中Q有些数据是刚才使用q的Q那么直接从资源高速缓存(sh)载入卛_。例如,RPG­游戏中主角从大地图进入一个房_(d)探烦(ch)一番后主角退出房_(d)此时只要直接从缓存(sh)载入大地图数据即可,节省?jin)从盘载入数据的时_(d)要知道从盘载入数据是非?shy;慢的。当?dng)如果你的游戏所使用的数据文件很,那么你可以在游戏q行q程中把q些数据完全储存在内存(sh)Q而不使用资源高速缓存?</p> <p><br>2.一个简单的资源高速缓存管理器 <br>    下面我将向你展示一个比较简单的资源高速缓存管理器Q源代码来自我上一个游戏,如果你需要知道更多关于资源高速缓存方面的知识Q请参?lt;<Game Coding Complete>>的第八章?<br>首先Q需要一个机制来唯一标识一个资源,我们用下面这个结构来做资源句柄:(x) <br>struct ResHandle <br>{ <br>     ResHandle(std::string &resName, void *buffer, int size) <br>     { <br>         m_resName = resName; <br>         m_size   = size; <br>         m_buffer = buffer; <br>     } </p> <p><br>     ~ResHandle() <br>     { <br>         if (m_buffer != 0) delete[] m_buffer; <br>     } </p> <p><br>     std::string   m_resName;    //资源?<br>     void          *m_buffer;    //资源句柄所标识的资?<br>     DWORD         m_size;       //资源所占内存大?</p> <p><br>}; </p> <p><br>好了(jin)Q现在我们可以从资源名来扑ևq个资源?jin),接下来实现这个资源高速缓存管理器Q?<br>class CacheManager <br>{ <br>public: <br>     CacheManager(); <br>     ~CacheManager(); </p> <p>     //载入资源QresName源名Q若载入成功size被设资源的大?<br>    //注意Q管理中的资源不能在理器外用delete昄的删除它 <br>    void*    Load(std::string resName, DWORD *size = 0); <br>    //讄~存大小Q单位MB <br>     void      SetCacheSize(int sizeMB)    { m_cacheSize = sizeMB * 1024 * 1024; } <br>     //得到~存大小Q单位MB <br>     int      GetCacheSize()              { return m_cacheSize / 1024 /1024; } </p> <p><br>private: <br>     void     Free();                          //释放lru链表中最后一个资?<br>     void     *Update(ResHandle *res);         //更新l(f)ru链表 <br>     ResHandle *Find(std::string &resName);     //扑և该资源名的资源句?</p> <p><br>private: <br>     DWORD m_cacheSize;     //~存大小 <br>     DWORD m_allocated;     //已用的~存大小 </p> <p><br>//lru链表Q记录最q被使用q的资源 <br>     std::list<ResHandle*>                m_lru;   <br>    //资源标识映射 <br>     std::map<std::string, ResHandle*>    m_resources; </p> <p> </p> <p>}; </p> <p><br>CacheManager:: CacheManager () <br>{ <br>     m_cacheSize = 0; <br>     m_allocated = 0; </p> <p><br>} </p> <p><br>CacheManager::~ CacheManager () <br>{ <br>          while (!m_lru.empty()) Free();   //释放所有管理中的资?</p> <p><br>} </p> <p><br>void * CacheManager::Load(std::string resName, DWORD *size) <br>{ <br>     ResHandle *handle = Find(resName);   //查找该资源是否在~存?sh)?</p> <p>     if (handle != 0) //如果扑ֈ该资源句柄,则返回该资源q更新l(f)ru链表 <br>     { <br>         if (size != 0) *size = handle->m_size; <br>         return Update(handle); <br>     } <br>     else <br>     { <br>         //先检资源大?<br>         DWORD _size = 资源大小; </p> <p><br>         //是否有够空? <br>         while (_size > (m_cacheSize - m_allocated)) <br>         { <br>              if (m_lru.empty()) break; <br>              Free(); <br>         } <br>         m_allocated += _size; </p> <p><br>         buffer = new char[_size]; <br>//在这里用M你能惛_的办法蝲入资源文件到buffer <br>         … <br>         … </p> <p><br>//记录当前资源 <br>         ResHandle *handle = new ResHandle(resName, buffer, _size); <br>         m_lru.push_front(handle); <br>         m_resources[resName] = handle; </p> <p><br>         if (size != 0) *size = _size; <br>         return buffer; <br>     } </p> <p><br>     return 0; </p> <p> </p> <p>} </p> <p><br>void CacheManager::Free() <br>{ <br>     std::list<ResHandle*>::iterator gonner = m_lru.end(); <br>     gonner--; <br>     ResHandle *handle = *gonner; <br>     m_lru.pop_back(); <br>     m_resources.erase(handle->m_resName); <br>     m_allocated -= handle->m_size; <br>     delete handle; </p> <p><br>} </p> <p><br>void * CacheManager::Update(ResHandle *res) <br>{ <br>     m_lru.remove(res); <br>     m_lru.push_front(res); <br>     m_size = res->m_size; <br>     return res->m_buffer; </p> <p><br>} <br><br>ResHandle * CacheManager::Find(std::string &resName) <br>{ <br>     std::map<std::string, ResHandle*>::iterator it = m_resources.find(resName); <br>     if (it == m_resources.end()) return 0; <br>     return (*it).second; </p> <p><br>} <br><br>x(chng)Q你已经可以在游戏中~存?sh)M你想~存的资源了(jin)^_^ </p> <p>3. 资源理q阶 <br>    x(chng)你已l可以在游戏中缓存(sh)Q何你想缓存的资源?jin),但是你的dq没完成Q当你请求的资源存在于缓存(sh)外时Q那个闪耀的硬盘灯可能是玩家最感兴的东西?jin)?<br>因此你必L据不同的游戏cd使用不同的蝲入方式:(x) <br>    一ơ蝲入所有东西:(x)适用于Q何以界面或关卡切换的游戏 <br>    只在关键点蝲入资源:(x)很多击游戏都用这L(fng)设计Q如“半条?#8221; <br>    持箋(hu)载入Q适用于开攑֞地图的游戏,?#8220;侠盗猎R?#8221; <br>    如果有可能的话,你还可以使用~存预测机制Q当CPU有额外时间的时候可以把未来可能用到的资源蝲入到资源高速缓存?<br>    最后,管在游戏的资源理中资源打包不是必ȝQ但仍然大家把资源文件按cd分别打包到单一的文件中Q这ؓ(f)你节省磁盘空_(d)q加快游戏的载入速度?</p> </div> <script type=text/javascript> //<![cdata[ Sys.WebForms.PageRequestManager._initialize('AjaxHolder$scriptmanager1', document.getElementById('Form1')); Sys.WebForms.PageRequestManager.getInstance()._updateControls(['tAjaxHolder$UpdatePanel1'], [], [], 90); //]]> </script> <img src ="http://www.shnenglu.com/Leaf/aggbug/83230.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Leaf/" target="_blank">Render Donkey</a> 2009-05-17 23:48 <a href="http://www.shnenglu.com/Leaf/archive/2009/05/17/83230.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>游戏开发中常用的设计模?/title><link>http://www.shnenglu.com/Leaf/archive/2009/05/17/83227.html</link><dc:creator>Render Donkey</dc:creator><author>Render Donkey</author><pubDate>Sun, 17 May 2009 15:36:00 GMT</pubDate><guid>http://www.shnenglu.com/Leaf/archive/2009/05/17/83227.html</guid><wfw:comment>http://www.shnenglu.com/Leaf/comments/83227.html</wfw:comment><comments>http://www.shnenglu.com/Leaf/archive/2009/05/17/83227.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Leaf/comments/commentRss/83227.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Leaf/services/trackbacks/83227.html</trackback:ping><description><![CDATA[<div> <p><font size=3><span>?gu)http://blog.csdn.net/duzhi5368/archive/2008/04/22/2314232.aspx<br></span></font></p> <p><font size=3><span>使用设计模式来提高程序库的重复利用性是大型E序目开发必ȝ。但是在“四h?#8221;的设计模式概qC提到?/span><span><font face="Times New Roman">23</font></span><span>U标准设计模式,不但难以CQ而且有些设计模式更多的适用于应用程序开发,Ҏ(gu)戏项目引擎设计ƈ没有很多的利用h(hun)倹{根据经验,_挑(xi)l选后Q笃志在q里记录一些自认ؓ(f)有利用h(hun)值的设计模式Q以便之后自p计时使用?/span></font></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <h2><span>一Q观察?/span><span>Observer</span></h2> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><strong><span>观察者的设计意图和作用是</span></strong><span>Q?/span><span><span><font face="Times New Roman"> </font></span></span><span>它将对象与对象之间创ZU依赖关p,当其中一个对象发生变化时Q它?x)将q个变化通知l与其创建关pȝ对象中,实现自动化的通知更新?/span></font></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><span><font face="Times New Roman">       </font></span></span><strong><span>游戏中观察者的适用环境?/span></strong><span>Q?/span><span><span><font face="Times New Roman"> </font></span></span></font></p> <p><font size=3><span><font face="Times New Roman">1</font></span><span>Q?/span><span><font face="Times New Roman">UI</font></span><span>控g理cR当我们?/span><span><font face="Times New Roman">GUI</font></span><span>控g都用观察者模式后Q那么用L(fng)M界面相关操作和改变都会(x)通知其关联对?/span><span><font face="Times New Roman">-----</font></span><span>我们?/span><span><font face="Times New Roman">UI</font></span><span>事g机?/span></font></p> <p><font size=3><span><font face="Times New Roman">2</font></span><span>Q动ȝ理器。很多时候我们在播放一个动L的时候,对其</span><span><font face="Times New Roman">Frame</font></span><span>有很大兴,此时我们讄一?/span><span><font face="Times New Roman">FrameLister</font></span><span>对象对其q行监视Q获得我们关?j)的事gq行处理是必ȝ?/span></font></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><strong><span>观察者伪代码</span></strong><strong><span>Q?/span></strong></font></p> <p><span><font size=3 face="Times New Roman">//-------------------------------------------------------------------------------------------------------</font></span></p> <p><font size=3><span><font face="Times New Roman">// </font></span><span>被观察对象目标类</span></font></p> <p><span><font size=3 face="Times New Roman">Class Subject</font></span></p> <p><span><font size=3 face="Times New Roman">{</font></span></p> <p><font size=3><span><font face="Times New Roman"><span>       </span>// </font></span><span>Ҏ(gu)目标l定一个观察?/span><span><font face="Times New Roman"> Attach( Observer );</font></span></font></p> <p><font size=3><span><font face="Times New Roman"><span>       </span>// </font></span><span>解除一个观察者的l定</span><span><font face="Times New Roman"><span>   </span>DeleteAttach( Observer );</font></span></font></p> <p><font size=3><span><font face="Times New Roman"><span>       </span>// </font></span><span>本目标发生改变(sh)(jin)Q通知所有的观察者,但没有传递改动了(jin)什?/span></font></p> <p><span><font size=3><font face="Times New Roman"><span>       </span>Notity()</font></font></span></p> <p><span><font size=3><font face="Times New Roman"><span>       </span>{</font></font></span></p> <p><font size=3><span><font face="Times New Roman"><span>              </span>For ( …</font></span><span>遍历整个</span><span><font face="Times New Roman">ObserverList …)</font></span></font></p> <p><span><font size=3><font face="Times New Roman"><span>              </span>{ pObserver ->Update(); }</font></font></span></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><font size=3><span><font face="Times New Roman">// </font></span><span>对观察者暴露的接口Q让观察者可获得本类有什么变?/span><span><font face="Times New Roman">GetState();</font></span></font></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><span><font size=3 face="Times New Roman">//-------------------------------------------------------------------------------------------------------</font></span></p> <p><font size=3><span><font face="Times New Roman">// </font></span><span>观察?/span><span><font face="Times New Roman">/</font></span><span>监听者类</span></font></p> <p><span><font size=3 face="Times New Roman">Class Observer</font></span></p> <p><span><font size=3 face="Times New Roman">{</font></span></p> <p><font size=3><span><font face="Times New Roman"><span>       </span>// </font></span><span>暴露l对象目标类的函敎ͼ当监听的对象发生?jin)变动,则它会(x)调用本函数通知观察?/span><span><font face="Times New Roman"> </font></span></font></p> <p><span><font size=3 face="Times New Roman">Void Update () </font></span></p> <p><span><font size=3 face="Times New Roman">{ </font></span></p> <p><font size=3><span><font face="Times New Roman">pSubject ->GetState(); // </font></span><span>获取监听对象发生?jin)什么变?/span><font face="Times New Roman"> </font></font></p> <p><font size=3><span><font face="Times New Roman">TODO</font></span><span>Q?/span><span><font face="Times New Roman">DisposeFun(); // </font></span><span>Ҏ(gu)状态不同,l予不同的处?/span></font></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><span><font size=3 face="Times New Roman">//-------------------------------------------------------------------------------------------------------</font></span></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><strong><span>非程序语a描述</span></strong><span>Q?/span></font></p> <p><font size=3><span><font face="Times New Roman">A</font></span><span>?/span><span><font face="Times New Roman">B</font></span><span>的好朋友Q对</span><span><font face="Times New Roman">B</font></span><span>的行为非常关?j)?/span><span><font face="Times New Roman">B</font></span><span>要出门,此时</span><span><font face="Times New Roman">A</font></span><span>l了(jin)</span><span><font face="Times New Roman">B</font></span><span>一个警报器Q告?/span><span><font face="Times New Roman">B</font></span><span>_(d)(x)“如果你有事,立刻按这个警报器告诉我?#8221;。结?/span><span><font face="Times New Roman">B</font></span><span>在外面遇上了(jin)ȝ(ch)Q按下警报器Q?/span><span><font face="Times New Roman">Update()</font></span><span>Q,</span><span><font face="Times New Roman">B</font></span><span>q?/span><span><font face="Times New Roman">A</font></span><span>Z(jin)事,于是p查一?/span><span><font face="Times New Roman">B</font></span><span>到底遇到?jin)什么麻?/span><span><font face="Times New Roman">(GetState())</font></span><span>Q当知道</span><span><font face="Times New Roman">B</font></span><span>原来是因人打?jin),于是立刻q行处理</span><span><font face="Times New Roman">DisposeFun()</font></span><span>Q派?jin)一手下帮</span><span><font face="Times New Roman">B</font></span><span>打架?/span></font></p> <p><font size=3><span>当然兛_(j)</span><span><font face="Times New Roman">A</font></span><span>的h可以不止一个,</span><span><font face="Times New Roman">C</font></span><span>Q?/span><span><font face="Times New Roman">D</font></span><span>可能也对</span><span><font face="Times New Roman">A</font></span><span>很关?j),于?/span><span><font face="Times New Roman">A</font></span><span>q里保存?sh)个所有关?j)它的h的链表,当遇到麻?ch)的时候,轮流l每个h一份通知?/span></font></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <h2><span>二:(x)单g模式</span><span>Singleton</span></h2> <p><font size=3><strong><span>单g模式的设计意囑֒作用?/span></strong><span>Q?/span><span><span><font face="Times New Roman">    </font></span></span><span>保证一个类仅有一个实例,q且Q仅提供一个访问它的全局讉K炏V?/span></font></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><strong><span>游戏中适用于单件模式的?/span></strong><span>Q?/span><span><span><font face="Times New Roman"> </font></span></span></font></p> <p><font size=3><span><font face="Times New Roman">1</font></span><span>Q所有的</span><span><font face="Times New Roman">Manger</font></span><span>。在大部分的行引擎中都存在着它的影子Q例?/span><span><font face="Times New Roman">SoundManager, ParticeManager</font></span><span>{?/span></font></p> <p><font size=3><span><font face="Times New Roman">2</font></span><span>Q大部分的工厂基cR这一点在大部分引擎中q是见不到的Q实际上Q我们的父类工厂采用唯一实例的话Q我们子c进行扩展时也会(x)有很大方ѝ?/span></font></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><strong><span>单g模式伪代?/span></strong><span>Q?/span></font></p> <p><span><font size=3 face="Times New Roman">//-------------------------------------------------------------------------------------------------------</font></span></p> <p><span><font size=3 face="Times New Roman">Class Singleton</font></span></p> <p><span><font size=3 face="Times New Roman">{</font></span></p> <p><font size=3><span><font face="Times New Roman"><span>       </span>Static MySingleton;<span>       </span>// </font></span><span>单g对象Q全局唯一的?/span></font></p> <p><font size=3><span><font face="Times New Roman"><span>       </span>Static Instance(){ return MySingleton;}<span>              </span>// </font></span><span>对外暴露接口</span></font></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><span><font size=3 face="Times New Roman">//-------------------------------------------------------------------------------------------------------</font></span></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <h2><span>三:(x)q代?/span><span>Iterator</span></h2> <p><span><span><font size=3 face="Times New Roman">       </font></span></span></p> <p><font size=3><span><span><font face="Times New Roman">       </font></span></span><strong><span>q代器设计意囑֒作用?/span></strong><span>Q?/span><span><span><font face="Times New Roman">    </font></span></span><span>提供一个方法,对一个组合聚合对象内各个元素q行讉KQ同时又不暴露该对象cȝ内部表示?/span></font></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><span><font face="Times New Roman">       </font></span></span><strong><span>游戏中适用于P代器模式的有</span></strong><span>Q?/span><span><span><font face="Times New Roman">    </font></span></span><span>因ؓ(f)</span><span><font face="Times New Roman">STL</font></span><span>的流行,q个设计已经qؓ(f)人知?jin),我们对Q何Ş式的资源通一理Ӟ不免?x)将其聚合v来,或?/span><span><font face="Times New Roman">List</font></span><span>Q或?/span><span><font face="Times New Roman">Vector</font></span><span>Q我们都需要一个对其进行访问的工具QP代器无疑是一个利器?/span></font></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><span><font face="Times New Roman">       </font></span></span><strong><span>q代器伪代码</span></strong><span>Q?/span></font></p> <p><span><font size=3 face="Times New Roman">//-------------------------------------------------------------------------------------------------------</font></span></p> <p><font size=3><span><font face="Times New Roman">// </font></span><span>q代器基c?/span></font></p> <p><span><font size=3><font face="Times New Roman"><span>       </span>Class Iterator</font></font></span></p> <p><span><font size=3 face="Times New Roman">{</font></span></p> <p><span><font size=3><font face="Times New Roman"><span>              </span>Virtual First();<span>               </span></font></font></span></p> <p><span><font size=3><font face="Times New Roman"><span>              </span>Virtual Next();<span> </span></font></font></span></p> <p><span><font size=3><font face="Times New Roman"><span>              </span>Virtual End();</font></font></span></p> <p><font size=3><span><font face="Times New Roman"><span>              </span>Virtual CurrentItem();<span>    </span>// </font></span><span>q回当前</span><span><font face="Times New Roman">Item</font></span><span>信息</span></font></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><span><font size=3 face="Times New Roman">//-------------------------------------------------------------------------------------------------------</font></span></p> <p><font size=3><span><font face="Times New Roman">// </font></span><span>聚合体的基类</span></font></p> <p><span><font size=3><font face="Times New Roman"><span>       </span>Class ItemAggregate</font></font></span></p> <p><span><font size=3 face="Times New Roman">{</font></span></p> <p><font size=3><span><font face="Times New Roman"><span>              </span>Virtual CreateIterator(); // </font></span><span>创徏讉K自n的一个P代器</span></font></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><span><font size=3 face="Times New Roman">//-------------------------------------------------------------------------------------------------------</font></span></p> <p><font size=3><span><font face="Times New Roman">// </font></span><span>实例化的目聚合?/span></font></p> <p><span><font size=3><font face="Times New Roman"><span>       </span>Class InstanceItemAggregate : public ItemAggregate</font></font></span></p> <p><span><font size=3><font face="Times New Roman"><span>       </span>{</font></font></span></p> <p><span><font size=3><font face="Times New Roman"><span>              </span>CreateIterator(){ return new InstanceIterator(this); }</font></font></span></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><span><font size=3 face="Times New Roman">//-------------------------------------------------------------------------------------------------------</font></span></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <h2><span>四:(x)讉K者模?/span><span>Visitor</span><span>Q?/span></h2> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><span><font face="Times New Roman">       </font></span></span><strong><span>讉K者设计意囑֒作用?/span></strong><span>Q?/span><span><span><font face="Times New Roman">    </font></span></span><span>当我们希望对一个结构对象添加一个功能时Q我们能够在不媄(jing)响结构的前提下,定义一个新的对其元素的操作。(实际上,我们只是把对该元素的操作分割l每个元素自w类中实C(jin)而已Q?/span></font></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><span><font face="Times New Roman">       </font></span></span><strong><span>游戏中适用于访问者模式的?/span></strong><span>Q?/span><span><span><font face="Times New Roman">    </font></span></span><span>M一个比较静(rn)态的复杂l构cM都适合采用一份访问者。这里的“比较?rn)态的复杂l构c?#8221;意思是Q该l构cM元素J多且种cd杂,且对应的操作较多Q但cd进行变化,我们p够将Q对q个l构cd素的操作独立出来Q避免污染这些元素对象?/span></font></p> <p><font size=3><span><font face="Times New Roman"><span>       </span>1</font></span><span>Q例如场景管理器中管理的场景节点Q是非常J多的,而且U类不一Q例如有</span><span><font face="Times New Roman">Ogre</font></span><span>中的</span><span><font face="Times New Roman">Root, Irrchit</font></span><span>中就把摄象机Q灯光,</span><span><font face="Times New Roman">Mesh</font></span><span>Q公告版Q声音都做ؓ(f)一U场景节点,每个节点cd是不同的Q虽然大安有共通的</span><span><font face="Times New Roman">Paint(),Hide()</font></span><span>{方法,但方法的实现形式是不同的Q当我们外界调用旉要统一接口Q那么我们很可能需要需要这L(fng)代码</span><span><font face="Times New Roman"> </font></span></font></p> <p><span><font size=3><font face="Times New Roman"><span>       </span>Hide( Object )</font></font></span></p> <p><span><font size=3><font face="Times New Roman"><span>       </span>{ if (Object == Mesh) HideMesh(); if (Object == Light) HideLight(); … }</font></font></span></p> <p><font size=3><span>此时若我们需要增加一?/span><span><font face="Times New Roman">Object</font></span><span>新的cd对象Q我们就不得不对该函数进行修正。而我们可以这样做Q让</span><span><font face="Times New Roman">Mesh,Light</font></span><span>他们都(h)承于</span><span><font face="Times New Roman">Object,</font></span><span>他们都实C个函?/span><span><font face="Times New Roman">Hide(),</font></span><span>那么变?/span></font></p> <p><span><font size=3><font face="Times New Roman"><span>       </span>Mesh::Hide( Visitor ) { Visitor.Hide (Mesh); }</font></font></span></p> <p><span><font size=3><font face="Times New Roman"><span>       </span>Light::Hide(Visitor ){ Visitor.Hide (Light); }</font></font></span></p> <p><font size=3><span>我们在调用时只需?/span><span><font face="Times New Roman">Object.Hide(Visitor){ return Visitor.Hide(Object); }</font></span></font></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span>q样做的<strong><span>好处</span></strong>Q我们免M(jin)寚w要函数的修正Q?/span><span><font face="Times New Roman">Object.Hide(Visitor){}</font></span><span>函数我们可以怹不变Q但?strong><span>坏处</span></strong>也是很明昄Q因为将Ҏ(gu)从对象集合结构中抽离出来Q就意味着我们每增加一个元素,它必ȝ(h)承于一个抽象的被访问者类Q实现其全部函数Q这个工作量很大?/span></font></p> <p><font size=3><span>所以,<span>讉K者是仅适合于一个装载不同对象的大容器,但同时又要求q个容器的元素节点不应当有大的变动时才?/span>。另外,废话一句,讉K者破坏了(jin)</span><span><font face="Times New Roman">OO</font></span><span>思想的?/span></font></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><span><font face="Times New Roman">       </font></span></span><strong><span>讉K者伪代码</span></strong><span>Q?/span></font></p> <p><span><font size=3 face="Times New Roman">//-------------------------------------------------------------------------------------------------------</font></span></p> <p><font size=3><span><font face="Times New Roman">// </font></span><span>讉K者基c?/span></font></p> <p><span><font size=3><font face="Times New Roman"><span>       </span>Class Visitor</font></font></span></p> <p><span><font size=3 face="Times New Roman">{</font></span></p> <p><font size=3><span><font face="Times New Roman"><span>              </span>Virtual VisitElement( A ){ … };<span>             </span>// </font></span><span>讉K的每个对象都要写q样一个方?/span></font></p> <p><span><font size=3><font face="Times New Roman"><span>              </span>Virtual VisitElement( B ){ … };</font></font></span></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><font face="Times New Roman">// </font></span><span>讉K者实?/span><span><font face="Times New Roman">A</font></span></font></p> <p><span><font size=3 face="Times New Roman">Class VisitorA</font></span></p> <p><span><font size=3 face="Times New Roman">{</font></span></p> <p><font size=3><span><font face="Times New Roman"><span>       </span>VisitElement( A ){ … };<span>         </span>// </font></span><span>实际的处理函?/span></font></p> <p><font size=3><span><font face="Times New Roman">VisitElement( B ){ … };<span>        </span>// </font></span><span>实际的处理函?/span></font></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><font face="Times New Roman">// </font></span><span>讉K者实?/span><span><font face="Times New Roman">B</font></span></font></p> <p><span><font size=3 face="Times New Roman">Class VisitorB</font></span></p> <p><span><font size=3 face="Times New Roman">{</font></span></p> <p><font size=3><span><font face="Times New Roman"><span>       </span>VisitElement( A ){ … };<span>         </span>// </font></span><span>实际的处理函?/span></font></p> <p><font size=3><span><font face="Times New Roman">VisitElement( B ){ … };<span>        </span>// </font></span><span>实际的处理函?/span></font></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><font face="Times New Roman">// </font></span><span>被访问者基c?/span></font></p> <p><span><font size=3 face="Times New Roman">Class Element</font></span></p> <p><span><font size=3 face="Times New Roman">{</font></span></p> <p><font size=3><span><font face="Times New Roman"><span>       </span>Virtual Accept( Visitor );<span>        </span>// </font></span><span>接受讉K?/span></font></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><font face="Times New Roman">// </font></span><span>被访问者实?/span><span><font face="Times New Roman">A</font></span></font></p> <p><span><font size=3 face="Times New Roman">Class ElementA</font></span></p> <p><span><font size=3 face="Times New Roman">{</font></span></p> <p><font size=3><span><font face="Times New Roman"><span>       </span>Accecpt( Visitor v ){ v-> VisitElement(this); };<span>    </span>// </font></span><span>调用注册到访问者中的处理函?/span></font></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><font face="Times New Roman">// </font></span><span>被访问者实?/span><span><font face="Times New Roman">B</font></span></font></p> <p><span><font size=3 face="Times New Roman">Class ElementB</font></span></p> <p><span><font size=3 face="Times New Roman">{</font></span></p> <p><font size=3><span><font face="Times New Roman"><span>       </span>Accecpt( Visitor v ){ v-> VisitElement(this); };<span>    </span>// </font></span><span>调用注册到访问者中的处理函?/span></font></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><span><font size=3 face="Times New Roman">//-------------------------------------------------------------------------------------------------------</font></span></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <h2><span>五:(x)外观模式</span><span>Façade</span></h2> <p><span><span><font size=3 face="Times New Roman">       </font></span></span></p> <p><font size=3><span><span><font face="Times New Roman">       </font></span></span><strong><span>外观模式的设计意囑֒作用?/span></strong><span>Q?/span><span><font face="Times New Roman">  </font></span><span>用h触的表层和内部子集的实现分离开发。实际上Q这个模式是个纸老虎Q之后我们看伪代码立d?x)发玎ͼq个模式实在用的太频J了(jin)?/span></font></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><span><font face="Times New Roman">       </font></span></span><strong><span>游戏中需要用外观模式的地方?/span></strong><span>Q?/span><span><span><font face="Times New Roman">   </font></span></span><span>q个非常多了(jin)QD几个比较重要的?/span></font></p> <p><font size=3><span><font face="Times New Roman"><span>       </span>1</font></span><span>Q实现^台无x(chng)。跨q_跨库的函数调用?/span></font></p> <p><font size=3><span><font face="Times New Roman"><span>       </span>2</font></span><span>Q同一个接口去d不同的资源?/span></font></p> <p><font size=3><span><font face="Times New Roman"><span>       </span>3</font></span><span>Q硬件自动识别处理系l?/span></font></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><span><font face="Times New Roman">       </font></span></span><strong><span>外观模式伪代?/span></strong></font></p> <p><span><font size=3 face="Times New Roman">//-------------------------------------------------------------------------------------------------------</font></span></p> <p><font size=3><span><font face="Times New Roman"><span>       </span>// </font></span><span>用户使用的接口类</span></font></p> <p><span><font size=3><font face="Times New Roman"><span>       </span>Class Interface</font></font></span></p> <p><span><font size=3 face="Times New Roman">{</font></span></p> <p><font size=3><span><font face="Times New Roman">// </font></span><span>暴露出来的函数接口函敎ͼ有且仅有一个,但内部实现是调用?jin)两个?/span></font></p> <p><span><font size=3><font face="Times New Roman"><span>       </span>Void InterfaceFun()</font></font></span></p> <p><span><font size=3 face="Times New Roman">{</font></span></p> <p><font size=3><span><font face="Times New Roman"><span>       </span>// </font></span><span>Ҏ(gu)某种条gQ底层自ȝ选择使用</span><span><font face="Times New Roman">A</font></span><span>?/span><span><font face="Times New Roman">B</font></span><span>的方法。用hd?j)底层实?/span></font></p> <p><span><font size=3><font face="Times New Roman"><span>       </span>If ( XXX )</font></font></span></p> <p><span><font size=3><font face="Times New Roman"><span>       </span>{</font></font></span></p> <p><span><font size=3><font face="Times New Roman"><span>              </span>ActualA->Fun();</font></font></span></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><span><font size=3 face="Times New Roman">Else</font></span></p> <p><span><font size=3 face="Times New Roman">{</font></span></p> <p><span><font size=3><font face="Times New Roman"><span>       </span>ActualB->Fun();</font></font></span></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><span><font size=3><font face="Times New Roman">};<span>    </span></font></font></span></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><font face="Times New Roman">// </font></span><span>实际的实玎ͼ不暴露给用户知道</span></font></p> <p><span><font size=3 face="Times New Roman">Class ActualA</font></span></p> <p><span><font size=3 face="Times New Roman">{</font></span></p> <p><span><font size=3><font face="Times New Roman"><span>       </span>Void Fun();</font></font></span></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><font face="Times New Roman">// </font></span><span>实际的实玎ͼ不暴露给用户知道</span></font></p> <p><span><font size=3 face="Times New Roman">Class ActualB</font></span></p> <p><span><font size=3 face="Times New Roman">{</font></span></p> <p><span><font size=3><font face="Times New Roman"><span>       </span>Void Fun();</font></font></span></p> <p><span><font size=3 face="Times New Roman">}</font></span></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><span><font size=3>怎么PU老虎吧,看v来很高深摸测的命名而已?/font></span></p> <p><span><font size=3 face="Times New Roman">//-------------------------------------------------------------------------------------------------------</font></span></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <h2><span>六:(x)抽象工厂模式</span><span>AbstractFactory</span></h2> <p><span><span><font size=3 face="Times New Roman">       </font></span></span></p> <p><font size=3><span><span><font face="Times New Roman">       </font></span></span><strong><span>抽象工厂的设计意囑֒作用?/span></strong><span>Q?/span><span><span><font face="Times New Roman">    </font></span></span><span>装Z个接口,q个接口负责创徏一pd互相兌的对象,但用户在使用接口时不需要指定对象所在的具体的类。从中文命名也很Ҏ(gu)明白它是q行扚w生的一个生产工厂的作用?/span></font></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><span><font face="Times New Roman">       </font></span></span><strong><span>游戏中用抽象工厂的地方?/span></strong><span>Q?/span><span><span><font face="Times New Roman">    </font></span></span><span>基本上Q何有扚w的同cdŞ式的子g地方׃(x)有工厂的存在。(补充一句:(x)下面代码中的</span><span><font face="Times New Roman">ConcreteFactory1</font></span><span>实例工厂是工厂Q而抽象工厂仅仅是工厂的一个抽象层而已?/span><span>Q?/span></font></p> <p><font size=3><span><font face="Times New Roman">1</font></span><span>Q例如,在音频方面,一个音频的抽象工厂zZ同的工厂Q有音乐工厂Q音效工厂。音效工厂中又有一个创?/span><span><font face="Times New Roman">3D</font></span><span>x(chng)节点的方法,一个创建普通音效节点的Ҏ(gu)。最l用户只需?/span><span><font face="Times New Roman">SoundFactory->Create3DNode( pFileName );</font></span><span>可以创Z个节点了(jin)?/span></font></p> <p><font size=3><span><font face="Times New Roman">2</font></span><span>Q场景对象?/span></font></p> <p><font size=3><span><font face="Times New Roman">3</font></span><span>Q渲染对象?/span></font></p> <p><font size=3><span><font face="Times New Roman">4</font></span><span>Q等{?#8230;…</span></font></p> <p><font size=3><span>工厂与单Ӟ理?/span><span><font face="Times New Roman">Manager</font></span><span>关系一定是非常紧密的?/span></font></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><span><font face="Times New Roman">       </font></span></span><strong><span>抽象工厂伪代?/span></strong><span>Q?/span></font></p> <p><span><font size=3 face="Times New Roman">//-------------------------------------------------------------------------------------------------------</font></span></p> <p><font size=3><font face="Times New Roman"><span><span>       </span></span><span>class AbstractProductA {}; // </span></font><span>抽象的?/span><span><font face="Times New Roman">A</font></span><span>基类</span></font><span><br></span><font size=3><span>  </span><span><font face="Times New Roman">class AbstractProductB {}; //</font></span><span>抽象的?/span><span><font face="Times New Roman">B</font></span><span>基类</span></font></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><font face="Times New Roman">// </font></span><span>抽象工厂基类</span></font><span><br></span><span><font size=3>  </font></span><font size=3><span><font face="Times New Roman">class AbstractFactory<br></font></span><span>  </span></font><font size=3><span><font face="Times New Roman">{<br></font></span><span>  </span></font><font size=3><span><font face="Times New Roman">public:<br></font></span><span>   </span><span><font face="Times New Roman">virtual AbstractProductA* CreateProductA() = 0 ;// </font></span><span>创徏</span></font><font size=3><span><font face="Times New Roman">ProductA<br></font></span><span>   </span><span><font face="Times New Roman">virtual AbstractProductB* CreateProductB() = 0 ;// </font></span><span>创徏</span></font><span><font size=3><font face="Times New Roman">ProductB<br>   <span>    </span>} ;</font></font></span></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span>  </span><span><font face="Times New Roman">class ProductA1 : public AbstractProductA {};<span>    </span>// </font></span><span>产品</span><span><font face="Times New Roman">A</font></span><span>的实?/span></font><font size=3><span><font face="Times New Roman">1<br></font></span><span>  </span><span><font face="Times New Roman">class ProductA2 : public AbstractProductA {};<span>    </span>// </font></span><span>产品</span><span><font face="Times New Roman">A</font></span><span>的实?/span><span><font face="Times New Roman">2</font></span></font></p> <p><font size=3><span>  </span><span><font face="Times New Roman">class ProductB1 : public AbstractProductB {};<span>    </span>// </font></span><span>产品</span><span><font face="Times New Roman">B</font></span><span>的实?/span></font><font size=3><span><font face="Times New Roman">1<br></font></span><span>  </span><span><font face="Times New Roman">class ProductB2 : public AbstractProductB {};<span>    </span>// </font></span><span>产品</span><span><font face="Times New Roman">B</font></span><span>的实?/span><span><font face="Times New Roman">2</font></span></font></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><font face="Times New Roman">// </font></span><span>实例工厂</span><span><font face="Times New Roman">1</font></span></font></p> <p><font size=3><span><font face="Times New Roman">     class ConcreteFactory1 : public AbstractFactory<br></font></span><span>  </span></font><font size=3><span><font face="Times New Roman">{<br></font></span><span>    </span></font><font size=3><span><font face="Times New Roman">virtual AbstractProductA* CreateProductA() { return new ProductA1() ; }<br></font></span><span>    </span></font><font size=3><span><font face="Times New Roman">virtual AbstractProductB* CreateProductB() { return new ProductB1() ; }<br></font></span><span>   </span><span><font face="Times New Roman"><span>    </span>static ConcreteFactory1* Instance() { } </font></span><span>  </span><span><font face="Times New Roman"><span>     </span>// </font></span><span>实例工厂量使用单g模式</span></font><span><br></span><font size=3><span>  </span><span><font face="Times New Roman">} ;</font></span></font></p> <p><span><font size=3 face="Times New Roman"> </font></span></p> <p><font size=3><span><font face="Times New Roman">// </font></span><span>实例工厂</span><span><font face="Times New Roman">2</font></span></font></p> <p><span><font size=3>class ConcreteFactory2 : public AbstractFactory<br></font></span><span><font size=3>  </font><font size=3><span>{<br></span>    </font><font size=3><span>virtual AbstractProductA* CreateProductA() { return new ProductA2() ; }<br></span>    </font><font size=3><span>virtual AbstractProductB* CreateProductB() { return new ProductB2() ; }<br></span>    <span>static ConcreteFactory2* Instance() {} </span></font></span><font size=3><span><font face="Times New Roman"><span>       </span>// </font></span><span>实例工厂量使用单g模式</span></font><span><br></span><span><font size=3>  <span>} ;</span></font></span></p> <p><span><font size=3>}</font></span></p> <p><span><font size=3 face="Times New Roman">//-------------------------------------------------------------------------------------------------------</font></span></p> <p><font size=3><strong><span>客户端代?/span></strong><span>Q?/span></font></p> <p><span><font size=3>Void main()<br>{<br></font></span><span><font size=3>  </font><font size=3><span>AbstractFactory *pFactory1 = ConcreteFactory1::Instance() ;<br></span>  </font><font size=3><span>AbstractProductA *pProductA1 = pFactory1->CreateProductA() ;<br></span>  </font><font size=3><span>AbstractProductB *pProductB1 = pFactory1->CreateProductB() ;<br></span>  </font><font size=3><span>AbstractFactory *pFactory2 = ConcreteFactory2::Instance() ;<br></span>  </font><font size=3><span>AbstractProductA *pProductA2 = pFactory2->CreateProductA() ;<br></span>  </font><span><font size=3>AbstractProductB *pProductB2 = pFactory2->CreateProductB() ;<br>}</font></span></span></p> <p><span><font size=3 face="Times New Roman">//-------------------------------------------------------------------------------------------------------</font></span></p> </div> <SCRIPT type=text/javascript> //<![CDATA[ Sys.WebForms.PageRequestManager._initialize('AjaxHolder$scriptmanager1', document.getElementById('Form1')); Sys.WebForms.PageRequestManager.getInstance()._updateControls(['tAjaxHolder$UpdatePanel1'], [], [], 90); //]]> </SCRIPT> <img src ="http://www.shnenglu.com/Leaf/aggbug/83227.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Leaf/" target="_blank">Render Donkey</a> 2009-05-17 23:36 <a href="http://www.shnenglu.com/Leaf/archive/2009/05/17/83227.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在VS2005下编译HGE例子 LIBC.lib问题http://www.shnenglu.com/Leaf/archive/2009/05/14/82985.htmlRender DonkeyRender DonkeyThu, 14 May 2009 12:04:00 GMThttp://www.shnenglu.com/Leaf/archive/2009/05/14/82985.htmlhttp://www.shnenglu.com/Leaf/comments/82985.htmlhttp://www.shnenglu.com/Leaf/archive/2009/05/14/82985.html#Feedback5http://www.shnenglu.com/Leaf/comments/commentRss/82985.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/82985.html再说?jin),不是说是向下兼容的吗Q怎么?x)出现无法编译?br>那就是一个很刺眼的问?br>无法扑ֈ LIBC.lib

我也查了(jin)一下午Q终于让我发C(jin)一些东?br>可以?libc.lib是一个被人遗弃的家伙QVS2005不再支持它了(jin)Q于是会(x)提示你找不到?br>贴子真多呀Q翻一N,也没见一个针Ҏ(gu)的?br>l于一哥们儿的BLOG开门见山就说了(jin)解决他的Ҏ(gu)


只要忽略q个库即?br>


发在q里Q只为再ơ搜索这个东西的兄弟多一个关键字。?br>

Render Donkey 2009-05-14 20:04 发表评论
]]>
3DSNAKE-DEMOhttp://www.shnenglu.com/Leaf/archive/2009/05/02/81731.htmlRender DonkeyRender DonkeySat, 02 May 2009 14:27:00 GMThttp://www.shnenglu.com/Leaf/archive/2009/05/02/81731.htmlhttp://www.shnenglu.com/Leaf/comments/81731.htmlhttp://www.shnenglu.com/Leaf/archive/2009/05/02/81731.html#Feedback0http://www.shnenglu.com/Leaf/comments/commentRss/81731.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/81731.html
感觉不管怎么学,q是得自己做东西才能有所提升Q毕竟书上的问题是死的,自己遇到的问题是zȝ?br>截图留念一下!



寝室同学说三l的有点晕,哈哈Q我调试的时候也玩晕?jin),不过现在习(fn)惯了(jin),呵呵Q有助于ȝ晕R哦!

Render Donkey 2009-05-02 22:27 发表评论
]]>
OGRE 中的 Terrianhttp://www.shnenglu.com/Leaf/archive/2009/04/27/81271.htmlRender DonkeyRender DonkeyMon, 27 Apr 2009 14:34:00 GMThttp://www.shnenglu.com/Leaf/archive/2009/04/27/81271.htmlhttp://www.shnenglu.com/Leaf/comments/81271.htmlhttp://www.shnenglu.com/Leaf/archive/2009/04/27/81271.html#Feedback2http://www.shnenglu.com/Leaf/comments/commentRss/81271.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/81271.html


Render Donkey 2009-04-27 22:34 发表评论
]]>
Ʒþۺ| Ʒþ߹ۿ| ƷþþӰ| ˾þþƷ| һƷþþ޹| 91þ㽶Ů߿| þþù99þùһ| ŷƷۺϾþ| þˮav뾫Ʒ鶹| þþƷݲݲ| 97Ƶþþ| Ʒ99þþþ | 97Ʒ˾þþô߽| ŷԴսþþþþ| .Ʒþþ鶹Ʒ| þۺɫ| һþþþþþ| þþ97ɫ| պŮ18վþþƷ| ٸþ| ˾þùѹۿƵ| Ʒþþþþþþ| þþþþþþ| þþƷ鶹| ɫ8þ97㽶987| þҹɫƷav| þþƷ9988| ƷþþĻѿ| þۺav| 뾫ƷþѼ| ɫþþۺ| ޹ƷȾþ| 99þþƷӰԺѼ| 77777ҹþö| ˾þվ| þùֱ| ŷþþþþ| AþþƷ| ھƷۺϾþþ40p| þþƷަvDz | þþƷѿ޹AV|