⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csdn_文档中心_alpha 闪烁效果.htm

📁 csdn10年中间经典帖子
💻 HTM
📖 第 1 页 / 共 4 页
字号:
      color_mode = rand() % NumColorModes;
   }
//0..5 0==无变化,1==饱和色,2==宝石色,3==柔和色,   //     4==亮色,5==暗色和冷色,<BR>但不适用于大多数情况,
   color_modifier_age--;
   if (color_modifier_age == 0) {
      color_modifier_age = min_color_modifier_age + (int)(rnd()* 
(max_color_modifier_age - min_color_modifier_age));
      color_modifier_mode = rand() % NumColorModifierModes;
   }
   //更新闪烁效果
   for (i=0; i&lt;nCurNumSparkles; i++) {
      sparkle[i].cur_age--;
      if (sparkle[i].cur_age == 0) {
         sparkle[i] = RandomSparkle();
      }
      sparkle[i].scale *= sparkle[i].delta_scale;
   }

}  // UpdateSparkles() 结束
</PRE>
            <P><B><FONT face=arial>DrawSparkles</B></FONT> 
            对粒子系统定位代码中使用的前面方向进行计算。该值被用来生成每个粒子各顶点的偏移量。图 5 对此进行了说明。</P><IMG 
            alt=粒子定位示意图 border=0 height=300 
            src="CSDN_文档中心_Alpha 闪烁效果.files/directx0900-5.gif" width=300> 
            <P><B>图 5. 粒子定位</B></P>
            <P>为了提高效率,闪烁效果按绘制的纹理进行排序。索引列表及 <B><FONT 
            face=arial>DrawIndexedPrimitive</B></FONT> 用来绘制粒子系统的四边形。</P><PRE class=clsCode>BOOL DrawSparkles(LPDIRECT3DDEVICE7 lpDev, D3DVECTOR from, D3DVECTOR at)
{
      D3DVECTOR   view_dir, position, dx, dy;
      UINT        i;

      view_dir = Normalize(at - from);
      dx = CrossProduct(view_dir, D3DVECTOR(0.0f, 1.0f, 0.0f));
      dy = CrossProduct(view_dir, dx);
      dx = CrossProduct(view_dir, dy);

      // 绘制闪烁效果
      // 为提高效率,我们要将所有使用相同纹理的闪烁效果
      // 批量处理并只进行一次 DrawPrim 调用
      int   flags[NumTextures];
      for (int tex=0; tex&lt;NumTextures; tex++) {
            flags[tex] = 0;
      }
      // 计算出正在使用哪些纹理
      for (i=0; i&lt;nCurNumSparkles; i++) {
            flags[sparkle[i].texture]++;
      }
      // 对于每种使用的纹理,批量处理闪烁效果并进行绘制
      for (tex=0; tex&lt;NumTextures; tex++) {
            if (flags[tex] == 0)
                  continue;

            // 设置正确的材质/纹理组合 
            lpDev-&gt;SetTexture(0,g_ptexSparkleTextures[tex]);
            
            //建造用于批处理的四边形
            int   num = 0;
            for (i=0; i&lt;nCurNumSparkles; i++) {
                  if (sparkle[i].texture != tex)
                        continue;

                  D3DVECTOR   sx  = dx * sparkle[i].scale;
                  D3DVECTOR   sy  = dy * sparkle[i].scale;
                  float       color_scale = (float)sparkle[i].cur_age /
                                     sparkle[i].age;
                  D3DVECTOR   cur_color = sparkle[i].color * color_scale;
                  D3DCOLOR    color = D3DRGB(cur_color[0], cur_color[1], 
                                     cur_color[2]);
                  position = sparkle[i].position;
                  s_mesh[num*4+0] = D3DLVERTEX(position+sx+sy, color, 0, 
                                                 1.0f, 1.0f);
                  s_mesh[num*4+1] = D3DLVERTEX(position-sx+sy, color, 0,
                                                 0.0f, 1.0f);
                  s_mesh[num*4+2] = D3DLVERTEX(position-sx-sy, color, 0,
                                                 0.0f, 0.0f);
                  s_mesh[num*4+3] = D3DLVERTEX(position+sx-sy, color, 0,
                                                 1.0f, 0.0f);
                  num++;
            }
            // 已完成批处理的创建,现在进行着色
            if (lpDev-&gt;DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
                                           D3DFVF_LVERTEX, (LPVOID)s_mesh,
                                           4*flags[tex], s_indices,
                                           6*flags[tex], 0) != D3D_OK)
                  return FALSE;
      }
      return TRUE;
}     // DrawSparkles() 结束
</PRE>
            <P>图 6 和图 7 显示了由 alpha 混色粒子系统产生的图像的附加屏幕快照。</P><IMG alt=屏幕保护程序的屏幕快照 
            border=0 height=338 
            src="CSDN_文档中心_Alpha 闪烁效果.files/directx0900-6.jpg" width=450> 
            <P><B>图 6. <FONT face=arial>MSDNSparkles</FONT> 屏幕快照 2</B></P><IMG 
            alt=屏幕保护程序的屏幕快照 border=0 height=338 
            src="CSDN_文档中心_Alpha 闪烁效果.files/directx0900-7.jpg" width=450> 
            <P><B>图 7. <FONT face=arial>MSDNSparkles</FONT> 屏幕快照 3</B></P>
            <P><B><FONT class=105v><FONT face=arial><FONT size=3>MSDNSparkles 
            的内部构件</FONT></B></FONT><FONT size=3> </FONT></FONT>
            <P>让我们继续探讨过载应用程序函数的实现过程。我在下面重新列出了函数的原型,这样您就不必回卷到本文开始的地方。我将对 Direct3D 
            屏幕保护程序框架允许覆盖的每个过载函数进行考查。</P><PRE class=clsCode>//--------------------------------------------------------------------------
