• [转]ID3DXSprite来实现DirectX 9.0C绘制2D


    关于ID3DXSprite绘制2D的例子真是少之又少。。。而我一直在寻找。。。

    下面是转载正文:

    最近我一直在不停地问有关2D游戏制做的技术。继上一篇DirectX9中的二维图片的加载以后,我再发一篇关于通过ID3DXSprite来实现DirectX 9.0C绘制2D动画的帖子,希望对大家有所帮助。


    DirectX9中的二维图片的加载
    http://www.dingge.com/forum/dispbbs.asp?boardID=46&ID=5578 (Soar:貌似打不开了,我试过了。。。)
    通过ID3DXSprite来实现DirectX 9.0C绘制2D动画
    http://www.dingge.com/forum/dispbbs.asp?boardid=46&id=5581(Soar:貌似打不开了,我试过了。。。) 


    在DirectX 8以前,2D都是DirectDraw来完成的,是Direct中非常重要的一个部分,但是到了DirectX 8以后,DirectDraw被合并到DirectX Graphics 当中了,所以在那以后就很少有人谈到如何用DirectX Graphics 实现2D效果。大多数需要2D的人都不辞辛苦用DirectDraw来实现了,毕竟用Direct 7的东西,后面的都是支持的。但是正如一个老外说的,喜欢用DirectDraw的人用用也无所谓,从Direct 8 以后学习的人再去学DirectDraw就不合适了,那么怎么实现自己需要的2D效果呢?我接触到了3种方法DirectX9中的二维图片的加载就是其中之一,这里我们要讲的是第二种通过ID3DXSprite来实现DirectX 9.0C绘制2D动画

    感谢Fenger提供的ID3DXSprite用法指导!!非常全面非常好!以下是引用Fenger的原话:


    建立D3D和其他相关的设备应该没有问题吧.
      然后再定义一个ID3DXSprite*变量:
        ID3DXSprite* pSprite = NULL;


      然后在创建D3D设备(假如是pd3dDevice)之后, 用D3DXCreateSprite创建Sprite:
        D3DXCreateSprite( pd3dDevice, &pSprite );

      记得在设备丢失/释放时使用: SAFE_RELEASE( pSprite );

      在渲染场景的时候, 使用:
        pSprite->Begin(x);
        ... // 具体绘制代码
        pSprite->End();

      其中的x可以是下面各值的组合, 如 D3DXSPRITE_ALPHABLEND | D3DXSPRITE_OBJECTSPACE
        D3DXSPRITE_DONOTSAVESTATE 调用Begin()或End()不保存/恢复设备状态. (如pd3dDevice->SetRenderState中设置的部分状态)(Soar:我在使用的过程中这个属性貌似会影响D3D的状态的,后来改成下面的DoNotModifyRenderState就没有问题了。。。)
        D3DXSPRITE_DONOTMODIFY_RENDERSTATE 不是很清楚, 呵呵, 表面上看好像是不改变渲染状态...
        D3DXSPRITE_OBJECTSPACE 不改变世界矩阵(WORLD)/投影矩阵(TRANSFORM)以及视点矩阵(VIEW), 使用设置在D3DDevice上的矩阵, 如果不指定这个标志, 3个矩阵自动改变为屏幕空间座标
        D3DXSPRITE_BILLBOARD BillBoard, 很清楚吧, 所有的Sprite都全部自动旋转来对着观看着
        D3DXSPRITE_ALPHABLEND 让Sprite支持AlphaBlend, 很重要, 几乎每次调用Begin都要指定此标志, 另外, D3DRS_ALPHATESTENABLE 状态必须设置为 TRUE, D3DBLEND_SRCALPHA / D3DBLEND_INVSRCALPHA 分别为源混和状态和目标很合状态
        D3DXSPRITE_SORT_TEXTURE Sprite会按照渲染先后排序, 当渲染在同一个深度的Sprite推荐使用.
        D3DXSPRITE_SORT_DEPTH_FRONTTOBACK 按照从前到后的渲染顺序对Sprite排序, 当在不同深度渲染有透明信息的Sprite时推荐使用.
        D3DXSPRITE_SORT_DEPTH_BACKTOFRONT 按照从后到前的渲染顺序对Sprite排序, 当在不同深度渲染透明Sprite时推荐使用
      一般就是D3DXSPRITE_ALPHABLEND, 或者根据需要再加上D3DXSPRITE_OBJECTSPACE, 其他的我都不怎么用.....
      中间的绘制代码使用 pSprite->Draw, 函数原型为:
      HRESULT Draw(
        LPDIRECT3DTEXTURE9 pTexture,
        CONST RECT *pSrcRect,
        CONST D3DXVECTOR3 *pCenter,
        CONST D3DXVECTOR3 *pPosition,
        D3DCOLOR Color );
      pTexture 是需要绘制的贴图
      pSrcRect 是需要绘制的贴图上的一个矩形区域, 绘制整过贴图可以指定为NULL.
      pCenter 是绘制的中心座标(旋转时会以此点为中心), 指定NULL表示中心座标为(0,0,0)
      pPosition 是绘制的位置座标, 也可以指定NULL表示(0,0,0)
      Color 是绘制的颜色, 一般情况下指定为 0xffffffff. 最高位到底位的各8字节为Alpha, 红, 绿, 蓝, 如果指定0x80ffffff就是半透明贴图. 如果0xffff0000就只保留贴图里的红色分量, 具体功能自己体会. 当然贴图本身可以包含Alpha信息.

      需要旋转等功能可以使用 pSprite->SetTransform(), 函数原型为:
      HRESULT SetTransform( CONST D3DXMATRIX *pTransform );
      相信这个不用解释都很清楚了吧.

      最后再提醒一点: pSprite->Begin和pSprite->End 必须成对的出现在 IDirect3DDevice9::BeginScene 和 IDirect3DDevice9::EndScene 之间.
      还有问题加QQ: 103226172. 指明原因(验证消息).




    前一种方法我们说过了,是单纯的图片加入,对于游戏而言没有太大的用处,游戏里面毕竟动态的东西比较多,怎么让他动起来呢?我们先看一下源代码。


    (本帖子不分析代码,主要留作讨论。代码分析在《超级马里奥.net游戏代码完全分析》中,欢迎下载)

    http://www.dingge.com/forum/dispbbs.asp?boardID=47&ID=5582&page=1

    以下代码在 Microsoft DirectX 9.0 SDK Update (August 2005)环境运行通过,如果遇到编译不通过在下面留言。

    把SDK中底个例子(纹理)中的banana.bmp(或者自己找一个不要太小的bmp文件)考到你的程序目录下。

    //--------------------------------程序2--------------------------------------

    // 学自网络 回馈网络
    //-----------------------------------------------------------------------------

    //-----------------------------------------------------------------------------
    #include <d3dX9.h>

    //-----------------------------------------------------------------------------
    LPDIRECT3D9 g_pD3D = NULL;
    LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
    LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;
    LPDIRECT3DTEXTURE9 g_pTexture = NULL;
    LPD3DXSPRITE g_pSprite = NULL;

    struct CUSTOMVERTEX
    {
    FLOAT x, y, z, rhw;
    DWORD color;
    };

    #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)


    RECT rct;

    //-----------------------------------------------------------------------------
    HRESULT InitD3D( HWND hWnd )
    {
    SetRect( &rct, 0,200, 100, 250 );

    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
    return E_FAIL;

    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof(d3dpp) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;


    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
    D3DCREATE_SOFTWARE_VERTEXPROCESSING,
    &d3dpp, &g_pd3dDevice ) ) )
    {
    return E_FAIL;
    }

    g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );


    D3DXCreateSprite( g_pd3dDevice, &g_pSprite );

    if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "banana.bmp", &g_pTexture ) ) )
    {

    if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "..\\banana.bmp", &g_pTexture ) ) )
    {
    MessageBox(NULL, "Could not find banana.bmp", "Textures.exe", MB_OK);
    return E_FAIL;
    }
    }


    g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
    g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
    return S_OK;
    }


    //-----------------------------------------------------------------------------
    HRESULT InitVB()
    {
    CUSTOMVERTEX vertices[] =
    {
    { 50.0f, 50.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
    { 250.0f, 50.0f, 0.5f, 1.0f, 0xff00ff00, },
    { 50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },
    { 250.0f, 250.0f, 0.5f,1.0f, 0xff00ffff, },
    };

    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 4*sizeof(CUSTOMVERTEX),
    0, D3DFVF_CUSTOMVERTEX,
    D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
    {
    return E_FAIL;
    }


    VOID* pVertices;
    if( FAILED( g_pVB->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 ) ) )
    return E_FAIL;
    memcpy( pVertices, vertices, sizeof(vertices) );
    g_pVB->Unlock();

    return S_OK;
    }

    //-----------------------------------------------------------------------------
    VOID Cleanup()
    {
    if( g_pVB != NULL )
    g_pVB->Release();

    if( g_pd3dDevice != NULL )
    g_pd3dDevice->Release();

    if( g_pD3D != NULL )
    g_pD3D->Release();
    }

    VOID Render()

    {
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );


    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {


    g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
    g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
    g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );

    if ( SUCCEEDED( g_pSprite->Begin(D3DXSPRITE_ALPHABLEND) ) )
    {
    rct.right +=1;
    rct.left +=1;


    g_pSprite->Draw(g_pTexture, &rct, NULL, NULL, 0xffffffff);
    g_pSprite->End();
    }



    g_pd3dDevice->EndScene();
    }


    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
    }

    LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
    {
    switch( msg )
    {
    case WM_DESTROY:
    Cleanup();
    PostQuitMessage( 0 );
    return 0;
    }

    return DefWindowProc( hWnd, msg, wParam, lParam );
    }

    INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
    {

    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
    GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
    "D3D Tutorial", NULL };
    RegisterClassEx( &wc );

    HWND hWnd = CreateWindow( "D3D Tutorial", "D3D Tutorial 02: Vertices",
    WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
    GetDesktopWindow(), NULL, wc.hInstance, NULL );


    if( SUCCEEDED( InitD3D( hWnd ) ) )
    {

    if( SUCCEEDED( InitVB() ) )
    {

    ShowWindow( hWnd, SW_SHOWDEFAULT );
    UpdateWindow( hWnd );


    MSG msg;
    ZeroMemory( &msg, sizeof(msg) );
    while( msg.message!=WM_QUIT )
    {
    if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
    {
    TranslateMessage( &msg );
    DispatchMessage( &msg );
    }
    else
    Render();
    }
    }
    }

    UnregisterClass( "D3D Tutorial", wc.hInstance );
    return 0;
    }

    Soar:之所以转载这篇文章,是因为 这篇文章确实是太好了。。。。

    看遍整个网络。。。。实在没找到更好的关于D3DxSprite 的文章了

  • 相关阅读:
    华为交换机端口安全
    华为路由交换命令收集
    Java使用JodaTime处理时间
    Java遍历Map对象的四种方式
    zabbix-2.4.8-1添加MySQL状态监控
    zabbix-2.4.8-1添加tcp状态监控
    zabbix-2.4.8-1添加nginx状态监控
    我的第四个Python小程序
    我的第三个Python小程序
    我的第二个Python小程序
  • 原文地址:https://www.cnblogs.com/SHGF/p/ID3DXSprite_Draw_2D.html
Copyright © 2020-2023  润新知