D3D中的Alpha颜色混合(2)

本篇是D3D中的Alpha颜色混合(1) 的后续篇,主要讲利用ID3DXSprite来实现图片间的颜色透明效果。

在一幅图象上透明的显示另一幅图象,是Alpha颜色混合的一个典型应用,如下图所示,瞄准镜图象背景透明地显示在老虎背景图象上。



实现瞄准镜的背景透明显示,首先需要准备如下两张图:

                                               
  瞄准镜源图  (图1)                                    瞄准镜Alpha通道(屏蔽图)(图2)

Alpha通道图(屏蔽图)的黑色像素对应的源图像素不被显示出来,Alpha通道图(屏蔽图)的白色像素对应的源图像素会显示出来。

Alpha 通道图(屏蔽图)的像素颜色值是作为DirectX颜色结构体的alpha分量值来使用的。图2所示的黑色像素将产生一个为0的Alpha值,而白色像素将产生一个为1的Alpha值。如果此时将渲染管道流水线的D3DRS_SRCBLEND源混合因子参数设置为D3DBLEND_SRCALPHA,目标混合因子参数设置为D3DBLEND_INVSRCALPHA,然后先绘制图1所示的纹理图,再绘制图2所示的纹理图,那么混合后的结果将是图1所示的白色背景不被显示出来,仅显示一个圆和一个十字形,正因为Alpha通道图具有以上的屏蔽效果,因此图2所示的Alpha通道图也称为屏蔽图。

如果直接采用上面的方法实现图形间的透明效果,那么需要进行3次纹理贴图,并设置好相应的混合参数。第一次先绘制出老虎背景图,接着绘制瞄准镜源图,最后绘制瞄准镜Alpha通道图。这样做显然是比较繁琐的,因此可用DirectX提供的ID3DXSprite接口进行绘制。

首先,在DirectX安装目录下的Utilities目录下执行DxTex.exe,这是DirectX提供的用于生成纹理图象的Alpha通道图的工具。