// 外部函数原型
//--------------------------------------------------------------------------
HRESULT App_ConfirmDevice( DDCAPS*, D3DDEVICEDESC* );
HRESULT App_OneTimeSceneInit();
VOID    App_DeleteDeviceObjects( HWND, LPDIRECT3DDEVICE7 );
HRESULT App_InitDeviceObjects( HWND, LPDIRECT3DDEVICE7 );
HRESULT App_FrameMove( LPDIRECT3DDEVICE7, FLOAT );
HRESULT App_Render( LPDIRECT3DDEVICE7 );
HRESULT App_RestoreSurfaces();
HRESULT App_FinalCleanup();
</PRE>
            <P><B><FONT face=arial>ConfirmDevice</FONT> </B>
            <P>MSDNSparkles <B><FONT face=arial>App_ConfirmDevice</B></FONT> 
            函数验证设备是否能够进行 ONE:ONE alpha 混色。这是 alpha 最简单的形式 — 
            并且,根据我的经验,所有的显卡都可以执行这种 alpha 混色。下面是 MSDNSparkles 实现 <B><FONT 
            face=arial>App_ConfirmDevice</B></FONT> 的过程。</P><PRE class=clsCode>HRESULT App_ConfirmDevice( DDCAPS* pddDriverCaps,
                           D3DDEVICEDESC7* pd3dDeviceDesc )
{
   // 获取 triangle caps(硬件或软件),并检验 alpha 混色
   LPD3DPRIMCAPS pdpc = &amp;pd3dDeviceDesc-&gt;dpcTriCaps;

   if( 0 == ( pdpc-&gt;dwSrcBlendCaps &amp; pdpc-&gt;dwDestBlendCaps &amp; D3DBLEND_ONE ) )
      return E_FAIL;

    return S_OK;
} 
</PRE>
            <P><B><FONT face=arial>OneTimeSceneInit</FONT> </B>
            <P><B><FONT face=arial>App_OneTimeSceneInit</FONT></B> 
            函数首先给随机数生成器播种,并设置背景颜色和初始化纹理列表。然后,它使用纹理列表创建 MSDNSparkles 使用的纹理。最后,调用 
            <B><FONT face=arial>InitSparkles</B></FONT> 对粒子系统进行初始化。</P><PRE class=clsCode>HRESULT App_OneTimeSceneInit()
{
   // 给随机数生成器播种
   srand(time(0));

   //初始化背景颜色
   bckColor = D3DRGB(0,0,0);

   //装载纹理数据
   memcpy(g_szSparkleTextures[0],"dx5.bmp",sizeof("dx5.bmp"));
   memcpy(g_szSparkleTextures[1],"dx7.bmp",sizeof("dx7.bmp"));
   memcpy(g_szSparkleTextures[2],"flare1.bmp",sizeof("flare1.bmp"));
   memcpy(g_szSparkleTextures[3],"flare2.bmp",sizeof("flare2.bmp"));
   memcpy(g_szSparkleTextures[4],"flare3.bmp",sizeof("flare3.bmp"));
   memcpy(g_szSparkleTextures[5],"flare4.bmp",sizeof("flare5.bmp"));
   memcpy(g_szSparkleTextures[6],"flare5.bmp",sizeof("flare5.bmp"));
   memcpy(g_szSparkleTextures[7],"flare6.bmp",sizeof("flare6.bmp"));
   memcpy(g_szSparkleTextures[8],"flare7.bmp",sizeof("flare7.bmp"));
   memcpy(g_szSparkleTextures[9],"flare8.bmp",sizeof("flare8.bmp"));
   memcpy(g_szSparkleTextures[10],"shine1.bmp",sizeof("flare1.bmp"));
   memcpy(g_szSparkleTextures[11],"shine2.bmp",sizeof("flare2.bmp"));
   memcpy(g_szSparkleTextures[12],"shine3.bmp",sizeof("flare3.bmp"));
   memcpy(g_szSparkleTextures[13],"shine4.bmp",sizeof("flare5.bmp"));
   memcpy(g_szSparkleTextures[14],"shine5.bmp",sizeof("flare5.bmp"));
   memcpy(g_szSparkleTextures[15],"shine6.bmp",sizeof("flare6.bmp"));

   for ( int i = 0; i &lt; NumTextures; i++)
      D3DTextr_CreateTextureFromFile( (char *)g_szSparkleTextures[i] );

   InitSparkles();

   return S_OK;
}
</PRE>
            <P><B><FONT face=arial>InitDeviceObjects</FONT> </B>
            <P><B><FONT face=arial>App_InitDeviceObjects</B> 函数使用 helper 函数 
            <B><FONT face=arial>SetTextureState</B>、<B>SetRenderState</B> 和 
            <B>SetViewState</B></FONT>。这些函数分别对纹理列表、应用程序所使用的着色状态和查看系统进行设置。请注意,已启用了alpha 
            混色,混色状态将为加色而设置成 ONE:ONE。</P><PRE class=clsCode>void SetTextureState(LPDIRECT3DDEVICE7 pd3dDevice )
{
   // 设置纹理状态
    D3DTextr_RestoreAllTextures( pd3dDevice );
   // 装载纹理表面
   for( int i=0; i&lt;NumTextures; i++ )
      g_ptexSparkleTextures[i] = D3DTextr_GetSurface( (char *)
                                     g_szSparkleTextures[i]);
}

