??xml version="1.0" encoding="utf-8" standalone="yes"?>久久综合久久美利坚合众国,66精品综合久久久久久久,色婷婷综合久久久久中文http://www.shnenglu.com/bloodbao/category/3956.htmlc++zh-cnSun, 09 Nov 2008 15:16:14 GMTSun, 09 Nov 2008 15:16:14 GMT60clip plane模拟Q抄自DXSDKQ?/title><link>http://www.shnenglu.com/bloodbao/archive/2008/11/09/66448.html</link><dc:creator>bloodbao</dc:creator><author>bloodbao</author><pubDate>Sun, 09 Nov 2008 12:47:00 GMT</pubDate><guid>http://www.shnenglu.com/bloodbao/archive/2008/11/09/66448.html</guid><wfw:comment>http://www.shnenglu.com/bloodbao/comments/66448.html</wfw:comment><comments>http://www.shnenglu.com/bloodbao/archive/2008/11/09/66448.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/bloodbao/comments/commentRss/66448.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/bloodbao/services/trackbacks/66448.html</trackback:ping><description><![CDATA[<p>DX9下?br>D3DXPLANE plane; <br> D3DXPlaneFromPointNormal( &plane, &vPoint, &vNormal ); //生成q个q面 <br>D3DXMatrixReflect( &matReflect, &plane ); //取得该^面的反射矩阵<br>//讄剪切q面Q反射面上的内容被渲染Q面下的被丢?<br> m_pd3dDevice->SetClipPlane( 0, plane ); <br> m_pd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE, 0x01 );<br>DX10下模拟:<br>User Clip PlanesUser Clip Planes are emulated by specifying a clip distance output from the Vertex Shader with the SV_ClipDistance[n] flag, where n is either 0 or 1. Each component can hold up to 4 clip distances in x, y, z, and w giving a total of 8 clip distances.</p> <p>    用户裁减q面通过在VS里设定一个SV_ClipDistance[n]标记Q定义一个裁减距输出得?n??。这里一p存放8个Clip Plane距离Q分别用数l两个元素的x,y,z,w通道?/p> <p>In this scenario, each clip planes is defined by a plane equation of the form:</p> <p>在这个场景里Q每个clip plane被一个^面方E定义:</p> <p>Ax + By + Cz + D =0;</p> <p>Where <A,B,C> is the normal of the plane, and D is the distance of the plane from the origin. Plugging in any point <x,y,z> into this equation gives its distance from the plane. Therefore, all points <x,y,z> that satisfy the equation Ax + By + Cz + D = 0 are on the plane. All points that satisfy Ax + By + Cz + D < 0 are below the plane. All points that satisfy Ax + By + Cz + D > 0 are above the plane.</p> <p><A,B,C>是^面法向,D是^面到原点的距R把L?lt;x,y,z>代入方程能得到它到^面的距离。所有满xE=0的点在^面上Q?lt;0的点在^面下?>0的点在^面上?/p> <p>In the Vertex Shader, each vertex is tested against each plane equation to produce a distance to the clip plane. Each of the three clip distances are stored in the first three components of the output component with the semantic SV_ClipDistance0. These clip distances get interpolated over the triangle during rasterization and clipped if the value every goes below 0.</p> <p>    在VS中,每个点会带入^面方E做试。每个三角Ş的Clip距离存在SV_ClipDistance0语义输出的前三个通道中。这个距d光栅化中被线性插|所有小?的像素被剔除?/p> <img src ="http://www.shnenglu.com/bloodbao/aggbug/66448.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/bloodbao/" target="_blank">bloodbao</a> 2008-11-09 20:47 <a href="http://www.shnenglu.com/bloodbao/archive/2008/11/09/66448.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>rendering调试http://www.shnenglu.com/bloodbao/archive/2008/10/23/64881.htmlbloodbaobloodbaoThu, 23 Oct 2008 13:55:00 GMThttp://www.shnenglu.com/bloodbao/archive/2008/10/23/64881.htmlhttp://www.shnenglu.com/bloodbao/comments/64881.htmlhttp://www.shnenglu.com/bloodbao/archive/2008/10/23/64881.html#Feedback0http://www.shnenglu.com/bloodbao/comments/commentRss/64881.htmlhttp://www.shnenglu.com/bloodbao/services/trackbacks/64881.html

bloodbao 2008-10-23 21:55 发表评论
]]>
Main Features in my blood enginehttp://www.shnenglu.com/bloodbao/archive/2008/08/11/58530.htmlbloodbaobloodbaoMon, 11 Aug 2008 07:05:00 GMThttp://www.shnenglu.com/bloodbao/archive/2008/08/11/58530.htmlhttp://www.shnenglu.com/bloodbao/comments/58530.htmlhttp://www.shnenglu.com/bloodbao/archive/2008/08/11/58530.html#Feedback0http://www.shnenglu.com/bloodbao/comments/commentRss/58530.htmlhttp://www.shnenglu.com/bloodbao/services/trackbacks/58530.htmlDirect3D 9 is used to render the scene
User input is gathered though DirectInput
Single pass multi-texturing using the fixed-function pipeline (FFP)
Light-mapping
Frustum culling
Simple skybox
Keyframe Animation with GPU-based frame interpolation through a custom vertex and pixel shader written in HLSL. This technique is also known as Vertex Tweening or even Morph Target
Support for Quake2 models (.md2)
Support for DirectX models (.x)
Support for PCX texture loading in addition to the other image formats already supported by Direct3D
Support for Quake3:Arena levels
Lightmaps
Curved surfaces using Bezier patches
Partial support of Quake3 materials and effects (.shader)
Uses the BSP/PVS to quickly discard non visible geometry
Collision detection using the BSP tree (supports ray, sphere and box sweeps)
A flexible scene graph system where entities can be attached to each other in order to perform hierarchical transformations and geometry culling
Quake-like player movement physics
A powerful in-game console system:
Outputs vital information
Can take command inputs from the user
Console variables can be dynamically edited at runtime
Commands and console variable settings can be loaded from a user-specified text file (cfg)
Garbage collection of unused resources through reference counting
Control keys can be dynamically changed in-game through the console, using the bind command
User input is abstracted through an Action Manager which maps inputs to actions
A smart chase-camera controller that will detect collisions with the world to prevent the view from being occluded by other pieces of world geometry.
Error handling through exceptions
The in-game HUD can display vital performance statistics about the game, such as frames per second, total number of triangles on the screen, number of textures loaded, etc…

bloodbao 2008-08-11 15:05 发表评论
]]>
又失败了http://www.shnenglu.com/bloodbao/archive/2008/08/06/58118.htmlbloodbaobloodbaoWed, 06 Aug 2008 02:36:00 GMThttp://www.shnenglu.com/bloodbao/archive/2008/08/06/58118.htmlhttp://www.shnenglu.com/bloodbao/comments/58118.htmlhttp://www.shnenglu.com/bloodbao/archive/2008/08/06/58118.html#Feedback9http://www.shnenglu.com/bloodbao/comments/commentRss/58118.htmlhttp://www.shnenglu.com/bloodbao/services/trackbacks/58118.html       Zq次面试Q我休息了很多天Q都没工作。结果,得到的又是一个失败的l局。分析原因,都认为我的C++基础很薄弱吧Q要不就是因为我以前从事的工作和现在的工作差别太大了?br>      作ؓ一名新手,我很qQ在学习(fn)的道路我没有被打败,却在两次面试中,深受打击。我不仅在想Q这是否是我要选择的\。仅剩半个多月的旉Q暑期就l束了,我再不出去,没Z了。事实上Q做不做游戏Q我无所谓,但现在的生活一直不是我惌的。我不断地在否定自已的\上,走远Q找不到真实的我?br>      两个月很快就q去了,我只能静下心来去做事情,把这些烦人的事,都抛于脑后。\q是要走QhL要成长的Q希望能从失败中走出来?br>      C今天的失败,以作自勉?/p>

bloodbao 2008-08-06 10:36 发表评论
]]>
DX10sample的阴?/title><link>http://www.shnenglu.com/bloodbao/archive/2008/07/20/56669.html</link><dc:creator>bloodbao</dc:creator><author>bloodbao</author><pubDate>Sun, 20 Jul 2008 02:48:00 GMT</pubDate><guid>http://www.shnenglu.com/bloodbao/archive/2008/07/20/56669.html</guid><wfw:comment>http://www.shnenglu.com/bloodbao/comments/56669.html</wfw:comment><comments>http://www.shnenglu.com/bloodbao/archive/2008/07/20/56669.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/bloodbao/comments/commentRss/56669.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/bloodbao/services/trackbacks/56669.html</trackback:ping><description><![CDATA[<img src="http://www.shnenglu.com/images/cppblog_com/bloodbao/self-shadow.jpg" border=0><br>主要是用模板~冲区来实现?br>DepthStencilState StencilShadow<br>{<br>    DepthEnable = true;<br>    DepthWriteMask = ZERO;<br>    DepthFunc = LESS;<br>    <br>    StencilEnable = true;<br>    StencilReadMask = 0xFFFFFFFF;<br>    StencilWriteMask = 0xFFFFFFFF;<br>    <br>    FrontFaceStencilFunc = ALWAYS;<br>    FrontFaceStencilPass = INCR;<br>    FrontFaceStencilFail = Keep;<br>    <br>    BackFaceStencilFunc = ALWAYS;<br>    BackFaceStencilPass = DECR;<br>  BackFaceStencilFail = Keep;<br>};<br>BlendState AdditiveBlending<br>{<br>    AlphaToCoverageEnable = FALSE;<br>    BlendEnable[0] = TRUE;<br>    SrcBlend = SRC_ALPHA ;<br>    DestBlend = INV_SRC_ALPHA ;<br>    BlendOp = ADD;<br>    SrcBlendAlpha = ZERO;<br>    DestBlendAlpha = ZERO;<br>    BlendOpAlpha = ADD;<br>    RenderTargetWriteMask[0] = 0x0F;<br>};<br> <h2><a name=Rendering_Shadows></a>Rendering Shadows</h2> <p>At the top level, the rendering steps look like the following:</p> <ul> <li>If ambient lighting is enabled, render the entire scene with ambient only. <li>For each light in the scene, do the following: <ul> <li>Disable depth-buffer and frame-buffer writing. <li>Prepare the stencil buffer render states for rendering the shadow volume. <li>Render the shadow volume mesh with a vertex extruding shader. This sets up the stencil buffer according to whether or not the pixels are in the shadow volume. <li>Prepare the stencil buffer render states for lighting. <li>Prepare the additive blending mode. <li>Render the scene for lighting with only the light being processed. </li> </ul> </li> </ul> <br>Shadow Volumeq不是一个没有缺L(fng)技术。除了高像素填充率和阴媄边界外Q在l制q程中还可能出现错误。错误的主要原因是当一个几何模型在计算自阴影时Q它的面通常被完全照亮或者完全变暗,q取决于q个面是否朝向光源。光照计必M用顶Ҏ(gu)向而非表面法向。对于接q^行光源的面,它会被完全照亮或者完全变暗,而实际上应该部分处于光源中。这是从stencil shadow volume中承来的问题,在计阴影时必须被考虑。这个问题可以通过增加mesh密度来解冻Iq也增加了处理mesh的时间。顶Ҏ(gu)向和面法向越接近Q表面的问题p。如果程序不能把问题限制在可接受的范围内Q就必须考虑使用其他的算法,比如PRT或者Shadow Map? <img src ="http://www.shnenglu.com/bloodbao/aggbug/56669.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/bloodbao/" target="_blank">bloodbao</a> 2008-07-20 10:48 <a href="http://www.shnenglu.com/bloodbao/archive/2008/07/20/56669.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>dx10之模拟DX9http://www.shnenglu.com/bloodbao/archive/2008/07/20/56663.htmlbloodbaobloodbaoSun, 20 Jul 2008 02:31:00 GMThttp://www.shnenglu.com/bloodbao/archive/2008/07/20/56663.htmlhttp://www.shnenglu.com/bloodbao/comments/56663.htmlhttp://www.shnenglu.com/bloodbao/archive/2008/07/20/56663.html#Feedback0http://www.shnenglu.com/bloodbao/comments/commentRss/56663.htmlhttp://www.shnenglu.com/bloodbao/services/trackbacks/56663.htmlFixed-function Lighting Pipeline
ColorsOutput CalcLighting( float3 worldNormal, float3 worldPos, float3 cameraPos )
{
    ColorsOutput output = (ColorsOutput)0.0;
   
    for(int i=0; i<8; i++)
{
     //光线方向
        float3 toLight = g_lights[i].Position.xyz - worldPos;
         //d源距?br>        float lightDist = length( toLight );
         //attenQ(1/(a[2]*d*d+a[1]*d+a[1])
        float fAtten = 1.0/dot( g_lights[i].Atten, float4(1,lightDist,lightDist*lightDist,0) );
        float3 lightDir = normalize( toLight );
         //H
        float3 halfAngle = normalize( normalize(-cameraPos) + lightDir );
       
         //Phong方程Q逐顶点光?br>        output.Diffuse += max(0,dot( lightDir, worldNormal ) * g_lights[i].Diffuse * fAtten) + g_lights[i].Ambient;
        output.Specular += max(0,pow( dot( halfAngle, worldNormal ), 64 ) * g_lights[i].Specular * fAtten );
    }
   
    return output;
}
单ALPHA试
//
// PS for rendering with alpha test
//
float4 PSAlphaTestmain(PSSceneIn input) : COLOR0
{       
         float4 color =  tex2D( g_samLinear, g_txDiffuse, input.tex ) * input.colorD;
         if( color.a < 0.5 )
                 discard;
         return color;
}
雑֌Q?/p>

//
// Calculates fog factor based upon distance
//
// E is defined as the base of the natural logarithm (2.71828)
float CalcFogFactor( float d )
{
         float fogCoeff = 1.0;
        
         if( FOGMODE_LINEAR == g_fogMode )
         {
                 fogCoeff = (g_fogEnd - d)/(g_fogEnd - g_fogStart);
         }
         else if( FOGMODE_EXP == g_fogMode )
         {
                 fogCoeff = 1.0 / pow( E, d*g_fogDensity );
         }
         else if( FOGMODE_EXP2 == g_fogMode )
         {
                 fogCoeff = 1.0 / pow( E, d*d*g_fogDensity*g_fogDensity );
         }
        
         return clamp( fogCoeff, 0, 1 );
}

Finally, the pixel shader uses the fog factor to determine how much of the original color and how much of the fog color to output to the pixel.

最后,PS使用雑֌参数定N色和U理颜色的؜合程度?br>return fog * normalColor + (1.0 - fog)*g_fogColor;



