alpha效果:Alpha 闪烁效果



欢迎阅读 Driving DirectX这个月我将通过开发个使用 alpha Direct3D 屏幕保护继续对 alpha 混色进行探索

图 1. MSDNSparkles 屏幕快照

图 1 显示了该举例个屏幕快照;要想真正欣赏这些图像您必须花上时间来观察屏幕保护形态变化

根据 Direct3D \"ScreenSaver\" 举例MSDNSparkles 屏幕保护个粒子系统和些随机戏法结合起来;如果这种方式和 alpha 混色相结合就会产生梦幻般图像这是个使用 _disibledevent=>在本专栏中我将简要概括 Direct3D 屏幕保护举例框架然后深入介绍 MSDNSparkles 实现其戏法细节我不会涉及编写 Win32 屏幕保护细节但您可以在 MSDN 上搜索讨论这主题文章

引言 Direct3D 屏幕保护框架由两部分组成:骨架和应用提供这些由每个屏幕保护覆盖图 2 显示了 SDK 屏幕保护样本工程视图Screensaver.cpp 提供了个使 D3DFrame 屏幕保护能够运行骨架如 d3dapp.cpp而 d3dapp.cpp 反过来又提供了 D3DFrame 应用骨架只要提供覆盖就可以得到个屏幕保护请记住如果要对屏幕保护进行测试则需要使用个命令行参数 –s 从 Visual C 中将其启动

\" width=225 border=0> 图 2. Direct3D 屏幕保护样本项目视图

该骨架使用了些类似于那些 D3DFrame 应用用于执行化、关闭和着色这些原型—Initialize3DEnvironmentCleanup3DEnvironmentRender3DEnvironment— 如下所示

//--------------------------------------------------------------------------// 局部原型//--------------------------------------------------------------------------HRESULT Initialize3DEnvironment( HWND );HRESULT Render3DEnvironment( HWND );VOID Cleanup3DEnvironment( HWND );

这 3个将完成设置 Direct3D、关闭 Direct3D 和对场景进行着色所有操作屏幕保护必须完成所有工作就是实现可以被覆盖这些类似于我们已经逐渐了解和喜爱 D3Dframe 对应;请参见下面原型

//--------------------------------------------------------------------------// 外部原型//--------------------------------------------------------------------------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;

我使用了举例中 screensaver.cpp并做了最少改动确发现从注册表中读取配置数据需要将参数由:

( ERROR_SUCCESS RegOpenKeyEx( HKEY_CURRENT_USER, strRegPath, KEY_READ, NULL, &hKey ) )

调换为:

( ERROR_SUCCESS RegOpenKeyEx( HKEY_CURRENT_USER, strRegPath, NULL, KEY_READ, &hKey ) )

该举例也未能对着色窗口可能移动进行处理因此我在 TestCooperativeLevel 的后把以下块加入了 Render3Denvironment

//请确保在屏幕控制面板中进行操作监视事物移动RECT rTmp;GetWindowRect( hWnd, &rTmp );g_pFramework->Move(rTmp.left, rTmp.top );

Direct3D 屏幕保护框架确实给出了 ConfigureDialog 开始部分以及种用于存储配置数据思路方法但我尚未针对 MSDNSparkles 对其进行扩充它不是个关键细节

样例屏幕保护个“特征”是:它使用 WM_TIMER 对着色进行控制在基于 Windows 2000 操作系统上这会产生个适当帧速率但基于 Windows9x 操作系统并不具有这样个允许使用良好帧速率 WM_TIMER 间隔尺寸考虑到这种情况我重新编写了这个屏幕保护使其使用线程对着色进行控制我没有将这部分代码包括进来它是个简单明了线程实现有兴趣员可以考虑增加多监视器功能、电源管理和口令 Direct3D 屏幕保护框架没有提供这些功能

高级别视图

既然这些细节已不成为问题我们就可以开始了图 3 显示了 Visual Studio Workspace 窗口针对 MSDNSparkles 举例内容该项目由 screensaver.cpp 文件(它是从 Direct3D 举例中得到如上面讨论所述)以及 sparkles.cpp 组成

\" width=227 border=0> 图 3. MSDNSparkles项目视图

Sparkles.cpp 包含两组组是可以覆盖我会在后面对其进行考查第 2组包含了闪烁效果为了对闪烁效果进行处理MSDNSparkles 定义了它自己小型 API它们是 RandomTextureRandomSparkleInitSparklesUpdateSparkleDrawSparkle

