个人对DirectX3D做2D编程的理解
来源:互联网 发布:js 提取 网页文本 编辑:程序博客网 时间:2024/05/17 05:05
很多年前就知道DirectX是用来做游戏的,从DOS时代直接操作显存,到Windows时代只能通过驱动,并觉得DirectX的API太多,弄不清楚,感觉太麻烦,一直以来想写个游戏都是用GDI,但是GDI的效率很低,游戏做不大,只好硬着头皮去啃DirectX的SDK了,还好现在网络发达,资源很多,总是能学会不是。
在网上看了很多文章,感觉对初学者还是太难,做2D游戏也不需要太多D3D知识,大概整理了一下可能对初学者有些帮忙吧。
以下是以DirectX9的SDK进行描述的,另外渲染跟绘制差不多意思。
1、初始化一个D3D的接口IDirect3D9,方法永远是Direct3DCreate9( D3D_SDK_VERSION );
2、获取设备能力,GetDeviceCaps,Adapter取默认值D3DADAPTER_DEFAULT,DeviceType一般选硬件显卡,即D3DDEVTYPE_HAL
3、获取显示模式描述表 GetAdapterDisplayMode,在这个描述表里可以修改高宽、颜色模式、缓冲区类型等一堆信息
4、创建设备IDirect3DDevice9,用CreateDevice来创建,设备有一个就行了,设备要与窗口句柄关联
5、其它设置,什么世界矩阵,渲染状态
HRESULT InitDirect3D( HWND hWnd, BOOL bWindowed ){ g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ); D3DCAPS9 d3dCaps; g_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps ); D3DDISPLAYMODE d3ddm; g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ); D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof(d3dpp) ); if( bWindowed == TRUE ) { d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = d3ddm.Format; } else { d3dpp.Windowed = FALSE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferWidth = SCREEN_WIDTH; d3dpp.BackBufferHeight = SCREEN_HEIGHT; d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; } d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Do NOT sync to vertical retrace //d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; // Sync to vertical retrace d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ); D3DXMATRIX matProj; D3DXMatrixPerspectiveFovLH( &matProj, D3DXToRadian( 45.0f ), SCREEN_WIDTH / SCREEN_HEIGHT, 0.1f, 100.0f ); g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE); g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); return S_OK;}
6、创建2D精灵,D3DXCreateSprite,一行就够了,这个精灵创建一个就行,可以加载多个纹理进行批量渲染
7、创建纹理,我们这里说的是加载2D图片,可以从文件加载,从内存加载,也可以创建一个空的,自己填数据
8、渲染,先Device.Clear,再开启设备渲染事务Device.BeginScene,然后可以进行精灵渲染,也可以通过获取设备后备缓冲直接写,最后结束设备渲染事务Device.EndScene
9、精灵渲染有很东西可以设置,很麻烦有兴趣的自己学习,这里只说一个一定要在精灵渲染事务里加允许透明渲染的标志D3DXSPRITE_ALPHABLEND,事务中可以进行多项纹理绘制,所有的绘制都必须在事务中才会生效
10、精灵渲染可以渲染整个纹理,也可以只渲染其中一部分
11、精灵渲染的缩放、旋转、位置的问题,在D3D里使用3D的向量,我们搞2D编程所以Z坐标永远是1.0,缩放可以纹理的表面进行复制自动缩放,有的版本可以直接在Draw方法里旋转和缩放
终于有时间,而且对渲染这一块又有了一些了解
12、渲染到纹理,一个纹理中可以有多个表面,不过通常只用一个,可以将这个表面设为当前渲染的表面,纹理创建时有要求
a)创建可以用GDI、GDI+作图的纹理,MipLevels=1,Usage=0,Pool=D3DPOOL_MANAGED
b)创建可以作为渲染目标的纹理,MipLevels=1,Usage=1,Pool=D3DPOOL_DEFAULT,取纹理第0个表面Texture.GetSurfaceLevel(0, surface);然后设置为渲染目标Device.SetRenderTarget(0, surface);,这样一样ID3DXLine、ID3DXFont都可以绘制到当前纹理了(太基础了,没什么人讲,弄了好久才明白),渲染完后应该还原
13、纹理之间可以通过Device.StrechRect、Device.UpdateSurface来进行数据复制(拉伸和原样复制,无法使用Alpha混合的效果)
14、Alpha混合,用于给纹理叠加颜色或叠加透明度,参数很多通过Device.SetRenderState来设置,用好了可以化腐朽为神奇
//设置Alpha混合模式 Sprite._Begin(D3DXSPRITE_DONOTSAVESTATE); Device.SetRenderState(D3DRS_ALPHABLENDENABLE, 1); Device.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_BLENDFACTOR); Device.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); Device.SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_ARGB(Round(255.0* Rate),Round(255.0* Rate),Round(255.0* Rate),Round(255.0* Rate)));//绘制纹理TDXManager.Sprite.Draw(texture, nil, 0, nil, $FFFFFFFF);
//设置透明度 Device.SetRenderState(D3DRS_ALPHABLENDENABLE, 1); Device.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); Device.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); Device.SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE); Device.SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_ARGB(255, 255, 255, 255));//然后绘制纹理。。。TDXManager.Sprite.Draw(texture, nil, 0, nil, $FFFFFFFF);
有空了我会上个图,最烦写渲染不上图的,没图对比根本看不懂嘛
- 个人对DirectX3D做2D编程的理解
- 谈一下个人对编程的理解
- 对TCP/socket编程的个人理解
- 对OSGI的个人理解,OSGI是什么,OSGI做什么
- 个人对c++STL及其它编程语言的理解
- Directx3D - 3D空间的坐标系
- Directx3D - 3D空间的坐标系
- Directx3D - 3D空间的坐标系(转载)
- 对DirectX3D的GetAdapterCount()函数的误解
- 个人对getInitParameter的理解
- 个人对宏观经济学的理解
- 个人对withValueBackReference的理解
- 个人对MVC的理解
- 对SVM的个人理解
- 个人对jms的理解
- 个人对aop的理解
- 个人对压缩的理解
- 个人对runtime的理解
- 携程技术中心React Native Meetup活动经验分享
- 信息采集循环入库,保存图片到本地,分页展示,memcache搜索判断次数,详情展示,防盗链
- Animations与Transitions的区别
- php遇到的一些问题
- JAVA入门基础详解之五
- 个人对DirectX3D做2D编程的理解
- Ubuntu16.04 Tomcat9的安装
- Java学习
- 软件开发工具和数据结构导论
- skycloud博客详细设计v1.0
- java nio的使用
- 就是一个广搜加一个状态压缩
- linux系统编程之基础必备(六):可重入函数、线程安全、volatile
- Java学习