• Direct3D轮回:基于ID3DXSprite的2D元素绘制


    D3D中的2D元素绘制主要是通过ID3DXSprite来完成的。

    我们通过调用D3DXCreateSprite来完成ID3DXSprite接口对象的创建,同时使用介于Begin与End之间的Draw方法来完成D3D中2D元素的绘制。

    下面,我们对IDirect3DTexture9和ID3DXSprite进行二次封装,使其接口趋于人性化,使用起来更加便捷:

    /*-------------------------------------

    代码清单:Texture2D.h
    来自:
    http://www.cnblogs.com/kenkao

    -------------------------------------
    */

    #include 
    "D3DInit.h"

    #pragma once

    class CTexture2D
    {
    public:
        CTexture2D(
    void);
        
    ~CTexture2D(void);
    public:
        
    void LoadTexture(                                             //纹理加载
            char* szFxFileName,                                       //文件路径
            UINT SizeX = D3DX_DEFAULT_NONPOW2,                        //X默认非2次幂尺寸
            UINT SizeY = D3DX_DEFAULT_NONPOW2                         //Y默认非2次幂尺寸
            );
        
    void Release()  {ReleaseCOM(m_pTexture);}                     //释放纹理
    public:
        UINT               GetWidth()       {
    return m_Width;}         //获得纹理宽
        UINT               GetHight()       {return m_Height;}        //获得纹理高
        RECT               GetRect()        {return m_SurRect;}       //获得纹理尺寸
        IDirect3DTexture9* GetTexture()     {return m_pTexture;}      //获得纹理指针
        D3DXIMAGE_INFO     GetTextureInfo() {return m_TextureInfo;}   //获得纹理信息
    private:
        IDirect3DTexture9
    * m_pTexture;                                //纹理指针
        D3DXIMAGE_INFO     m_TextureInfo;                             //纹理信息
        RECT               m_SurRect;                                 //纹理尺寸
        UINT               m_Width;                                   //纹理宽
        UINT               m_Height;                                  //纹理高
    };
    /*-------------------------------------

    代码清单:Texture2D.cpp
    来自:
    http://www.cnblogs.com/kenkao

    -------------------------------------
    */

    #include 
    "StdAfx.h"
    #include 
    "Texture2D.h"
    #include 
    "D3DGame.h"

    extern IDirect3DDevice9* g_pD3DDevice;

    CTexture2D::CTexture2D(
    void):m_pTexture(NULL)
    {
    }

    CTexture2D::
    ~CTexture2D(void)
    {
    }

    void CTexture2D::LoadTexture(char* szFxFileName, UINT SizeX, UINT SizeY)
    {
        D3DXCreateTextureFromFileEx(
            g_pD3DDevice,
            szFxFileName,
            SizeX, 
            SizeY,
            D3DX_FROM_FILE,
            D3DPOOL_DEFAULT,
            D3DFMT_FROM_FILE,
            D3DPOOL_MANAGED,
            D3DX_DEFAULT,
            D3DX_DEFAULT,
            D3DCOLOR_COLORVALUE(
    0.0f,0.0f,0.0f,1.0f),
            
    &m_TextureInfo,
            NULL,
            
    &m_pTexture);
        
    if(SizeX==(UINT)-2)
            m_Width 
    = m_TextureInfo.Width;
        
    else
            m_Width 
    = SizeX;
        
    if(SizeY==(UINT)-2)
            m_Height 
    = m_TextureInfo.Height;
        
    else
            m_Height 
    = SizeY;
        m_SurRect.top    
    = 0;
        m_SurRect.left   
    = 0;
        m_SurRect.right  
    = m_Width;
        m_SurRect.bottom 
    = m_Height;
    }

    我们依然通过调用D3DXCreateTextureFromFileEx函数从特定的Img文件产生纹理,只不过这次通过传入特定的参数使其产生专门用于2D绘制的纹理。

    大家可以看到LoadTexture中的SizeX,SizeY我给定了默认值D3DX_DEFAULT_NONPOW2,意在使所获得的纹理默认支持非二次幂尺寸;而两个值如果默认为0的话,纹理尺寸会被自动拉伸到最相近的二次幂值,这不是我们所期待的结果。

    加载完毕的纹理必要信息,会被存放到一个D3DXIMAGE_INFO类型的结构体中,其定义可以参看SDK,很好理解~

    /*-------------------------------------

    代码清单:D3DSprite.h
    来自:
    http://www.cnblogs.com/kenkao

    -------------------------------------
    */

    #include 
    "Texture2D.h"

    #pragma once

    class CD3DSprite
    {
    public:
        CD3DSprite(IDirect3DDevice9
    * pDevice);
        
    ~CD3DSprite(void);
    public:
        
    void Begin(DWORD Flags);                 // 开启Sprite绘制
        void End();                              // 结束Sprite绘制
        void Draw(                               // 绘制Sprite
            CTexture2D* pTexture,                // 2D纹理
            const POINT& Position,               // 位置
            D3DCOLOR Color                       // 色相
            );
        
    void Draw(
            CTexture2D
    * pTexture, 
            
    const POINT& Position, 
            
    const RECT& SurRect,                 // 指定绘制纹理区域
            D3DCOLOR Color
            );
        
    void Draw(
            CTexture2D
    * pTexture, 
            
    const POINT& Pos, 
            
    const D3DXMATRIX& TransMatrix,       // 变换矩阵
            const RECT& SurRect, 
            D3DCOLOR Color
            );
        
    void Draw(
            CTexture2D
    * pTexture, 
            
    const POINT& Pos, 
            
    const POINT& Size,                   // 绘制尺寸
            const RECT& SurRect, 
            D3DCOLOR Color
            );
        
    void Draw(
            CTexture2D
    * pTexture, 
            
    const RECT& DesRect,                 // 指定绘制目标区域
            const RECT& SurRect, 
            D3DCOLOR Color
            );
        
    void Draw(
            CTexture2D
    * pTexture, 
            
    const RECT& DesRect, 
            D3DCOLOR Color
            );
        
    void Release(){ReleaseCOM(m_pSprite)};   // 释放Sprite
    public:
        ID3DXSprite
    * GetSprite(){return m_pSprite;}   // 获得Sprite指针
    private:
        ID3DXSprite
    * m_pSprite;                  // Sprite指针
        D3DXMATRIX   m_orgMatrix;                // 原始矩阵
    };
    /*-------------------------------------

    代码清单:D3DSprite.cpp
    来自:
    http://www.cnblogs.com/kenkao

    -------------------------------------
    */

    #include 
    "StdAfx.h"
    #include 
    "D3DSprite.h"

    CD3DSprite::CD3DSprite(IDirect3DDevice9
    * pDevice)
    {
        D3DXCreateSprite(pDevice, 
    &m_pSprite);
        D3DXMatrixTranslation(
    &m_orgMatrix,1.0f,1.0f,0.0f);
    }

    CD3DSprite::
    ~CD3DSprite(void)
    {
    }

    void CD3DSprite::Begin(DWORD Flags)
    {
        m_pSprite
    ->Begin(Flags);
    }

    void CD3DSprite::End()
    {
        m_pSprite
    ->End();
    }

    void CD3DSprite::Draw(CTexture2D* pTexture, const POINT& Pos, D3DCOLOR Color)
    {
        Draw(pTexture,Pos,pTexture
    ->GetRect(),Color);
    }

    void CD3DSprite::Draw(CTexture2D* pTexture, const POINT& Pos, const RECT& SurRect, D3DCOLOR Color)
    {
        m_pSprite
    ->Draw(pTexture->GetTexture(),&SurRect,&D3DXVECTOR3(0.0f,0.0f,0.0f),&D3DXVECTOR3(Pos.x,Pos.y,0.0f),Color);
    }

    void CD3DSprite::Draw(CTexture2D* pTexture, const POINT& Pos, const D3DXMATRIX& TransMatrix, const RECT& SurRect, D3DCOLOR Color)
    {
        
    // 设置缩放矩阵
        m_pSprite->SetTransform(&TransMatrix);
        Draw(pTexture,Pos,SurRect,Color);
        
    // 还原缩放矩阵
        m_pSprite->SetTransform(&m_orgMatrix);
    }

    void CD3DSprite::Draw(CTexture2D* pTexture, const POINT& Pos, const POINT& Size, const RECT& SurRect, D3DCOLOR Color)
    {
        D3DXMATRIX TransMatrix;
        FLOAT ScalX, ScalY;
        ScalX 
    = (FLOAT)Size.x/(FLOAT)(SurRect.right-SurRect.left);
        ScalY 
    = (FLOAT)Size.y/(FLOAT)(SurRect.bottom-SurRect.top);
        D3DXMatrixScaling(
    &TransMatrix,ScalX,ScalY,0.0f);
        Draw(pTexture,Pos,TransMatrix,SurRect,Color);
    }

    void CD3DSprite::Draw(CTexture2D* pTexture, const RECT& DesRect, const RECT& SurRect, D3DCOLOR Color)
    {
        POINT Pos;
        Pos.x 
    = DesRect.left;
        Pos.y 
    = DesRect.top;
        POINT Size;
        Size.x 
    = DesRect.right - DesRect.left;
        Size.y 
    = DesRect.bottom - DesRect.top;
        Draw(pTexture, Pos, Size, SurRect, Color);
    }

    void CD3DSprite::Draw(CTexture2D* pTexture, const RECT& DesRect, D3DCOLOR Color)
    {
        Draw(pTexture,DesRect,pTexture
    ->GetRect(),Color);
    }

    我们的CD3DSprite在原有ID3DXSprite基础上所做的主要工作是提供了大量的重载Draw函数,以更加人性化的参数设计提供更加便捷的函数调用。

    这里值得一提的是

    m_pSprite->SetTransform(&TransMatrix);

    方法的调用。所传入参数就目前测试来看,只可以是缩放矩阵,平移与旋转矩阵被认定是非法的。ID3DXSprite接口对象就是通过这种方式来完成2D图像的缩放工作的。(感谢CSDN游戏开发论坛一位大侠的提点 ^ ^)

    D3DGame.cpp
    /*-------------------------------------

    代码清单:D3DGame.cpp
    来自:
    http://www.cnblogs.com/kenkao

    -------------------------------------
    */

    #include 
    "StdAfx.h"
    #include 
    "D3DGame.h"
    #include 
    "D3DCamera.h"
    #include 
    "D3DEffect.h"
    #include 
    "CoordCross.h"
    #include 
    "SimpleXMesh.h"
    #include 
    "Texture2D.h"
    #include 
    "D3DSprite.h"
    #include 
    <stdio.h>

    //---通用全局变量

    HINSTANCE  g_hInst;
    HWND       g_hWnd;
    D3DXMATRIX g_matProjection;

    //---D3D全局变量

    IDirect3D9       
    *g_pD3D           = NULL;
    IDirect3DDevice9 
    *g_pD3DDevice     = NULL;
    CMouseInput      
    *g_pMouseInput    = NULL;
    CKeyboardInput   
    *g_pKeyboardInput = NULL;
    CD3DCamera       
    *g_pD3DCamera     = NULL;
    CCoordCross      
    *g_pCoordCross    = NULL;
    CSimpleXMesh     
    *g_pSimpleXMesh   = NULL;
    CD3DEffect       
    *g_pD3DEffect     = NULL;
    CD3DSprite       
    *g_pD3DSprite     = NULL;
    CTexture2D       
    *g_pTexture2D     = NULL;

    //---HLSL全局变量句柄

    D3DXHANDLE   g_CurrentTechHandle 
    = NULL;
    D3DXHANDLE   g_matWorldViewProj  
    = NULL;  
    D3DXHANDLE   g_matWorld          
    = NULL;
    D3DXHANDLE   g_vecEye            
    = NULL;
    D3DXHANDLE   g_vecLightDir       
    = NULL;
    D3DXHANDLE   g_vDiffuseColor     
    = NULL;
    D3DXHANDLE   g_vSpecularColor    
    = NULL;
    D3DXHANDLE   g_vAmbient          
    = NULL;

    // HLSL特效参数设置
    void GetParameters();
    void SetParameters();

    void Initialize(HINSTANCE hInst, HWND hWnd)
    {
        g_hInst 
    = hInst;
        g_hWnd  
    = hWnd;
        InitD3D(
    &g_pD3D, &g_pD3DDevice, g_matProjection, hWnd);
        g_pMouseInput 
    = new CMouseInput;
        g_pMouseInput
    ->Initialize(hInst,hWnd);
        g_pKeyboardInput 
    = new CKeyboardInput;
        g_pKeyboardInput
    ->Initialize(hInst,hWnd);
        g_pD3DCamera 
    = new CD3DCamera;
    }

    void LoadContent()
    {
        g_pCoordCross 
    = new CCoordCross;
        
    // 设置摄影机位置
        g_pD3DCamera->SetCameraPos(D3DXVECTOR3(0.5f,0.5f,-5.0f));
        g_pSimpleXMesh 
    = new CSimpleXMesh;
        
    // 加载X网格
        g_pSimpleXMesh->LoadXMesh("teapot.X");
        g_pD3DEffect 
    = new CD3DEffect;
        
    char ErrMsg[60];
        
    // 加载fx特效
        if(!g_pD3DEffect->LoadEffect("Light.fx",ErrMsg))
            ::MessageBox(g_hWnd,ErrMsg,
    0,0);
        
    // 获得句柄
        GetParameters();
        g_pD3DSprite 
    = new CD3DSprite(g_pD3DDevice);
        g_pTexture2D 
    = new CTexture2D;
        
    // 加载纹理
        g_pTexture2D->LoadTexture("img.jpg");
    }

    void Update()
    {
        g_pMouseInput
    ->GetState();
        g_pKeyboardInput
    ->GetState();
        g_pD3DCamera
    ->Update();
    }

    void Draw()
    {
        
    // 参数设定
        SetParameters();
        g_pD3DDevice
    ->SetTransform(D3DTS_VIEW,&g_pD3DCamera->GetViewMatrix());
        POINT pos;
        pos.x
    =0;
        pos.y
    =0;
        g_pD3DDevice
    ->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(100,149,237,255), 1.0f0);
        
    if(SUCCEEDED(g_pD3DDevice->BeginScene())) 
        {
            g_pCoordCross
    ->Draw();

            
    // Sprite绘制开始
            g_pD3DSprite->Begin(D3DXSPRITE_ALPHABLEND);
            
    // Sprite绘制
            g_pD3DSprite->Draw(g_pTexture2D,pos,g_pTexture2D->GetRect(),D3DXCOLOR_WHITE);
            
    // Sprite绘制结束
            g_pD3DSprite->End();

            UINT numPasses;
            
    // 开启特效
            g_pD3DEffect->BeginEffect(numPasses);
            
    for(UINT i=0;i<numPasses;i++)
            {
                
    // 开启路径
                g_pD3DEffect->GetEffect()->BeginPass(i);
                
    for(DWORD j=0;j<g_pSimpleXMesh->GetMaterialNum();j++)
                {
                    g_pSimpleXMesh
    ->DrawXMeshSubset(j);
                }
                
    // 路径结束
                g_pD3DEffect->GetEffect()->EndPass();
            }
            
    // 特效结束
            g_pD3DEffect->EndEffect();
        
            g_pD3DDevice
    ->EndScene();
        }
        g_pD3DDevice
    ->Present(NULL, NULL, NULL, NULL);
    }

    void UnloadContent()
    {
        ReleaseCOM(g_pTexture2D);
        ReleaseCOM(g_pD3DSprite);
        ReleaseCOM(g_pD3DEffect);
        ReleaseCOM(g_pSimpleXMesh);
        ReleaseCOM(g_pCoordCross);
    }

    void Dispose()
    {
        ReleaseCOM(g_pD3DCamera);
        ReleaseCOM(g_pKeyboardInput);
        ReleaseCOM(g_pMouseInput);
        ReleaseCOM(g_pD3DDevice);
        ReleaseCOM(g_pD3D);
    }

    void GetParameters()
    {
        
    // 获得HLSL中各个全局变量句柄
        g_CurrentTechHandle = g_pD3DEffect -> GetEffect() -> GetTechniqueByName("SpecularLight");
        g_matWorldViewProj  
    = g_pD3DEffect -> GetEffect() -> GetParameterByName(0"matWorldViewProj");
        g_matWorld          
    = g_pD3DEffect -> GetEffect() -> GetParameterByName(0"matWorld");
        g_vecEye            
    = g_pD3DEffect -> GetEffect() -> GetParameterByName(0"vecEye");
        g_vecLightDir       
    = g_pD3DEffect -> GetEffect() -> GetParameterByName(0"vecLightDir");
        g_vDiffuseColor     
    = g_pD3DEffect -> GetEffect() -> GetParameterByName(0"vDiffuseColor");
        g_vSpecularColor    
    = g_pD3DEffect -> GetEffect() -> GetParameterByName(0"vSpecularColor");
        g_vAmbient          
    = g_pD3DEffect -> GetEffect() -> GetParameterByName(0"vAmbient");
    }

    void SetParameters()
    {
        
    // 设定当前技术
        g_pD3DEffect -> GetEffect() -> SetTechnique(g_CurrentTechHandle);
        
    // 设定HLSL中的各个参数
        D3DXMATRIX worldMatrix;
        D3DXMatrixTranslation(
    &worldMatrix,0.0f,0.0f,0.0f);
        g_pD3DEffect 
    -> GetEffect() -> SetMatrix(g_matWorldViewProj,&(worldMatrix*g_pD3DCamera->GetViewMatrix()*g_matProjection));
        g_pD3DEffect 
    -> GetEffect() -> SetMatrix(g_matWorld,&worldMatrix);
        D3DXVECTOR3 cameraPos 
    = g_pD3DCamera->GetCameraPos();
        D3DXVECTOR4 vecEye 
    = D3DXVECTOR4(cameraPos.x,cameraPos.y,cameraPos.z,0.0f);
        g_pD3DEffect 
    -> GetEffect() -> SetVector(g_vecEye,&vecEye);
        D3DXVECTOR4 vLightDirection 
    = D3DXVECTOR4(0.0f0.0f-1.0f1.0f);
        g_pD3DEffect 
    -> GetEffect() -> SetVector(g_vecLightDir,&vLightDirection);
        D3DXVECTOR4 vColorDiffuse 
    = D3DXVECTOR4(0.8f0.0f0.0f1.0f);
        D3DXVECTOR4 vColorSpecular 
    = D3DXVECTOR4(1.0f1.0f1.0f1.0f);
        D3DXVECTOR4 vColorAmbient 
    = D3DXVECTOR4(0.1f0.1f0.1f1.0f);
        g_pD3DEffect 
    -> GetEffect() -> SetVector(g_vDiffuseColor,&vColorDiffuse);
        g_pD3DEffect 
    -> GetEffect() -> SetVector(g_vSpecularColor,&vColorSpecular);
        g_pD3DEffect 
    -> GetEffect() -> SetVector(g_vAmbient,&vColorAmbient);
    }

    效果图:

  • 相关阅读:
    四则运算题目的程序
    Github注册账户过程
    目前流行的源程序版本管理软件和项目管理软件都有哪些?各有什么优缺点?
    学习进度总结
    学习进度总结
    7月29 日实习日志及总结
    7月28日实习日志
    7月27实习日志
    7月26日实习日志
    7月25日实习日志
  • 原文地址:https://www.cnblogs.com/kenkao/p/2096657.html
Copyright © 2020-2023  润新知