使用DirectX让进行Alpha混合的子图形移动(精灵动画)
来源:互联网 发布:数据分析师需要的技能 编辑:程序博客网 时间:2024/04/27 18:36
使用DirectX让进行Alpha混合的子图形移动(精灵动画)
最近我在二维动画的问题上总是不得其解。因为没有进行Alpha混合的二维动画,在外表上一定会很难看。所以我没有办法,只好四处求解。但是好像大家都没有给出我满意的答案。还好,我在一个源码库(http://www.hackchina.com/)中搜索到了一个示例程序,这个示例程序做得真的好,很逼真。所以我一定要把它拿来进行剖析。在了解到了我必须抛弃以前的surface结构后,我毅然决然地使用了例子中的sprite结构体。这样好了,我左试右试,最后终于成功了。为此我自己又做了一个tga图,和自己用Easy Paint Tool SAI修改的一个tga图。这样的话,我的演示程序就非常得好看了。
下面就是我的MainFrame.cpp文件:
- /*---------------------------------------------------------------------------
- 蒋轶民制作 E-mail:jiangcaiyang123@163.com
- 文件名:MainFrame.cpp
- 作用:子图像和Alpha融合的主框架
- ----------------------------------------------------------------------------*/
- /*--------------------------------------------------------------------------*/
- // 头文件
- #include<windows.h>
- #include<d3d9.h>
- #include<d3dx9.h>
- #include<stdio.h>
- // 库文件
- #pragma comment( lib, "d3d9.lib")
- #pragma comment( lib, "d3dx9.lib")
- // 定义的宏
- #define JCLASSNAME "优化的程序"
- #define JCAPTION "程序演示"
- #define WINDOW_WIDTH 320
- #define WINDOW_HEIGHT 320
- #define FULLSCREEN FALSE// 全屏非全屏的标识符
- #define SAFE_RELEASE( p ) if ( p ) p->Release(); p = NULL;
- // 调整编译器设置
- #pragma warning( disable: 4100 )
- #if FULLSCREEN // 全屏非全屏的设置
- #define WINDOW_STYLE WS_EX_TOPMOST | WS_POPUP | WS_VISIBLE
- #else
- #define WINDOW_STYLE WS_CAPTION | WS_SYSMENU
- #endif
- /*----------------------------------------------------------------------------*/
- // 全局变量
- LPDIRECT3D9 g_JD3D = NULL;// D3D结构体
- LPDIRECT3DDEVICE9 g_JDevice = NULL;// D3D装置结构体
- LPD3DXFONT g_FPSFont = NULL;// 指向FPS字体的指针
- RECT g_FPSFontPos = { WINDOW_WIDTH - 100, WINDOW_HEIGHT - 15,
- WINDOW_WIDTH, WINDOW_HEIGHT};// FPS所在的矩形框
- INT g_FrameCount = 0;// 帧的计数器
- INT g_lastTime = 0;// 记录上一秒的时间
- INT g_currentTime = 0;// 记录当前的时间
- CHAR g_FPSstr[25] = { 0 };// 记录当前帧率的字符串
- IDirect3DSurface9* g_surface = NULL;// 平面的指针
- /*----------------------------------------------------------------------------*/
- // 子图像和Alpha融合的头文件
- #include "AlphaBlend.h"
- /*----------------------------------------------------------------------------*/
- // 函数的声明
- BOOL InitializeD3D( HWND hWnd )
- {
- D3DDISPLAYMODE displayMode;
- //创建D3D对象
- g_JD3D = Direct3DCreate9( D3D_SDK_VERSION );
- if ( g_JD3D == NULL )
- return FALSE;
- // 获取显示器的模式
- if ( FAILED( g_JD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &displayMode ) ) )
- return FALSE;
- // D3D显示的参数
- D3DPRESENT_PARAMETERS jd3dpp;
- ZeroMemory( &jd3dpp, sizeof( jd3dpp ) );
- // 初始化D3DPRESENT_PARAMETERS
- jd3dpp.Windowed = !FULLSCREEN;
- jd3dpp.BackBufferWidth = WINDOW_WIDTH;
- jd3dpp.BackBufferHeight = WINDOW_HEIGHT;
- jd3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
- jd3dpp.BackBufferFormat = displayMode.Format;
- jd3dpp.EnableAutoDepthStencil = TRUE;
- jd3dpp.AutoDepthStencilFormat = D3DFMT_D16;
- // 创建设备
- if(FAILED( g_JD3D->CreateDevice( D3DADAPTER_DEFAULT,
- D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
- &jd3dpp, &g_JDevice ) ) )
- return FALSE;
- // 设置渲染状态
- g_JDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
- g_JDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );
- // 创建字体
- if ( FAILED( D3DXCreateFont( g_JDevice, 15, 0, 1, 1, 0, DEFAULT_CHARSET,
- OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
- "Impact", &g_FPSFont ) ) ) return FALSE;
- // 创建离屏平面
- if ( FAILED ( g_JDevice->CreateOffscreenPlainSurface( WINDOW_WIDTH, WINDOW_HEIGHT,
- D3DFMT_X8R8G8B8, // 平面格式
- D3DPOOL_DEFAULT, // 内存池格式
- &g_surface, // 保存结果的缓存
- NULL) ) ) // 保留参数
- return FALSE;
- // 载入背景平面图像
- if ( FAILED( D3DXLoadSurfaceFromFile( g_surface, NULL, NULL, "背景图案.tga",
- NULL, D3DX_DEFAULT, 0, NULL ) ) ) return FALSE;
- // 初始化子图形
- if ( InitialSprite() == FALSE )
- return FALSE;
- return TRUE;
- }
- /*----------------------------------------------------------------------------*/
- // 释放所有资源
- void ReleaseMemory( void )
- {
- SAFE_RELEASE( g_JD3D );
- SAFE_RELEASE( g_JDevice );
- SAFE_RELEASE( g_FPSFont );
- SAFE_RELEASE( g_surface );
- AdditionalRelease();// 释放sprite和texture所占用的内存
- }
- /*----------------------------------------------------------------------------*/
- // 渲染屏幕
- void RenderScene( void )
- {
- // 计数器开始计数(以毫秒计)
- g_currentTime = GetTickCount();
- if ( g_currentTime - g_lastTime > 1000 )
- {
- sprintf_s( g_FPSstr, 25, "当前FPS:%d", g_FrameCount );
- g_lastTime = g_currentTime;
- g_FrameCount = 0;
- }
- else g_FrameCount++;
- g_JDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
- D3DCOLOR_XRGB( 0, 0, 0), 1.0f, 0);// 清除屏幕
- // 载入背景平面图像
- IDirect3DSurface9* backbuffer = NULL;
- g_JDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO,
- &backbuffer );// 获取后台缓存
- g_JDevice->StretchRect( g_surface, NULL,
- backbuffer, NULL, D3DTEXF_NONE );// 将后台矩形放入前景矩形
- // 开始渲染
- g_JDevice->BeginScene();
- RenderSprite();// 使用Alpha混合渲染子图形
- g_FPSFont->DrawText( NULL, g_FPSstr, -1, &g_FPSFontPos, DT_CENTER,
- D3DCOLOR_XRGB( 0, 0, 0 ) );// 显示字体
- // 结束渲染
- g_JDevice->EndScene();
- g_JDevice->Present( NULL, NULL, NULL, NULL );
- }
- /*----------------------------------------------------------------------------*/
- // 回调函数,用来处理消息
- HRESULT CALLBACK MyAppProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
- {
- switch ( msg )
- {
- case WM_DESTROY:
- PostQuitMessage( 0 );
- return 0;
- case WM_KEYDOWN:
- if ( wParam == VK_ESCAPE ) PostQuitMessage( 0 );
- return 0;
- }
- return (HRESULT)DefWindowProc( hWnd, msg, wParam, lParam );
- };
- /*----------------------------------------------------------------------------*/
- // 程序的入口,主函数
- INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmd, INT show )
- {
- // 设置Window Class结构并且注册它
- WNDCLASSEX jWndCls = { sizeof( jWndCls ), CS_CLASSDC, MyAppProc, 0L, 0L, hInst,
- NULL, LoadCursor( NULL, IDC_ARROW) , 0, NULL, JCLASSNAME, NULL };
- RegisterClassEx( &jWndCls );
- // 设置窗口并且显示窗口
- HWND hWnd = CreateWindow( JCLASSNAME, JCAPTION, WINDOW_STYLE, 100, 40,
- WINDOW_WIDTH, WINDOW_HEIGHT, GetDesktopWindow(), NULL, jWndCls.hInstance, NULL);
- if ( hWnd == NULL )
- return FALSE;
- ShowWindow( hWnd, SW_SHOWDEFAULT );
- UpdateWindow( hWnd );
- // 初始化设置
- if ( InitializeD3D( hWnd ) == FALSE )
- return FALSE;
- // 进入消息循环
- MSG msg;
- ZeroMemory( &msg, sizeof( msg ) );
- while( msg.message != WM_QUIT )
- {
- if ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
- {
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- }
- else
- {
- // 渲染屏幕
- RenderScene();
- }
- }
- // 程序结束,释放内存所有资源
- ReleaseMemory();
- // 解除窗口注册
- UnregisterClass( JCLASSNAME, jWndCls.hInstance );
- return ( INT ) msg.wParam;
- }
下面就是我的AlphaBlend.h文件的内容:
- /*---------------------------------------------------------------------------
- 蒋轶民制作 E-mail:jiangcaiyang123@163.com
- 文件名:AlphaBlend.cpp
- 作用:载入子图像和Alpha融合
- ----------------------------------------------------------------------------*/
- /*--------------------------------------------------------------------------*/
- // 条件编译
- #ifndef _ALPHABLEND_H_
- #define _ALPHABLEND_H_
- // 定义的宏
- #define SPRITE_WIDTH 120
- #define SPRITE_HEIGHT 164
- /*----------------------------------------------------------------------------*/
- // 全局变量
- LPD3DXSPRITE g_Sprite = NULL;// 指向sprite结构的指针
- LPDIRECT3DTEXTURE9 g_Texture = NULL;// 指向纹理的指针
- /*----------------------------------------------------------------------------*/
- // 初始化子图形
- bool InitialSprite( void )
- {
- // 载入纹理图像并使用双线性滤波
- if ( FAILED ( D3DXCreateTextureFromFileEx( g_JDevice, "POP_Sprite.tga",
- SPRITE_WIDTH, // 我不得不手动设置。D3DPOOL_DEFAULT在纹理中起作用,但是应用在D3DXSPRITE中会产生问题。
- SPRITE_HEIGHT, // 我不得不手动设置。D3DPOOL_DEFAULT在纹理中起作用,但是应用在D3DXSPRITE中会产生问题。
- 1, // 不要创建mip-map。它在子图形动画中会抛弃像素数学计算
- D3DPOOL_DEFAULT,
- D3DFMT_UNKNOWN,
- D3DPOOL_DEFAULT,
- D3DX_DEFAULT,
- D3DX_DEFAULT,
- D3DCOLOR_XRGB( 0, 0, 0),
- NULL,
- NULL,
- &g_Texture ) ) )
- return false;
- g_JDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
- g_JDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
- // 设置三角形的背面不被剔除
- g_JDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
- // 创建子图形
- if ( FAILED( D3DXCreateSprite( g_JDevice, &g_Sprite ) ) )
- return false;
- return true;
- }
- /*----------------------------------------------------------------------------*/
- // 使用Alpha混合渲染子图形
- void RenderSprite( void )
- {
- // 设置静态变量,以便迭代而多次不初始化。它相当于全局变量
- static float fPosition = 0.0f;
- // 设置D3DXVECTOR3结构体,在D3DXSPRITE::Draw函数中有应用
- D3DXVECTOR3 vCenter( 0.0f, 0.0f, 0.0f );
- D3DXVECTOR3 vPosition( fPosition, 150.0f, 0.0f );
- // 渲染Sprite
- g_Sprite->Begin( D3DXSPRITE_ALPHABLEND );// 以Alpha混合形式进行渲染
- g_Sprite->Draw( g_Texture, NULL, &vCenter, &vPosition,
- D3DCOLOR_XRGB( 255, 255, 255 ) );
- g_Sprite->End();// 结束渲染
- if ( fPosition++ > WINDOW_WIDTH )// 检测越界
- fPosition = 0.0f - SPRITE_WIDTH;
- }
- /*----------------------------------------------------------------------------*/
- // 释放sprite和texture所占用的内存
- void AdditionalRelease( void )
- {
- SAFE_RELEASE( g_Sprite );
- SAFE_RELEASE( g_Texture );
- }
- #endif
我使用的tga格式展示给大家看看。其中sprite纹理的宽和高分别是120×164。
程序的演示效果如下:
我更多的DirectX程序,请看:
为DirectX游戏计算帧率
设计DirectX游戏开头动画效果设计DirectX游戏开头画面淡入淡出的效果
为自己创作一个好的DirectX程序风格
我的游戏:走迷宫(DirectX版)
- 使用DirectX让进行Alpha混合的子图形移动(精灵动画)
- 使用DirectX让子图形移动(精灵动画)
- 使用GDI+进行alpha混合
- learn opencv-使用OpenCV进行Alpha混合(C ++ / Python)
- Alpha动画的简单使用
- 【Visual C++】游戏开发五十五 浅墨DirectX教程二十二 水乳交融的美学:alpha混合技术
- 【Visual C++】游戏开发五十五 浅墨DirectX教程二十二 水乳交融的美学:alpha混合技术
- 扩展图形函数3,alpha混合
- Managed Directx 使用 Sprite 的精灵绘制实现镜像
- Qt移动应用开发(三):使用精灵图片实现帧动画
- Qt移动应用开发:使用精灵图片实现帧动画
- NGUI研究院之Sprite精灵与精灵动画的使用(二)
- NGUI研究院之Sprite精灵与精灵动画的使用(二)
- NGUI研究院之Sprite精灵与精灵动画的使用(二)
- 一起学习NGUI之Sprite精灵与精灵动画的使用(2)
- NGUI研究院之Sprite精灵与精灵动画的使用(二)
- NGUI研究院之Sprite精灵与精灵动画的使用(二)
- NGUI研究院之Sprite精灵与精灵动画的使用(二)
- 我的第一篇日记
- 我要加油喽!!!
- 一个简单的hibernate程序
- ppt
- oracle导数据及其常用积累
- 使用DirectX让进行Alpha混合的子图形移动(精灵动画)
- 好久没有写东西了!
- ExpandableListView的小图标有个状态
- HTML----CSSa样式(一)
- ubuntu 端口操作
- 随笔
- 我的第一个DirectX程序
- a
- ASP.NET中的状态