bloodbao 2008-07-20 10:31 发表评论
]]>
由文g导入引发的。?/title><link>http://www.shnenglu.com/bloodbao/archive/2008/07/17/56387.html</link><dc:creator>bloodbao</dc:creator><author>bloodbao</author><pubDate>Thu, 17 Jul 2008 02:26:00 GMT</pubDate><guid>http://www.shnenglu.com/bloodbao/archive/2008/07/17/56387.html</guid><wfw:comment>http://www.shnenglu.com/bloodbao/comments/56387.html</wfw:comment><comments>http://www.shnenglu.com/bloodbao/archive/2008/07/17/56387.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.shnenglu.com/bloodbao/comments/commentRss/56387.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/bloodbao/services/trackbacks/56387.html</trackback:ping><description><![CDATA[<p>刚开始学?fn)DX10Q发觉模型文件已l从原来的X格式变ؓSDKMESH格式Q也是说DX10不直接支持X文g了,<br>那现在该怎么办,我在NVSDK下找C他的解决Ҏ(gu)Q先用DX9的接口打开X文gQ再用DX10接口来渲染文件?br>         在DX10下,~少了很多以前在DX9下的元素。比如,光照Q材质等?br>         要实现这些元素,必dSHADER下手动去实现Q那意味着你必ȝ(zhn)图形学的内容,特别是其中的光照模型{内宏V?br>比如Q方向光的实玎ͼ<br>    //directional light-----------------------------------------------------------------<br>    float3 lightDir = g_lightPos - In.worldPos;<br>    float3 lightDirNorm = normalize(lightDir);<br>    float3 SDir = normalize( g_lightPos - g_eyePos);<br>    float cosGammaDir = dot(SDir, V);<br>    float dirLighting = g_Kd*dirLightIntensity*saturate( dot( N,lightDirNorm ) );<br>    //diffuse<br>    float3 diffuseDirLight = dirLighting*exDir;        <br>    //airlight<br>    float3 dirAirLight = phaseFunctionSchlick(cosGammaDir)* dirLightIntensity*float3(1-exDir.x,1-exDir.y,1-exDir.z);<br>    //specular<br>    float3 specularDirLight = saturate( pow(  dot(lightDirNorm,reflVect),g_specPower)) * dirLightIntensity * g_KsDir * exDir;<br>点光源的实现Q?br>  //point light 1---------------------------------------------------------------------<br>    //diffuse surface radiance and airlight due to point light<br>    float3 pointLightDir = g_PointLightPos - In.worldPos;<br>    //diffuse<br>    float3 diffusePointLight1 = calculateDiffusePointLight(0.1,Dvp,g_DSVPointLight,pointLightDir,N,V);<br>    //airlight<br>    float3 airlight1 = calculateAirLightPointLight(Dvp,g_DSVPointLight,g_VecPointLightEye,V);<br>    //specular<br>    float3 specularPointLight = Specular(g_PointLightIntensity, g_KsPoint, length(pointLightDir), Dvp, g_specPower, normalize(pointLightDir), reflVect);<br>计算点光源的漫射光:<br>float3 calculateDiffusePointLight(float Kd,float Dvp,float Dsv,float3 pointLightDir,float3 N,float3 V)<br>{</p> <p>    float Dsp = length(pointLightDir);<br>    float3 L = pointLightDir/Dsp;<br>    float thetas = acos(dot(N, L));<br>    float lightIntensity = g_PointLightIntensity * 100;<br>    <br>    //spotlight<br>    float angleToSpotLight = dot(-L, g_SpotLightDir);<br>    if(g_useSpotLight)<br>    {    if(angleToSpotLight > g_cosSpotlightAngle)<br>             lightIntensity *= abs((angleToSpotLight - g_cosSpotlightAngle)/(1-g_cosSpotlightAngle));<br>         else<br>             lightIntensity = 0;         <br>    }   <br>    <br>    //diffuse contribution<br>    float t1 = exp(-g_beta.x*Dsp)*max(cos(thetas),0)/Dsp;<br>    float4 t2 = g_beta.x*Gtable.SampleLevel(samLinearClamp, float2((g_beta.x*Dsp-g_diffXOffset)*g_diffXScale, (thetas-g_diffYOffset)*g_diffYScale),0)/(2*PI);<br>    float rCol = (t1+t2.x)*exp(-g_beta.x*Dvp)*Kd*lightIntensity/Dsp;<br>    float diffusePointLight = float3(rCol,rCol,rCol);  <br>    return diffusePointLight.xxx;<br>}<br>计算高光Q?br>float3 Specular(float lightIntensity, float Ks, float Dsp, float Dvp, float specPow, float3 L, float3 VReflect)<br>{<br>    lightIntensity = lightIntensity * 100;<br>    float LDotVReflect = dot(L,VReflect);<br>    float thetas = acos(LDotVReflect);</p> <p>    float t1 = exp(-g_beta*Dsp)*pow(max(LDotVReflect,0),specPow)/Dsp;<br>    float4 t2 = g_beta.x*G_20table.SampleLevel(samLinearClamp, float2((g_beta.x*Dsp-g_20XOffset)*g_20XScale, (thetas-g_20YOffset)*g_20YScale),0)/(2*PI);<br>    float specular = (t1+t2.x)*exp(-g_beta.x*Dvp)*Ks*lightIntensity/Dsp;<br>    return specular.xxx;<br>}<br>下一步,考虑如何不通过DX9接口Q直接导入X文g?/p> <img src ="http://www.shnenglu.com/bloodbao/aggbug/56387.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/bloodbao/" target="_blank">bloodbao</a> 2008-07-17 10:26 <a href="http://www.shnenglu.com/bloodbao/archive/2008/07/17/56387.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习(fn)光线q踪http://www.shnenglu.com/bloodbao/archive/2008/07/06/55457.htmlbloodbaobloodbaoSun, 06 Jul 2008 02:53:00 GMThttp://www.shnenglu.com/bloodbao/archive/2008/07/06/55457.htmlhttp://www.shnenglu.com/bloodbao/comments/55457.htmlhttp://www.shnenglu.com/bloodbao/archive/2008/07/06/55457.html#Feedback0http://www.shnenglu.com/bloodbao/comments/commentRss/55457.htmlhttp://www.shnenglu.com/bloodbao/services/trackbacks/55457.html                           学习(fn)光线q踪Q格式都׃Q郁P
线cȝ定义Q?br>class Ray
{
   public:
 Ray() : m_Origin( vector3( 0, 0, 0 ) ), m_Direction( vector3( 0, 0, 0 ) ) {};
 Ray( vector3& a_Origin, vector3& a_Dir );
   private:
 vector3 m_Origin;
 vector3 m_Direction;
};
光线q踪法Q?br>For each pixel
{
 Construct ray from camera through pixel
 Find first primitive hit by ray
 Determine color at intersection point
 Draw color

求最q交?br> // find the nearest intersection
for ( int s = 0; s < m_Scene->GetNrPrimitives(); s++ )
{
 Primitive* pr = m_Scene->GetPrimitive( s );
 int res;
 if (res = pr->Intersect( a_Ray, a_Dist ))
 {
  prim = pr;
  result = res; // 0 = miss, 1 = hit, -1 = hit from inside primitive
 }
}
交点的颜Ԍ
// determine color at point of intersection
pi = a_Ray.GetOrigin() + a_Ray.GetDirection() * a_Dist;
// trace lights
for ( int l = 0; l < m_Scene->GetNrPrimitives(); l++ )
{
 Primitive* p = m_Scene->GetPrimitive( l );
 if (p->IsLight())
 {
  Primitive* light = p;
  // calculate diffuse shading
  vector3 L = ((Sphere*)light)->GetCentre() - pi;
  NORMALIZE( L );
  vector3 N = prim->GetNormal( pi );
  if (prim->GetMaterial()->GetDiffuse() > 0)
  {
   float dot = DOT( N, L );
   if (dot > 0)
   {
    float diff = dot * prim->GetMaterial()->GetDiffuse();
    // add diffuse component to ray color
    a_Acc += diff * prim->GetMaterial()->GetColor() * light->GetMaterial()->GetColor();
   }
  }
 }
}
计算反射Q?br>// calculate reflection
float refl = prim->GetMaterial()->GetReflection();
if (refl > 0.0f)
{
 vector3 N = prim->GetNormal( pi );
 vector3 R = a_Ray.GetDirection() - 2.0f * DOT( a_Ray.GetDirection(), N ) * N;
 if (a_Depth < TRACEDEPTH)
 {
  Color rcol( 0, 0, 0 );
  float dist;
  Raytrace( Ray( pi + R * EPSILON, R ), rcol, a_Depth + 1, a_RIndex, dist );
  a_Acc += refl * rcol * prim->GetMaterial()->GetColor();
 }
}
Phong光照公式Qintensity = diffuse * (L.N) + specular * (V.R)n

vector3 V = a_Ray.GetDirection();
vector3 R = L - 2.0f * DOT( L, N ) * N;
float dot = DOT( V, R );
if (dot > 0)
{
 float spec = powf( dot, 20 ) * prim->GetMaterial()->GetSpecular() * shade;
// add specular component to ray color
a_Acc += spec * light->GetMaterial()->GetColor();
}
计算阴媄
// handle point light source
float shade = 1.0f;
if (light->GetType() == Primitive::SPHERE)
{
 vector3 L = ((Sphere*)light)->GetCentre() - pi;
 float tdist = LENGTH( L );
 L *= (1.0f / tdist);
 Ray r = Ray( pi + L * EPSILON, L );
 for ( int s = 0; s < m_Scene->GetNrPrimitives(); s++ )
 {
  Primitive* pr = m_Scene->GetPrimitive( s );
  if ((pr != light) && (pr->Intersect( r, tdist )))
  {
   shade = 0;
   break;
  }
 }
}



bloodbao 2008-07-06 10:53 发表评论
]]>
我名字的由来http://www.shnenglu.com/bloodbao/archive/2008/06/29/54909.htmlbloodbaobloodbaoSun, 29 Jun 2008 09:42:00 GMThttp://www.shnenglu.com/bloodbao/archive/2008/06/29/54909.htmlhttp://www.shnenglu.com/bloodbao/comments/54909.htmlhttp://www.shnenglu.com/bloodbao/archive/2008/06/29/54909.html#Feedback3http://www.shnenglu.com/bloodbao/comments/commentRss/54909.htmlhttp://www.shnenglu.com/bloodbao/services/trackbacks/54909.htmlBlizzard=暴雪
Bloodbao=血?雪v-----------------刚好和暴雪的音相反!
沉迷于游戏,沉迷于游戏编E,Bloodbao正在逐渐成长?br>特记录,以作怀念!


bloodbao 2008-06-29 17:42 发表评论
]]>
3DEditorhttp://www.shnenglu.com/bloodbao/archive/2008/06/17/53706.htmlbloodbaobloodbaoTue, 17 Jun 2008 07:27:00 GMThttp://www.shnenglu.com/bloodbao/archive/2008/06/17/53706.htmlhttp://www.shnenglu.com/bloodbao/comments/53706.htmlhttp://www.shnenglu.com/bloodbao/archive/2008/06/17/53706.html#Feedback0http://www.shnenglu.com/bloodbao/comments/commentRss/53706.htmlhttp://www.shnenglu.com/bloodbao/services/trackbacks/53706.html我做的第二个~辑器,是基于OPENGL+WXWIDGETS的,本来x囄的?br>但昨天看了群里AZ的设计界面,深感作品的不成熟Q所以对界面开始重新编写?/p> q个~辑器,用来做地形的Q参考了很多人的作品Q希望最l不要成为四不象Q?br>l箋努力中。。。?br>MARK!

bloodbao 2008-06-17 15:27 发表评论
]]>
IRR的效果图http://www.shnenglu.com/bloodbao/archive/2008/06/05/52224.htmlbloodbaobloodbaoThu, 05 Jun 2008 02:33:00 GMThttp://www.shnenglu.com/bloodbao/archive/2008/06/05/52224.htmlhttp://www.shnenglu.com/bloodbao/comments/52224.htmlhttp://www.shnenglu.com/bloodbao/archive/2008/06/05/52224.html#Feedback3http://www.shnenglu.com/bloodbao/comments/commentRss/52224.htmlhttp://www.shnenglu.com/bloodbao/services/trackbacks/52224.htmll箋学习(fn)?

 