(注:如果你执行DxTex.exe时系统提示如下信息:

Unable to create Direct3D Device. Please make sure your desktop color depth is 16 or 32 bit, and that d3dref.dll is installed.

请参考解决方案 运行DxTex.exe碰到的问题

首先执行"File - Open"菜单,将图1所示的瞄准镜源图打开,然后执行"Change Surface Format ..." 菜单,重新设置bmp图象的像素颜色格式为A8R8G8B8,即添加一个Alpha颜色值。

              

执行新增加的"File - Open onto alpha channel of this texture..."菜单,弹出一个文件打开对话框,选择图2所示的瞄准镜Alpha通道图并打开,DxTex将自动把Alpha通道图的屏蔽信息插入图象中。如下图所示,DxTex默认的淡蓝色背景色表示该像素颜色已为透明色。最后,执行"File - Save"菜单,将同时具有源图信息和Alpha通道信息的图象保存为DDS格式的gun.dds。



生成瞄准镜的DDS文件后,就可以利用d3dx9.lib库的ID3DXSprite提供的方法,将瞄准镜背景透明地显示出来。ID3DXSprite接口对象是通过D3DXCreateSprite函数进行创建的,来看看该函数的具体使用信息:

Creates a sprite object which is associated with a particular device. Sprite objects are used to draw 2D images to the screen.

HRESULT D3DXCreateSprite(
LPDIRECT3DDEVICE9 pDevice,
LPD3DXSPRITE * ppSprite
);

Parameters

pDevice
[in] Pointer to an IDirect3DDevice9 interface, the device to be associated with the sprite.
ppSprite
[out] Address of a pointer to an ID3DXSprite interface. This interface allows the user to access sprite functions.

Return Values

If the function succeeds, the return value is S_OK. If the function fails, the return value can be one of the following: D3DERR_INVALIDCALL, E_OUTOFMEMORY.

Remarks

This interface can be used to draw two dimensional images in screen space of the associated device.


再来看看SDK文档提供的有关ID3DXSprite的使用说明:

The ID3DXSprite interface provides a set of methods that simplify the process of drawing sprites using Microsoft Direct3D.

ID3DXSprite Members

Method Description
ID3DXSprite::Begin Prepares a device for drawing sprites.
ID3DXSprite::Draw Adds a sprite to the list of batched sprites.
ID3DXSprite::End Calls ID3DXSprite::Flush and restores the device state to how it was before ID3DXSprite::Begin was called.
ID3DXSprite::Flush Forces all batched sprites to be submitted to the device. Device states remain as they were after the last call to ID3DXSprite::Begin. The list of batched sprites is then cleared.
ID3DXSprite::GetDevice Retrieves the device associated with the sprite object.
ID3DXSprite::GetTransform Gets the sprite transform.
ID3DXSprite::OnLostDevice Use this method to release all references to video memory resources and delete all stateblocks. This method should be called whenever a device is lost or before resetting a device.
ID3DXSprite::OnResetDevice Use this method to re-acquire resources and save initial state.
ID3DXSprite::SetTransform Sets the sprite transform.
ID3DXSprite::SetWorldViewLH Sets the left-handed world-view transform for a sprite. A call to this method is required before billboarding or sorting sprites.
ID3DXSprite::SetWorldViewRH Sets the right-handed world-view transform for a sprite. A call to this method is required before billboarding or sorting sprites.

Remarks

The ID3DXSprite interface is obtained by calling the D3DXCreateSprite function.

The application typically first calls ID3DXSprite::Begin, which allows control over the device render state, alpha blending, and sprite transformation and sorting. Then for each sprite to be displayed, call ID3DXSprite::Draw. ID3DXSprite::Draw can be called repeatedly to store any number of sprites. To display the batched sprites to the device, call ID3DXSprite::End or ID3DXSprite::Flush.

The LPD3DXSPRITE type is defined as a pointer to the ID3DXSprite interface.

typedef interface ID3DXSprite ID3DXSprite;
typedef interface ID3DXSprite *LPD3DXSPRITE;

Begin方法和End方法表明绘制精灵图象的开始和结束,这是一对配套函数,必须用在IDirect3DDevice9::BeginScene和IDirect3DDevice9::EndScene的调用之间。

接着来看看Begin方法的使用说明:

Prepares a device for drawing sprites.

HRESULT Begin(
DWORD Flags
);

Parameters

Flags
[in] Combination of zero or more flags that describe sprite rendering options. For this method, the valid flags are:
  • D3DXSPRITE_ALPHABLEND
  • D3DXSprite__BILLBOARD
  • D3DXSPRITE_DONOTMODIFY_RENDERSTATE
  • D3DXSPRITE_DONOTSAVESTATE
  • D3DXSPRITE_OBJECTSPACE
  • D3DXSprite__SORT_DEPTH_BACKTOFRONT
  • D3DXSprite__SORT_DEPTH_FRONTTOBACK
  • D3DXSprite__SORT_TEXTURE
For a description of the flags and for information on how to control device state capture and device view transforms, see D3DXSPRITE.

Return Values

If the method succeeds, the return value is S_OK. If the method fails, the return value can be one of the following: D3DERR_INVALIDCALL, D3DERR_OUTOFVIDEOMEMORY, D3DXERR_INVALIDDATA, E_OUTOFMEMORY.

Remarks

This method must be called from inside a IDirect3DDevice9::BeginScene . . . IDirect3DDevice9::EndScene sequence. ID3DXSprite::Begin cannot be used as a substitute for either IDirect3DDevice9::BeginScene or ID3DXRenderToSurface::BeginScene.

This method will set the following states on the device.

Render States:

Type (D3DRENDERSTATETYPE) Value
D3DRS_ALPHABLENDENABLE TRUE
D3DRS_ALPHAFUNC D3DCMP_GREATER
D3DRS_ALPHAREF 0x00
D3DRS_ALPHATESTENABLE AlphaCmpCaps
D3DRS_BLENDOP D3DBLENDOP_ADD
D3DRS_CLIPPING TRUE
D3DRS_CLIPPLANEENABLE FALSE
D3DRS_COLORWRITEENABLE D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED
D3DRS_CULLMODE D3DCULL_NONE
D3DRS_DESTBLEND D3DBLEND_INVSRCALPHA
D3DRS_DIFFUSEMATERIALSOURCE D3DMCS_COLOR1
D3DRS_ENABLEADAPTIVETESSELLATION FALSE
D3DRS_FILLMODE D3DFILL_SOLID
D3DRS_FOGENABLE FALSE
D3DRS_INDEXEDVERTEXBLENDENABLE FALSE
D3DRS_LIGHTING FALSE
D3DRS_RANGEFOGENABLE FALSE
D3DRS_SEPARATEALPHABLENDENABLE FALSE
D3DRS_SHADEMODE D3DSHADE_GOURAUD
D3DRS_SPECULARENABLE FALSE
D3DRS_SRCBLEND D3DBLEND_SRCALPHA
D3DRS_SRGBWRITEENABLE FALSE
D3DRS_STENCILENABLE FALSE
D3DRS_VERTEXBLEND FALSE
D3DRS_WRAP0 0

Texture Stage States:

Stage Identifier Type (D3DTEXTURESTAGESTATETYPE) Value
0 D3DTSS_ALPHAARG1 D3DTA_TEXTURE
0 D3DTSS_ALPHAARG2 D3DTA_DIFFUSE
0 D3DTSS_ALPHAOP D3DTOP_MODULATE
0 D3DTSS_COLORARG1 D3DTA_TEXTURE
0 D3DTSS_COLORARG2 D3DTA_DIFFUSE
0 D3DTSS_COLOROP D3DTOP_MODULATE
0 D3DTSS_TEXCOORDINDEX 0
0 D3DTSS_TEXTURETRANSFORMFLAGS D3DTTFF_DISABLE
1 D3DTSS_ALPHAOP D3DTOP_DISABLE
1 D3DTSS_COLOROP D3DTOP_DISABLE

Sampler States:

Sampler Stage Index Type (D3DSAMPLERSTATETYPE) Value
0 D3DSAMP_ADDRESSU D3DTADDRESS_CLAMP
0 D3DSAMP_ADDRESSV D3DTADDRESS_CLAMP
0 D3DSAMP_MAGFILTER D3DTEXF_ANISOTROPIC if TextureFilterCaps includes D3DPTFILTERCAPS_MAGFANISOTROPIC; otherwise D3DTEXF_LINEAR
0 D3DSAMP_MAXMIPLEVEL 0
0 D3DSAMP_MAXANISOTROPY MaxAnisotropy
0 D3DSAMP_MINFILTER D3DTEXF_ANISOTROPIC if TextureFilterCaps includes D3DPTFILTERCAPS_MINFANISOTROPIC; otherwise D3DTEXF_LINEAR
0 D3DSAMP_MIPFILTER D3DTEXF_LINEAR if TextureFilterCaps includes D3DPTFILTERCAPS_MIPFLINEAR; otherwise D3DTEXF_POINT
0 D3DSAMP_MIPMAPLODBIAS 0
0 D3DSAMP_SRGBTEXTURE 0

Note    This method disables N-patches.


参数Flags允许设置的D3DXSPRITE模式如下所示:

The following flags are used to specify sprite rendering options to the flags parameter in the ID3DXSprite::Begin method:

#define Description
D3DXSPRITE_DONOTSAVESTATE The device state is not to be saved or restored when ID3DXSprite::Begin or ID3DXSprite::End is called.
D3DXSPRITE_DONOTMODIFY_RENDERSTATE The device render state is not to be changed when ID3DXSprite::Begin is called. The device is assumed to be in a valid state to draw vertices containing UsageIndex = 0 in the D3DDECLUSAGE_POSITION, D3DDECLUSAGE_TEXCOORD, and D3DDECLUSAGE_COLOR data.
D3DXSPRITE_OBJECTSPACE The world, view, and projection transforms are not modified. The transforms currently set to the device are used to transform the sprites when the batched sprites are drawn (when ID3DXSprite::Flush or ID3DXSprite::End is called). If this flag is not specified, then world, view, and projection transforms are modified so that sprites are drawn in screen-space coordinates.
D3DXSPRITE_BILLBOARD Each sprite will be rotated about its center so that it is facing the viewer. ID3DXSprite::SetWorldViewLH or ID3DXSprite::SetWorldViewRH must be called first.
D3DXSPRITE_ALPHABLEND Enables alpha blending with D3DRS_ALPHATESTENABLE set to TRUE (for nonzero alpha). D3DBLEND_SRCALPHA will be the source blend state, and D3DBLEND_INVSRCALPHA will be the destination blend state in calls to IDirect3DDevice9::SetRenderState. See Alpha Blending State (Direct3D 9). ID3DXFont expects this flag to be set when drawing text.
D3DXSPRITE_SORT_TEXTURE Sort sprites by texture prior to drawing. This can improve performance when drawing non-overlapping sprites of uniform depth.

You may also combine D3DXSPRITE_SORT_TEXTURE with either D3DXSPRITE_SORT_DEPTH_FRONTTOBACK or D3DXSPRITE_SORT_DEPTH_BACKTOFRONT. This will sort the list of sprites by depth first and texture second.

D3DXSPRITE_SORT_DEPTH_FRONTTOBACK Sprites are sorted by depth in front-to-back order prior to drawing. This procedure is recommended when drawing opaque sprites of varying depths.

You may combine D3DXSPRITE_SORT_DEPTH_FRONTTOBACK with D3DXSPRITE_SORT_TEXTURE to sort first by depth, and second by texture.

D3DXSPRITE_SORT_DEPTH_BACKTOFRONT Sprites are sorted by depth in back-to-front order prior to drawing. This procedure is recommended when drawing transparent sprites of varying depths.

You may combine D3DXSPRITE_SORT_DEPTH_BACKTOFRONT with D3DXSPRITE_SORT_TEXTURE to sort first by depth, and second by texture.

D3DXSPRITE_DO_NOT_ADDREF_TEXTURE Disables calling AddRef() on every draw, and Release() on Flush() for better performance.

再来看看End方法的使用信息:

Calls ID3DXSprite::Flush and restores the device state to how it was before ID3DXSprite::Begin was called.

HRESULT End();

Parameters

None.

Return Values

If the method succeeds, the return value is S_OK. If the method fails, the following value will be returned.

D3DERR_INVALIDCALL

Remarks

ID3DXSprite::End cannot be used as a substitute for either IDirect3DDevice9::EndScene or ID3DXRenderToSurface::EndScene.


Draw方法用来在指定位置绘制精灵,来看看它的使用说明:

Adds a sprite to the list of batched sprites.

HRESULT Draw(
LPDIRECT3DTEXTURE9 pTexture,
CONST RECT * pSrcRect,
CONST D3DXVECTOR3 * pCenter,
CONST D3DXVECTOR3 * pPosition,
D3DCOLOR Color
);

Parameters

pTexture
[in] Pointer to an IDirect3DTexture9 interface that represents the sprite texture.
pSrcRect
[in] Pointer to a RECT structure that indicates the portion of the source texture to use for the sprite. If this parameter is NULL, then the entire source image is used for the sprite.
pCenter
[in] Pointer to a D3DXVECTOR3 vector that identifies the center of the sprite. If this argument is NULL, the point (0,0,0) is used, which is the upper-left corner.
pPosition
[in] Pointer to a D3DXVECTOR3 vector that identifies the position of the sprite. If this argument is NULL, the point (0,0,0) is used, which is the upper-left corner.
Color
[in] D3DCOLOR type. The color and alpha channels are modulated by this value. A value of 0xFFFFFFFF maintains the original source color and alpha data. Use the D3DCOLOR_RGBA macro to help generate this color.

Return Values

If the method succeeds, the return value is S_OK. If the method fails, the return value can be one of the following: D3DERR_INVALIDCALL, D3DXERR_INVALIDDATA.

Remarks

To scale, rotate, or translate a sprite, call ID3DXSprite::SetTransform with a matrix that contains the scale, rotate, and translate (SRT) values, before calling ID3DXSprite::Draw. For information about setting SRT values in a matrix, see Matrix Transforms.

 

好了,现在来看一个例子:

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


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

源码及素材下载

来看看shoot.h的定义:
 
/*************************************************************************************
 [Include File]

 PURPOSE: 
    Define for alpha blending test, use ID3DXSprit interface.
*************************************************************************************/


#ifndef SHOOT_H
#define SHOOT_H

class SHOOT
{
private:
    IDirect3D9* _d3d;
    IDirect3DDevice9* _d3d_device;
    IDirect3DTexture9* _texture_tiger;
    IDirect3DTexture9* _texture_gun;
    ID3DXSprite* _sprite_tiger;
    ID3DXSprite* _sprite_gun;

public:
    float m_gun_pos_x, m_gun_pos_y;

public:
    SHOOT();
    ~SHOOT();
    
    bool Create_D3D_Device(HWND hwnd, bool full_screen = true);
    bool Create_Sprite();
    bool Create_Sprite_Texture(IDirect3DTexture9** texture, const char* image_file);
    void Render();
    void Release_COM_Object();
};

#endif

再来看看shoot.cpp的定义:

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

 PURPOSE: 
    Define for alpha blending test, use ID3DXSprit interface.
*************************************************************************************/


#include "GE_COMMON.h"
#include "GE_INPUT.h"
#include "shoot.h"

//------------------------------------------------------------------------------------
// Constructor, initialize data.
//------------------------------------------------------------------------------------
SHOOT::SHOOT()
{
    _d3d            = NULL;
    _d3d_device     = NULL;
    _texture_tiger  = NULL;
    _texture_gun    = NULL;
    _sprite_tiger   = NULL;
    _sprite_gun     = NULL;

    m_gun_pos_x     = 500.0f;
    m_gun_pos_y     = 180.0f;
}

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

//------------------------------------------------------------------------------------
// Create direct3D interface and direct3D device.
//------------------------------------------------------------------------------------
bool SHOOT::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;
}