// 闪烁效果Int RandomTexture( overflow);Sparkle RandomSparkle(void);Void InitSparkles(void);Void UpdateSparkles(void);BOOL DrawSparkles(LPDIRECT3DDEVICE7 lpDev, D3DVECTOR from, D3DVECTOR at);

除了 RandomTexture 以外所有这些都对 Sparkle 结构进行操作Sparkle 结构包含用于每个粒子外观和行为信息而每个粒子都作为粒子系统部分

//闪烁效果结构typedef struct t_sparkle { texture; age, cur_age; // start at age and tick down to 0 float scale, delta_scale; D3DVECTOR position; D3DVECTOR velocity; D3DVECTOR color;} Sparkle;

元素 positionvelocity随同 scaledelta_scale 起由粒子系统使用用于生成粒子各个位置元素 texturecolor 定义作为外观随机化算法部分粒子外观

外观随机化通过使用个衰老系统对转换进行控制其中元素 agecur_age 给出了个倒计时系统转换发生方式有 3种:

  • 当某纹理时限到期时从列表中随机选择种纹理

  • color_mode 用来生成种基色

  • color_modier_mode 用来以些有趣方式对基色进行修改
这些随机纹理和色彩随后会对粒子外观进行完整定义某些精巧随机数学思路方法所生成内容确实相当奇妙

RandomTexture 用来帮助从纹理列表中选择种纹理