bloodbao 2008-06-05 10:33 发表评论
]]>
转随风对BSP的分析(原文有图Q?/title><link>http://www.shnenglu.com/bloodbao/archive/2008/05/30/51631.html</link><dc:creator>bloodbao</dc:creator><author>bloodbao</author><pubDate>Fri, 30 May 2008 12:11:00 GMT</pubDate><guid>http://www.shnenglu.com/bloodbao/archive/2008/05/30/51631.html</guid><wfw:comment>http://www.shnenglu.com/bloodbao/comments/51631.html</wfw:comment><comments>http://www.shnenglu.com/bloodbao/archive/2008/05/30/51631.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/bloodbao/comments/commentRss/51631.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/bloodbao/services/trackbacks/51631.html</trackback:ping><description><![CDATA[<p>BSP技术详?</p> <p>eXtreme3D</p> <p>译自一老外的文?lt;Binary Space Partioning Trees and Polygon Removal in Real Time 3D Rendering>,最后一Ҏ(gu)有翻译完,呵呵,不太好意?!!!!<br>BSP技术作为室内引擎渲染的L技术虽然已l存在多q?但是生命力仍焉帔R?最新的DOOM3,HL2仍然它作ؓ渲染的主技?但是在网上对它介l文章虽然多却非常浅?大多是用Q3的BSP文gq行渲染,而BSP文g如何产生则介l非常少,盖因一部分是场景编辑器的工?而完成一个这L(fng)BSP~辑器是非常困难?需要掌握的知识非常?下面我将对BSP~辑器这一部分需要用到的BSP知识q行一下介l?q只是一些很初步的知?如希望了解更多的内容,Q2开源代码中有一个BSP~辑器的代码是你研究的重?q有是HL2泄露代码中的~辑器代?(一个痛苦的研究q程,可能要花费你几个月甚至一q的旉,不过q是值得?如果你想完成一个主的击游戏引擎的话,没有BSP~辑器是不可惌?.</p> <p><br>W一?BSP Trees<br>BSP Trees英文全称为Binary Space Partioning treesQ二l空间分割树(wi)Q简UCؓ二叉?wi)。它?969q被Shumacker在文章《Study for Applying Computer-Generated Images to Visual Simulation》首ơ提出,q被ID公司W一ơ用到FPS游戏Doom中,Doom的推得了I前的成功,不仅奠定了ID公司在FPS游戏开发的宗师CQ也使BSP技术成为室内渲染的工业标准Q从BSP产生到现在已l有30多年了,光虽然产生了大量的室内渲染的算法,但却无h能撼动它的地位,对于以摩?dng)定律发展的计算Z来说q不能不是一个奇qV?br>Z么用BSP Trees<br>一个BSP Trees如同它的名字一h一个层ơ树(wi)的结构,q个?wi)的叶节点保存了分割室内I间所得到的图元集合。现在随着g加速Z~冲的出玎ͼ我们只需要用很小的代价就可以对空间中的图元进行排序,但是?0q代初由于硬件的限制Q用BSP的主要原因是因ؓ它可以对I间中的囑օq行排序来保证渲染图元的序是按照由后至前进行的Q换句话_Z值最的物体L最后被渲染。当然还有其他的法可以完成q个功能Q例如著名的d法Q但是它与BSP比较h速度太慢了,q是因ؓBSP通常对图元排序是预先计算好的而不是在q行时进行计。从某种意义上说BSP技术实际上是画家算法的扩展Q正如同BSP技术的原始设计一Pd法也是使用由后臛_的顺序对场景中的物体q行渲染。但是画家算法有以下的缺点:<br>l 如果一个物体从另一个物体中I过时它不能被正的渲染Q?br>l 在每一帧对被渲染的物体q行排序是非常困隄Q同时运的代h(hun)非常大;<br>l 它无法管理@环覆盖的情况Q如图所C?</p> <p>          ?.1<br>BSP原理<br>建立BSP Trees的最初想法是获得一个图元的集合Q这个集合是场景的一部分Q然后分割这个图元集合ؓ更小的子集合Q这里必L意子集合必须?#8220;凸多边Ş”。这意味着子集合中M个多边Ş都位于相同集合中其它多边形的“前面”。是不是有点难以理解呢,举一个例子,如果多边形A的每一个顶炚w位于由多边ŞB所l成的一个面的正面,那么可以说多边ŞA位于多边形B?#8220;前面”Q参考左图。我们可以想象一下,一个盒子是?个面l成的,如果所有的面都朝向盒子的内部,那么我们可以说盒子是一?#8220;凸多边Ş”Q如果不是都朝向盒子的内部,那么盒子׃?#8220;凸多边Ş”?nbsp;                                               </p> <p>?.2<br>下面让我们看一下如何确定一个图元集合是否是一?#8220;凸多边Ş”Q伪法如下Q?br>l 函数CLASSIFY-POINT<br>l 参数:<br>l Polygon – 定一?DI间中点相对位置的参考多边Ş?br>l Point – 待确定的3DI间中的炏V?br>l q回?<br>l 点位于多边Ş的哪一辏V?br>l 功能:<br>l 定一个点位于被多边Ş定义的面的哪一辏V?br>CLASSIFY-POINT (Polygon, Point)<br>1 Sidevalue = Polygon.Normal * Point<br>2 if (Sidevalue == Polygon.Distance)<br>3 then return COINCIDING<br>4 else if (Sidevalue < Polygon.Distance)<br>5 then return BEHIND<br>6 else return INFRONT<br>l 函数 POLYGON-INFRONT<br>l 参数:<br>l Polygon1 – 用来定其它多边形是否在?#8220;前面”的多边Ş?br>l Polygon2 – 是否在W一个多边Ş“前面”的多边Ş?br>l q回?<br>l W二个多边Ş是否在第一个多边Ş?#8220;前面”?br>l 功能:<br>l 第二个多边形的每一个顶Ҏ(gu)否在W一个多边Ş?#8220;前面”?br>POLYGON-INFRONT (Polygon1, Polygon2)<br>1 for each point p in Polygon2<br>2 if (CLASSIFY-POINT (Polygon1, p) <> INFRONT)<br>3 then return false<br>4 return true<br>l 函数 IS-CONVEX-SET<br>l 参数:<br>l PolygonSet – 用来是否ؓ“凸多边Ş”的图元集合?br>l q回?<br>l 集合是否?#8220;凸多边Ş”?br>l 功能:<br>l 相对于集合中的其它多边Ş查每一个多边ŞQ看是否位于其它多边形的“前面”Q如果有L两个多边形不满q个规则Q那么这个集合不?#8220;凸多边Ş”?br>IS-CONVEX-SET (PolygonSet)<br>1 for i = 0 to PolygonSet.Length ()<br>2 for j = 0 to PolygonSet.Length ()<br>3 if(i != j && not POLYGON-INFRONT(PolygonSet, PolygonSet[j]))<br>4 then return false<br>5 return true</p> <p>在函数POLYGON-INFRONT中ƈ没有q行对称的比较,q意味着如果多边形A位于多边形B?#8220;前面”你ƈ不能惛_然的认ؓ多边形B一定位于多边ŞB?#8220;前面”。下面的例子单的昄了这一炏V?br>      <br>                ?.3<br>在图1.3中我们可以看到多边Ş1位于多边??#8220;前面”Q这是因为顶点p3、p4位于多边??#8220;前面”Q而多边Ş2却没有位于多边Ş1?#8220;前面”Q因为顶点p2位于多边??#8220;后面”?br>对于一个BSP层次?wi)来说可以用下面l构来定义:<br>class BSPTree<br>{<br>BSPTreeNode RootNode // ?wi)的根节?br>}<br>class BSPTreeNode<br>{<br>BSPTree Tree // 接点所属的层次?br>BSPTreePolygon Divider // 位于两个子树(wi)之间的多边Ş<br>BSPTreeNode *RightChild // 节点的右子树(wi)<br>BSPTreeNode *LeftChild // 节点的左子树(wi)<br>BSPTreePolygon PolygonSet[] // 节点中的多边形集?br>}<br>class BSPTreePolygon<br>{<br>3DVector Point1 // 多边形的点1<br>3DVector Point3 // 多边形的点2<br>3DVector Point3 // 多边形的点3<br>}<br>现在你可以看见每一个多边Ş?个顶Ҏ(gu)定义Q这是因为硬件加速卡使用三角形来对多边Şq行渲染。将多边形集合分割ؓ更小的子集合有很多方法,例如你可以Q意选择I间中的一个面然后用它来对I间中的多边形进行分Ԍ把位于分割面正面的多边Ş保存到右子树(wi)中而位于反面的多边形保存到左子?wi)中。用这个方法的~点非常明显Q那是如果想选择一个将I间中的多边形分割ؓ两个相等的子集合的面非常困难Q这是因为在场景中有无数个可选择的面。如何在集合中选择一个最佳的分割面呢Q下面我对q个问题l出一个比较适当的解x案?br>我们现在已经有了一个函数POLYGON-INFRONTQ它的功能是定一个多边Ş是否位于其它多边形的正面。现在我们要做的是修改这个函敎ͼ使它也能够确定一个多边Ş是否横跨q其它多边Ş定义的分割面。算法如下:<br>l 函数 CALCULATE-SIDE<br>l 参数 :<br>l Polygon1 – 定其它多边形相对位|的多边形?br>l Polygon2 – 定相对位置的多边Ş?br>l q回?<br>l 多边?位于多边?的哪一?br>l 功能:<br>l 通过W一个多边Ş对第二个多边形上的每一个顶点进行检。如果所有的点位于W二个多边Ş的正面,那么多边?被认Z于多边Ş1?#8220;前面”。如果第二个多边形的所有顶炚w位于W一个多边Ş的反面,那么多边?被认Z于多边Ş1?#8220;后面”。如果第二个多边形的所有顶点位于第一个多边Ş之上Q那么多边Ş2被认Z于多边Ş1的内部。最后一U可能是所有的点即位于正面有位于反面Q那么多边Ş2被认为横跨过多边??br>CALCULATE-SIDE (Polygon1, Polygon2)<br>1 NumPositive = 0, NumNegative = 0<br>2 for each point p in Polygon2<br>3 if (CLASSIFY-POINT (Polygon1, p) = INFRONT)<br>4 then NumPositive = NumPositive + 1<br>5 if (CLASSIFY-POINT (Polygon1, p) = BEHIND)<br>6 then NumNegative = NumNegative + 1<br>7 if (NumPositive > 0 && NumNegative = 0)<br>8 then return INFRONT<br>9 else if(NumPositive = 0 && NumNegative > 0)<br>10 then return BEHIND<br>11 else if(NumPositive = 0 && NumNegative = 0)<br>12 then return COINCIDING<br>13 else return SPANNING<br>上面的算法也l我们解{了一个问题,当一个多边Ş横跨q分割面时如何进行处理,上面的算法中多边Ş分割Z个多边ŞQ这样就解决了画家算法中的两个问题:循环覆盖和多边Ş怺。下面的囑Ş昄了多边Ş如何q行分割的?br>            </p> <p>?.4<br>如图1.4所C,多边?为分割面Q而多边Ş2横跨q多边Ş1Q如囑֏Ҏ(gu)C,多边形被分割??两部分,多边?位于分割面的“前面”而多边Ş3位于分割面的“后面”?br>当徏立一个BSP?wi)时Q首先需要确定的问题是如何保证二叉树(wi)的^衡,q意味着对于每一个叶节点的分割深度而言不能有太大的差异Q同时每一个节点的左、右子树(wi)需要限制分割的ơ数。这是因为每一ơ的分割都会产生新的多边形,如果在徏立BSP?wi)时产生太多的多边Ş的话Q在囑Ş加速卡对场景渲染时会加重渲染器的负担,从而降低速。同时一个不q的二叉树(wi)在进行遍历时会耗费许多无谓的时间。因此我们需要确定一个合理的分割ơ数以便于获得一个较为^衡的二叉?wi),同时可以减少新多边Ş的生。下面的代码昄了如何通过循环多边形集合来获得最佳的分割多边形?br>l 函数 CHOOSE-DIVIDING-POLYGON<br>l 参数:<br>l PolygonSet – 用于查找最?jng)_割面的多边Ş集合?br>l q回?<br>l 最佳的分割多边形?br>l 功能:<br>l Ҏ(gu)定的多边形集合进行搜索,q回其分割为最?jng)_集合的多边Ş。如果指定的集合是一?#8220;凸多边Ş”则返回?br>CHOOSE-DIVIDING-POLYGON (PolygonSet)<br>1 if (IS-CONVEX-SET (PolygonSet))<br>2 then return NOPOLYGON<br>3 MinRelation = MINIMUMRELATION<br>4 BestPolygon = NOPOLYGON<br>5 LeastSplits = INFINITY<br>6 BestRelation = 0<br>l 循环查找集合的最?jng)_割面?br>7 while(BestPolygon = NOPOLYGON)<br>8 for each 多边形P1 in PolygonSet<br>9 if (多边形P1在二叉树(wi)建立q程中没有作为分割面)<br>l 计算被当前多边Ş定义的分割面的正面、反面和横跨q分割面的多边Ş的数量?br>10 NumPositive = 0, NumNegative = 0, NumSpanning = 0<br>11 for each 多边形P2 in PolygonSet except P1<br>12 value = CALCULATE-SIDE(P1, P2)<br>13 if(value = INFRONT)<br>14 NumPositive = NumPositive + 1<br>15 else if(value = BEHIND)<br>16 NumNegative = NumNegative + 1<br>17 else if(value = SPANNING)<br>18 NumSpanning = NumSpanning + 1<br>l 计算被当前多边Ş分割的两个子集合的多边Ş数量的比倹{?br>19 if (NumPositive < NumNegative)<br>20 Relation = NumPositive / NumNegative<br>21 else<br>22 Relation = NumNegative / NumPositive<br>l 比较由当前多边Ş获得的结果。如果当前多边Ş分割了较?yu)的多边形同时分割后的子集合比值可以接受的话,那么保存当前的多边Ş为新的候选分割面?br>l 如果当前多边形和最?jng)_割面一样分割了相同数量的多边Ş而分割后的子集合比值更大的话,当前多边Ş作ؓ新的候选分割面?br>23 if (Relation > MinRelation &&<br>(NumSpanning < LeastSplits ||<br>(NumSpanning = LeastSplits &&<br>Relation > BestRelation))<br>24 BestPolygon = P1<br>25 LeastSplits = NumSpanning<br>26 BestRelation = Relation<br>l 通过除以一个预先定义的帔R来减可接受的最比倹{?br>27 MinRelation = MinRelation / MINRELATIONSCALE<br>28 return BestPolygon<br>法分析<br>对于上面的函数来_Ҏ(gu)场景数据大小的不同它可能p很长一D|间。常量MINRELATIONSCALE用来定在每ơ@环时所分割的子集合多边形数量的比值每ơ减多,Z么要使用q个帔R呢,考虑一下,对于l定的MinRelation如果我们找不到最佳的分割面,通过除以q个帔R比值减来重新q行循环查找Q这样可以防止死循环的出玎ͼ因此当这个比D够小时我们必定可以获得可接受的最佳结果。最坏的事情是我们有一个包含N个多边Ş的非“?#8221;集合Q分割多边Ş集合分割ؓ一个包含N-1个多边Ş的部分和一个包?个多边Ş的部分。这个结果只有在最比值小?/(n-1)才是可以接受的(参考算法的19-23行)。这意味着MinRelation /MINRELATIONSCALEi < 1/(n-1)Q这里i是@环重复的ơ数。让我们假设MinRelation的初始化gؓ1Q由于比值永qؓ0-1之间的值因此这是最可能的|参考算法的19-22行)。我们有<br>1 / MINRELATIONSCALEi < 1/(n-1)<br>1 < MINRELATIONSCALEi/(n-1)<br>(n-1) < MINRELATIONSCALEi<br>logMINRELATIONSCALE (n-1) < i<br>q里的i没有上边界,但是因ؓi非常接近于logMINRELATIONSCALE (n-1)Q我们可以简单的假设两者是相等的。另外我们也假设MINRELATIONSCALE永远大于或等?Q因此我们可以有<br>logMINRELATIONSCALE (n-1) = i <br>MINRELATIONSCALE >= 2<br>i = logMINRELATIONSCALE (n-1) < lg(n-1) = O(lg n)<br>在@环的内部Q对多边形的集合需要重复进行两ơ@环,因此Ҏ(gu)们来说最坏的情况下这个算法的复杂度ؓO(n2lg n)Q而通常情况下这个算法的复杂度接q于O(n2)?br>在函数CHOOSE-DIVIDING-POLYGON的@环中看v来如果不发生什么事情的话好象永q不会停止,但是q不会发生,q是因ؓ如果多边形集合ؓ?#8220;?#8221;集合的话总能扑ֈ一个多边Ş来把集合分割Z个子集合。CHOOSE-DIVIDING-POLYGON函数L选择分割集合的多边Ş数量最的多边形,Z防止选择q不分割集合的多边ŞQ分割后的子集合的多边Ş数量之比必须大于预先定义的倹{ؓ了更好的理解我上面所讲解的内容,下面我将举一个例子来说明如何选择一个多边Ş对一个很数量多边Ş的集合进行分剌Ӏ?/p> <p>      ?.5<br>在上面的例子中无Z选择多边???q是多边?q行渲染旉不会分割M其它的多边ŞQ换句话说也是所有的其它多边形都位于q些多边形的“正面”?br>关于分割旉择产生多边形最的分割面另外一个不太好的原因是大多数时候它所产生的层ơ树(wi)通常是不q的,而一个^衡的层次?wi)在q行的时候通常比不q的层ơ树(wi)性能更好?br>当获得最佳的分割面后伴随着必然产生一些被分割的多边ŞQ如何对被分割的多边形进行处理呢Q这里有两个Ҏ(gu)Q?br>1. 建立一个带叶节点的二叉?wi),q意味着每一个多边Ş被攑֜叶节点中Q因此每一个被分割的多边Ş也将被分开攑֜二叉?wi)的一辏V?br>2. 另外一个方法是被分割的多边Ş保存到公p点中Q对每一个子?wi)重复这个过E直到每一个叶节点都包含了一?#8220;?#8221;多边形集合ؓ止?br>产生带叶节点的BSP?wi)的法如下Q?br>l 函数GENERATE-BSP-TREE<br>l 参数:<br>l Node – Ʋ徏立的cd为BSPTreeNode的子?wi)?br>l PolygonSet – 建立BSP-tree的多边Ş集合?br>l q回?<br>l 保存到输入的父节点中的BSP-tree?br>l 功能:<br>l 对一个多边Ş集合产生一个BSP-tree?br>GENERATE-BSP-TREE (Node, PolygonSet)<br>1 if (IS-CONVEX-SET (PolygonSet))<br>2 Tree = BSPTreeNode (PolygonSet)<br>3 Divider = CHOOSE-DIVIDING-POLYGON (PolygonSet)<br>4 PositiveSet = {}<br>5 NegativeSet = {}<br>6 for each polygon P1 in PolygonSet<br>7 value = CALCULATE-SIDE (Divider, P1)<br>8 if(value = INFRONT)<br>9 PositiveSet = PositiveSet U P1<br>10 else if (value = BEHIND)<br>11 NegativeSet = NegativeSet U P1<br>12 else if (value = SPANNING)<br>13 Split_Polygon10 (P1, Divider, Front, Back)<br>14 PositiveSet = PositiveSet U Front<br>15 NegativeSet = NegativeSet U Back<br>16 GENERATE-BSP-TREE (Tree.RightChild, PositiveSet)<br>17 GENERATE-BSP-TREE (Tree.LeftChild, NegativeSet)<br>法分析<br>函数CHOOSE-DIVIDING-POLYGON的时间复杂度为O(n2 lg n)Q除非出现递归调用否则它将控制其它的函敎ͼ如果我们假设对多边Ş集合的分割是比较公^的话Q那么我们可以通过公式来对函数GENERATE-BSP-TREE的复杂度q行表达Q?br>T(n) = 2T(n/2) + O(n2 lg n)<br>通过公式我们可以知道q个函数的复杂度为Q (n2 lg n)。这里n入的多边形集合的多边形数量?br>下面我要用一个例子来演示如何产生一个BSP-tree。下面的l构是一个多边Ş的原始集合,Z表示方便Ҏ(gu)一个多边Ş都进行了~号Q这个多边Ş集合被分割Z个BSP-tree?/p> <p><br>            ?.6<br>Z能够q行q个法我们必须对常量MINIMUMRELATION和MINRELATIONSCALEq行赋|在实际运行中我们发现当MINIMUMRELATION=0.8而MINRELATIONSCALE=2时可以获得比较好的结果。但是你也可以对q些数D行试验来比较一下,通常当常数MINIMUMRELATION比较大时获得的层ơ树(wi)会比较^衡但同时分割产生的多边Ş也会大量增加。在上图昄的多边Ş集合q不是一?#8220;?#8221;的,因此首先我们需要选择一个合适的分割面。在快速的对上面的l构q行一下浏览后我们可以知道多边形(1???2?8Q不能被用来作ؓ分割面,q是因ؓ它们定义了包含所有多边Ş集合的外形。但是其它的多边形都可以作ؓ候选的分割面。分割生的多边形最同时分割ؓ两个子集合的多边形数目之比ؓ最佳的多边形是16?7Q它们位于同一条直U上同时q不会分割Q何的多边形。而分割后的子集合的多边Ş数目也是一L(fng)Q都?#8220;正面”?3?#8220;反面”?5。让我们选择多边?6作ؓ分割面,那么分割后的的结构如下:<br>                        </p> <p>?.7<br>现在从图1.7我们可以看到无论是左子树(wi)q是叛_?wi)都没有包?#8220;?#8221;多边形集合,因此需要对两个子树(wi)l箋q行分割?br>在左子树(wi)中多边Ş1???作ؓ多边形集合的“凸边”不能用做分割面,而多边Ş4?0在同一条直U上同时没有分割M多边形,而分割后的多边Ş子集合:“正面”??#8220;反面”?非常的^衡,我们选择多边?为分割面?br>在右子树(wi)中多边Ş16?7?2?3?8不能作ؓ分割面,而多边Ş18?9?6?7虽然没有分割M多边形但是分割后的多边Ş子集合:“正面”?1?#8220;反面”?Q?/11q个比值小于最比?.5因此我们需要寻扑օ它更适合的多边Ş。多边Ş20?1?4?5都只分割了一个多边ŞQ但是多边Ş21看v来分割后的结果更合理Q在分割q多边Ş22后多边Ş子集合的l果为:“正面”??#8220;反面”??br>下图昄了操作后的结果:</p> <p><br>                ?.8<br>在图中每一个子集合q不是一?#8220;?#8221;集合Q因此需要l进行分Ԍ按照上面的法则对?.8所C的l构q行分割后,l果如下Q?br>                      </p> <p>?.9<br>上图昄了最后的l果Q这可能不是最优的l果但是我们对它q行处理所p的时间ƈ不太ѝ?br>渲染BSP<br>现在我们已经建立好一个BSP?wi)了Q可以很Ҏ(gu)Ҏ(gu)(wi)中的多边形进行正的渲染Q而不会生Q何错误。下面的法描述了如何对它进行渲染,q里我们假设函数IS-LEAF的功能ؓl定一个BSP节点如果为叶节点q回真否则返回假?br>函数DRAW-BSP-TREE<br>参数:<br>l Node – 被渲染的节点?br>l Position – 摄象机的位置?br>l q回?<br>l None<br>l 功能:<br>l 渲染包含在节点及其子?wi)中的多边Ş?br>DRAW-BSP-TREE (Node, Position)<br>1 if (IS-LEAF(Node))<br>2 DRAW-POLYGONS (Node.PolygonSet)<br>3 return</p> <p>l 计算摄象机包含在哪一个子?wi)中?br>4 Side = CLASSIFY-POINT (Node.Divider, Position)<br>l 如果摄象机包含在叛_?wi)中先渲染右子?wi)再渲染左子树(wi)?br>5 if (Side = INFRONT || Side = COINCIDING)<br>6 DRAW-BSP-TREE (Node.RightChild, Position)<br>7 DRAW-BSP-TREE (Node.LeftChild, Position)</p> <p>l 否则先渲染左子树(wi)?br>8 else if(value = BEHIND)<br>9 DRAW-BSP-TREE (Node.LeftChild, Position)<br>10 DRAW-BSP-TREE (Node.RightChild, Position)<br>用这个方法进行渲染ƈ没有减少渲染到屏q上的多边Ş数量Q由于一个场景可能包含成百上千个多边形因此这个方法ƈ不是很好的解x案。通常情况下有大量的节点和多边形ƈ没有处于摄象机的视野范围之内Q它们ƈ不需要被渲染到屏q上Q如何查找这些不可见的节点和多边形防止它们渲染到屏幕上呢Q隐藏面剔除是Z解决q个问题而提ZҎ(gu)术,在下一节中我们对q项技术进行详l的阐述?br>BSP技术详?</p> <p>eXtreme3D</p> <p><br>W二?隐藏面剔?br>    对不可见物体q行剔除是游戏行业ؓ了满x高画面渲染速度的要求而生的一Ҏ(gu)术,是在硬件加速技术飞跃发展的今天Q虽然现在已l可以完成许多在q去被认为是不可能实现的工作Q但是对于隐藏面q行剔除仍是加速图形渲染的一w要技术。通常当一个游戏运行的时候,它最需要以每秒30帧的速度q行。在几年前这意味着如果每一帧你渲染的带U理的多边Ş数量过5000个就被认为是不可接受的,而现在几乎所有的商业昑֍每一U都可以渲染几千万个多边形。可是现在仍焉要用隐藏面剔除q项技术,q是Z么呢Q显而易见,对不可见物体渲染以后会被可见物体遮挡住Q这样做无谓的浪费了昑֍的带宽,但是同时它也增加了场景的l节Q游戏画面看v来更加吸引h。现在的问题是多大程度上来剔除隐藏的多边形,象view frustum culling和portal渲染q样的技术来剔除一个不可见多边形是非常耗费旉的,用来dq些计算的CPU旉可以用来完成其它诸如AI或碰撞检这L(fng)工作Q因此开发一个隐藏面剔除法必须注意到这一炏V对于现在的游戏来说几乎没有一个是每一个隐藏的多边形都q行剔除Q而是剔除一个多边Ş的集合如一个节Ҏ(gu)一个物体等{。对于一个单独的多边形它q不q行剔除Q因此一个正的隐藏面剔除方案是允许一定的重复渲染来适当的减计量?br>    当徏立一个FPS游戏时进行隐藏面剔除最通常的方法是使用portal渲染。这Ҏ(gu)术可以非常充分的利用BSP的优点,但是h意portal技术ƈ不仅仅只能用于BSP中。Portal技术还可以用来产生一些特效如镜子和监视器{等?br>Portal渲染<br>在这里我介l一下portal技术的原理Q通常对于一个室内场景来说它可以被描qCؓ׃个个“z口”怺q接?#8220;戉K”l成Q这?#8220;z口”被称为portal?#8220;戉K”被称为sectorQ通常sector被定义ؓ一?#8220;?#8221;?#8220;闭合”的多边Ş集合Q定义中?#8220;?#8221;阅读q前面的内容你应当已l能很好的理解了Q?#8220;闭合”是什么意思呢Q它意味着在sector内部Lq接两个点做一条线D,q条U段不会和其它的多边形相交。换句话说如果你惛_sector内部LM条线D通到sector的外部必定与l成sector的多边Ş怺。这也意味着q接每一个sector?#8220;z口”必须被一个组成portal的多边Ş所填充Q而对于放|portal多边形来说你既可以手工放|也可以q序自动生,在我讲解q项技术之前我必须提醒一下,׃g加速Z~冲的出现对sector必须?#8220;?#8221;的限制已l消除,因此有许多游戏引擎已l不再遵守这个标准,但是在这里我q是要对q去的方法进行一下介l?br>一个portal引擎的基本方法是当你通过一个指定观察位|的可视qx体(view frustumQ进行渲染时Q如果一个portal出现在可视范围内Q那么portal对可视qx体进行剪切,q样与其相连的sector会通过一个观察位|相同但已经改变q的可视qx体进行渲染。这是一个非常简单而且非常适合q行递归调用的方法,׃可视qx体被portalq行了精的限制Q因此被隐藏的物体可以很单进行剔除。下面的例图昄了一个portal引擎中的可视qx体是如何被剪切的?br>                <br>?.10<br>在图6.10中观察者的位置位于VQ而初始的可视qx体ؓF1Q当它通过一个portal多边形P1后被P1剪切产生新的可视qx体F2Q接着当它通过portal多边形P2、P3后F2被剪切ؓF3、F4Q而F3通过P4后被剪切为F5而F4被剪切ؓF6。观察这个过E我们可以发现portal技术非帔R合q行递归调用?br>接着需要考虑的是如何对物体进行拣选剔除,通常对于所有的3D引擎来说都需要通过一pd步骤来加速这个处理过E,回忆一下前面讲解的内容Q这个过E首先要计算出物体的“最大包围球”或是“最大包围盒”Q它是包含了物体所有顶点的最包围体Q接着用包围体来和“可视qx?#8221;每一个剪切面q行撞,如果包围体位于每一个剪切面?#8220;反面”那么物体不会进行渲染,下图昄了这个过E:<br>        <br>?.11<br>图中物体1位于叛_切面?#8220;正面”但位于左剪切面的“反面”因此它将不会被渲染,而物?不仅位于左剪切面?#8220;正面”而且有一部分位于叛_切面?#8220;正面”因此会被渲染出来?br>Portal技术最初的x是通过剪切多边形来保证只有物体可见的部分被渲染出来Q也是无效渲染的多边Ş数量?。但是现在这U想法被认ؓ不是很理惻I因ؓ它无谓的费了处理时间。但是由于一个多边Ş在递归循环q程中将被遍历多ơ因此我们需要知道在渲染场景时它是否已经被渲染过Q一个较好的Ҏ(gu)是用一个数来标识q个多边形,q样可以很容易的来描q这个多边Ş在上一帧是否被渲染q。再看一下图6.10中最双的墙Q它同时通过F5和F6来进行渲染,通过对它q行标识我们可以知道它是否被渲染q,否则׃产生Z~冲错误?br>Z便于在portal引擎中进行渲染我们需要对“可视qx?#8221;q行一下定义,一?#8220;可视qx?#8221;是一个保存了多个剪切面的l构Q每一个剪切面的法UK指?#8220;可视qx?#8221;的内部,因此在它内部生一个闭合的锥体。下面的法昄了如何计一个多边Ş是否包含?#8220;可视qx?#8221;的内部。在q个法中我们用了一个函数CLASSIFY-POINTQ它使用一个剪切面和一个点作ؓ输入参数?br>l 函数INSIDE-FRUSTUM<br>l 参数:<br>l Frustum – 用于多边Ş是否位于其中?#8220;可视qx?#8221;?br>l Polygon – 用于的多边形?br>l q回?<br>l 多边形是否位?#8220;可视qx?#8221;的内部?br>l 功能:<br>l 使用“可视qx?#8221;的每一个剪切面来对多边形的每一个顶点进行检,如果所有的点都位于所有剪切面?#8220;正面”Q那么多边Ş处于“可视qx?#8221;的内部?</p> <p>INSIDE-FRUSTUM (Frustum, Polygon)<br>1 for each point Pt in Polygon<br>2 Inside = true<br>3 for each plane Pl in Frustum<br>4 if (CLASSIFY-POINT (Pl, Pt) <> INFRONT)<br>5 Inside f false<br>6 if (Inside)<br>7 return true<br>8 return false<br>在一个portal引擎中它的主渲染函数可以单的用下面的Ҏ(gu)来实现?br>函数RENDER-PORTAL-ENGINE<br>参数:<br>Sector – 观察者所处的sector?br>ViewFrustum – 当前?#8220;可视qx?#8221;?br>q回?<br>None<br>功能:<br>渲染portal引擎中的多边形,场景被描qCؓ由多个portalq接的sectors所l成?br>RENDER-PORTAL-ENGINE (Sector, ViewFrustum)<br>1 for each polygon P1 in Sector<br>2 if (P1是一个portal and INSIDE-FRUSTUM (ViewFrustum, P1))<br>3 NewFrustum = CLIP-FRUSTUM (ViewFrustum, P1)<br>4 NewSector = 获得由当前sector通过portal P1相连接的sector<br>5 RENDER-PORTAL-ENGINE (NewSector, NewFrustum)<br>6 else if (P1ȝ没有被渲?<br>7 draw P1<br>8 return<br>如何攄portal<br>正如我前面提到的在一个portal引擎中最大的问题是如何攄portalQ如果手工来攄它的话非常花Ҏ(gu)_同时要求地图的设计者有熟练的技巧。因此一个良好的自动攄portal的算法非常有必要Q在q里我将要介l一下关于这斚w的几个解x案,q些Ҏ(gu)都用了BSP?br>我介l的W一个解x案是q典DICE公司的Andreas Brinck提出的,它的原理非常单,观察一下一个完整的BSP层次?wi),可以发现q样一个现象,对于每一个portal来说它必定与BSP层次?wi)中由分割多边Ş定义的分割面位置相同Q因此在相同的位|上我们可以在分割面之外建立一个portal多边形,portal多边形被初始化ؓ一个矩形,q个矩Ş的大将过portal所处的BSP节点?#8220;最大包围盒”的大,接着portal多边形放入包含它的节Ҏ(gu)位于的子?wi)中Q当节点不是叶节Ҏ(gu)Q那么portall被传送到节点的子?wi)中Q这样子节点中的分割面将对它q行分割Q而当包含它的节点为叶节点Ӟ它也会被节点中的多边形进行剪切,因ؓportal初始化的大小过了节点的范围。当portal被分割后Q被分割的两个部分会l箋传送到最层的节炚w复这个过E,而当portal不需要进行分割时Q根据它所处于分割面的位置来放|到相应的子节点中,如果位于分割面的“正面”它将被放|在叛_?wi)中Q而当它位于分割面?#8220;反面”被攄于左子树(wi)中。如果portal正好位于分割面之上它?yu)同时放在左叛_?wi)中?br>Z方便方便所有的portal攄到BSP中我们需要定义如何对一个多边Şq行分割Qؓ了方便用我们假讑֮成这个功能的函数为INTERSECTION-POINTQ它?yu)返回一个面与一个线D늚交点?br>l 函数CLIP-POLYGON<br>l 参数:<br>l Clipper – d割其它多边Ş的多边Ş或面?br>l Polygon – 被分割的多边形?br>l q回?<br>l 被分割后的两个部分?br>l 功能:<br>l 由指定的分割面来分割多边形。如果多边Ş没有被分割将会返回一个空的多边Ş?br>CLIP-POLYGON (Clipper, Polygon)<br>1 RightPart = {}<br>2 LeftPart = {}<br>3 for each point edge E in Polygon<br>4 Side1 = CLASSIFY-POINT (Clipper, E.Point1)<br>5 Side2 = CLASSIFY-POINT (Clipper, E.Point2)<br>6 if (Side1 <> Side2 and<br>Side1 <> COINCIDING and<br>Side2 <> COINCIDING)<br>7 Ip = INTERSECTION-POINT (Clipper, E)<br>8 if (Side1 = INFRONT)<br>9 RightPart = RightPart U E.Point1<br>10 RightPart = RightPart U Ip<br>11 LeftPart = LeftPart U Ip<br>12 LeftPart = LeftPart U E.Point2<br>13 if (Side1 = BEHIND)<br>14 LeftPart = LeftPart U E.Point1<br>15 LeftPart = LeftPart U Ip<br>16 RightPart = RightPart U Ip<br>17 RightPart = RightPart U E.Point2<br>18 else<br>19 if (Side1 = INFRONT or Side2 = INFRONT or<br>Side1 = COINCIDING and Side2 = COINCIDING)<br>20 RightPart = RightPart U E.Point1<br>21 RightPart = RightPart U E.Point2<br>22 if (Side1 = BEHIND or Side2 = BEHIND)<br>23 LeftPart = LeftPart U E.Point1<br>24 LeftPart = LeftPart U E.Point2<br>25 return (RightPart, LeftPart)<br>现在我们可以定义如何在一个BSP层次?wi)中对portalq行分配了,在算法中portal被初始化Z个大于BSP根节?#8220;最大包围盒”的多边Ş?br>l 函数PLACE-PORTALS<br>l 参数:<br>l PortalPolygon – 攄到BSP中的多边形?br>l Node – 我们当前遍历的节炏V?br>l q回?<br>l None<br>l 功能:<br>l 攄一个portal多边形到BSP层次?wi)中Q如果需要的话对它进行剪切。这个函数将会生一个节点将由portalq接而每一个节点将包含一个portal多边形列表的BSP层次?wi)?br>PLACE-PORTALS (PortalPolygon, Node)<br>1 if (IS-LEAF (Node))</p> <p>l portal和节点中的每一个多边Şq行。当portal所包含的多边Ş和由一个多边Ş定义的面怺时它?yu)被q个面进行分Ԍ分割后的两个部分被重新传送到最层的节点中l箋q行?br>2 for (each polygon P2 in Node)<br>3 IsClipped = false<br>4 if (CALCULATE-SIDE (P2, PortalPolygon) = SPANNING)<br>5 IsClipped = true<br>6 (RightPart, LeftPart) = CLIP-POLYGON (P2, PortalPolygon)<br>7 PLACE-PORTALS (RightPart, RootNode)<br>8 PLACE-PORTALS (LeftPart, RootNode)<br>9 if (not IsClipped)<br>10 从当前节点中portal的多边Ş剔除Q因为它的位|和节点中一个多边Ş的位|相同?br>l 参考下面的描述?br>11 d当前节点到portal多边形所q接的节炚w合中?br>12 else<br>13 if (当前节点的分割多边Ş没有攄在树(wi)?<br>14 建立一个多边ŞPQ它的大将过包含当前节点所有多边Ş的最大包围盒的范_q且和分割多边Ş的位|相同?br>15 PLACE-PORTALS (P, Node.LeftChild)<br>16 PLACE-PORTALS (P, Node.RightChild)<br>17 Side = CALCULATE-SIDE (Node.Divider, PortalPolygon)<br>18 if (Side = POSITIVE)<br>19 (RightPart, LeftPart) = CLIP-POLYGON(P2, PortalPolygon)<br>20 PLACE-PORTALS (RightPart, RootNode)<br>21 PLACE-PORTALS (LeftPart, RootNode)<br>22 if (Side = POSITIVE or COINCIDING)<br>23 PLACE-PORTALS (PortalPolygon, Node.RightChild)<br>24 if (Side = NEGATIVE or COINCIDING)<br>25 PLACE-PORTALS (PortalPolygon, Node.LeftChild)<br>下面我将对算法中的第10行进行一下解释,当剔除和当前节点中一个多边Ş位置相同的portal多边形部分将会生什么样的结果。参考一下图6.12?/p> <p>?.12<br>在图6.12中一个portal已经到达了一个叶节点Q图中灰色的区域是是portal多边形在遍历BSP?wi)过E中被剔除的区域U它?。而图中标注ؓ2??的亮灰色部分是和portal多边形位|相重叠的多边ŞQ因此这一部分的portal多边形也会被剔除,而剩下的部分5被用来做ؓ一个portal?br>在上面的法W一ơ看的话会觉的非常复杂,但实际上它非常简单和Ҏ(gu)理解Q最l的l果是每一个portal会在两个节点上l束而对于Q一个portal来说它必定可以和一个portal之间怺可见。在下面我将用一个实际的例子来解释一下这个算法?/p> <p>?.13<br>对于?.13中的l构Q需要进行下面的几步Q?br>W一步,portal多边形s1q入节点n1中?/p> <p>    在节点n1中portal多边形s1会被分Ԍ因ؓ它的一部分和节点中间的一个多边Ş位置相同Q因此portal多边形s1会被分割ؓ两部分分别ؓp1、p2Q重叠的部分被剔除?br>W二步,p1、p2q入节点s2中?br>在节点s2中由于p1位于分割面s2?#8220;正面”Q因此将和分割面s2一赯送入到节点n2中,而p2׃位于分割面s2?#8220;反面”Q因此将和分割面s2一赯送入到节点s3中。由于p1、p2没有和分割面怺因此q一步没有出现分割操作?br>W三步,p1、s2q入节点n2中?/p> <p>在节点n2中n2被认可作Z个portalQ因此在节点n1和n2中它不会再发生Q何变化。而多边Şp3的一部分会被剔除,因ؓ它的一部分和节点中间的一个多边Ş位置相同Q在上一步中多边形s2也被送入到节点s3中,而在q里它又被称为p3?/p> <p>W四步,p3和s3q入节点n3中?/p> <p>在节点n3中多边Şp3被认可ؓ一个portalQ而多边Şs3的一部分因ؓ和上面的原因一栯剔除Q同时在q里它又被称为p4?/p> <p><br>W五步,p2和p4q入节点s4中?br>没有M多边形要q行分割Q因此多边Şp2和p4与s4一赯送入节点n4中,而s4被单独送入节点n5中?br>W六步,p2、p4和s4一赯入节点n4中?/p> <p>无论是p2q是p4都不需要分Ԍ但是׃s4和中间的一个多边Ş完全重叠因此会被剔除?/p> <p><br>W七步,l束Q没有Q何多边Şq入节点n5中?br>q个节点没有portalQ因为对于Q何节Ҏ(gu)说它都是不可见的Q而从q个节点位置上将不会看见M一个节炏V?br>l果Q?br>portal p1同时位于节点n1和n2中;<br>portal p2同时位于节点n1和n4中;<br>portal p1同时位于节点n2和n3中;<br>portal p1同时位于节点n3和n4中?/p> <p>上面我所讲解的内Ҏ(gu)建立一个简单的portal引擎所必备的功能,它能l我们提供一个较高的q行帧速?br>PVS<br>    一个portal引擎虽然能够提供许多非常好的Ҏ(gu),但是它的l构太复杂。当你用portal技术来构徏一个游戏引擎时你会发现它存在许多问题,最大的一个问题是在渲染场景的每一帧都需要进行可视性检,q会产生大量的多边Ş剪切操作Q在场景非常复杂的情况下Q运的费用会非常的高,因此需要寻找一U技术来对场景中可视性检进行预计算而不是在q行期间q行计算。PVSQPotentially Visible SetQ可视性集合,是Z解决q个问题而出现的一Ҏ(gu)术,可以通过对BSP中每一个叶节点讄一个PVSQ这个PVS保存了从W一个叶节点开始看到的叶节炚w合,它不仅可以用来帮助加速场景渲染,q可以用来加速场景中光照q算和进行网l优化?br>PVS是在场景q行预渲染时计算出来的,每一个BSP的叶节点都保存一个可视节点的集合Q当对场景进行渲染时Q摄象机所在的叶节点将被渲染,同时保持在PVS中的叶节点也会被渲染出来,q里需要一些算法来避免场景重复渲染Q由于今天硬件加速卡的发展,它所提供的硬件Z~冲的大已l可以方便的解决q个问题?br>计算PVS<br>如果要求PVS必须在BSP的叶节点之间q行标准的光U跟t计,来查找一下在一个叶节点中Q一个点是否在其它叶节点中可见。ؓ了加速光U跟t的计算Q在每一个叶节点中必LZ些典型的位置Ҏ(gu)避免无谓的计,现在的问题就是如何放|这些典型的炏V?br>对于一个portal引擎的portal来说Q典型点可以沿着?wi)的分割面放|,q是因ؓ只有在两个portal是相互开攄情况下才可以q行可视化检。如果位于一个叶节点中间的一个点被从另一个叶节点发射出来的光U认为是可见的话Q那么这条光U必焉过q接两个节点的portalQ参考下图:</p> <p>?.14<br>在图6.14中我们可以看见如果在一个节点中的一个点可以从其它节点看见,那么视线必然通过两个节点怺q通的区域。这是非常明昄Q如果视U被物体L的话那么两点之间必定不可见。因此将典型Ҏ(gu)|在两个节点之间所开攄区域是非常合适的Q下面描q的法在一个BSP?wi)上攄典型炏V对于这个函数需要一l帮助函数来把点攄在一个节点上Q它们是<br>l DISTRIBUTE-POINTS (Node) q个函数按照一定的间隔沿着l定节点的分割面来放|点Q点的位|会处于节点包围盒的内部。它?yu)返回一个点的集合,复杂度ؓO(xy)Q这里x点包围盒内分割面的宽度,而y为高度?br>l CLEANUP-POINTS (Node, PointSet) 从点的集合中剔除不合格的点,q些点可能和节点中的一个多边Ş位置相同Q也可能是位于节点包围盒的外部。函数的复杂度ؓO(np)Q这里n点中多边形的数量而p为集合中点的数量?br>l 函数 DISTRIBUTE-SAMPLE-POINTS<br>l 参数:<br>l Node – 当前我们遍历的节炏V?br>l PointSet – 攄到给定节点子?wi)中的点的集合?br>l q回?<br>l None<br>l 功能Q?br>l 沿着l定节点的分割面攄炏V它?yu)按照分割面的位|来对输入的点进行检,如果q些点和节点中的一个多边Ş位置相同Q或者位于节点包围盒的外部那么将会被剔除。新产生的点会被添加到左、右两个集合中,当一个点的集合遍历到一个叶节点旉么它?yu)是q个叶节点的典型炏V?br>DISTRIBUTE-SAMPLE-POINTS (Node, PointSet)<br>1 CLEANUP-POINTS (Node, PointSet)<br>2 if (IS-LEAF (Node))<br>3 讄点的集合为当前节点的典型炏V?br>4 else<br>5 RightPart = NewPoints<br>6 NewPoints = DISTRIBUTE-POINTS (Node)<br>7 RightPart = NewPoints<br>8 LeftPart = NewPoints<br>9 for each point P in PointSet<br>10 Side = CLASSIFY-POINT (Node.Divider, P)<br>11 if (Side = COINCIDING)<br>12 RightPart = RightPart U P<br>13 LeftPart = LeftPart U P<br>14 if (Side = INFRONT)<br>15 RightPart = RightPart U P<br>16 if (Side = BEHIND)<br>17 LeftPart = LeftPart U P<br>18 DISTRIBUTE-SAMPLE-POINTS (Node.LeftChild, LeftPart)<br>19 DISTRIBUTE-SAMPLE-POINTS (Node.RightChild, RightPart)<br>法分析<br>    每一ơ调用这个函数的复杂度ؓO(np + xy)Q参考函数CLEANUP-POINTS?br>DISTRIBUTE-POINTSQ,Z计算完整的复杂度我们可以用下面的公式来表C(我们假设典型点的集合同时分布在两个集合之中)Q?br>T(n) = 2T(n/2) + O(np + xy)<br>q个函数W一ơ调用时会从BSP?wi)的根节点开始ƈ会传入一个空的集合。换句话说它是按照下面的Ҏ(gu)q行的,它是从被BSP?wi)根节点所定义的分割面上的点开始的Q由于一个面的大没有限制因此也会有无限个典型点Q因此就需要对典型点进行限Ӟq个现在是根节点的包围盒?br>在根节点上获得合格的典型点后需要把所有的点发送到根节点的两个子树(wi)中,当一个典型点的集合进入一个节点后会被分割Z个部分,一个部分包含了所有位于节点分割面?#8220;正面”的点Q而另一部分包含了所有位于节点分割面?#8220;反面”的点。而位于分割面上的点将会同时放在两个集合中。接着“正面”集合会被传入到叛_?wi)中?#8220;反面”集合会被传入到左子?wi)中。重复这个过E直到进行到叶节Ҏ(gu)l束Q在q些操作后每一个叶节点包含一个典型点的集合,q些炚w位于节点所q通的地方?br>如果我们现在在这个阶D对每一个节点进行光U跟t那么是非常耗费旉的,但是如果我们知道叶节Ҏ(gu)与哪一个节点相q的Q那么这个过E将会变的简单,因ؓq样可以减少一些不必要的光U跟t运。查扄互连接的叶节炚w常简单,可以通过每一个叶节点的典型点来查找,如果同时有两个节点共享一个点那么q两个节点必然是怺q通的Q因为在遍历BSP?wi)放|典型点的过E中Q点不是没有攄到节点上是同时攄在两个节点上。当我们知道哪些节点是相互连通的Q就可以定义q行光线跟踪的算法了Q不q首先我们需要定义一些帮助函数?br>Z方便q行光线跟踪我们需要一些基本的光线跟踪函数QBSP?wi)是非常适合q行光线跟踪的结构,因ؓ大部分不可见的区域通过BSP?wi)可以很单的剔除掉,不用q行遍历Q因此花费的旉也非常少。我们需要的函数如下Q?br>POLYGON-IS-HIT (Polygon, Ray) q回光线是否和多边Ş怺?br>RAY-INTERSECTS-SOMETHING-IN-TREE (Node, Ray) q回光线是否和节点中的子?wi)相交?br>INTERSECTS-SPHERE (Sphere, Ray) q回光线是否和球体相交?br>CREATE-RAY (Point1, Point2) 通过两个Ҏ(gu)建立一条光Uѝ?br>上面的函数RAY-INTERSECTS-SOMETHING-IN-TREE是一个非常有的函数Q因为它昄了一些BSP?wi)的优点Q同时也昄了如何用BSP?wi)来加速光U跟t的处理。它是一个递归函数Q首先在?wi)的根节点上使用Q伪法如下Q?br>l 函数RAY-INTERSECTS-SOMETHING-IN-TREE<br>l 参数Q?br>l Node – 用来q行跟踪的节炏V?br>l Ray – 用来q行求交的光Uѝ?br>l q回|<br>l 光线是否和节点中的物体相交?br>l 功能Q?br>l 光U是否与l定节点极其子树(wi)中的物体怺?br>RAY-INTERSECTS-SOMETHING-IN-TREE (Node, Ray)<br>1 for each polygon P in Node<br>2 POLYGON-IS-HIT (P, Ray)<br>3 startSide = CLASSIFY-POINT (Ray.StartPoint, Node.Divider)<br>4 endSide = CLASSIFY-POINT (Node.EndPoint, Node.Divider)<br>l 如果光线和节点的分割面相交或和分割面的位|重叠,对节点的两个子节点进行检?br>5 if ((startSide = COINCIDING and endSide = COINCIDING) or<br>startSide <> endSide and startSide <> COINCIDING and<br>endSide <> COINCIDING)<br>6 if (RAY-INTERSECTS-SOMETHING-IN-TREE (Node.LeftChild, Ray))<br>7 return true<br>8 if (RAY-INTERSECTS-SOMETHING-IN-TREE (Node.RightChild, Ray))<br>9 return true<br>l 如果光线只位于分割面?#8220;正面”对节点的叛_?wi)进行检。在if语句中用or操作W是因ؓ光线的一个端点可能与分割面的位置重叠?br>10 if (startSide = INFRONT or endSide = INFRONT)<br>11 if(RAY-INTERSECTS-SOMETHING-IN-TREE (Node.RightChild, Ray))<br>12 return true<br>l 如果光线只位于分割面?#8220;反面”对节点的左子?wi)进行检。在if语句中用or操作W是因ؓ光线的一个端点可能与分割面的位置重叠?br>13 if (startSide = BEHIND or endSide = BEHIND)<br>14 if (RAY-INTERSECTS-SOMETHING-IN-TREE (Node.LeftChild, Ray))<br>15 return true<br>l 光线没有和Q何物体相交,q回C一层?br>16 return false<br>法分析<br>最坏的情况是光UK历了BSP?wi)中每一个节点,q样光线与节点中每一个单独的多边形进行检,q时函数的复杂度ؓO(n)Q这里n为BSP?wi)中所有多边Ş的数量。一般情况下光线q不会检树(wi)中的每一个节点,q样会大大减少q行的多边形数量。最佳的情况是光U被限制在一个节点中Q这时函数的复杂度接q于Q?lg n)Q这取决于BSP?wi)的l构大小?br>l 函数CHECK-VISIBILITY<br>l 参数Q?br>l Node1 – 开始处的节炏V?br>l Node2 – l束处的节点?br>l q回|<br>l Node2是否可以被node1看见?br>l 功能Q?br>l 在两个叶节点的典型点之间q行跟踪Q检两个节点之间是否可见?br>CHECK-VISIBILITY (Node1, Node2)<br>1 Visible = false<br>2 for each 典型点P1 in Node1<br>3 for each 典型点P2 in Node2<br>4 Ray = CREATE-RAY (P1, P2)<br>5 if(not RAY-INTERSECTS-SOMETHING-IN-TREE(Node1.Tree.RootNode,<br>Ray)<br>6 Visible = true<br>7 return Visible<br>法分析<br>函数CHECK-VISIBILITY非常耗费旉Q当我们在两个叶节点之间q行光线跟踪来检两者之间是否可见时Q我们不得不从Node1的每一个典型点开始对Node2的每一个典型点q行跟踪Q最坏的情况是每一ơ跟t都对?wi)中所有的多边形进行检,q时函数的复杂度O(s1 s2 p)Q这里s1为Node1中典型点的数量,s2为Node2中典型点的数量,p为树(wi)中多边Ş的数量。通常它的性能是比较好的,接近于O(s1 s2 lg p)?br>l 函数TRACE-VISIBILITY<br>l 参数Q?br>l Tree – 去进行光U跟t的BSP-tree?br>l q回|<br>l None<br>l 功能Q?br>l 对于?wi)中每一个叶节点Q它?yu)进行光U跟t运来和它相q的节点的可见性。每一个被发现是可见的节点会被添加到当前节点的PVS中。当一个叶节点发现是可见的Q我们还要对和它相连的节点进行光U跟t运来可见性?br>TRACE-VISIBILITY (Tree)<br>1 for (each ?wi)中的叶节点L)<br>2 for (each 和叶节点L相连的叶节点C)<br>3 d节点C到节点L的PVS?br>4 for (each ?wi)中的叶节点L1)<br>5 while (在叶节点L的PVS中存在一个叶节点L2Q它所q接的节Ҏ(gu)有进行可见性检?<br>5 for (each q接到节点L2中的叶节点C)<br>6 if (节点C没有位于节点L1的PVS?and<br>CHECK-VISIBILITY (L1, C))<br>7 d节点C到节点L1的PVS?br>7 d节点L1到节点C的PVS?br>法分析<br>如果我们没有使用Ҏ(gu)叶节点的相连情况来进行处理的优化技术,那么必须Ҏ(gu)(wi)中的每一个叶节点q行,q时函数的复杂度为O(n2)Q这里n为树(wi)中叶节点的数量。要对上面的法估计一个对处理q程提高了多性能的具体数值非常困难,因ؓ它依赖于所处理的结构的大小。对于每一个叶节点与其它节炚w是可见的l构Q这个算法不会做M优化。对于每一个叶节点只有一C个可见的节点的结构,q个法会产生非常大优化,它的复杂度接q与O(n)?br>现在在一个设计良好的地图上所产生的结构在每一帧上会避免大量的多边形。一个设计良好的地图在徏立时会考虑物体的可见性,q意味着应尽可能的在地图中放入一些能障碍视线的物体,如墙壁等。如果在地图中包含一个有大量l节的大戉KQ那么在上面的算法中Q或在一个portal引擎中)q行的隐藏面剔除工作对它不会产生M效果。这时我们需要用其它类gLODq样的技术来q行多边形剔除?/p> <p>静态物?br>考虑一下这L(fng)场景Q一个球体位于一个立方体的中心,如果用BSP对它q行渲染那么会产生大量的节点,q会产生大量的分割多边ŞQ这是因为在球体上的每一个多边Ş都会送入到叶节点中。如果球体有200个多边Ş当渲染时׃产生200个叶节点的BSP?wi)。这样做非常影响q行的速度Q因此必d找一个方法来避免q种现象的发生?br>Z解决q个问题地图的设计者可以选择l成地图的几何体Q在上面的例子中也就是立方体Q接着剩余的物体做ؓ静态物体,它们不会用来对BSP?wi)进行渲染或q可见性检,但是它们会参与到地图的光照运当中去。当q行可见性运时每一个静态物体会被添加到BSP?wi)中Q每一个静态物体的多边形将会被d到BSP?wi)中Q这个过E如下:<br>l 函数PUSH-POLYGON<br>l 参数Q?br>l Node – 多边形当前所在的节点?br>l Polygon – 被d的多边Ş?br>l q回|<br>l None<br>l 功能Q?br>l 多边Şd到树(wi)中。如果多边Ş的一些点与节点的分割面相交将会被分割。分割后的部分将会被l箋向下传送。当一个多边Şq入一个叶节点后它?yu)被d到叶节点的多边Ş集合中?br>PUSH-POLYGON (Node, Polygon)<br>1 if (IS-LEAF (Node))<br>2 Node.PolygonSet = Node.PolygonSet U Polygon<br>3 else<br>4 value = CALCULATE-SIDE (Node.Divider, Polygon)<br>5 if (value = INFRONT or value = SPANNING)<br>6 PUSH-POLYGON (Node.RightChild, Polygon)<br>7 else if (value = BEHIND)<br>8 PUSH-POLYGON (Node.LeftChild, Polygon)<br>9 else if (value = SPANNING)<br>10 Split_Polygon28 (P1, Divider, Front, Back)<br>11 PUSH-POLYGON (Node.RightChild, Front)<br>12 PUSH-POLYGON (Node.LeftChild, Front)<br>PUSH-POLYGON是一个递归函数Q它?yu)一个多边Şd到BSP?wi)中Q这个函数对每一个静态物体的每一个多边Ş都会调用一ơ,<br>在这个过E处理之后叶节点可能不再成ؓ一?#8220;?#8221;集合Q这在进行碰撞检时可能会生一些问题,后面的内容将会对q个问题q行阐述?br>BSP技术详?</p> <p>eXtreme3D</p> <p>W三?室内场景中光照运?br>关于Radiosity的算法最早是由Goral、Cindy M、Torrance、Kenneth E、Greenberg、Donald P、Battaile和Bennett在论文《Modelling the interaction of light between diffuse surfaces》提出的。他们用Radiosity来模拟能量在漫反表面之间进行传送,漫反表面对照到表面上的光线在所有的方向上都q行相同的反,和它相反的是镜面反射表面Q它只在反射方向上传播反光。由于O反射表面的这个特性,q就意味着对于所有的观察角度而言看v来表面都是相同的Q这样对于场景中的每一个表面只需要进行一ơ光照运,而且可以在场景的预渲染时q行Q因此这Ҏ(gu)术被大量?D游戏所采用?br>下面我再短的讲解一下Radiosity是如何工作的Q而将主要的精力放在如何用BSP?wi)来加速Radiosity的计,对于Radiosity的详l介l请参考前面的章节。Radiosity技术是设计用来使场景中光照看v来更加真实和光滑Q如果我们用一个一直向前传播而不考虑反射的光照模型,那么当场景中的灯光照亮场景中的物体时Qƈ不会计算q处l过反射q来的光U,q样场景中的阴媄看v来非常尖锐而物体表面也看v来非怸真实。ؓ了用radiosity技术我们需要把场景分割成一块一块很的部分Q每一部分我们U它为patchQ每一个patch都有一个初始化的能量别,如果它不是一个灯光这L(fng)发光体的话通常?Q有许多Ҏ(gu)来分配场景中的能量,q里我们要使用的方法称Z互式radiosity。这个方法的q程是我们从场景中未发送能量的U别最高的patch开始发送能量,能量l过传递后不再发送能量的patch的等U设?Q重复这个过E直到场景中的每一个patch的能量等U都于一个预定gؓ止?br>当能量从一个patchQjQ开始发送到另一个patchQiQ时我们使用下面的公式:<br>Bi = Bi + Bj * Fij * Ai / Aj<br>q里Bi = patchQiQ的能量U别    Bj = patchQjQ的能量U别 <br>    Ai= patchQiQ的作用区域    Aj = patchQjQ的作用区域<br>    Fij = patchQiQ与patchQjQ之间的pL<br>在公式中pLFij是由以下公式来确定的Q?br>Fij = (cos qi * cos qj) / d2 * Hij<br>q里Fij = patchQiQ与patchQjQ之间的pL<br>qi = patchQiQ与patchQjQ法U之间的夹角<br>qj = patchQiQ与patchQjQ法U之间的夹角<br>d = patchQiQ与patchQjQ之间的距离<br>Hij = patchQiQ与patchQjQ之间的可见性系数。如果在两个patch之间只有一条光U可以跟t,q个gؓ1Q如果没有光U可以跟tؓ0。一般情况下׃每一个patch都不是一个点而是一个区域,因此光线有很多条?br>从上面的公式中我们可以看到在场景中进行radiosity计算是非常耗费旉的。这个函数的复杂度ؓO(n3)Q这里的n为场景中patch的数量。由于对于场景中每一个patch你需要发送最一条光U到其它patch上,因此需要对场景中的几乎所有的多边形都q行光线跟踪计算。在上面的公式中pLH的计非常耗费旉Q下面我们将看一下如何在BSP?wi)中对它的计进行优化?</p> <p>    BSP?wi)中的radiosity计算<br>在进行场景中的光照计之前需要把场景中的面分割ؓpatchQ一个方法是在开始的时候设定每一个patch为预定的大小Q当计算每一个patch的能量时Q如果在patch上的能量_大,对这个patchq行分割。不q这个方法是非常耗费旉的,因此必须L一个更好的Ҏ(gu)来通过BSP?wi)对计算q行优化?br>在radiosity的一般算法中场景中的每一个光源都被看作ؓ一个或多个patchQ这里我们可以改q一下,每一个光源放在它所位于的叶节点中,接下来每一个光源都发送自q能量到场景中所有的patch上,当这个过E完成后radiosity计算也就l束了。ؓ了最后的l果看v来更好可以用一U称?#8220;渐进_N?#8221;Qprogressive refinementQ的技术来对这个方法进行很的修改。在每一ơ过E中Q叶节点中具有高能量的patch发送能量到其它低能量的patch上,q样做的l果是高亮度的patch发送能量到处于阴媄中patch上。这是因为在实际生活中ƈ没有真正黑暗的地方,它多多少要获得一些其它物体反过来的光亮?br>׃计算非常耗费旉需要做一下优化,使用渲染BSP?wi)时获得的PVS信息可以在选择哪些patch接受能量时剔除一些无用的计算。因为在计算PVS时用了相同的方法来q行光线跟踪?br>通过场景来分配能量的法如下Q?br>l 函数RADIOSITY<br>l 参数Q?br>l Tree – q行radiosity计算的BSP?wi)?br>l q回|<br>l None<br>l 功能Q?br>l 在场景中的patch之间发送能量?br>RADIOSITY (Tree)<br>1 for(each leaf L in Tree)<br>2 for(each light S in L)<br>3 for(each leaf V that is in L’s PVS)<br>4 Send S’s energy to the patches in V<br>l 下面语句5是ؓ了让地图~辑者在M时候都可以查场景渲染的效果Q如果他感到看v来已l够好了可以中断能量的传播?br>5 while(not looks good enough)<br>6 for(each leaf L in Tree)<br>7 for(each leaf V that is in L’s PVS)<br>8 Send energy from the patch with the most unsent energy in L<br>to all patches in V.<br>复杂度分?br>q个函数的运费用实在是太高昂了Q可以称为时间杀手,在最坏的情况下每一条光U将不得不检场景中的每一个多边ŞQ此时复杂度为O(n3)Q这里n为树(wi)中patch的数量。一般情况下׃q行了优化可以减大量的计算Q但是减多ƈ不能计算出来Q因依赖于树(wi)l构的复杂度?br>上面的函数给Z一个充分利用BSP?wi)的优点来加速场景光照运的Ҏ(gu)Q尤其是可以显著的减光U跟t的计算量,而且地图设计者可以来军_当场景渲染时如果渲染的效果可以接受中断渲染@环。这对地囄预渲染实在是太方便了Q运行的旉可以Ҏ(gu)渲染的效果来军_?br>W四?BSP?wi)的预渲?br>现在我们需要完成一个完整BSP引擎的预处理q程Q下面的法昄如何场景渲染到BSP?wi)中?br>l 函数RENDER-SCENE<br>l 参数Q?br>l Scene – 被渲染的场景<br>l q回|<br>l 一个BSP?wi)?br>l 功能<br>l 预渲染来获得一个包含场景信息的BSP?wi)?br>RENDER-SCENE (Scene)<br>l 使用描述场景中图元的物体来渲染BSP?wi)?br>1 GeometryPolygons = {}<br>2 for (每一个包含场景图元的物体object O)<br>3 GeometryPolygons = GeometryPolygons U O.PolygonSet<br>4 GENERATE-BSP-TREE (Tree.RootNode, GeometryPolygons)<br>l 分配叶节点上的取L(fng)?br>5 DISTRIBUTE-SAMPLE-POINTS (Tree.RootNode, {})<br>6 TRACE-VISIBILITY (Tree)<br>7 for 每一个场景中的静态物体object O<br>8 for 物体O中每一个多边ŞP<br>9 PUSH-POLYGON (Node, P)<br>l 函数CREATE-PATCHES是一个未定义的函敎ͼ׃我们的解x案效率ƈ不是太好Q因此没有对它进行详l的介绍?br>10 CREATE-PATCHES (Tree)<br>11 RADIOSITY (Tree)<br>    复杂度分?br>函数的复杂度如下Q?br>函数 最坏情?一般情?描述<br>GENERATE-BSP-TREE O(n2 lg n) O(n2) n为场景中多边形的数量<br>DISTRIBUTE-SAMPLE-POINTS Q (np + xy) Q (np + xy) n为树(wi)中多边Ş的数量,p为树(wi)中典型点的数量,x和y为分割面的宽度和高度?br>TRACE-VISIBILITY O(n2) O(n lg n), n为树(wi)中多边Ş的数量?br>RADIOSITY O(n3) O(n2 lg n) n为树(wi)中patch的数?br>在一般情况这一列中昄了算法通常所需q行的时_对算法时间媄响最大的是函数RADIOSITYQ它使整个算法的复杂度趋向于O(n3)?/p> <img src ="http://www.shnenglu.com/bloodbao/aggbug/51631.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/bloodbao/" target="_blank">bloodbao</a> 2008-05-30 20:11 <a href="http://www.shnenglu.com/bloodbao/archive/2008/05/30/51631.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ogre+ceguihttp://www.shnenglu.com/bloodbao/archive/2008/05/30/51615.htmlbloodbaobloodbaoFri, 30 May 2008 09:32:00 GMThttp://www.shnenglu.com/bloodbao/archive/2008/05/30/51615.htmlhttp://www.shnenglu.com/bloodbao/comments/51615.htmlhttp://www.shnenglu.com/bloodbao/archive/2008/05/30/51615.html#Feedback0http://www.shnenglu.com/bloodbao/comments/commentRss/51615.htmlhttp://www.shnenglu.com/bloodbao/services/trackbacks/51615.html
OGRE是拿来玩的,IRR是拿来做目的,BLOOD是最强大的DX10引擎Q?

bloodbao 2008-05-30 17:32 发表评论
]]>
DX10之GS生成?/title><link>http://www.shnenglu.com/bloodbao/archive/2008/05/28/51359.html</link><dc:creator>bloodbao</dc:creator><author>bloodbao</author><pubDate>Wed, 28 May 2008 01:33:00 GMT</pubDate><guid>http://www.shnenglu.com/bloodbao/archive/2008/05/28/51359.html</guid><wfw:comment>http://www.shnenglu.com/bloodbao/comments/51359.html</wfw:comment><comments>http://www.shnenglu.com/bloodbao/archive/2008/05/28/51359.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/bloodbao/comments/commentRss/51359.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/bloodbao/services/trackbacks/51359.html</trackback:ping><description><![CDATA[<p align=left>                                             DX10之GS生成?br>1.׃角Ş生成金字塔:<br>析:triangle GSPS_INPUT input[3]代表输入的三角Ş<br> inout TriangleStream<GSPS_INPUT> TriStream 代表输出的三角Ş-即金字塔?2个顶?br>W一个@环计三个标出法向量的三角ŞQ如图所C?br>W二个@环计出三角形与输入的三角Ş一P但^面的法向量刚好相反?img src="http://www.shnenglu.com/images/cppblog_com/bloodbao/gs.jpg" border=0></p> <p>//--------------------------------------------------------------------------------<br>// Geometry Shader<br>//--------------------------------------------------------------------------------<br>[maxvertexcount(12)]<br>void GS( triangle GSPS_INPUT input[3], inout TriangleStream<GSPS_INPUT> TriStream )<br>{<br>    GSPS_INPUT output;<br>    <br>    //<br>    // Calculate the face normal<br>    //<br>    float3 faceEdgeA = input[1].Pos - input[0].Pos;<br>    float3 faceEdgeB = input[2].Pos - input[0].Pos;<br>    float3 faceNormal = normalize( cross(faceEdgeA, faceEdgeB) );<br>    float3 ExplodeAmt = faceNormal*Explode;<br>    <br>    //<br>    // Calculate the face center<br>    //<br>    float3 centerPos = (input[0].Pos.xyz + input[1].Pos.xyz + input[2].Pos.xyz)/3.0;<br>    float2 centerTex = (input[0].Tex + input[1].Tex + input[2].Tex)/3.0;<br>    centerPos += faceNormal*Explode;<br>    <br>    //<br>    // Output the pyramid<br>    //<br>    for( int i=0; i<3; i++ )<br>    {<br>        output.Pos = input[i].Pos + float4(ExplodeAmt,0);<br>        output.Pos = mul( output.Pos, View );<br>        output.Pos = mul( output.Pos, Projection );<br>        output.Norm = input[i].Norm;<br>        output.Tex = input[i].Tex;<br>        TriStream.Append( output );<br>        <br>        int iNext = (i+1)%3;<br>        output.Pos = input[iNext].Pos + float4(ExplodeAmt,0);<br>        output.Pos = mul( output.Pos, View );<br>        output.Pos = mul( output.Pos, Projection );<br>        output.Norm = input[iNext].Norm;<br>        output.Tex = input[iNext].Tex;<br>        TriStream.Append( output );<br>        <br>        output.Pos = float4(centerPos,1) + float4(ExplodeAmt,0);<br>        output.Pos = mul( output.Pos, View );<br>        output.Pos = mul( output.Pos, Projection );<br>        output.Norm = faceNormal;<br>        output.Tex = centerTex;<br>        TriStream.Append( output );<br>        <br>        TriStream.RestartStrip();<br>    }<br>    <br>    for( int i=2; i>=0; i-- )<br>    {<br>        output.Pos = input[i].Pos + float4(ExplodeAmt,0);<br>        output.Pos = mul( output.Pos, View );<br>        output.Pos = mul( output.Pos, Projection );<br>        output.Norm = -input[i].Norm;<br>        output.Tex = input[i].Tex;<br>        TriStream.Append( output );<br>    }<br>    TriStream.RestartStrip();<br>}<br>2.GS_子<br>实现像烟׃L(fng)效果?br>首先要了解五U基本粒子?br>Launcher Particles 发射_子Q不Ud也不dQ用来发Shell_子。一旦发完Shell_子Q就重置旉?br>Shell Particles 由发粒子发出随机速度的的Shell_子Q在生命周期内不发射本类型的_子Q而发出一些Ember1和Ember2cd的粒子?br>Ember1 Particles 由Shell_子发射Q拥有很短的生命周期Q随着旉而E出死去,q不发射_子?br>Ember2 Particles 由Shell_子发射Q在生命周期末发出Ember3_子Q第二次的爆炸源?br>Ember3 Particles cMEmber1_子Q除了有不同的颜艌Ӏ?br>[maxvertexcount(128)]<br>void GSAdvanceParticlesMain(point VSParticleIn input[1], inout PointStream<VSParticleIn> ParticleOutputStream)<br>{<br>    if( input[0].Type == PT_LAUNCHER )<br>        GSLauncherHandler( input[0], ParticleOutputStream );<br>    else if ( input[0].Type == PT_SHELL )<br>        GSShellHandler( input[0], ParticleOutputStream );<br>    else if ( input[0].Type == PT_EMBER1 ||<br>              input[0].Type == PT_EMBER3 )<br>        GSEmber1Handler( input[0], ParticleOutputStream );<br>    else if( input[0].Type == PT_EMBER2 )<br>        GSEmber2Handler( input[0], ParticleOutputStream );<br>}</p> <p> </p> <img src ="http://www.shnenglu.com/bloodbao/aggbug/51359.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/bloodbao/" target="_blank">bloodbao</a> 2008-05-28 09:33 <a href="http://www.shnenglu.com/bloodbao/archive/2008/05/28/51359.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从dll导出其对应的libhttp://www.shnenglu.com/bloodbao/archive/2008/05/17/50174.htmlbloodbaobloodbaoSat, 17 May 2008 11:39:00 GMThttp://www.shnenglu.com/bloodbao/archive/2008/05/17/50174.htmlhttp://www.shnenglu.com/bloodbao/comments/50174.htmlhttp://www.shnenglu.com/bloodbao/archive/2008/05/17/50174.html#Feedback0http://www.shnenglu.com/bloodbao/comments/commentRss/50174.htmlhttp://www.shnenglu.com/bloodbao/services/trackbacks/50174.html  Visual   C++   开发工h供了两个命o行工P一个是dumpbin.exe,另一个是lib.exe。利用这两个工具卛_从dll导出其对应的lib?nbsp; 
   
  1、在命o行执行:  
  dumpbin   /exports   yourdll.dll   >   yourdll.def  
   
  2、编?nbsp;  yourdll.def   文gQ之格式与.def文g格式一致。比如:  
   
  EXPORTS;  
                fn1;  
                fn2;  
   
  3、在命o行执行:  
  lib   /def:yourdll.def   /machine:i386   /out:yourdll.lib  
   
  q样可以导出对应的LIB了,但你要用的话Q要在工E中自己手工加上