//------------------------------------------------------------------------------------
// Creates two sprite objects which is associated with a particular device. 
// Sprite objects are used to draw 2D images to the screen.
//------------------------------------------------------------------------------------
bool SHOOT::Create_Sprite()
{
    
// create sprite for image tiger
    if(FAILED(D3DXCreateSprite(_d3d_device, &_sprite_tiger)))
    {
        MessageBox(NULL, "Create sprite tiger failed!", "ERROR", MB_OK);
        
return false;
    }

    
// create sprite for image gun
    if(FAILED(D3DXCreateSprite(_d3d_device, &_sprite_gun)))
    {
        MessageBox(NULL, "Create sprite gun failed!", "ERROR", MB_OK);
        
return false;
    }

    
// create texture for tiger sprite
    if(! Create_Sprite_Texture(&_texture_tiger, "tiger.jpg"))
    {
        MessageBox(NULL, "Create texture interface for sprite tiger failed.", "ERROR", MB_OK);
        
return false;
    }

    
// create texture for gun sprite
    if(! Create_Sprite_Texture(&_texture_gun, "gun.dds"))
    {
        MessageBox(NULL, "Create texture interface for sprite gun failed.", "ERROR", MB_OK);
        
return false;
    }

    
return true;
}

//------------------------------------------------------------------------------------
// Creates a texture from image file.
//------------------------------------------------------------------------------------
bool SHOOT::Create_Sprite_Texture(IDirect3DTexture9** texture, const char* image_file)
{
    
if(FAILED(D3DXCreateTextureFromFile(_d3d_device, image_file, texture)))
        
return false;

    
return true;
}

