D3D中的Alpha颜色混合(1)

来源:互联网 发布:淘宝的店铺号在哪里看 编辑:程序博客网 时间:2024/05/18 13:42

D3D中的Alpha颜色混合(1)

 

提示:

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



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

颜色混合原理

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

Color = SrcColor * SrcBlend + DestColor * DestBlend

这里,SrcBlendDestBlend为源混合因子和目标混合因子,分别乘以源颜色和目标颜色。SrcColorSrcBlend DestColorDestBlend都是一个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_SRCBLENDD3DRS_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_SRCALPHAD3DBLEND_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 theSrcBlendCaps orDestBlendCaps members ofD3DCAPS9.

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 theSrcBlendCaps orDestBlendCaps members ofD3DCAPS9.

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 thes andd 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_ALPHABLENDENABLEtrue.
 

// 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_Buffer1Init_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;
}
 


运行效果:

 

 

原创粉丝点击