bloodbao 2008-05-17 19:39 发表评论
]]>
underwater scenehttp://www.shnenglu.com/bloodbao/archive/2008/05/16/50088.htmlbloodbaobloodbaoFri, 16 May 2008 12:46:00 GMThttp://www.shnenglu.com/bloodbao/archive/2008/05/16/50088.htmlhttp://www.shnenglu.com/bloodbao/comments/50088.htmlhttp://www.shnenglu.com/bloodbao/archive/2008/05/16/50088.html#Feedback0http://www.shnenglu.com/bloodbao/comments/commentRss/50088.htmlhttp://www.shnenglu.com/bloodbao/services/trackbacks/50088.html工作啊,工作Q有朋友说要推荐M和q东啦,不过Q估计还是要面试Q怕怕!
最q要写析多写CODE了!
刚做的场景:



bloodbao 2008-05-16 20:46 发表评论
]]>
HLSLd员(DX9待改Q?/title><link>http://www.shnenglu.com/bloodbao/archive/2008/05/12/49659.html</link><dc:creator>bloodbao</dc:creator><author>bloodbao</author><pubDate>Mon, 12 May 2008 11:51:00 GMT</pubDate><guid>http://www.shnenglu.com/bloodbao/archive/2008/05/12/49659.html</guid><wfw:comment>http://www.shnenglu.com/bloodbao/comments/49659.html</wfw:comment><comments>http://www.shnenglu.com/bloodbao/archive/2008/05/12/49659.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/bloodbao/comments/commentRss/49659.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/bloodbao/services/trackbacks/49659.html</trackback:ping><description><![CDATA[<p>有Effect版:<br>    DWORD         g_dwShaderFlags; // Shader compilate and link flags<br>      LPD3DXBUFFER  g_pCompiledFragments = NULL;  </p> <p>    D3DXGatherFragmentsFromFile( L"FragmentLinker.fx", NULL, <br>                NULL, g_dwShaderFlags, &g_pCompiledFragments, NULL );</p> <p>D3DXGatherFragmentsFromFile requires the .fx file, pointers to the #define and #include handlers (both set to NULL in this example), and the shader compile flags. The method returns a buffer which contains the compiled shader fragment. The method can return a second buffer with compile errors, which is set to NULL in this example because it is not used. D3DXGatherFragments is overloaded to handle loading fragments from a string, a file, or a resource.</p> <p>Set your debugger to break on this method to look for compile errors in the debugger. The compiler can catch errors in syntax, but it cannot check for registers that are shared incorrectly due to the fact that it has no way to predict which parameters a user may want to share between fragments.</p> <p>You need a fragment linker to manage the compiled fragments. Create the fragment linker by calling D3DXCreateFragmentLinker:</p> <p>ID3DXFragmentLinker* g_pFragmentLinker = NULL;     // Fragment linker interface<br>IDirect3DDevice9*    pd3dDevice        = NULL;</p> <p>    // Initialize the device before using it<br> ...<br> <br>    // Create the fragment linker interface<br>    D3DXCreateFragmentLinker( pd3dDevice, 0, &g_pFragmentLinker );</p> <p>Then simply add the compiled fragments to the fragment linker using ID3DXFragmentLinker::AddFragments.</p> <p>    // Add the compiled fragments to a list<br>    g_pFragmentLinker->AddFragments(     <br>              (DWORD*)g_pCompiledFragments->GetBufferPointer() );</p> <p>ID3DXFragmentLinker::AddFragments requires a pointer to the DWORD stream that contains the compiled shader.</p> <p>After compiling fragments and creating a fragment linker, there are several ways to link fragments. One way to link a vertex shader fragment is to call ID3DXFragmentLinker::LinkVertexShader. Here is an example that links two vertex shader fragments:</p> <p>    // Get a handle to each fragment    <br>    D3DXHANDLE fragmentHandle[2];<br> fragmentHandle[0] = <br>     (D3DXHANDLE)g_pFragmentLinker->GetFragmentHandleByName("Ambient");<br> fragmentHandle[1] = <br>     (D3DXHANDLE)g_pFragmentLinker->GetFragmentHandleByName("AmbientDiffuseFragment");<br>    <br>    // Link the fragments together to form a vertex shader<br>    IDirect3DVertexShader9* pVertexShader = NULL;<br>    g_pFragmentLinker->LinkVertexShader( "vs_1_1", g_dwShaderFlags, <br>           fragmentHandle, 2, &pVertexShader, NULL );</p> <p>This requires a shader compile target, the shader compile and link flags, and a handle to each of the fragments to link. If the fragments are successfully linked, ID3DXFragmentLinker::LinkVertexShader returns a vertex shader (IDirect3DVertexShader9). The vertex shader needs to be set in the effect before rendering. But before this, here's how the shader is declared in the effect:</p> <p>VertexShader MyVertexShader; // Vertex shader set by the application</p> <p>The effect technique contains all the state set for a pass. This pass specifies the vertex shader like this:</p> <p>technique RenderScene<br>{<br>    pass P0<br>    {<br>        VertexShader = <MyVertexShader>;    <br>        PixelShader = compile ps_1_1 ModulateTexture();    <br>    }<br>} </p> <p>With the effect's vertex shader created and initialized, the render code also sets the uniform constants and calls the render loop. Set the uniform constants similar to this:</p> <p>    // Update the uniform shader constants.<br>    g_pEffect->SetMatrix( "g_mWorldViewProjection", &mWorldViewProjection );<br>    g_pEffect->SetMatrix( "g_mWorld", &mWorld );<br>    g_pEffect->SetFloat( "g_fTime", (float)fTime );    <br>Then render the effect by setting the current technique and pass:</p> <p>    // Render the scene<br>    if( SUCCEEDED( pd3dDevice->BeginScene() ) )<br>    {  <br>        // Apply the technique contained in the effect<br>        UINT cPasses, iPass;<br>        g_pEffect->Begin(&cPasses, 0);</p> <p>        for (iPass = 0; iPass < cPasses; iPass++)<br>        {<br>            g_pEffect->BeginPass(iPass);</p> <p>            // Render the mesh with the applied technique<br>            g_pMesh->DrawSubset(0);</p> <p>            g_pEffect->EndPass();<br>        }<br>        g_pEffect->End();</p> <p>        pd3dDevice->EndScene();<br>    }</p> <p>When setting uniform shader constants, it is more efficient to cache a handle to the parameter by calling ID3DXBaseEffect::GetParameterByName. This avoids the string lookup that is necessary when calling effect methods like ID3DXBaseEffect::SetMatrix.</p> <p>  // Instead of setting a uniform constant like this in the render loop<br>  g_pEffect->SetMatrix( "g_mWorldViewProjection", &mWorldViewProjection );</p> <p>  // Get a handle to a uniform constant outside of the render loop<br>  D3DXHANDLE hParameter;<br>  GetParameterByName( hParameter,"g_mWorldViewProjection");</p> <p>  ...<br>  <br>  // Use the handle to set the uniform constant in the render loop<br>  g_pEffect->SetMatrix(hParameter); </p> <p>无Effect版:<br> LPD3DXCONSTANTTABLE pConstantTable;<br>    LPD3DXBUFFER pShaderBuf;<br>    IDirect3DVertexShader9* pVertexShader = NULL;</p> <p>    // Compile the fragments to a buffer.<br>    D3DXGatherFragmentsFromFile( L"FragmentLinker.fx", NULL, NULL, <br>         g_dwShaderFlags, &g_pCompiledFragments, NULL );<br>    <br>    g_pFragmentLinker->AddFragments((DWORD*)g_pCompiledFragments->GetBufferPointer());<br>    g_pFragmentLinker->LinkShader( <br>     "vs_1_1",<br>     g_dwShaderFlags,<br>     aHandles,<br>     NUM_FRAGMENTS,<br>     &pShaderBuf,<br>     NULL);<br>    D3DXGetShaderConstantTable( <br>     (DWORD*)pShaderBuf->GetBufferPointer(),<br>     &pConstantTable );<br>    <br>    pDevice->CreateVertexShader(<br>     (DWORD*)pShaderBuf->GetBufferPointer(),<br>     &pVertexShader);<br>    RELEASE(pShaderBuf);</p> <img src ="http://www.shnenglu.com/bloodbao/aggbug/49659.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/bloodbao/" target="_blank">bloodbao</a> 2008-05-12 19:51 <a href="http://www.shnenglu.com/bloodbao/archive/2008/05/12/49659.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OGRE场景理析(待改Q?/title><link>http://www.shnenglu.com/bloodbao/archive/2008/05/11/49504.html</link><dc:creator>bloodbao</dc:creator><author>bloodbao</author><pubDate>Sun, 11 May 2008 03:42:00 GMT</pubDate><guid>http://www.shnenglu.com/bloodbao/archive/2008/05/11/49504.html</guid><wfw:comment>http://www.shnenglu.com/bloodbao/comments/49504.html</wfw:comment><comments>http://www.shnenglu.com/bloodbao/archive/2008/05/11/49504.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/bloodbao/comments/commentRss/49504.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/bloodbao/services/trackbacks/49504.html</trackback:ping><description><![CDATA[<p>OGRE场景理Q?br>PCZSceneManager : public SceneManager<br>节点Q?br>    typedef std::list < SceneNode * > NodeList;<br>    typedef std::list < WireBoundingBox * > BoxList;<br>摄像机:<br>    class PCZCamera;<br>天空Q?br>    void setSkyZone(PCZone * zone);<br>光照Q?br>    createLight(const String& name);<br>地带Q?br>    class PCZone;<br>    PCZone * createZone(const String& zoneType, const String& instanceName);<br>释放节点Q?br>    void removeSceneNode( SceneNode * );<br>节点查找Q?br>    void findNodesIn( const AxisAlignedBox &box, <br>        PCZSceneNodeList &list, <br>        PCZone * startZone,<br>        PCZSceneNode *exclude = 0 );</p> <p>    class PCZIntersectionSceneQuery;Q-Q-Q相交查?br>    class PCZRaySceneQuery;Q-Q-Q-Q-Q射U查?br>    class PCZSphereSceneQuery;Q-Q-Q-Q-球面查询<br>    class PCZAxisAlignedBoxSceneQuery;Q-Q-Q-查询(沿u向)<br>    class PCZPlaneBoundedVolumeListSceneQuery;-----Q-表查?br>单地看了OGRE的场景管理,除了OGREMAIN部分Q还用了PCZ插g来实l承q实现?br>Qclass PCZSceneManagerFactory : public SceneManagerFactoryQ挺复杂的,相比之下Q鬼火的场景理q单了Q?br>可调用多U节炏V?/p> <img src ="http://www.shnenglu.com/bloodbao/aggbug/49504.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/bloodbao/" target="_blank">bloodbao</a> 2008-05-11 11:42 <a href="http://www.shnenglu.com/bloodbao/archive/2008/05/11/49504.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>里的朋友做?/title><link>http://www.shnenglu.com/bloodbao/archive/2008/05/10/49472.html</link><dc:creator>bloodbao</dc:creator><author>bloodbao</author><pubDate>Sat, 10 May 2008 14:00:00 GMT</pubDate><guid>http://www.shnenglu.com/bloodbao/archive/2008/05/10/49472.html</guid><wfw:comment>http://www.shnenglu.com/bloodbao/comments/49472.html</wfw:comment><comments>http://www.shnenglu.com/bloodbao/archive/2008/05/10/49472.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/bloodbao/comments/commentRss/49472.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/bloodbao/services/trackbacks/49472.html</trackback:ping><description><![CDATA[<img src="http://www.shnenglu.com/images/cppblog_com/bloodbao/32.jpg" border=0><img src="http://www.shnenglu.com/images/cppblog_com/bloodbao/31.jpg" border=0> <img src ="http://www.shnenglu.com/bloodbao/aggbug/49472.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/bloodbao/" target="_blank">bloodbao</a> 2008-05-10 22:00 <a href="http://www.shnenglu.com/bloodbao/archive/2008/05/10/49472.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>nd面试分析http://www.shnenglu.com/bloodbao/archive/2008/05/08/49212.htmlbloodbaobloodbaoThu, 08 May 2008 06:38:00 GMThttp://www.shnenglu.com/bloodbao/archive/2008/05/08/49212.htmlhttp://www.shnenglu.com/bloodbao/comments/49212.htmlhttp://www.shnenglu.com/bloodbao/archive/2008/05/08/49212.html#Feedback7http://www.shnenglu.com/bloodbao/comments/commentRss/49212.htmlhttp://www.shnenglu.com/bloodbao/services/trackbacks/49212.html一天坐了九(ji)个小时的车,我算是体验到了讨生活的艰辛?br>中午坐R的时候天q是炎热的,下午开始狂下雨Q我I着两g服q一直在发抖?br>先来谈谈感受Q?br>1.公司内部环境不错Q很漂亮的游xQ攀沿壁Q会议室Q食堂。我比较喜欢那个游泳池,感觉很不错?br>2.女很多Q特别是Z部门的,那么L(fng)天气Q穿着短裙,是要风度不要温度。不q,特别ȝ?br>3.工作环境Q两三百个h挤在一个大厅中。好像,各个开发组都在一起吧Q有些成员面前放着两台很大的液Ӟ很上d挺爽的。只是这么吵杂的环境适合开发吗Q偶是不知道的?br>4.Z部的MM挺勤快的Q不q,依旧有被扔在一旁的感觉Q特别是在等与主E见面的旉Q差不多快一个小时。幸好旁边的一个帅哥给了本杂志Q让我打发时间?br>5.每时每刻都有人在应聘Q不q,都是招文员。感觉就M一个PHP的,也算技术的?br>6.ȝ很厉宻I用现在的话讲Q叫很牛。h事的MMQ说他很严格Q面试的题目都是他出的,非常难。面谈时果然很严Q偶不是计算机科班出w的Q虽然C++用的不是炉火U青Q但也有两三q的基础Q对基本概念都是懂的,可是要我按书本上背出来,让我有点难以接受Q也背不出来啊)?br>至于题目的难度,有用的C++的朋友,应该都是了解的。还有就是那个主E一直想让我讲优点和~点Q估计是Z岗位安排考虑Q可是俺一直找不来自已的特Ԍq算是我面试的|W吧。最大的败笔可能是对Z的MMQ说了句q考题太EASY了?br>7.带去代码用的调试环境太高Q这是我的错Q哎Q谁让我的开发环境是VISTA+VC2008Q嗯Q难道ND都没有一台电(sh)脑跑q个的?
那主E说E序打不开。哎Q我的错。直觉告诉我Q这个主E比华ؓ面试官差多了Q简直是两个档次的。以前,在和华ؓ的交时Q那态度啊,对代码的分析Q都很不错。可怜,那时我刚学C++Q傻乎乎的就跑去面试Q华为招g+C的比较多Q和偶的不适合Q我不懂数字?sh)\Q模늭g斚w的知识)?br>8.我说了我的优势在Ҏ(gu)学的了解上,比如矩阵可能在引擎上有一定的应用。那ȝ直接和我_数学在游戏开发上应用不太。我忽视了,ND好像用的是UNREALQ别人的引擎Q不用自已开发底层吧Q?br>C++
1.什么是l承Q?br>2.什么是多态性?
3.什么是Iterator,有什么作用?
4.STL是什么?
5.STACK,LIST和MAP有什么不同?
6.什么是重蝲Qoverloading)和重写(overridding)Q有什么区别?
7.多线E有几种。。。?
8.MUTEX和CRITICALSECTION有什么区别?
9.ENTERCRITICALSECTION和TRYENTERCRITICALSECTION有什么不同?
D3D
1.材质是什么?有些什么元素?
2.LOD时生T型裂~和呼吸效应Q有什么优化方案?
3.解HDR技术?
4.什么是BILLBOARDQ怎么实现Q?br>5.什么是BSP?用在室内q是室外Q怎么实现Q?br>6.模板~冲区的应用Q?br>7.逆矩阉|什么应用?
面试Ӟ
1.D3D或ONPENGLQ实C个三角ŞQ(q程Q?br>2.用过什么物理引擎?
3.用过什么脚本?
4.自已的优~点Q?br>5.有什么作品ƈ介绍Q?br>6.?D中的什么最熟?zhn)Q?br>ȝQ|军之,谈什么都是没用的Q找不到好工作苦的是自已Q赶快加pw的修养。特别是表达和沟通能力?

