zoukankan      html  css  js  c++  java
  • D3D中的Alpha颜色混合(1)

    提示:

    阅读本文需要一定的3D图形学和DirectX9基础,如果你发现阅读困难,请参阅D3D中的材质和光照处理
    本文用到的坐标系统变换函数请参阅DirectX 9的坐标系统变换



    渲染管道流水线通常需要将来自顶点的颜色,纹理像素的颜色,光照颜色以及物体表面材质反射光颜色进行混合,生成计算机屏幕的像素颜色。将多种颜色混合在一起,必须考虑各种颜色的成分比例,这个比例由Alpha因子决定。对于游戏开发来说,利用Alpha颜色混合可产生背景透明的渲染效果。

    颜色混合原理

    一般的,屏幕像素的当前颜色值SrcColor可与目标像素颜色值DestColor进行如下运算,然后将获得的颜色值Color作为该像素的新颜色,以实现像素的目标颜色与源颜色的混合。

    Color = SrcColor * SrcBlend + DestColor * DestBlend

    这里,SrcBlend和DestBlend为源混合因子和目标混合因子,分别乘以源颜色和目标颜色。SrcColor ,SrcBlend , DestColor ,DestBlend都是一个4维向量,而乘法运算 * 则是一个一个向量点积运算。

    假设4维向量SrcColor=(Rs, Gs, Bs, As),SrcBlend=(S1, S2, S3, S4), DestColor=(Rd, Gd, Bd, Ad),DestBlend(D1, D2, D3, D4),则混合颜色Color可用4维向量表示为:

    Color = (Rs * S1 + Rd * D1, Gs * S2 + Gd * D2, Bs * S3 + Bd * D3, As * S4 + Ad * D4)

    利用Direct3D设备接口提供的SetRenderState函数可将所要使用的混合因子设置给渲染管道流水线。此时,函数的第一个参数必须指定为D3DRS_SRCBLEND或D3DRS_DESTBLEND,分别表示设置源混合因子和目标混合因子,如下所示:
     
    // IDirect3DDevice9* _d3d_device;

    // set alpha blend for source color
     _d3d_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);

     
    // set alpha blend for dest color
      _d3d_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

    D3DBLEND_SRCALPHA和D3DBLEND_INVSRCALPHA均为DirectX预定义的混合因子宏,来看看具体定义:

    Defines the supported blend mode.

    typedef enum D3DBLEND
    {
    D3DBLEND_ZERO = 1,
    D3DBLEND_ONE = 2,
    D3DBLEND_SRCCOLOR = 3,
    D3DBLEND_INVSRCCOLOR = 4,
    D3DBLEND_SRCALPHA = 5,
    D3DBLEND_INVSRCALPHA = 6,
    D3DBLEND_DESTALPHA = 7,
    D3DBLEND_INVDESTALPHA = 8,
    D3DBLEND_DESTCOLOR = 9,
    D3DBLEND_INVDESTCOLOR = 10,
    D3DBLEND_SRCALPHASAT = 11,
    D3DBLEND_BOTHSRCALPHA = 12,
    D3DBLEND_BOTHINVSRCALPHA = 13,
    D3DBLEND_BLENDFACTOR = 14,
    D3DBLEND_INVBLENDFACTOR = 15,
    D3DBLEND_FORCE_DWORD = 0x7fffffff,
    } D3DBLEND, *LPD3DBLEND;

    Constants

    D3DBLEND_ZERO
    Blend factor is (0, 0, 0, 0).
    D3DBLEND_ONE
    Blend factor is (1, 1, 1, 1).
    D3DBLEND_SRCCOLOR
    Blend factor is (Rs, Gs, Bs, As).
    D3DBLEND_INVSRCCOLOR
    Blend factor is (1 - Rs, 1 - Gs, 1 - Bs, 1 - As).
    D3DBLEND_SRCALPHA
    Blend factor is (As, As, As, As).
    D3DBLEND_INVSRCALPHA
    Blend factor is ( 1 - As, 1 - As, 1 - As, 1 - As).
    D3DBLEND_DESTALPHA
    Blend factor is (Ad Ad Ad Ad).
    D3DBLEND_INVDESTALPHA
    Blend factor is (1 - Ad 1 - Ad 1 - Ad 1 - Ad).
    D3DBLEND_DESTCOLOR
    Blend factor is (Rd, Gd, Bd, Ad).
    D3DBLEND_INVDESTCOLOR
    Blend factor is (1 - Rd, 1 - Gd, 1 - Bd, 1 - Ad).
    D3DBLEND_SRCALPHASAT
    Blend factor is (f, f, f, 1); where f = min(As, 1 - Ad).
    D3DBLEND_BOTHSRCALPHA
    Obsolete. Starting with DirectX 6, you can achieve the same effect by setting the source and destination blend factors to D3DBLEND_SRCALPHA and D3DBLEND_INVSRCALPHA in separate calls.
    D3DBLEND_BOTHINVSRCALPHA
    Source blend factor is (1 - As, 1 - As, 1 - As, 1 - As), and destination blend factor is (As, As, As, As); the destination blend selection is overridden. This blend mode is supported only for the D3DRS_SRCBLEND render state.
    D3DBLEND_BLENDFACTOR
    Constant color blending factor used by the frame-buffer blender. This blend mode is supported only if D3DPBLENDCAPS_BLENDFACTOR is set in the SrcBlendCaps or DestBlendCaps members of D3DCAPS9.
    D3DBLEND_INVBLENDFACTOR
    Inverted constant color-blending factor used by the frame-buffer blender. This blend mode is supported only if the D3DPBLENDCAPS_BLENDFACTOR bit is set in the SrcBlendCaps or DestBlendCaps members of D3DCAPS9.
    D3DBLEND_FORCE_DWORD
    Forces this enumeration to compile to 32 bits in size. Without this value, some compilers would allow this enumeration to compile to a size other than 32 bits. This value is not used.

    Remarks

    In the preceding member descriptions, the RGBA values of the source and destination are indicated by the s and d subscripts.

    The values in this enumerated type are used by the following render states:

    • D3DRS_DESTBLEND
    • D3DRS_SRCBLEND
    • D3DRS_DESTBLENDALPHA
    • D3DRS_SRCBLENDALPHA

    由于渲染管道流水线的默认Alpha颜色混合功能是禁用的,因此必须调用SetRenderState函数设置D3DRS_ALPHABLENDENABLE为true.
     
    // enable alpha-blended transparency
    _d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);

     

    来看一个具体的例子:

    需要在工程中设置链接d3dx9.lib d3d9.lib。
    由于文件中用到了GE_APP这个类,它的具体使用说明请参阅 主窗口和DirectInput的封装。


    若发现代码中存在错误,敬请指出。

    源码下载

    来看看AlphaBlend.h的定义:

     
    /*************************************************************************************
     [Include File]

     PURPOSE: 
        Define for alpha blend.
    *************************************************************************************/


    #ifndef ALPHA_BLEND_H
    #define ALPHA_BLEND_H

    struct CUSTOM_VERTEX
    {
        float x, y, z;
        float nx, ny, nz;
    };

    #define CUSTOM_VERTEX_FVF   (D3DFVF_XYZ | D3DFVF_NORMAL)

    class ALPHA_BLEND
    {
    private:
        IDirect3D9* _d3d;
        IDirect3DDevice9* _d3d_device;
        IDirect3DVertexBuffer9* _vertex_buffer1;
        IDirect3DVertexBuffer9* _vertex_buffer2;

    public:
        ALPHA_BLEND();
        ~ALPHA_BLEND();

        bool Create_D3D_Device(HWND hwnd, bool full_screen = true);
        bool Init_Vertex_Buffer1();
        bool Init_Vertex_Buffer2();
        void Compute_Triangle_Normal(D3DXVECTOR3& v1, D3DXVECTOR3& v2, D3DXVECTOR3& v3, D3DVECTOR& normal);
        void Set_Camera();
        void Set_Point_Light();
        void Set_Object_Material(D3DCOLORVALUE& dif, D3DCOLORVALUE& amb, D3DCOLORVALUE& spe, 
                                 D3DCOLORVALUE& emi, float power);
        void Render();
        void Release_COM_Object();
    };

    #endif

    以上的头文件定义了两个三棱锥的顶点格式和顶点结构体,函数Init_Vertex_Buffer1个Init_Vertex_Buffer2分别用来装入这两个三棱锥的顶点数据,Render函数则设置了渲染管道流水线的 Alpha颜色混合状态值。

    再来看看AlphaBlend.cpp的定义:

     
    /*************************************************************************************
     [Implement File]

     PURPOSE: 
        Define for alpha blend.
    *************************************************************************************/


    #include "GE_COMMON.h"
    #include "AlphaBlend.h"

    //------------------------------------------------------------------------------------
    // Constructor, initialize all pointer with NULL.
    //------------------------------------------------------------------------------------
    ALPHA_BLEND::ALPHA_BLEND()
    {
        _d3d            = NULL;
        _d3d_device     = NULL;
        _vertex_buffer1 = NULL;
        _vertex_buffer2 = NULL;
    }

    //------------------------------------------------------------------------------------
    // Destructor, release all COM object.
    //------------------------------------------------------------------------------------
    ALPHA_BLEND::~ALPHA_BLEND()
    {
        Release_COM_Object();
    }

    //------------------------------------------------------------------------------------
    // Create direct3D interface and direct3D device.
    //------------------------------------------------------------------------------------
    bool ALPHA_BLEND::Create_D3D_Device(HWND hwnd, bool full_screen)
    {
        // Create a IDirect3D9 object and returns an interace to it.
        _d3d = Direct3DCreate9(D3D_SDK_VERSION);
        if(_d3d == NULL)
            return false;

        // retrieve adapter capability
        D3DCAPS9 d3d_caps;    
        _d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3d_caps);
        
        bool hardware_process_enable = (d3d_caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ? true : false);

        // Retrieves the current display mode of the adapter.
        D3DDISPLAYMODE display_mode;
        if(FAILED(_d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &display_mode)))
            return false;

        // set present parameter for direct3D device
        D3DPRESENT_PARAMETERS present_param;

        ZeroMemory(&present_param, sizeof(present_param));

        present_param.BackBufferWidth      = WINDOW_WIDTH;
        present_param.BackBufferHeight     = WINDOW_HEIGHT;
        present_param.BackBufferFormat     = display_mode.Format;
        present_param.BackBufferCount      = 1;
        present_param.hDeviceWindow        = hwnd;
        present_param.Windowed             = !full_screen;
        present_param.SwapEffect           = D3DSWAPEFFECT_FLIP;
        present_param.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;

        // Creates a device to represent the display adapter.
        DWORD behavior_flags;

        behavior_flags = hardware_process_enable ?
     D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING;

        if(FAILED(_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, behavior_flags, 
                                     &present_param, &_d3d_device)))
        {
            return false;
        }
        
        // create successfully
        return true;
    }

    //------------------------------------------------------------------------------------
    // Initialize vertex buffer for cone.
    //------------------------------------------------------------------------------------
    bool ALPHA_BLEND::Init_Vertex_Buffer1()
    {
        CUSTOM_VERTEX custom_vertex[12];
        
        D3DXVECTOR3 v[] = 
        {
            D3DXVECTOR3(5.0f, 6.0f, 5.0f),    // left triangle
            D3DXVECTOR3(6.0f, 0.0f, 3.0f),
            D3DXVECTOR3(1.0f, 0.0f, 7.0f),  
            D3DXVECTOR3(5.0f, 6.0f, 5.0f),    // right triangle
            D3DXVECTOR3(10.0f, 0.0f, 8.0f),
            D3DXVECTOR3(6.0f, 0.0f, 3.0f), 
            D3DXVECTOR3(5.0f, 6.0f, 5.0f),    // back triangle
            D3DXVECTOR3(1.0f, 0.0f, 7.0f),
            D3DXVECTOR3(10.0f, 0.0f, 8.0f),
            D3DXVECTOR3(1.0f, 0.0f, 7.0f),    // bottom triangle
            D3DXVECTOR3(6.0f, 0.0f, 3.0f),
            D3DXVECTOR3(10.0f, 0.0f, 8.0f)      
        };

        D3DVECTOR normal;

        // compute all triangle normal
        for(int i = 0; i < 12; i += 3)
        {
            // compute current triangle's normal
            Compute_Triangle_Normal(v[i], v[i+1], v[i+2], normal);

            // assign current vertex coordinate and current triangle normal to custom vertex array
            for(int j = 0; j < 3; j++)
            {
                int k = i + j;

                custom_vertex[k].x  = v[k].x;
                custom_vertex[k].y  = v[k].y;
                custom_vertex[k].z  = v[k].z;
                custom_vertex[k].nx = normal.x;
                custom_vertex[k].ny = normal.y;
                custom_vertex[k].nz = normal.z;
            }
        }

        BYTE* vertex_data;

        // create vertex buffer
        if(FAILED(_d3d_device->CreateVertexBuffer(12 * sizeof(CUSTOM_VERTEX), 0, CUSTOM_VERTEX_FVF,
                                D3DPOOL_DEFAULT, &_vertex_buffer1, NULL)))
        {
            return false;
        }

        // get data pointer to vertex buffer
        if(FAILED(_vertex_buffer1->Lock(0, 0, (void **) &vertex_data, 0)))
            return false;

        // copy custom vertex data into vertex buffer
        memcpy(vertex_data, custom_vertex, sizeof(custom_vertex));

        // unlock vertex buffer
        _vertex_buffer1->Unlock();

        return true;
    }

    //------------------------------------------------------------------------------------
    // Initialize vertex buffer for cone.
    //------------------------------------------------------------------------------------
    bool ALPHA_BLEND::Init_Vertex_Buffer2()
    {
        CUSTOM_VERTEX custom_vertex[12];

        float add = 1.3f;
        
        D3DXVECTOR3 v[] = 
        {
            D3DXVECTOR3(5.0f + add, 6.0f + add, 5.0f + add),    // left triangle
            D3DXVECTOR3(6.0f + add, 0.0f + add, 3.0f + add),
            D3DXVECTOR3(1.0f + add, 0.0f + add, 7.0f + add),  
            D3DXVECTOR3(5.0f + add, 6.0f + add, 5.0f + add),    // right triangle
            D3DXVECTOR3(10.0f + add, 0.0f + add, 8.0f + add),
            D3DXVECTOR3(6.0f + add, 0.0f + add, 3.0f + add), 
            D3DXVECTOR3(5.0f + add, 6.0f + add, 5.0f + add),    // back triangle
            D3DXVECTOR3(1.0f + add, 0.0f + add, 7.0f + add),
            D3DXVECTOR3(10.0f + add, 0.0f + add, 8.0f + add),
            D3DXVECTOR3(1.0f + add, 0.0f + add, 7.0f + add),    // bottom triangle
            D3DXVECTOR3(6.0f + add, 0.0f + add, 3.0f + add),
            D3DXVECTOR3(10.0f + add, 0.0f + add, 8.0f + add)      
        };

        D3DVECTOR normal;

        // compute all triangle normal
        for(int i = 0; i < 12; i += 3)
        {
            // compute current triangle's normal
            Compute_Triangle_Normal(v[i], v[i+1], v[i+2], normal);

            // assign current vertex coordinate and current triangle normal to custom vertex array
            for(int j = 0; j < 3; j++)
            {
                int k = i + j;

                custom_vertex[k].x  = v[k].x;
                custom_vertex[k].y  = v[k].y;
                custom_vertex[k].z  = v[k].z;
                custom_vertex[k].nx = normal.x;
                custom_vertex[k].ny = normal.y;
                custom_vertex[k].nz = normal.z;
            }
        }

        BYTE* vertex_data;

        // create vertex buffer
        if(FAILED(_d3d_device->CreateVertexBuffer(12 * sizeof(CUSTOM_VERTEX), 0, CUSTOM_VERTEX_FVF,
                                D3DPOOL_DEFAULT, &_vertex_buffer2, NULL)))
        {
            return false;
        }

        // get data pointer to vertex buffer
        if(FAILED(_vertex_buffer2->Lock(0, 0, (void **) &vertex_data, 0)))
            return false;

        // copy custom vertex data into vertex buffer
        memcpy(vertex_data, custom_vertex, sizeof(custom_vertex));

        // unlock vertex buffer
        _vertex_buffer2->Unlock();

        return true;
    }

    //------------------------------------------------------------------------------------
    // Set camera position.
    //------------------------------------------------------------------------------------
    void ALPHA_BLEND::Set_Camera()
    {
        D3DXVECTOR3 eye(-6.0, 1.5, 10.0);
        D3DXVECTOR3 at(6.0, 2.0, 3.0);
        D3DXVECTOR3 up(0.0, 1.0, 0.0);

        D3DXMATRIX view_matrix;

        // Builds a left-handed, look-at matrix.
        D3DXMatrixLookAtLH(&view_matrix, &eye, &at, &up);

        // Sets d3d device view transformation state.
        _d3d_device->SetTransform(D3DTS_VIEW, &view_matrix);

        D3DXMATRIX proj_matrix;

        // Builds a left-handed perspective projection matrix based on a field of view.
        D3DXMatrixPerspectiveFovLH(&proj_matrix, D3DX_PI/2, WINDOW_WIDTH / WINDOW_HEIGHT, 1.0, 1000.0);
        
        // Sets d3d device projection transformation state.
        _d3d_device->SetTransform(D3DTS_PROJECTION, &proj_matrix);
        // enable automatic normalization of vertex normals
        _d3d_device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
    }

    //------------------------------------------------------------------------------------
    // Set point light.
    //------------------------------------------------------------------------------------
    void ALPHA_BLEND::Set_Point_Light()
    {
        D3DLIGHT9 light;

        // clear memory with 0
        ZeroMemory(&light, sizeof(D3DLIGHT9));

        light.Type          = D3DLIGHT_POINT;

        light.Diffuse.r     = 1.0;
        light.Diffuse.g     = 0.0;
        light.Diffuse.b     = 0.0;

        light.Ambient.r     = 0.0;
        light.Ambient.g     = 1.0;
        light.Ambient.b     = 0.0;

        light.Specular.r    = 0.0;
        light.Specular.g    = 0.0;
        light.Specular.b    = 0.0;
        
        light.Position.x    = 5.0;
        light.Position.y    = 6.0;
        light.Position.z    = -20.0;

        light.Attenuation0  = 1.0;
        light.Attenuation1  = 0.0;
        light.Attenuation2  = 0.0;

        light.Range         = 1000.0;

        // Assigns point lighting properties for this device
        _d3d_device->SetLight(0, &light);
        // enable point light
        _d3d_device->LightEnable(0, TRUE);
        // enable light 
        _d3d_device->SetRenderState(D3DRS_LIGHTING, TRUE);
        // add ambient light
        _d3d_device->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50));
    }

    //------------------------------------------------------------------------------------
    // Sets the material properties for the device.
    //------------------------------------------------------------------------------------
    void ALPHA_BLEND::Set_Object_Material(D3DCOLORVALUE& dif, D3DCOLORVALUE& amb, D3DCOLORVALUE& spe, 
                                           D3DCOLORVALUE& emi, float power)
    {
        D3DMATERIAL9 material;

        material.Diffuse  = dif;
        material.Ambient  = amb;
        material.Specular = spe;
        material.Emissive = emi;
        material.Power    = power;

        // Sets the material properties for the device.
        _d3d_device->SetMaterial(&material);
    }

    //------------------------------------------------------------------------------------
    // Compute triangle normal.
    //------------------------------------------------------------------------------------
    void ALPHA_BLEND::Compute_Triangle_Normal(D3DXVECTOR3& v1, D3DXVECTOR3& v2, D3DXVECTOR3& v3, D3DVECTOR& normal)
    {
        D3DXVECTOR3 vec1 = v1 - v2;
        D3DXVECTOR3 vec2 = v1 - v3;
        D3DXVECTOR3 normal_vec;

        D3DXVec3Cross(&normal_vec, &vec1, &vec2);
        D3DXVec3Normalize(&normal_vec, &normal_vec);

        normal = (D3DVECTOR) normal_vec;
    }

    //------------------------------------------------------------------------------------
    // Draw cones.
    //------------------------------------------------------------------------------------
    void ALPHA_BLEND::Render()
    {
        if(_d3d_device == NULL)
            return;

        // clear surface with black
        _d3d_device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0);

        // begin scene
        _d3d_device->BeginScene();

        // 1) draw cone 1

        // Binds a vertex buffer to a device data stream.
        _d3d_device->SetStreamSource(0, _vertex_buffer1, 0, sizeof(CUSTOM_VERTEX));

        // Sets the current vertex stream declaration.
        _d3d_device->SetFVF(CUSTOM_VERTEX_FVF);

        // Renders a sequence of nonindexed, geometric primitives of the specified type from the current 
        // set of data input streams.
        _d3d_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 4);

        // enable alpha-blended transparency
        _d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
        
        // set alpha blend for source cone
        _d3d_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
        // set alpha blend for dest cone
        _d3d_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

        // 2) draw cone 2

        // Binds a vertex buffer to a device data stream. 
        _d3d_device->SetStreamSource(0, _vertex_buffer2, 0, sizeof(CUSTOM_VERTEX));

        // Sets the current vertex stream declaration.
        _d3d_device->SetFVF(CUSTOM_VERTEX_FVF);

        // draw square
        _d3d_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 4);

        // disable alpha blend for d3d device
        _d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);

        // end scene
        _d3d_device->EndScene();

        // Presents the contents of the next buffer in the sequence of back buffers owned by the device.
        _d3d_device->Present(NULL, NULL, NULL, NULL);
    }

    //------------------------------------------------------------------------------------
    // Release all COM object.
    //------------------------------------------------------------------------------------
    void ALPHA_BLEND::Release_COM_Object()
    {
        Safe_Release(_vertex_buffer1);
        Safe_Release(_vertex_buffer2);
        Safe_Release(_d3d_device);
        Safe_Release(_d3d);
    }

    main.cpp的实现很简单,它首先调用类ALPHA_BLEND的函数创建两个三棱锥的顶点缓冲区,然后进行取景并设置材质光源,最后调用Render函数进行混色渲染。

     
    /*************************************************************************************
     [Implement File]

     PURPOSE: 
        Test for alpha blending.
    *************************************************************************************/


    #define DIRECTINPUT_VERSION 0x0800

    #include "GE_COMMON.h"
    #include "GE_APP.h"
    #include "AlphaBlend.h"

    #pragma warning(disable : 4305 4996)

    int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR cmd_line, int cmd_show)
    {
        GE_APP ge_app;
        ALPHA_BLEND alpha_blend;

        MSG msg = {0};

        
    // create window
        if(! ge_app.Create_Window("Alpha blending test", instance, cmd_show))
            
    return false;

        HWND hwnd = ge_app.Get_Window_Handle();    

        SetWindowPos(hwnd, 0, 0,0,0,0, SWP_NOSIZE);
        SetCursorPos(0, 0);
        
        
    // Create direct3D interface and direct3D device.
        if(! alpha_blend.Create_D3D_Device(hwnd, false))
            
    return false;

        
    // Initialize cone 1 vertex buffer with curstom vertex structure.
        if(! alpha_blend.Init_Vertex_Buffer1())
            
    return false;

        
    // Initialize cone 2 vertex buffer with curstom vertex structure.
        if(! alpha_blend.Init_Vertex_Buffer2())
            
    return false;
        
        
    // Set camera position.
        alpha_blend.Set_Camera();

        D3DCOLORVALUE dif = {1.0f, 1.0f, 1.0f, 0.6f};
        D3DCOLORVALUE amb = {1.0f, 1.0f, 1.0f, 0.0f};
        D3DCOLORVALUE spe = {0.0f, 0.0f, 0.0f, 0.0f};
        D3DCOLORVALUE emi = {0.0f, 0.0f, 0.0f, 0.0f};

        
    // Sets the material properties for the device.
        alpha_blend.Set_Object_Material(dif, amb, spe, emi, 0);

        
    // Set point light.
        alpha_blend.Set_Point_Light();

        
    // Draw all cones
        alpha_blend.Render();

        
    while(msg.message != WM_QUIT)
        {
            
    if(PeekMessage(&msg, NULL, 0,0 , PM_REMOVE))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }    

        UnregisterClass(WINDOW_CLASS_NAME, instance);

        
    return true;
    }
     

    运行效果:


  • 相关阅读:
    App自动化01-Appium概述
    App绕过SSL Pinning机制抓取Https请求
    手机大厂必备测试技能-GMS 认证
    手机大厂必备测试技能-CTS 兼容测试
    一文搞定web自动化环境常见问题
    Airtest-UI 自动化集大成者
    shell三剑客之sed
    shell三剑客之grep
    二月主题读书整理——元技能系列
    深度学习目标检测综述推荐之 Xiaogang Wang ISBA 2015
  • 原文地址:https://www.cnblogs.com/flying_bat/p/900557.html
Copyright © 2011-2022 走看看