RandomTexture( texture, overflow){ retVal; (texture NumTextures) { retVal = overflow;// init to random from the n , overflow } { retVal = texture; // init to current in the 0..n-1 } retVal;}

RandomSparkle 通过生成些颜色增量值开始它随后开始着手置入个 Sparkles 结构该结构用时限、标度和位置值来表示粒子闪烁效果纹理是通过 RandomTexture 选择随后color_modecolor_modier_mode 被用来生成该粒子颜色

Color_mode 确定哪种思路方法被用于生成基本颜色随机模式还是 rgb 颤动模式随机模式只是随机地选取种颜色而 RGB 颤动模式则进行些精巧颜色增量计算在某颜色范围内平滑地移动Color_modier_mode 控制着基色修改可以选择 4种变量:饱和色、宝石色、柔和色或亮色这些模式中种都执行种略微区别计算借以对基色进行修改

Sparkle RandomSparkle(void){ Sparkle ret; float red = 1.0f, grn = 1.0f, blu = 1.0f; float d_red = -(min_color_delta + rnd*max_color_delta); float d_grn = -(min_color_delta + rnd*max_color_delta); float d_blu = -(min_color_delta + rnd*max_color_delta); ret.age = min_age + ()(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) { 0 : //随机 ret.color = D3DVECTOR(rnd, rnd, rnd); ; 1 : //rgb 颤动 red d_red; (red > 1.0f) { red = 1.0f; d_red = -(min_color_delta + rnd*max_color_delta); } (red < 0.0f) { red = 0.0f; d_red = min_color_delta + rnd*max_color_delta; } grn d_grn; (grn > 1.0f) { grn = 1.0f; d_grn = -(min_color_delta + rnd*max_color_delta); } (grn < 0.0f) { grn = 0.0f; d_grn = min_color_delta + rnd*max_color_delta; } blu d_blu; (blu > 1.0f) { blu = 1.0f; d_blu = -(min_color_delta + rnd*max_color_delta); } (blu < 0.0f) { blu = 0.0f; d_blu = min_color_delta + rnd*max_color_delta; } ret.color = D3DVECTOR(red, grn, blu); ; default : ret.color = D3DVECTOR(0.0f, 0.5f, 1.0f); ; } switch (color_modier_mode) { 0 : // 无变化 ; 1 : // 饱和色 ret.color /= Max(ret.color); ; 2 : // 宝石色 ret.color -= Min(ret.color); ret.color /= Max(ret.color); ; 3 : // 柔和色 ret.color -= Min(ret.color); ret.color /= Max(ret.color); ret.color = D3DVECTOR(0.6f) + 0.4f * ret.color; ; 4 : // 亮色和冷色并可用于大多数情况 ret.color *= 1.2f; ; default : ; } ret;}



InitSparkles 选择起始纹理然后为粒子列表分配内存个粒子基本上是由两个 3角形构成 4边形对粒子介绍说明请参见图 4

\" width=300 border=0> 图 4. 粒子

接下来每个闪烁效果都通过 RandomSparkle 被随机地最后为每个粒子生成索引绘图下标

void InitSparkles(void){ texture = 1;// 以 dx7 位图开始 sparkle = (Sparkle *)malloc(nMaxNumSparkles * (Sparkle)); for (UINT i=0; i<nCurNumSparkles; i) { sparkle[i] = RandomSparkle; } // 设置下标 for (i=0; i<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 结束

UpdateSparklestexture_agecolor_agecolor_modier_age 当前值递减随后如果时限值已经倒数至 0则会生成 texture (使用 RandomTexture)、color_mode 以及 color_modier_mode 随机值此操作旦完成RandomSparkle 将被再次用来随机生成每个粒子下位置、纹理和颜色最后对标度进行调整

void UpdateSparkles(void){ UINT i; //0..n 0..n-1当前n随机 texture_age--; (texture_age 0) { texture_age = min_texture_age + (unsigned )(rnd * (max_texture_age - min_texture_age)); texture = rand % (NumTextures); texture = RandomTexture(rand % (NumTextures-1)); } //0..1 0随机1rgb 颤动 color_age--; (color_age 0) { color_age = min_color_age + ()(rnd*(max_color_age – min_color_age)); color_mode = rand % NumColorModes; } //0..5 0无变化1饱和色2宝石色3柔和色 // 4亮色5暗色和冷色但不适用于大多数情况 color_modier_age--; (color_modier_age 0) { color_modier_age = min_color_modier_age + ()(rnd*(max_color_modier_age - min_color_modier_age)); color_modier_mode = rand % NumColorModierModes; } //更新闪烁效果 for (i=0; i<nCurNumSparkles; i) { sparkle[i].cur_age--; (sparkle[i].cur_age 0) { sparkle[i] = RandomSparkle; } sparkle[i].scale *= sparkle[i].delta_scale; }} // UpdateSparkles 结束

DrawSparkles 对粒子系统定位代码中使用前面方向进行计算该值被用来生成每个粒子各顶点偏移量图 5 对此进行了介绍说明

\" width=300 border=0> 图 5. 粒子定位

为了提高效率闪烁效果按绘制纹理进行排序索引列表及 DrawIndexedPrimitive 用来绘制粒子系统 4边形

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 flags[NumTextures]; for ( tex=0; tex<NumTextures; tex) { flags[tex] = 0; } // 计算出正在使用哪些纹理 for (i=0; i<nCurNumSparkles; i) { flags[sparkle[i].texture]; } // 对于每种使用纹理批量处理闪烁效果并进行绘制 for (tex=0; tex<NumTextures; tex) { (flags[tex] 0) continue; // 设置正确材质/纹理组合 lpDev->SetTexture(0,g_ptexSparkleTextures[tex]); //建造用于批处理 4边形 num = 0; for (i=0; i<nCurNumSparkles; i) { (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; } // 已完成批处理创建现在进行着色 (lpDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, D3DFVF_LVERTEX, (LPVOID)s_mesh, 4*flags[tex], s_indices,6*flags[tex], 0) != D3D_OK) FALSE; } TRUE;} // DrawSparkles 结束



图 6 和图 7 显示了由 alpha 混色粒子系统产生图像附加屏幕快照

图 6. MSDNSparkles 屏幕快照 2

图 7. MSDNSparkles 屏幕快照 3

MSDNSparkles 内部构件 让我们继续探讨过载应用实现过程我在下面重新列出了原型这样您就不必回卷到本文开始地方我将对 Direct3D 屏幕保护框架允许覆盖每个过载进行考查

//--------------------------------------------------------------------------// 外部原型//--------------------------------------------------------------------------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;

ConfirmDevice MSDNSparkles App_ConfirmDevice 验证设备是否能够进行 _disibledevent=>HRESULT App_ConfirmDevice( DDCAPS* pddDriverCaps,D3DDEVICEDESC7* pd3dDeviceDesc ){ // 获取 triangle caps(硬件或软件Software)并检验 alpha 混色 LPD3DPRIMCAPS pdpc = &pd3dDeviceDesc->dpcTriCaps; ( 0 ( pdpc->dwSrcBlendCaps & pdpc->dwDestBlendCaps & D3DBLEND_ONE ) ) E_FAIL; S_OK;}

OneTimeSceneInit App_OneTimeSceneInit 首先给随机数生成器播种并设置背景颜色和化纹理列表然后它使用纹理列表创建 MSDNSparkles 使用纹理最后 InitSparkles 对粒子系统进行

HRESULT App_OneTimeSceneInit{ // 给随机数生成器播种 srand(time(0)); //化背景颜色 bckColor = D3DRGB(0,0,0); //装载纹理数据 memcpy(g_szSparkleTextures[0],\"dx5.bmp\",(\"dx5.bmp\")); memcpy(g_szSparkleTextures[1],\"dx7.bmp\",(\"dx7.bmp\")); memcpy(g_szSparkleTextures[2],\"flare1.bmp\",(\"flare1.bmp\")); memcpy(g_szSparkleTextures[3],\"flare2.bmp\",(\"flare2.bmp\")); memcpy(g_szSparkleTextures[4],\"flare3.bmp\",(\"flare3.bmp\")); memcpy(g_szSparkleTextures[5],\"flare4.bmp\",(\"flare5.bmp\")); memcpy(g_szSparkleTextures[6],\"flare5.bmp\",(\"flare5.bmp\")); memcpy(g_szSparkleTextures[7],\"flare6.bmp\",(\"flare6.bmp\")); memcpy(g_szSparkleTextures[8],\"flare7.bmp\",(\"flare7.bmp\")); memcpy(g_szSparkleTextures[9],\"flare8.bmp\",(\"flare8.bmp\")); memcpy(g_szSparkleTextures[10],\"shine1.bmp\",(\"flare1.bmp\")); memcpy(g_szSparkleTextures[11],\"shine2.bmp\",(\"flare2.bmp\")); memcpy(g_szSparkleTextures[12],\"shine3.bmp\",(\"flare3.bmp\")); memcpy(g_szSparkleTextures[13],\"shine4.bmp\",(\"flare5.bmp\")); memcpy(g_szSparkleTextures[14],\"shine5.bmp\",(\"flare5.bmp\")); memcpy(g_szSparkleTextures[15],\"shine6.bmp\",(\"flare6.bmp\")); for ( i = 0; i < NumTextures; i) D3DTextr_CreateTextureFromFile( (char *)g_szSparkleTextures[i] ); InitSparkles; S_OK;}

InitDeviceObjects App_InitDeviceObjects 使用 helper SetTextureStateSetRenderStateSetViewState这些分别对纹理列表、应用所使用着色状态和查看系统进行设置请注意已启用了alpha 混色混色状态将为加色而设置成 _disibledevent=>void SetTextureState(LPDIRECT3DDEVICE7 pd3dDevice ){ // 设置纹理状态 D3DTextr_RestoreAllTextures( pd3dDevice ); // 装载纹理表面 for( i=0; i<NumTextures; i ) g_ptexSparkleTextures[i] = D3DTextr_GetSurface( (char *)g_szSparkleTextures[i]);}void SetRenderState(LPDIRECT3DDEVICE7 pd3dDevice ){ // alpha 混色状态 pd3dDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); pd3dDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, srcBlend); pd3dDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, dstBlend); // 过滤器状态 pd3dDevice->SetTextureStageState(0,D3DTSS_MINFILTER, D3DFILTER_LINEAR); pd3dDevice->SetTextureStageState(0,D3DTSS_MAGFILTER, D3DFILTER_LINEAR); pd3dDevice->SetTextureStageState(0,D3DTSS_MIPFILTER, D3DFILTER_LINEAR); // 设置非纹理着色状态 pd3dDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE); pd3dDevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, FALSE); pd3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); pd3dDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, FALSE); pd3dDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); // 注:在 DX7 中要关闭顶点照明需要将 D3DRENDERSTATE_LIGHTING 设置为 FALSE // (并改用 D3DLVERTEX 中颜色) pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, FALSE );}void SetViewState(LPDIRECT3DDEVICE7 pd3dDevice ){ // 获取宽高比 pd3dDevice->GetViewport(&vp); FLOAT fAspect = ((FLOAT)vp.dwHeight) / vp.dwWidth; // 设置变换矩阵 D3DUtil_SetProjectionMatrix( proj, g_PI/4,//1.0f; fAspect,1.0f, MAX_DIST ); pd3dDevice->SetTransform( D3DTRANSFORMSTATE_PROJECTION, &proj); D3DUtil_SetViewMatrix( view, from, at, up ); pd3dDevice->SetTransform( D3DTRANSFORMSTATE_VIEW, &view); D3DUtil_SetIdentityMatrix( world ); pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &world);}HRESULT App_InitDeviceObjects( HWND hWnd, LPDIRECT3DDEVICE7 pd3dDevice ){ // 检查参数 ( NULLpd3dDevice ) E_INVALIDARG; // 设置纹理状态 SetTextureState( pd3dDevice ); // 设置着色状态 SetRenderState( pd3dDevice ); // 设置查看系统 SetViewState( pd3dDevice ); S_OK;}



FrameMove App_FrameMove 使用 UpdateSparkles 对粒子系统模拟进行更新

HRESULT App_FrameMove( LPDIRECT3DDEVICE7 pd3dDevice, FLOAT fTimeKey ){ // 好现在可以使用闪烁效果了 UpdateSparkles; S_OK;}

着色 App_Render 相当简单首先我们使用时间和 RandomViewpo 随时间推移对视点进行修改然后我们让 DrawSparkles 绘制粒子系统太简单了!

void RandomViewpo(LPDIRECT3DDEVICE7 pd3dDevice,float tic){ float fromX, fromY, fromZ; fromX = (float)sin(tic*0.59); fromZ = (float)cos(tic*0.59); ( texture <= 9 ) fromY = (float)sin(tic*0.72); fromY = (float)cos(tic*0.72); from = D3DVECTOR(orbit_size*fromX, orbit_size*fromY, orbit_size*fromZ ); D3DUtil_SetViewMatrix( view, from, at, up ); pd3dDevice->SetTransform( D3DTRANSFORMSTATE_VIEW, &view);}HRESULT App_Render( LPDIRECT3DDEVICE7 pd3dDevice ){ float tic = -rnd * 10000.0f; // 清除取景框 pd3dDevice->Clear( 0UL, NULL, D3DCLEAR_TARGET, bckColor, 1.0f, 0L ); // 开始场景 ( FAILED( pd3dDevice->BeginScene ) ) S_OK; // Don\'t a \"fatal\" error // tic 来回移动物品 tic 0.005f; // 在随机定位中使用 start_scale = 0.05f + (float)(sin(tic * 0.100) + 1.0f)*0.4f; world_size = 0.10f + (float)(cos(tic * 0.072) + 1.0f)*10.0f; // 修改取景框 RandomViewpo(pd3dDevice,tic); // 绘制闪烁效果 (!DrawSparkles(pd3dDevice, from, at)) E_FAIL; // 结束场景 pd3dDevice->EndScene; S_OK;}

DeleteDeviceObjects App_DeleteDeviceObjects 使纹理列表中纹理失效

VOID App_DeleteDeviceObjects( HWND hWnd, LPDIRECT3DDEVICE7 pd3dDevice){ D3DTextr_InvalidateAllTextures;}

RestoreSurfaces< 对于 MSDNSparkles 举例App_RestoreSurfaces 为空操作

HRESULT App_RestoreSurfaces{ S_OK;}

FinalCleanup App_FinalCleanup 删除闪烁效果列表所使用内存

HRESULT App_FinalCleanup{ free(sparkle); S_OK;}

MSDNSparkles 实现过程到此结束当您构建这个项目时可以通过用鼠标右键单击 MSDNSparkles.scr 文件对产生屏幕保护进行测试、配置和安装图 6 对此进行了介绍说明结果是基本但也不无快意\" width=400 border=0>

图 8. 单击右键可对屏幕保护进行测试、配置和安装

结语 欢迎您反馈意见欢迎通过下面地址给我写信请附上您意见、问题、对专题看法或是您自己有关本专栏所涉及专题观点变化链接尽管如此请不要期待个别回信或向我发送需求技术支持问题请记住Microsoft 保持着个活跃邮件列表 DirectXDev它是个志趣相投开发人员共享信息论坛可以在 http://DISCUSS.MICROSOFT.COM/archives/DIRECTXDEV.html(英文)找到相应 Web 界面提问前请阅读 http://msdn.microsoft.com/library/techart/dxfaq2.htm(英文)上常见问题解答




经过过去 4年对 DirectX 宣传Philip Taylor 直在不断前进他现在是 DirectX SDK PM(项目经理(project manager))自从 DirectX 1 个公共 beta 版实际上应该是很久以前交货 DirectX 2 游戏以来直致力于 DirectX 工作在业余时间里他隐身于许多 3维图形编程邮件列表中可以通过 [email protected] 和他联系

归档 Driving DirectX 专栏文章 2000 年
8月22日 现在您看到了现在您还没有看到:Alpha 混色第 2 部分(英文)


7月26日 现在您看到了现在您还没有看到:Alpha 混色第 1 部分(英文)
6月22日 您能得到怎样光亮?(英文)
5月15日 D3DFrame 入门(英文)
4月17日 对 DirectX 点主张(英文)





Tags:  文字闪烁效果 flash闪烁效果 闪烁效果 alpha效果

延伸阅读

最新评论

发表评论