//------------------------------------------------------------------------------------
// Draw alpha blend image.
//------------------------------------------------------------------------------------
void SHOOT::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);

    
// 1) draw tiger

    // begin scene
    _d3d_device->BeginScene();    

    
// Prepares a device for drawing sprites.
    _sprite_tiger->Begin(D3DXSPRITE_ALPHABLEND);
    
    
// Adds a sprite to the list of batched sprites.
    if(FAILED(_sprite_tiger->Draw(_texture_tiger, NULL, NULL, NULL, 0xFFFFFFFF)))
    {
        MessageBox(NULL, "Draw image tiger failed.", "ERROR", MB_OK);
        
return;
    }

    
// restores the device state to how it was before ID3DXSprite::Begin was called.
    _sprite_tiger->End();

    
// 2) draw gun

    // prepare for begin draw 
    _sprite_gun->Begin(D3DXSPRITE_ALPHABLEND);

    D3DXVECTOR3 pos(m_gun_pos_x, m_gun_pos_y, 0);

    
// draw gun now
    if(FAILED(_sprite_gun->Draw(_texture_gun, NULL, NULL, &pos, 0xFFFFFFFF)))
    {
        MessageBox(NULL, "Draw gun failed.", "ERROR", MB_OK);
        
return;
    }

    