void SetRenderState(LPDIRECT3DDEVICE7 pd3dDevice )
{
   // alpha 混色状态
   pd3dDevice-&gt;SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);   
   pd3dDevice-&gt;SetRenderState(D3DRENDERSTATE_SRCBLEND,  srcBlend);
   pd3dDevice-&gt;SetRenderState(D3DRENDERSTATE_DESTBLEND, dstBlend);

   // 过滤器状态
   pd3dDevice-&gt;SetTextureStageState(0,D3DTSS_MINFILTER, D3DFILTER_LINEAR);
   pd3dDevice-&gt;SetTextureStageState(0,D3DTSS_MAGFILTER, D3DFILTER_LINEAR);
   pd3dDevice-&gt;SetTextureStageState(0,D3DTSS_MIPFILTER, D3DFILTER_LINEAR);

   // 设置非纹理着色状态
   pd3dDevice-&gt;SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE);
   pd3dDevice-&gt;SetRenderState(D3DRENDERSTATE_SPECULARENABLE, FALSE);
   pd3dDevice-&gt;SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE);
   pd3dDevice-&gt;SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE);
   pd3dDevice-&gt;SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);

   // 注:在 DX7 中,要关闭顶点照明,需要将 D3DRENDERSTATE_LIGHTING 设置为 FALSE
   // (并改用 D3DLVERTEX 中的颜色)
   pd3dDevice-&gt;SetRenderState( D3DRENDERSTATE_LIGHTING, FALSE );

}

void SetViewState(LPDIRECT3DDEVICE7 pd3dDevice )
{
   // 获取宽高比
   pd3dDevice-&gt;GetViewport(&amp;vp);
   FLOAT fAspect = ((FLOAT)vp.dwHeight) / vp.dwWidth;

   // 设置变换矩阵
   D3DUtil_SetProjectionMatrix( proj, 
                         g_PI/4,//1.0f;
                         fAspect, 
                         1.0f, MAX_DIST );
   pd3dDevice-&gt;SetTransform( D3DTRANSFORMSTATE_PROJECTION, &amp;proj);
   D3DUtil_SetViewMatrix( view, from, at, up );
   pd3dDevice-&gt;SetTransform( D3DTRANSFORMSTATE_VIEW, &amp;view);
   D3DUtil_SetIdentityMatrix( world );
   pd3dDevice-&gt;SetTransform( D3DTRANSFORMSTATE_WORLD, &amp;world);
}

HRESULT App_InitDeviceObjects( HWND hWnd, LPDIRECT3DDEVICE7 pd3dDevice )
{
    // 检查参数
    if( NULL==pd3dDevice )
        return E_INVALIDARG;

   // 设置纹理状态
    SetTextureState( pd3dDevice );

   // 设置着色状态
    SetRenderState( pd3dDevice );
   
   // 设置查看系统
    SetViewState( pd3dDevice );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -