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

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

📁 csdn10年中间经典帖子
💻 HTM
📖 第 1 页 / 共 4 页
字号:
HRESULT Render3DEnvironment( HWND );
VOID    Cleanup3DEnvironment( HWND );
</PRE>
            <P>这三个函数将完成设置 Direct3D、关闭 Direct3D 
            和对场景进行着色的所有操作。屏幕保护程序必须完成的所有工作就是实现可以被覆盖的函数。这些函数类似于我们已经逐渐了解和喜爱的 
            D3Dframe 对应函数;请参见下面的函数原型。</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>我使用了示例中的 screensaver.cpp,并做了最少的改动。我的确发现,从注册表中读取配置数据的调用需要将参数由:</P><PRE class=clsCode>      if( ERROR_SUCCESS == RegOpenKeyEx( HKEY_CURRENT_USER, strRegPath,
                                           KEY_READ, NULL, &amp;hKey ) )
</PRE>
            <P>调换为:</P><PRE class=clsCode>      if( ERROR_SUCCESS == RegOpenKeyEx( HKEY_CURRENT_USER, strRegPath,
                                           NULL, KEY_READ, &amp;hKey ) )
</PRE>
            <P>该示例也未能对着色窗口可能的移动进行处理,因此我在调用 <B><FONT 
            face=arial>TestCooperativeLevel()</FONT></B> 之后把以下程序块加入了 <B><FONT 
            face=arial>Render3Denvironment()</FONT></B> 函数。</P><PRE class=clsCode>   //请确保在屏幕控制面板中进行操作,监视事物的移动
   RECT rTmp;
   GetWindowRect( hWnd, &amp;rTmp );
      g_pFramework-&gt;Move(rTmp.left, rTmp.top );
</PRE>
            <P>Direct3D 屏幕保护程序框架确实给出了 ConfigureDialog 
            函数的开始部分以及一种用于存储配置数据的方法,但我尚未针对 MSDNSparkles 对其进行扩充,因为它不是一个关键细节。</P>
            <P>样例屏幕保护程序的另一个“特征”是:它使用 WM_TIMER 对着色进行控制。在基于 Windows 2000 
            的操作系统上,这会产生一个适当的帧速率,但基于 Windows9<I>x</I> 的操作系统并不具有这样一个允许使用良好帧速率的 
            WM_TIMER 
            间隔尺寸。考虑到这种情况,我重新编写了这个屏幕保护程序,使其使用线程对着色进行控制。我没有将这部分代码包括进来,因为它是一个简单明了的线程实现。有兴趣的程序员可以考虑增加多监视器功能、电源管理和口令,因为 
            Direct3D 屏幕保护程序框架没有提供这些功能。</P>
            <P><B><FONT class=105v><FONT size=3>高级别视图</FONT></B></FONT> 
            <P>既然这些细节已不成为问题,我们就可以开始了。图 3 显示了 Visual Studio Workspace 窗口针对 
            MSDNSparkles 示例的内容。该项目由 screensaver.cpp 文件(它是从 Direct3D 
            示例中得到的,如上面的讨论所述)以及 sparkles.cpp 组成。</P><IMG alt=屏幕快照 border=0 
            height=286 src="CSDN_文档中心_Alpha 闪烁效果.files/directx0900-3.gif" 
            width=227> 
            <P><B>图 3. <FONT face=arial>MSDNSparkles</FONT>项目视图</B></P>
            <P>Sparkles.cpp 
            包含两组函数。第一组是可以覆盖的函数,我会在后面对其进行考查。第二组包含了闪烁效果函数。为了对闪烁效果函数进行处理,MSDNSparkles 
            定义了它自己的小型 API,它们是 <B><FONT 
            face=arial>RandomTexture</B>、<B>RandomSparkle</B>、<B>InitSparkles</B>、<B>UpdateSparkle</B> 
            和 <B>DrawSparkle</FONT></B>。</P><PRE class=clsCode>// 闪烁效果函数
Int RandomTexture(int overflow);
Sparkle RandomSparkle(void);
Void InitSparkles(void);
Void UpdateSparkles(void);
BOOL DrawSparkles(LPDIRECT3DDEVICE7 lpDev, D3DVECTOR from, D3DVECTOR at);
</PRE>
            <P>除了 <B><FONT face=arial>RandomTexture</FONT></B> 以外,所有这些函数都对 
            <B><FONT face=arial>Sparkle</FONT></B> 结构进行操作。<B><FONT 
            face=arial>Sparkle</FONT></B> 
            结构包含用于每个粒子的外观和行为的信息,而每一个粒子都作为粒子系统的一部分。</P><PRE class=clsCode>//闪烁效果的结构
typedef struct t_sparkle {
   int         texture;
   int         age, cur_age;  // start at age and tick down to 0
   float       scale, delta_scale;
   D3DVECTOR   position;
   D3DVECTOR   velocity;
   D3DVECTOR   color;
} Sparkle;
</PRE>
            <P>元素 <B><FONT face=arial>position</B> 和 <B>velocity</FONT></B>,随同 
            <B><FONT face=arial>scale</B> 和 <B>delta_scale</FONT></B> 
            一起由粒子系统使用,用于生成粒子的各个位置。元素 <B><FONT face=arial>texture</B> 与 
            <B>color</FONT></B> 定义作为外观随机化算法一部分的粒子外观。</P>
            <P>外观随机化通过使用一个衰老系统对转换进行控制,其中,元素 <B><FONT face=arial>age</B> 与 
            <B></FONT><FONT face=新宋体><CODE>cur_age</CODE></FONT></B> 
            给出了一个倒计时系统。转换发生的方式有三种:</P>
            <UL type=disc>
              <LI>当某纹理的时限到期时,从列表中随机选择一种纹理。<BR><BR>
              <LI>color_mode 用来生成一种基色。<BR><BR>
              <LI>color_modifier_mode 用来以一些有趣的方式对基色进行修改。 </LI></UL>
            <P>这些随机纹理和色彩随后会对粒子的外观进行完整定义。某些精巧的随机数学方法所生成的内容确实相当奇妙。</P>
            <P><B><FONT face=arial>RandomTexture</FONT></B> 
