个人对DirectX3D做2D编程的理解

很多年前就知道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);


有空了我会上个图,最烦写渲染不上图的,没图对比根本看不懂嘛


  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值