bloodbao 2008-05-08 14:38 发表评论
]]>
anorasi目剖析Q?Q?/title><link>http://www.shnenglu.com/bloodbao/archive/2008/05/08/49187.html</link><dc:creator>bloodbao</dc:creator><author>bloodbao</author><pubDate>Thu, 08 May 2008 02:31:00 GMT</pubDate><guid>http://www.shnenglu.com/bloodbao/archive/2008/05/08/49187.html</guid><wfw:comment>http://www.shnenglu.com/bloodbao/comments/49187.html</wfw:comment><comments>http://www.shnenglu.com/bloodbao/archive/2008/05/08/49187.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/bloodbao/comments/commentRss/49187.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/bloodbao/services/trackbacks/49187.html</trackback:ping><description><![CDATA[<p>该项目用INI来实现数据的d?br>比如Q?br>1.节点d<br>INI部分Q?br>外观<br>Look<br> Body<br>  model=impreza.3ds<br>  scale=1 1 1<br> Wheels<br>  model=wheel.3ds<br>  scale=1 1 1<br>声音<br>Sound<br> Engine<br>  wave=206_engine.wav<br>  pitch_low=0.2<br>  pitch_high=1.5<br>E序部分Q?br>//load car</p> <p> body.node=loadModel(cfg, "Look/Body/", device, sm, driver);</p> <p> body.node_debug=sm->addCubeSceneNode(1, 0, -1, core::vector3df(0, 0, 0), core::vector3df(0, 0, 0),<br>  cfg.Getval_vector("Body/Chassis/1/scale", core::vector3df(1, 1, 1))<br>  );<br> body.node_debug->setMaterialTexture(0, driver->getTexture("data/misc/checked.jpg"));<br>2.车轮的属?br> Wheel #default<br>  damp=30000<br>  spring=50000<br>  radius=0.38<br>  weight=20<br>  width=0.10 #not yet used if user specifies wheel model<br>  brakes=0 # 0.0 - 1.0<br> Wheel_1 #fl<br>  pos=1.39 -0.145 0.823<br>  attr=STEER<br>  brakes=0.8<br>  rotation_z=1.5707963 #used just by client part<br> Wheel_2 #fr<br>  pos=1.39 -0.145 -0.823<br>  attr=STEER<br>  brakes=0.8<br>  rotation_z=4.7123889<br> Wheel_3 #rl<br>  pos=-1.350 -0.15 0.823<br>  attr=STRAIGHT|THURST<br>  brakes=0.2<br>  rotation_z=1.5707963<br> Wheel_4 #rr<br>  pos=-1.350 -0.15 -0.823<br>  attr=STRAIGHT|THURST<br>  brakes=0.2<br>  rotation_z=4.7123889<br>for (int i=0; ; i++) {<br>  char buf2[128];</p> <p>  sprintf(buf2, "Body/Wheel_%d/", i+1);<br>  buf=buf2;</p> <p>  if (!cfg.Getval_exists(buf+"attr")) break;</p> <p>  double radius=cfg.Getval_double((string)buf+"radius", cfg.Getval_double("Body/Wheel/radius", 1));<br>  double width=cfg.Getval_double((string)buf+"width", cfg.Getval_double("Body/Wheel/width", 1));</p> <p>  scene::ISceneNode* node=loadModel(cfg, "Look/Wheels/", device, sm, driver);<br>  CModelAttr wm;</p> <p>  scene::IMesh* cm=CreateCylinder(25, 2, 1);<br>  scene::ISceneNode* node_debug=sm->addMeshSceneNode(cm);<br>  node_debug->setScale(core::vector3df((f32)(radius), (f32)width, (f32)(radius)));<br>  node_debug->setMaterialTexture(0, driver->getTexture("data/misc/checked.jpg"));<br>  node_debug->getMaterial(0).EmissiveColor.set(255,255,255,255);</p> <p>  wm.arot=core::vector3df((f32)cfg.Getval_double(buf+"rotation_x", 0),<br>    (f32)cfg.Getval_double(buf+"rotation_y", 0),<br>    (f32)cfg.Getval_double(buf+"rotation_z", 0));<br>  wm.node=node;<br>  wm.node_debug=node_debug;</p> <p>  wheels.push_back(wm);<br> }<br>3.声音Q-QR开动时的蘪鸣声<br> //load sounds<br> try {<br>  snd_engine = new openalpp::Source((ALbyte*)("data/cars/"+profile+"/"+cfg.Getval_str("Sound/Engine/wave")).c_str());<br>  if (!snd_engine.valid())<br>   DBGCOUT("ALUT", "Coulnd't load file", ("data/cars/"+profile+"/"+cfg.Getval_str("Sound/Engine/wave")).c_str());<br>  else {<br>   snd_engine->setGain(1);<br>   snd_engine->setPosition(0.0,0.0,0.0);<br>   snd_engine->setLooping(true);<br>  }<br>  snd_engine_pitch_low=cfg.Getval_double("Sound/Engine/pitch_low");<br>  snd_engine_pitch_high=cfg.Getval_double("Sound/Engine/pitch_high");<br> } catch(openalpp::Error e) {<br>  std::cerr << e << "\n";<br> }</p> <img src ="http://www.shnenglu.com/bloodbao/aggbug/49187.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/bloodbao/" target="_blank">bloodbao</a> 2008-05-08 10:31 <a href="http://www.shnenglu.com/bloodbao/archive/2008/05/08/49187.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ODE?/title><link>http://www.shnenglu.com/bloodbao/archive/2008/05/08/49186.html</link><dc:creator>bloodbao</dc:creator><author>bloodbao</author><pubDate>Thu, 08 May 2008 02:27:00 GMT</pubDate><guid>http://www.shnenglu.com/bloodbao/archive/2008/05/08/49186.html</guid><wfw:comment>http://www.shnenglu.com/bloodbao/comments/49186.html</wfw:comment><comments>http://www.shnenglu.com/bloodbao/archive/2008/05/08/49186.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.shnenglu.com/bloodbao/comments/commentRss/49186.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/bloodbao/services/trackbacks/49186.html</trackback:ping><description><![CDATA[<p>ODE常用变量Q?br>dWorldID world;<br>dSpaceID space;<br>dJointGroupID  contactgroup;<br>dBodyID body;<br>dGeomID geom;<br>初始化:<br>void InitODE(){<br> dInitODE();<br> world=dWorldCreate();<br> space=dHashSpaceCreate(0);<br> contactgroup=dJointGroupCreate(0);<br> dWorldSetGravity(world,0,-9.8,0);<br>}<br>回调函数Q计碰撞点<br>void nearCallback(void* node, dGeomID o1, dGeomID o2)<br>{<br>  int i=0;<br>  dBodyID b1=dGeomGetBody(o1);<br>  dBodyID b2=dGeomGetBody(o2);<br>  const int MAX_CONTACTS = 8;<br>  if(b1 && b2 && dAreConnectedExcluding(b1,b2,dJointTypeContact))return;<br>  dContact contact[MAX_CONTACTS];<br>    for(i=0;i<MAX_CONTACTS;++i)<br>  {<br>    contact[i].surface.mode=dContactBounce | dContactSoftCFM;<br>    contact[i].surface.mu=100000.0;<br>    contact[i].surface.mu2=.00001;<br>    contact[i].surface.bounce=.2;<br>    contact[i].surface.bounce_vel=.1;<br>    contact[i].surface.soft_cfm=.0000001;<br>  }<br>    int numc=dCollide(o1,o2,MAX_CONTACTS,&contact[0].geom,sizeof(dContact));<br>  if(numc>0)<br>  {<br>    for(i=0;i<numc;i++)<br>    {<br>      dJointID c=dJointCreateContact(world,contactgroup,&contact[i]);<br>      dJointAttach(c,b1,b2);<br>    }<br>  }<br>}<br>E序d@?br>while(device->run())<br> {<br>  setPosition(geom);<br>  dJointGroupEmpty (contactgroup);    //清空撞点组<br>  driver->beginScene(true, true, SColor(0,200,200,200));<br>  dSpaceCollide (space,0,&nearCallback); //通过回调函数计算撞点等数据<br>  dWorldQuickStep(world,0.025); //使物理世界随着旉变化<br>  smgr->drawAll();<br>  guienv->drawAll();</p> <p>  driver->endScene();<br> }</p> <img src ="http://www.shnenglu.com/bloodbao/aggbug/49186.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/bloodbao/" target="_blank">bloodbao</a> 2008-05-08 10:27 <a href="http://www.shnenglu.com/bloodbao/archive/2008/05/08/49186.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>rain析(待改Q?/title><link>http://www.shnenglu.com/bloodbao/archive/2008/05/08/49184.html</link><dc:creator>bloodbao</dc:creator><author>bloodbao</author><pubDate>Thu, 08 May 2008 02:25:00 GMT</pubDate><guid>http://www.shnenglu.com/bloodbao/archive/2008/05/08/49184.html</guid><wfw:comment>http://www.shnenglu.com/bloodbao/comments/49184.html</wfw:comment><comments>http://www.shnenglu.com/bloodbao/archive/2008/05/08/49184.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/bloodbao/comments/commentRss/49184.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/bloodbao/services/trackbacks/49184.html</trackback:ping><description><![CDATA[<p><img src="http://www.shnenglu.com/images/cppblog_com/bloodbao/sshot_lg.jpg" border=0><br>概要Q雨_子每刻的动M用输出流Q在每一帧都使用geometry Shader扩成billboard.<br>最后,雨粒子的渲染使用的纹理库存储在一个纹理阵列。用DX10和GeForce8 pdGPU?br>1.应用风和重力使粒子一直在作动甅R?br>2.把粒子扩成要在每一帧渲染的_?br>3.渲染_<br>1.Q?QC++使用输出?br>//讄渲染点列表,每个_子存一个顶炏V?br>pd3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_POINTLIST);<br>pd3dDevice->IASetInputLayout(g_pVertexLayoutRainVertex);<br>//军_哪个点~冲我们既将要渲?br>假如q是W一帧我们渲染一个预产生的顶点g_pParticleStart<br> static bool firstFrame=true;<br> ID3D10Buffer* pBuffers[1];<br> if(firstFrame)<br>  pBuffers[0]=g_pParticleStart;<br> else<br>  pBuffers[0]=g_pParticleDrawFrom;<br> pDevice->IASetVertexBuffers(0,1,pBuffers,stride,offset);<br> //指向正确的输出缓?br> pBuffers[0] = g_pParticleStreamTo;<br>        pd3dDevice->SOSetTargets( 1, pBuffers, offset );<br>        <br>        // dQɾ_子动画<br>        D3D10_TECHNIQUE_DESC techDesc;<br>        g_pTechniqueAdvanceRain->GetDesc( &techDesc );<br>        g_pTechniqueAdvanceRain->GetPassByIndex(0)->Apply(0);</p> <p>        pd3dDevice->Draw(g_numRainVertices , 0 );</p> <p>        // Get back to normal<br>        pBuffers[0] = NULL;<br>        pd3dDevice->SOSetTargets( 1, pBuffers, offset );</p> <p>        // Swap buffers交换~冲?br>        ID3D10Buffer* pTemp = g_pParticleDrawFrom;<br>        g_pParticleDrawFrom = g_pParticleStreamTo;<br>        g_pParticleStreamTo = pTemp;<br>    <br>        firstFrame = false;<br>2.Q?QHLSLQ-使用Geometry shader Expanding</p> <p>GeometryShader gsStreamOut = ConstructGSWithSO( CompileShader( vs_4_0, VSAdvanceRain() ), "POSITION.xyz; SEED.xyz; SPEED.xyz; RAND.x; TYPE.x" );  <br>technique10 AdvanceParticles<br>{<br>    pass p0<br>    {<br>        SetVertexShader( CompileShader( vs_4_0, VSAdvanceRain() ) );<br>        SetGeometryShader( gsStreamOut );<br>        SetPixelShader( NULL );<br>        <br>        SetDepthStencilState( DisableDepth, 0 );<br>    }  <br>}<br>Q?QHLSLQ-使用Geometry shader Extruding<br>// GS for rendering rain as point sprites.  Takes a point and turns it into 2 tris.<br>[maxvertexcount(4)]<br>void GSRenderRain(point VSParticleIn input[1], inout TriangleStream<PSSceneIn> SpriteStream)<br>{<br>    float totalIntensity = g_PointLightIntensity*g_ResponsePointLight + dirLightIntensity*g_ResponseDirLight;<br>    if(!cullSprite(input[0].pos,2*g_SpriteSize) && totalIntensity > 0)<br>    {    <br>        PSSceneIn output = (PSSceneIn)0;<br>        output.type = input[0].Type;<br>        output.random = input[0].random;<br>       <br>        float3 pos[4];<br>        GenRainSpriteVertices(input[0].pos.xyz, input[0].speed.xyz/g_FrameRate + g_TotalVel, g_eyePos, pos);<br>        <br>        float3 closestPointLight = g_PointLightPos;<br>        float closestDistance = length(g_PointLightPos - pos[0]);<br>        if( length(g_PointLightPos2 - pos[0]) < closestDistance )<br>           closestPointLight = g_PointLightPos2;<br>        <br>        output.pos = mul( float4(pos[0],1.0), g_mWorldViewProj );<br>        output.lightDir = g_lightPos - pos[0];<br>        output.pointLightDir = closestPointLight - pos[0];<br>        output.eyeVec = g_eyePos - pos[0];<br>        output.tex = g_texcoords[0];<br>        SpriteStream.Append(output);<br>                <br>        output.pos = mul( float4(pos[1],1.0), g_mWorldViewProj );<br>        output.lightDir = g_lightPos - pos[1];<br>        output.pointLightDir = closestPointLight - pos[1];<br>        output.eyeVec = g_eyePos - pos[1];<br>        output.tex = g_texcoords[1];<br>        SpriteStream.Append(output);<br>        <br>        output.pos = mul( float4(pos[2],1.0), g_mWorldViewProj );<br>        output.lightDir = g_lightPos - pos[2];<br>        output.pointLightDir = closestPointLight - pos[2];<br>        output.eyeVec = g_eyePos - pos[2];<br>        output.tex = g_texcoords[2];<br>        SpriteStream.Append(output);<br>                <br>        output.pos = mul( float4(pos[3],1.0), g_mWorldViewProj );<br>        output.lightDir = g_lightPos - pos[3];<br>        output.pointLightDir = closestPointLight - pos[3];<br>        output.eyeVec = g_eyePos - pos[3];<br>        output.tex = g_texcoords[3];<br>        SpriteStream.Append(output);<br>        <br>        SpriteStream.RestartStrip();<br>    }   <br>}</p> <p>3.<br>渲染点精?br>使用DX10新特性Texture Array<br>渲染?br>q行范例Q?br>范例昄两个点光源和一条直光下的桥?br>左键控制直射光?br></p> <img src ="http://www.shnenglu.com/bloodbao/aggbug/49184.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/bloodbao/" target="_blank">bloodbao</a> 2008-05-08 10:25 <a href="http://www.shnenglu.com/bloodbao/archive/2008/05/08/49184.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Racehttp://www.shnenglu.com/bloodbao/archive/2008/05/06/49052.htmlbloodbaobloodbaoTue, 06 May 2008 13:28:00 GMThttp://www.shnenglu.com/bloodbao/archive/2008/05/06/49052.htmlhttp://www.shnenglu.com/bloodbao/comments/49052.htmlhttp://www.shnenglu.com/bloodbao/archive/2008/05/06/49052.html#Feedback0http://www.shnenglu.com/bloodbao/comments/commentRss/49052.htmlhttp://www.shnenglu.com/bloodbao/services/trackbacks/49052.html