// indicate end draw for sprite gun
    _sprite_gun->End();

    
// 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 SHOOT::Release_COM_Object()
{
    Safe_Release(_texture_tiger);
    Safe_Release(_texture_gun);
    Safe_Release(_sprite_tiger);
    Safe_Release(_sprite_gun);    
    Safe_Release(_d3d_device);
    Safe_Release(_d3d);
}

Create_Sprite方法用来创建背景图和瞄准镜的ID3DXSprite精灵接口对象和纹理接口对象, Create_Sprite_Texture方法根据图象文件创建精灵的纹理对象,这里使用DDS格式的文件创建出一个背景透明的瞄准器精灵对象。 Render方法调用ID3DXSprite接口的Begin,Draw,End方法绘制出背景图和背景透明的瞄准镜图象。

再来看看测试代码main.cpp:

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

 PURPOSE: 
    Test for sprite draw with alpha blending.
*************************************************************************************/


#define DIRECTINPUT_VERSION 0x0800

#include "GE_COMMON.h"
#include "GE_APP.h"
#include "GE_INPUT.h"
#include "shoot.h"

#pragma warning(disable : 4305 4996)

int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR cmd_line, int cmd_show)
{
    GE_APP ge_app;
    GE_INPUT ge_input;
    SHOOT shoot;

    MSG msg = {0};

    
// create window
    if(! ge_app.Create_Window("Sprite draw test with Alpha blending", 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 direct input
    ge_input.Create_Input(instance, hwnd);    
    
    
// Create direct3D interface and direct3D device.
    if(! shoot.Create_D3D_Device(hwnd, false))
        
return false;

    
// create all sprites
    if(! shoot.Create_Sprite())
        
return false;

    
// Draw all cones
    shoot.Render();

    
while(msg.message != WM_QUIT)
    {
        
if(PeekMessage(&msg, NULL, 0,0 , PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        
else
        {
            
// get keyboard input
            if(ge_input.Read_Keyboard())
            {
                
if(ge_input.Is_Key_Pressed(DIK_ESCAPE))
                    PostQuitMessage(0);

                
if(ge_input.Is_Key_Pressed(DIK_RIGHT))
                {
                    shoot.m_gun_pos_x += 5.5;
                    shoot.Render();
                }

                
if(ge_input.Is_Key_Pressed(DIK_LEFT))
                {
                    shoot.m_gun_pos_x -= 5.5;
                    shoot.Render();
                }

                
if(ge_input.Is_Key_Pressed(DIK_UP))
                {
                    shoot.m_gun_pos_y -= 5.5;
                    shoot.Render();
                }

                
if(ge_input.Is_Key_Pressed(DIK_DOWN))
                {
                    shoot.m_gun_pos_y += 5.5;
                    shoot.Render();
                }
            }
        }
    }    

    UnregisterClass(WINDOW_CLASS_NAME, instance);

    
return true;
}
 
posted @ 2007-09-20 21:35  至尊王者  阅读(2988)  评论(0编辑  收藏  举报