用来帮助从纹理列表中选择一种纹理。</P><PRE class=clsCode>int RandomTexture(int texture, int overflow)
{
      int retVal;

      if (texture == NumTextures) 
      {
            retVal = overflow;// init to random from the n case, overflow
      } 
      else 
      {
            retVal = texture; // init to current in the 0..n-1 case
      }
      return retVal;
}
</PRE>
            <P><B><FONT face=arial>RandomSparkle</FONT></B> 
            通过生成一些颜色增量值开始。它随后开始着手置入一个 Sparkles 
            结构,该结构用时限、标度和位置值来表示粒子。闪烁效果的纹理是通过调用 <B><FONT 
            face=arial>RandomTexture</FONT></B> 选择的。随后,<B><FONT 
            face=arial>color_mode</B> 和 <B>color_modifier_mode</FONT></B> 
            被用来生成该粒子的颜色。</P>
            <P><B><FONT face=arial>Color_mode</FONT></B> 确定哪一种方法被用于生成基本颜色,随机模式还是 
            rgb 颤动模式。随机模式只是随机地选取一种颜色。而 RGB 
            颤动模式则进行一些精巧的颜色增量计算,在某一颜色范围内平滑地移动。<B><FONT 
            face=arial>Color_modifier_mode</FONT></B> 
            控制着基色的修改。可以选择四种变量:饱和色、宝石色、柔和色或亮色。这些模式中的每一种都执行一种略微不同的计算,借以对基色进行修改。</P><PRE class=clsCode>Sparkle RandomSparkle(void)
{
      Sparkle     ret;
      static float      red = 1.0f, grn = 1.0f, blu = 1.0f;
      static float      d_red = -(min_color_delta + rnd()*max_color_delta);
      static float      d_grn = -(min_color_delta + rnd()*max_color_delta);
      static float      d_blu = -(min_color_delta + rnd()*max_color_delta);

      ret.age           = min_age + (int)(rnd() * (max_age-min_age));
      ret.cur_age       = ret.age;
      ret.scale         = start_scale;
      ret.delta_scale   = min_delta + rnd() * (max_delta - min_delta);
      ret.position      = D3DVECTOR(world_size * (rnd()-rnd()), 
                                    world_size * (rnd()-rnd()), 
                                    world_size * (rnd()-rnd()));
      ret.velocity      = D3DVECTOR(0.0f);
      ret.texture       = RandomTexture(rand() % (NumTextures-1));

      switch (color_mode) {
            case 0 : //随机
                  ret.color = D3DVECTOR(rnd(), rnd(), rnd());
                  break;
            case 1 : //rgb 颤动
                  red += d_red;
                  if (red &gt; 1.0f) {
                        red = 1.0f;
                        d_red = -(min_color_delta + rnd()*max_color_delta);
                  } else if (red &lt; 0.0f) {
                        red = 0.0f;
                        d_red = min_color_delta + rnd()*max_color_delta;
                  }
                  grn += d_grn;
                  if (grn &gt; 1.0f) {
                        grn = 1.0f;
                        d_grn = -(min_color_delta + rnd()*max_color_delta);
                  } else if (grn &lt; 0.0f) {
                        grn = 0.0f;
                        d_grn = min_color_delta + rnd()*max_color_delta;
                  }
                  blu += d_blu;
                  if (blu &gt; 1.0f) {
                        blu = 1.0f;
                        d_blu = -(min_color_delta + rnd()*max_color_delta);
                  } else if (blu &lt; 0.0f) {
                        blu = 0.0f;
                        d_blu = min_color_delta + rnd()*max_color_delta;
                  }

                  ret.color = D3DVECTOR(red, grn, blu);
                  break;
            default :
                  ret.color = D3DVECTOR(0.0f, 0.5f, 1.0f);
                  break;
      }

      switch (color_modifier_mode) {
            case 0 :    // 无变化
                  break;
            case 1 :    // 饱和色
                  ret.color /= Max(ret.color);
                  break;
            case 2 :    // 宝石色
                  ret.color -= Min(ret.color);
                  ret.color /= Max(ret.color);
                  break;
            case 3 :    // 柔和色
                  ret.color -= Min(ret.color);
                  ret.color /= Max(ret.color);
                  ret.color = D3DVECTOR(0.6f) + 0.4f * ret.color;
                  break;
            case 4 :    // 亮色和冷色,并可用于大多数情况
                  ret.color *= 1.2f;
                  break;
            default :
                  break;
      }

      return ret;
}
</PRE>
            <P><B><FONT face=arial>InitSparkles</FONT></B> 
            选择起始纹理,然后为粒子列表分配内存。一个粒子基本上是由两个三角形构成的四边形。对粒子的说明,请参见图 4。</P><IMG 
            alt=粒子示意图 border=0 height=300 
            src="CSDN_文档中心_Alpha 闪烁效果.files/directx0900-4.gif" width=300> 
            <P><B>图 4. 粒子</B> </P>
            <P>接下来,每个闪烁效果都通过 <B><FONT face=arial>RandomSparkle</B></FONT> 
            被随机地初始化。最后,为每个粒子生成索引绘图的下标。</P><PRE class=clsCode>void InitSparkles(void)
{ 
   texture = 1;// 以 dx7 位图开始
   sparkle = (Sparkle *)malloc(nMaxNumSparkles * sizeof(Sparkle));
   for (UINT i=0; i&lt;nCurNumSparkles; i++) {
      sparkle[i] = RandomSparkle();
   }

   // 设置下标
   for (i=0; i&lt;nMaxNumSparkles; i++) {
      s_indices[i*6+0] = 4*i + 0;
      s_indices[i*6+1] = 4*i + 1;
      s_indices[i*6+2] = 4*i + 2;
      s_indices[i*6+3] = 4*i + 0;
      s_indices[i*6+4] = 4*i + 2;
      s_indices[i*6+5] = 4*i + 3;
   }
}  // InitSparkles() 结束
</PRE>
            <P><B><FONT face=arial>UpdateSparkles</B> 将 
            <B>texture_age</B>、<B>color_age</B> 和 
            <B>color_modifier_age</B></FONT> 的当前值递减。随后,如果时限值已经倒数至 0,则会生成 
            <B><FONT face=arial>texture</B></FONT> (使用 <B><FONT 
            face=arial>RandomTexture</B></FONT>)、<B><FONT 
            face=arial>color_mode</B></FONT> 以及 <B><FONT 
            face=arial>color_modifier_mode</B></FONT> 的新的随机值。此操作一旦完成,<B><FONT 
            face=arial>RandomSparkle</B></FONT> 
            将被再次用来随机生成每个粒子下一帧的位置、纹理和颜色。最后对标度进行调整。</P><PRE class=clsCode>void UpdateSparkles(void)
{
   UINT  i;
//0..n 0..n-1==当前,n==随机
   texture_age--;
   if (texture_age == 0) {
      texture_age = min_texture_age + (unsigned int)(rnd() * 
(max_texture_age - min_texture_age));
      texture = rand() % (NumTextures);
      texture = RandomTexture(rand() % (NumTextures-1));
   }
//0..1 0==随机,1==rgb 颤动
   color_age--;
   if (color_age == 0) {
      color_age = min_color_age + (int)(rnd()*(max_color_age –
 min_color_age));

⌨️ 快捷键说明

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