bloodbao 2008-05-06 21:28 发表评论
]]>
crimson projecthttp://www.shnenglu.com/bloodbao/archive/2008/05/04/48788.htmlbloodbaobloodbaoSun, 04 May 2008 07:37:00 GMThttp://www.shnenglu.com/bloodbao/archive/2008/05/04/48788.htmlhttp://www.shnenglu.com/bloodbao/comments/48788.htmlhttp://www.shnenglu.com/bloodbao/archive/2008/05/04/48788.html#Feedback1http://www.shnenglu.com/bloodbao/comments/commentRss/48788.htmlhttp://www.shnenglu.com/bloodbao/services/trackbacks/48788.html

bloodbao 2008-05-04 15:37 发表评论
]]>
newton冲突Q-QFOR IRRLICHThttp://www.shnenglu.com/bloodbao/archive/2008/05/04/48762.htmlbloodbaobloodbaoSun, 04 May 2008 04:20:00 GMThttp://www.shnenglu.com/bloodbao/archive/2008/05/04/48762.htmlhttp://www.shnenglu.com/bloodbao/comments/48762.htmlhttp://www.shnenglu.com/bloodbao/archive/2008/05/04/48762.html#Feedback0http://www.shnenglu.com/bloodbao/comments/commentRss/48762.htmlhttp://www.shnenglu.com/bloodbao/services/trackbacks/48762.html//Function to create a NewtonCollision from irrlicht mesh 
NewtonCollision 
*CreateCollisionFromMesh(NewtonWorld *nWorld, scene::IMesh *mesh) 

  
//Get number of vertices 
  u32 nVertices 
