文档章节

D3D中的Alpha颜色混合(1)

rise-worlds
 rise-worlds
发布于 2016/06/20 13:38
字数 2453
阅读 1
收藏 0

提示:

阅读本文需要一定的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 (R s, G s, B s, A s).
D3DBLEND_INVSRCCOLOR
Blend factor is (1 - R s, 1 - G s, 1 - B s, 1 - A s).
D3DBLEND_SRCALPHA
Blend factor is (A s, A s, A s, A s).
D3DBLEND_INVSRCALPHA
Blend factor is ( 1 - A s, 1 - A s, 1 - A s, 1 - A s).
D3DBLEND_DESTALPHA
Blend factor is (A d A d A d A d).
D3DBLEND_INVDESTALPHA
Blend factor is (1 - A d 1 - A d 1 - A d 1 - A d).
D3DBLEND_DESTCOLOR
Blend factor is (R d, G d, B d, A d).
D3DBLEND_INVDESTCOLOR
Blend factor is (1 - R d, 1 - G d, 1 - B d, 1 - A d).
D3DBLEND_SRCALPHASAT
Blend factor is (f, f, f, 1); where f = min(A s, 1 - A d).
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 - A s, 1 - A s, 1 - A s, 1 - A s), and destination blend factor is (A s, A s, A s, A s); 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 ;
}
 

运行效果:


本文转载自:http://www.cnblogs.com/flying_bat/archive/2007/09/20/900557.html

rise-worlds

rise-worlds

粉丝 3
博文 1755
码字总数 0
作品 0
深圳
程序员
私信 提问
OpenGL超级宝典笔记——混合

混合 在正常情况下,OpenGL渲染时会把颜色值输入到颜色缓冲区中,深度值输入到深度缓冲区中。如果我们关闭深度测试,那么新的颜色值会简单地覆盖已经存在于颜色缓冲区中的值。当开启深度测试...

Mario_Q
2013/10/17
3K
0
HLSL 研究学习之六章三节

注:所有代码均由红孩儿编写或以Microsoft DX9 SDK Sample 代码修改而成,转载请注明. (6_3)3D三角形纹理与色彩混合(fx中单一色,不用PS) hlsl.fx: // ---------------------------------------...

长平狐
2013/03/19
21
0
HLSL 研究学习之六章三节

注:所有代码均由红孩儿编写或以Microsoft DX9 SDK Sample 代码修改而成,转载请注明. (6_3)3D三角形纹理与色彩混合(fx中单一色,不用PS) hlsl.fx: // ---------------------------------------...

长平狐
2012/11/19
17
0
HLSL 研究学习之第七章第二节

注:所有代码均由红孩儿编写或以Microsoft DX9 SDK Sample 代码修改而成,转载请注明. (7_2)3D三角形纹理与色彩混合(用原来色彩,不用PS) // ------------------------------------------------...

长平狐
2012/11/19
28
0
HLSL 研究学习之第七章第二节

注:所有代码均由红孩儿编写或以Microsoft DX9 SDK Sample 代码修改而成,转载请注明. (7_2)3D三角形纹理与色彩混合(用原来色彩,不用PS) // ------------------------------------------------...

长平狐
2013/03/19
8
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 如果是个帅小伙你愿意和他出去吗

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 小小编辑推荐:《Ghost 》游戏《死亡搁浅》原声 《Ghost 》游戏(《死亡搁浅》原声) - Au/Ra / Alan Walker 手机党少年们想听歌,请使劲儿戳...

小小编辑
51分钟前
84
5
java通过ServerSocket与Socket实现通信

首先说一下ServerSocket与Socket. 1.ServerSocket ServerSocket是用来监听客户端Socket连接的类,如果没有连接会一直处于等待状态. ServetSocket有三个构造方法: (1) ServerSocket(int port);...

Blueeeeeee
今天
6
0
用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
5
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
16
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
19
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部