= 0, nMeshBuffer; 
  
for( nMeshBuffer = 0 ; nMeshBuffer < mesh->getMeshBufferCount(); ++nMeshBuffer) 
  { 
    scene::IMeshBuffer 
*buffer = mesh->getMeshBuffer(nMeshBuffer); 
    nVertices 
+= buffer->getVertexCount(); 
  } 

  
// allocate block for positions of every vertex in mesh, no need to delete 
  
// anything, the array cleans up for us. 
  core::
array<core::vector3df> vertices; 
  vertices.reallocate(nVertices); 

  
//Get mesh buffers and copy face vertices 
  
for( nMeshBuffer = 0 ; nMeshBuffer < mesh->getMeshBufferCount(); ++nMeshBuffer) 
  { 
    scene::IMeshBuffer 
*buffer = mesh->getMeshBuffer(nMeshBuffer); 

    
// handle the irrlicht supported vertex types 
    switch(buffer
->getVertexType()) 
    { 
    
case video::EVT_STANDARD: 
      { 
        video::S3DVertex
* verts = (video::S3DVertex*)buffer->getVertices(); 
        
for(u32 v = 0; v < buffer->getVertexCount(); ++v) 
          vertices.push_back(verts[v].Pos); 
      } 
      break; 

    
case video::EVT_2TCOORDS: 
      { 
        video::S3DVertex2TCoords
* verts = (video::S3DVertex2TCoords*)buffer->getVertices(); 
        
for(u32 v = 0; v < buffer->getVertexCount(); ++v) 
          vertices.push_back(verts[v].Pos); 
      } 
      break; 

    
case video::EVT_TANGENTS: 
      { 
        video::S3DVertexTangents
* verts = (video::S3DVertexTangents*)buffer->getVertices(); 
        
for(u32 v = 0; v < buffer->getVertexCount(); ++v) 
          vertices.push_back(verts[v].Pos); 
      } 
      break; 

    default: 
      return 
0// don't know vertex type! bail. 
    } 
  } 

  
//Create Newton collision object 
  return NewtonCreateConvexHull(nWorld, nVertices, 
&vertices[0].X, sizeof(core::vector3df), NULL); 
}

core::
array<f32> vertices; 
vertices.reallocate(nVertices 
* 3); 

// each loop should be updated 
for(u32 v = 0; v < buffer->getVertexCount(); ++v) 

  vertices.push_back(verts[v].Pos.X); 
  vertices.push_back(verts[v].Pos.Y); 
  vertices.push_back(verts[v].Pos.Z); 


// this should be passed to the convex hull function 
return NewtonCreateConvexHull(nWorld, nVertices, 
&vertices[0], sizeof(f32 * 3), NULL);

bloodbao 2008-05-04 12:20 发表评论
]]>
MARK,单笔?/title><link>http://www.shnenglu.com/bloodbao/archive/2008/05/04/48761.html</link><dc:creator>bloodbao</dc:creator><author>bloodbao</author><pubDate>Sun, 04 May 2008 04:17:00 GMT</pubDate><guid>http://www.shnenglu.com/bloodbao/archive/2008/05/04/48761.html</guid><wfw:comment>http://www.shnenglu.com/bloodbao/comments/48761.html</wfw:comment><comments>http://www.shnenglu.com/bloodbao/archive/2008/05/04/48761.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/bloodbao/comments/commentRss/48761.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/bloodbao/services/trackbacks/48761.html</trackback:ping><description><![CDATA[<p>IRRLICHT的实玎ͼ<br>1.波浪是如何实现的Q?br>先对每个点计高度,<br></p> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">void addWave(vector3df</span><span style="COLOR: #000000">&</span><span style="COLOR: #000000"> dest, </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> vector3df source, f32 </span><span style="COLOR: #0000ff">time</span><span style="COLOR: #000000">) <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>{ <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>     dest.Y </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> source.Y </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"><br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top> (sinf(((source.X</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">WaveLength) </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">time</span><span style="COLOR: #000000">)) </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> WaveHeight) </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"><br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top> (cosf(((source.Z</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">WaveLength) </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">time</span><span style="COLOR: #000000">)) </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> WaveHeight);<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>}</span></div> <p><br>然后再计法U,<br>recalculateNormals(Mesh);<br>2.ATMOSphere<br>太阳嘛,是个跟随时间移动的BILLBOARD,边缘最好加上雾化效果?br>3.地Ş~辑器代?br></p> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">( Terrain </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> !RightMouseDown </span><span style="COLOR: #000000">&&</span><span style="COLOR: #000000"> Terrain</span><span style="COLOR: #000000">-></span><span style="COLOR: #000000">getTriangleSelector() )<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>{<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>LastMousePosition.set( Device</span><span style="COLOR: #000000">-></span><span style="COLOR: #000000">getCursorControl()</span><span style="COLOR: #000000">-></span><span style="COLOR: #000000">getPosition().X, Device</span><span style="COLOR: #000000">-></span><span style="COLOR: #000000">   getCursorControl()</span><span style="COLOR: #000000">-></span><span style="COLOR: #000000">getPosition().Y );<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">//</span><span style="COLOR: #000000">计算从鼠标位|到观察点的线<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>core::line3df line </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> CollisionMgr</span><span style="COLOR: #000000">-></span><span style="COLOR: #000000">getRayFromScreenCoordinates( <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top> core::position2d</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">s32</span><span style="COLOR: #000000">></span><span style="COLOR: #000000">( LastMousePosition.X, LastMousePosition.Y ) );<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">//</span><span style="COLOR: #000000">计算以交点ؓ中心Q一定半径范围内的点<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>core::vector3df spherePosition;<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">( CollisionMgr</span><span style="COLOR: #000000">-></span><span style="COLOR: #000000">getClosestVertex( line, Terrain</span><span style="COLOR: #000000">-></span><span style="COLOR: #000000">getTriangleSelector(), <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top> spherePosition, CurrentVertexIndex ) )<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>      {<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>       LeftMouseDown </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>       </span><span style="COLOR: #000000">//</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">Get</span><span style="COLOR: #000000"> all vertices </span><span style="COLOR: #0000ff">with</span><span style="COLOR: #000000"> the circle<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>       SelectedTerrainVertices.clear();<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>       core::vector3df intersection;<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>       scene::SCollisionTriangle tri;<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>       </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">( CollisionMgr</span><span style="COLOR: #000000">-></span><span style="COLOR: #000000">getCollisionPoint( line, Terrain</span><span style="COLOR: #000000">-></span><span style="COLOR: #000000">getTriangleSelector(), intersection, tri ) )<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>       {<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>        u32 count </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>        SelectedTerrainVertices.reallocate( Terrain</span><span style="COLOR: #000000">-></span><span style="COLOR: #000000">getTriangleSelector()</span><span style="COLOR: #000000">-></span><span style="COLOR: #000000">getTriangleCount() );<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>        Terrain</span><span style="COLOR: #000000">-></span><span style="COLOR: #000000">getTriangleSelector()</span><span style="COLOR: #000000">-></span><span style="COLOR: #000000">getVerticesInRadius( SelectedTerrainVertices.pointer(), Terrain</span><span style="COLOR: #000000">-></span><span style="COLOR: #000000">getTriangleSelector()</span><span style="COLOR: #000000">-></span><span style="COLOR: #000000">getTriangleCount(), count, intersection, RedCircleRadius );<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>        SelectedTerrainVertices.set_used( count );<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>       }<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>       return </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>      }<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>     }<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span></div> <br><img src="http://www.shnenglu.com/images/cppblog_com/bloodbao/draft.jpg" border=0> <img src ="http://www.shnenglu.com/bloodbao/aggbug/48761.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/bloodbao/" target="_blank">bloodbao</a> 2008-05-04 12:17 <a href="http://www.shnenglu.com/bloodbao/archive/2008/05/04/48761.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ATMOSphere----日夜循环http://www.shnenglu.com/bloodbao/archive/2008/05/01/48594.htmlbloodbaobloodbaoThu, 01 May 2008 08:40:00 GMThttp://www.shnenglu.com/bloodbao/archive/2008/05/01/48594.htmlhttp://www.shnenglu.com/bloodbao/comments/48594.htmlhttp://www.shnenglu.com/bloodbao/archive/2008/05/01/48594.html#Feedback0http://www.shnenglu.com/bloodbao/comments/commentRss/48594.htmlhttp://www.shnenglu.com/bloodbao/services/trackbacks/48594.html



bloodbao 2008-05-01 16:40 发表评论
]]>
VolumeLightSceneNodehttp://www.shnenglu.com/bloodbao/archive/2008/05/01/48573.htmlbloodbaobloodbaoThu, 01 May 2008 03:16:00 GMThttp://www.shnenglu.com/bloodbao/archive/2008/05/01/48573.htmlhttp://www.shnenglu.com/bloodbao/comments/48573.htmlhttp://www.shnenglu.com/bloodbao/archive/2008/05/01/48573.html#Feedback0http://www.shnenglu.com/bloodbao/comments/commentRss/48573.htmlhttp://www.shnenglu.com/bloodbao/services/trackbacks/48573.html



bloodbao 2008-05-01 11:16 发表评论
]]>
SceneEdit试版上?/title><link>http://www.shnenglu.com/bloodbao/archive/2008/04/30/48544.html</link><dc:creator>bloodbao</dc:creator><author>bloodbao</author><pubDate>Wed, 30 Apr 2008 11:22:00 GMT</pubDate><guid>http://www.shnenglu.com/bloodbao/archive/2008/04/30/48544.html</guid><wfw:comment>http://www.shnenglu.com/bloodbao/comments/48544.html</wfw:comment><comments>http://www.shnenglu.com/bloodbao/archive/2008/04/30/48544.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/bloodbao/comments/commentRss/48544.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/bloodbao/services/trackbacks/48544.html</trackback:ping><description><![CDATA[<p>现将场景~辑器测试版上传Q望q大朋友试Q多谢!<br>l过一周的改写Q完成部分功能,q个版本非完全版?br>下蝲地址Q?a >http://pickup.mofile.com/7877768148587694</a><br>׃n提取码:7877768148587694<br>囄在本博客都有Q?br>VISTA下测试通过Q?br>嗯,昑֍臛_要DX9吧,下一阶段把草圎ͼ水面Q碰撞补齐!</p> <img src ="http://www.shnenglu.com/bloodbao/aggbug/48544.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/bloodbao/" target="_blank">bloodbao</a> 2008-04-30 19:22 <a href="http://www.shnenglu.com/bloodbao/archive/2008/04/30/48544.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.monggo.cn" target="_blank">vĻþ</a>| <a href="http://www.qdyshl.cn" target="_blank">vĻþ</a>| <a href="http://www.pnpxnc.cn" target="_blank">þþƷۺһ</a>| <a href="http://www.shishanfz.cn" target="_blank">ƷþþӰ㽶</a>| <a href="http://www.snailwr.cn" target="_blank">þþƷŷպ</a>| <a href="http://www.benok.cn" target="_blank">ĻƷþþþ</a>| <a href="http://www.hrwp.net.cn" target="_blank">պavþþƷ</a>| <a href="http://www.chazhaoyouhui.cn" target="_blank">97þ㽶߿ۿ</a>| <a href="http://www.dicy888.cn" target="_blank">Ʒ˾þþþþþ</a>| <a href="http://www.badnao.cn" target="_blank">պݺݾþ͵͵ɫۺ </a>| <a href="http://www.hetiandai.cn" target="_blank">þþþþaëƬ</a>| <a href="http://www.9xz.com.cn" target="_blank">þþžȫ</a>| <a href="http://www.nxol.net.cn" target="_blank">ŷƷһþ</a>| <a href="http://www.4o2ptp.cn" target="_blank">ŷvaþþþ</a>| <a href="http://www.dhxxw.cn" target="_blank">Ʒ99þþƷ</a>| <a href="http://www.fjzgh.cn" target="_blank">鶹Ʒþþþþþ99</a>| <a href="http://www.oahk.cn" target="_blank">Ʒһþ㽶߿ </a>| <a href="http://www.dgjiajun.net.cn" target="_blank">þþþþþþƷɫ</a>| <a href="http://www.linkyes.cn" target="_blank">þþþŮAAƬ</a>| <a href="http://www.uzri.cn" target="_blank">þseֻоƷ</a>| <a href="http://www.chainou.cn" target="_blank">ɫۺϾþþþһ</a>| <a href="http://www.haiyunfu.cn" target="_blank">þ99Ʒþ99ý</a>| <a href="http://www.callmanager.cn" target="_blank">ľþþþ</a>| <a href="http://www.ichz.cn" target="_blank">ȾþֻоƷ</a>| <a href="http://www.rolanskin.cn" target="_blank">þþþþþƷþþþ</a>| <a href="http://www.changde8.cn" target="_blank">Ʒ˿þþþþò</a>| <a href="http://www.musqm.cn" target="_blank">޹Ʒþþ</a>| <a href="http://www.royfq.cn" target="_blank">þۺϾƷһ</a>| <a href="http://www.37photo.com.cn" target="_blank">볬鱬Ļþ</a>| <a href="http://www.cysq88.cn" target="_blank">þþþAV</a>| <a href="http://www.hxstone.com.cn" target="_blank">þҹɫƷAV</a>| <a href="http://www.c6t9.cn" target="_blank">޹˾þþƷ99</a>| <a href="http://www.0577114.cn" target="_blank">þþƷ99Ʒ </a>| <a href="http://www.g33e.cn" target="_blank">Ʒþþþù </a>| <a href="http://www.dywanjiale.cn" target="_blank">þþþ޾Ʒһ</a>| <a href="http://www.6dou.net.cn" target="_blank">˳þõӰվ</a>| <a href="http://www.cnhtyy.cn" target="_blank">99þ99þþƷƬ </a>| <a href="http://www.bukrrlg.cn" target="_blank">ھƷþþþþ99</a>| <a href="http://www.markey.com.cn" target="_blank">AƬٸþ</a>| <a href="http://www.hzyzhongyuan.cn" target="_blank">þù׾Ʒҹ</a>| <a href="http://www.kunqun168.cn" target="_blank">þþƷ鶹</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>