青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

天行健 君子當自強而不息

網格模型高級技術(16)

索引頂點混合

Direct3D通過索引頂點混合,擴展了使用多個混合矩陣對頂點進行混合的支持。在索引頂點混合中,混合矩陣被保存在矩陣調色板(可以看成一個矩陣數組)中,使用矩陣索引來引用特定的混合矩陣。矩陣索引使用8位無符號整數表示,由每個頂點提供,因為Direct3D中限定每個頂點最多受到4個混合矩陣的影響,所以每個頂點最多具有4個矩陣索引,每個頂點的矩陣索引被組合成一個DWORD類型的整數存儲和表示。因為每個頂點最多受4個混合矩陣的影響,所以在渲染一個三角形時最多可能需要使用12個混合矩陣,在這種情況下,矩陣調色板中最少需要包含12個混合矩陣。

下圖演示了一個頂點使用矩陣索引引用4個混合矩陣,圖中的頂點通過矩陣索引引用矩陣調色板中索引為0、2、5、6的混合矩陣:

下圖演示了渲染一個三角形時,如何通過矩陣索引引用矩陣調色板中的12個混合矩陣:

在渲染圖形時,要想啟用索引頂點混合,需要將渲染狀態D3DRS_INDEXEDVERTEXBLENDENABLE設置為TRUE,如果啟用了索引頂點混合,則在頂點數據中就需要包含矩陣索引數據。如果 將渲染狀態D3DRS_INDEXEDVERTEXBLENDENABLE設置為FALSE則禁用索引頂點混合,但是又啟用了圖形混合功能,這時在頂點數據中就不需要包含矩陣索引數據,每個頂點的矩陣索引默認為0~3。

D3DRS_INDEXEDVERTEXBLENDENABLE
bool value that enables or disables indexed vertex blending. The default value is FALSE. When set to TRUE, indexed vertex blending is enabled. When set to FALSE, indexed vertex blending is disabled. If this render state is enabled, the user must pass matrix indices as a packed DWORDwith every vertex. When the render state is disabled and vertex blending is enabled through the D3DRS_VERTEXBLEND state, it is equivalent to having matrix indices 0, 1, 2, 3 in every vertex.

D3DCAPS結構體的成員變量MaxVertexBlendMatrixIndex表示當前設備對索引頂點混合的支持,如果MaxVertexBlendMatrixIndex的值為0,表示當前硬件設備不支持索引頂點混合。如果MaxVertexBlendMatrixIndex的值不為0,表示混合矩陣的最大索引為MaxVertexBlendMatrixIndex,也就是當前硬件設備支持的矩陣調色 板最大容量為MaxVertexBlendMatrixIndex+1,表示矩陣調色板最大可以容納MaxVertexBlendMatrixIndex+1個混合矩陣。如果頂點中包含法線信息, 則也需要對法線數據進行混合,這時矩陣調色板中矩陣的最大數量為(MaxVertexBlendMatrixIndex+1)/ 2。如果使用軟件頂點處理模式,則矩陣調色板的最大容量為256,不管是否需要對法線向量進行混合。

MaxVertexBlendMatrixIndex
DWORD value that specifies the maximum matrix index that can be indexed into using the per-vertex indices. The number of matrices is MaxVertexBlendMatrixIndex + 1, which is the size of the matrix palette. If normals are present in the vertex data that needs to be blended for lighting, then the number of matrices is half the number specified by this capability flag. If MaxVertexBlendMatrixIndex is set to zero, the driver does not support indexed vertex blending. If this value is not zero then the valid range of indices is zero through MaxVertexBlendMatrixIndex.

A zero value for MaxVertexBlendMatrixIndex indicates that the driver does not support indexed matrices.

When software vertex processing is used, 256 matrices could be used for indexed vertex blending, with or without normal blending.

For a given physical device, this capability may vary across Direct3D devices depending on the parameters supplied to IDirect3D9::CreateDevice.

綜合上面圖形混合和索引頂點混合的內容,對頂點混合可以總結如下:

(1)不管是否使用索引頂點混合,混合矩陣都是通過索引從矩陣調色板中引用。

(2)如果不使用索引頂點混合,則混合矩陣索引最大為3,而且在頂點數據中不需要包含矩陣索引,矩陣索引默認為0~3。

(3)如果使用索引頂點混合,矩陣索引最大為255,而且在頂點數據中需要指定影響該頂點混合矩陣的索引。

(4)使用圖形混合之前,首先需要檢查當前設備支持的調色板容量是否滿足要求,因為使用軟件頂點處理模式時,最大混合矩陣索引為255,肯定能滿足要求,所以如果硬件頂點處理模式下矩陣調色板容量不能滿足要求,只需簡單轉換為使用軟件頂點處理模式即可。

 

蒙皮骨骼動畫跟單純的骨骼動畫相比,只是使用了頂點混合技術,解決單純的骨骼動畫存在的問題。

首先我們需要定義包含頂點混合權重和法線向量的結構體,還需要定義兩個混合矩陣:

struct sBlendVertex
{
D3DXVECTOR3 pos;
float blend;
D3DXVECTOR3 normal;
};
#define BLEND_VERTEX_FVF (D3DFVF_XYZB1 | D3DFVF_NORMAL)
CDXUTMesh*	g_dxut_mesh;
D3DXMATRIX g_blend_matrix_1;
D3DXMATRIX g_blend_matrix_2;

因為頂點所有骨骼權重之和是1,所以如果1個頂點受到n塊骨骼的影響,那么為頂點指定n-1個權重即可,最后一個權重可以通過1減去n-1個權重之和得到。這里每個頂點只受兩個骨骼矩陣的影響,所以在上面的頂點結構中只需提供一個頂點權重即可。

接著在回調函數ModifyDeviceSetttings()中用下列語句檢查硬件是否支持索引頂點混合,如果當前硬件不支持索引頂點混合,則使用軟件頂點處理模式:

if(pDeviceSettings->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING)
pDeviceSettings->BehaviorFlags = D3DCREATE_MIXED_VERTEXPROCESSING;
// if current device does not support vertex blending, use software device.
if(pCaps->MaxVertexBlendMatrices < 1)
pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

接下來在回調函數OnCreateDevice()中從.x文件中加載網格模型,因為該網格模型中并沒有包含骨骼權重信息,所以首先調用CDXUTMesh:SetFVF()設置網格模型的頂點靈活格式,然后為該網格模型的每個頂點添加權重:

g_dxut_mesh = new CDXUTMesh();
V_RETURN(g_dxut_mesh->Create(pd3dDevice, L"mslogo.x"));
// add vertex blending weight and normal information
g_dxut_mesh->SetFVF(pd3dDevice, BLEND_VERTEX_FVF);
DWORD num_vertices = g_dxut_mesh->GetMesh()->GetNumVertices();
IDirect3DVertexBuffer9* vertex_buffer;
g_dxut_mesh->GetMesh()->GetVertexBuffer(&vertex_buffer);
sBlendVertex* blend_vertices;
vertex_buffer->Lock(0, 0, (void**)&blend_vertices, 0);
// count min and max x coordinate of all vertices for calculating vertex blending weight
float min_x =  1e10f;
float max_x = -1e10f;
for(DWORD i = 0; i < num_vertices; i++)
{
if(blend_vertices[i].pos.x < min_x)
min_x = blend_vertices[i].pos.x;
	if(blend_vertices[i].pos.x > max_x)
max_x = blend_vertices[i].pos.x;
}
// calculate for all vertices blending weight
for(DWORD i = 0; i < num_vertices; i++)
{
float scale = (blend_vertices[i].pos.x - min_x) / (max_x - min_x);
blend_vertices[i].blend = 1.0f - sinf(scale * D3DX_PI);
}
vertex_buffer->Unlock();
vertex_buffer->Release();

接下來在回調函數中OnFrameMove()中實時構造并設置骨骼變換矩陣:

float scale = (float) fTime;
// calculate blend matrix
D3DXVECTOR3 axis(2 + sinf(scale * 3.1f), 2 + sinf(scale * 3.3f), sinf(scale * 3.5f));
D3DXMatrixIdentity(&g_blend_matrix_1);
D3DXMatrixRotationAxis(&g_blend_matrix_2, &axis, sinf(3 * scale));
// set vertex blend method and blend matrix
pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_1WEIGHTS);
pd3dDevice->SetTransform(D3DTS_WORLDMATRIX(0), &g_blend_matrix_1);
pd3dDevice->SetTransform(D3DTS_WORLDMATRIX(1), &g_blend_matrix_2);

上面代碼中的最后三行是相互對應的,缺一不可。首先將渲染狀態D3DRS_VERTEXBLEND設置為D3DVBF_1WEIGHTS,渲染狀態D3DRS_VERTEXBLEND用來指定進行頂點混合時所使用的矩陣的數目,這里將它設置為D3DVBF_1WEIGHTS,表示用宏D3DTS_WORLDMATRIX(index)設置兩個骨骼矩陣進行頂點混合,而且這兩個骨骼矩陣的索引號分別是0和1。

因為要進行頂點混合,所以函數SetTransform()將要設置的不再是普通的世界坐標變換矩陣,而是骨骼變換矩陣,所以它的第一個參數應該采用宏D3DTS_WORLDMATRIX(index)的格式,而不像以前一樣使用標識符D3DTS_WORLD。宏D3DTS_WORLDMATRIX(index)的定義如下:

#define D3DTS_WORLDMATRIX(index) (D3DTRANSFORMSTATETYPE)(index + 256)

該宏負責將索引號index映射到相應的變換狀態下。

在設置好各個骨骼矩陣之后,在回調函數OnFrameRender()中渲染網格模型:

g_dxut_mesh->Render(pd3dDevice);

 

運行截圖:

 

主程序:

#include "dxstdafx.h"
#include 
"resource.h"

#pragma warning(disable : 
4127 4995)

struct sBlendVertex
{
    D3DXVECTOR3 pos;
    
float        blend;
    D3DXVECTOR3 normal;
};

#define BLEND_VERTEX_FVF (D3DFVF_XYZB1 | D3DFVF_NORMAL)

#define IDC_TOGGLE_FULLSCREEN    1
#define IDC_TOGGLE_REF            2
#define IDC_CHANGE_DEVICE        3

#define release_com(p)    do { if(p) { (p)->Release(); (p) = NULL; } } while(0)

ID3DXFont
*                    g_font;
ID3DXSprite
*                g_text_sprite;
bool                        g_show_help;

CDXUTDialogResourceManager    g_dlg_resource_manager;
CD3DSettingsDlg                g_settings_dlg;
CDXUTDialog                    g_button_dlg;

CDXUTMesh
*                    g_dxut_mesh;
D3DXMATRIX                    g_blend_matrix_1;
D3DXMATRIX                    g_blend_matrix_2;

//--------------------------------------------------------------------------------------
// Rejects any devices that aren't acceptable by returning false
//--------------------------------------------------------------------------------------
bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, 
                                  D3DFORMAT BackBufferFormat, 
bool bWindowed, void* pUserContext )
{
    
// Typically want to skip backbuffer formats that don't support alpha blending

    IDirect3D9
* pD3D = DXUTGetD3DObject(); 

    
if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType, AdapterFormat, 
                    D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
        
return false;

    
return true;
}


//--------------------------------------------------------------------------------------
// Before a device is created, modify the device settings as needed.
//--------------------------------------------------------------------------------------
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext )
{
    
// If video card does not support hardware vertex processing, then uses sofaware vertex processing.
    if((pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0)
        pDeviceSettings
->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

    
static bool is_first_time = true;

    
if(is_first_time)
    {
        is_first_time 
= false;

        
// if using reference device, then pop a warning message box.
        if(pDeviceSettings->DeviceType == D3DDEVTYPE_REF)
            DXUTDisplaySwitchingToREFWarning();
    }

    
if(pDeviceSettings->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING)
        pDeviceSettings
->BehaviorFlags = D3DCREATE_MIXED_VERTEXPROCESSING;

    
// if current device does not support vertex blending, use software device.
    if(pCaps->MaxVertexBlendMatrices < 1)
        pDeviceSettings
->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

    
return true;
}

//--------------------------------------------------------------------------------------
// Remove path from fullname, and convert filename from multibyte to wchar.
//--------------------------------------------------------------------------------------
void RemovePathFromFileName(LPSTR fullname, LPWSTR wfilename)
{
    WCHAR wbuf[MAX_PATH]  
= {0};
    MultiByteToWideChar(CP_ACP, 
0, fullname, -1, wbuf, MAX_PATH);

    LPWSTR w_last_back_slash 
= wcsrchr(wbuf, '\\');

    
if(w_last_back_slash)
        lstrcpy(wfilename, 
++w_last_back_slash);
    
else
        lstrcpy(wfilename, wbuf);
}


//--------------------------------------------------------------------------------------
// Create any D3DPOOL_MANAGED resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, 
                                 
const D3DSURFACE_DESC* pBackBufferSurfaceDesc, 
                                 
void* pUserContext )
{
    HRESULT    hr;

    V_RETURN(g_dlg_resource_manager.OnCreateDevice(pd3dDevice));
    V_RETURN(g_settings_dlg.OnCreateDevice(pd3dDevice));

    D3DXCreateFont(pd3dDevice, 
180, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
                   DEFAULT_PITCH 
| FF_DONTCARE, L"Arial"&g_font);
    
    g_dxut_mesh 
= new CDXUTMesh();
    V_RETURN(g_dxut_mesh
->Create(pd3dDevice, L"mslogo.x"));

    
// add vertex blending weight and normal information
    g_dxut_mesh->SetFVF(pd3dDevice, BLEND_VERTEX_FVF);
    
    IDirect3DVertexBuffer9
* vertex_buffer;
    g_dxut_mesh
->GetMesh()->GetVertexBuffer(&vertex_buffer);

    sBlendVertex
* blend_vertices;
    vertex_buffer
->Lock(00, (void**)&blend_vertices, 0);

    
// count min and max x coordinate of all vertices for calculating vertex blending weight

    DWORD num_vertices 
= g_dxut_mesh->GetMesh()->GetNumVertices();

    
float min_x =  1e10f;
    
float max_x = -1e10f;    

    
for(DWORD i = 0; i < num_vertices; i++)
    {
        
if(blend_vertices[i].pos.x < min_x)
            min_x 
= blend_vertices[i].pos.x;

        
if(blend_vertices[i].pos.x > max_x)
            max_x 
= blend_vertices[i].pos.x;
    }

    
// calculate for all vertices blending weight
    for(DWORD i = 0; i < num_vertices; i++)
    {
        
float scale = (blend_vertices[i].pos.x - min_x) / (max_x - min_x);
        blend_vertices[i].blend 
= 1.0f - sinf(scale * D3DX_PI);
    }

    vertex_buffer
->Unlock();
    vertex_buffer
->Release();        

    
return S_OK;
}


//--------------------------------------------------------------------------------------
// Create any D3DPOOL_DEFAULT resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
                                
const D3DSURFACE_DESC* pBackBufferSurfaceDesc, 
                                
void* pUserContext )
{
    HRESULT hr;

    V_RETURN(g_dlg_resource_manager.OnResetDevice());
    V_RETURN(g_settings_dlg.OnResetDevice());
    V_RETURN(g_font
->OnResetDevice());
    V_RETURN(D3DXCreateSprite(pd3dDevice, 
&g_text_sprite));

    
// set dialog position and size

    g_button_dlg.SetLocation(pBackBufferSurfaceDesc
->Width - 1700);
    g_button_dlg.SetSize(
170170);    

    
// setup view matrix

    D3DXMATRIX mat_view;
    D3DXVECTOR3 eye(
0.0f0.0f,  -10.0f);
    D3DXVECTOR3  at(
0.0f0.0f,    0.0f);
    D3DXVECTOR3  up(
0.0f1.0f,    0.0f);

    D3DXMatrixLookAtLH(
&mat_view, &eye, &at, &up);
    pd3dDevice
->SetTransform(D3DTS_VIEW, &mat_view);

    
// set projection matrix
    D3DXMATRIX mat_proj;
    
float aspect = (float)pBackBufferSurfaceDesc->Width / pBackBufferSurfaceDesc->Height;
    D3DXMatrixPerspectiveFovLH(
&mat_proj, D3DX_PI/4, aspect, 1.0f100.0f);
    pd3dDevice
->SetTransform(D3DTS_PROJECTION, &mat_proj);    

    
// set material
    D3DMATERIAL9 material;
    ZeroMemory(
&material, sizeof(D3DMATERIAL9));

    material.Ambient.r 
= material.Diffuse.r = 1.0f;
    material.Ambient.g 
= material.Diffuse.g = 1.0f;
    material.Ambient.b 
= material.Diffuse.b = 1.0f;
    material.Ambient.a 
= material.Diffuse.a = 1.0f;

    pd3dDevice
->SetMaterial(&material);

    
// setup light
    
    D3DLIGHT9 light;
    ZeroMemory(
&light, sizeof(D3DLIGHT9));

    light.Type       
= D3DLIGHT_DIRECTIONAL;
    light.Diffuse.r  
= 1.5f;
    light.Diffuse.g  
= 0.8f;
    light.Diffuse.b  
= 1.0f;    

    D3DXVECTOR3 light_dir(
0.0f0.0f10.0f);    
    D3DXVec3Normalize((D3DXVECTOR3
*&light.Direction, &light_dir);
    pd3dDevice
->SetLight(0&light);
    pd3dDevice
->LightEnable(0, TRUE);
    pd3dDevice
->SetRenderState(D3DRS_LIGHTING, TRUE);

    pd3dDevice
->SetRenderState(D3DRS_AMBIENT, 0x00404040);

    
return S_OK;
}

//--------------------------------------------------------------------------------------
// Release resources created in the OnResetDevice callback here 
//--------------------------------------------------------------------------------------
void CALLBACK OnLostDevice( void* pUserContext )
{
    g_dlg_resource_manager.OnLostDevice();
    g_settings_dlg.OnLostDevice();
    g_font
->OnLostDevice();

    release_com(g_text_sprite);
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnCreateDevice callback here
//--------------------------------------------------------------------------------------
void CALLBACK OnDestroyDevice( void* pUserContext )
{
    g_dlg_resource_manager.OnDestroyDevice();
    g_settings_dlg.OnDestroyDevice();    

    release_com(g_font);
    SAFE_DELETE(g_dxut_mesh);
}

//--------------------------------------------------------------------------------------
// Handle updates to the scene
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{    
    
float scale = (float) fTime;

    
// calculate blend matrix
    D3DXVECTOR3 axis(2 + sinf(scale * 3.1f), 2 + sinf(scale * 3.3f), sinf(scale * 3.5f));
    D3DXMatrixIdentity(
&g_blend_matrix_1);
    D3DXMatrixRotationAxis(
&g_blend_matrix_2, &axis, sinf(3 * scale));

    
// set vertex blend method and blend matrix
    pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_1WEIGHTS);
    pd3dDevice
->SetTransform(D3DTS_WORLDMATRIX(0), &g_blend_matrix_1);
    pd3dDevice
->SetTransform(D3DTS_WORLDMATRIX(1), &g_blend_matrix_2);
}

//--------------------------------------------------------------------------------------
// Render the helper information
//--------------------------------------------------------------------------------------
void RenderText()
{
    CDXUTTextHelper text_helper(g_font, g_text_sprite, 
20);
    
    text_helper.Begin();

    
// show frame and device states
    text_helper.SetInsertionPos(55);
    text_helper.SetForegroundColor( D3DXCOLOR(
1.0f0.475f0.0f1.0f) );
    text_helper.DrawTextLine( DXUTGetFrameStats(
true) );
    text_helper.DrawTextLine( DXUTGetDeviceStats() );

    
// show helper information
    
    
const D3DSURFACE_DESC* surface_desc = DXUTGetBackBufferSurfaceDesc();

    
if(g_show_help)
    {
        text_helper.SetInsertionPos(
10, surface_desc->Height - 15 * 6);
        text_helper.SetForegroundColor( D3DXCOLOR(
1.0f0.475f0.0f1.0f) );
        text_helper.DrawTextLine(L
"Controls (F1 to hide):");
        
        text_helper.SetInsertionPos(
40, surface_desc->Height - 15 * 4);
        text_helper.DrawTextLine(L
"Quit: ESC");
    }
    
else
    {
        text_helper.SetInsertionPos(
10, surface_desc->Height - 15 * 4);
        text_helper.SetForegroundColor( D3DXCOLOR(
1.0f1.0f1.0f1.0f) );
        text_helper.DrawTextLine(L
"Press F1 for help");
    }

    text_helper.End();
}

//--------------------------------------------------------------------------------------
// Render the scene 
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    HRESULT hr;

    
if(g_settings_dlg.IsActive())
    {
        g_settings_dlg.OnRender(fElapsedTime);
        
return;
    }

    
// Clear the render target and the zbuffer 
    V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0000), 1.0f0) );

    
// Render the scene
    if( SUCCEEDED( pd3dDevice->BeginScene() ) )
    {                    
        g_dxut_mesh
->Render(pd3dDevice);
        RenderText();
        V(g_button_dlg.OnRender(fElapsedTime));

        V( pd3dDevice
->EndScene() );
    }
}


//--------------------------------------------------------------------------------------
// Handle messages to the application 
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                          
bool* pbNoFurtherProcessing, void* pUserContext )
{
    
*pbNoFurtherProcessing = g_dlg_resource_manager.MsgProc(hWnd, uMsg, wParam, lParam);
    
if(*pbNoFurtherProcessing)
        
return 0;

    
if(g_settings_dlg.IsActive())
    {
        g_settings_dlg.MsgProc(hWnd, uMsg, wParam, lParam);
        
return 0;
    }

    
*pbNoFurtherProcessing = g_button_dlg.MsgProc(hWnd, uMsg, wParam, lParam);
    
if(*pbNoFurtherProcessing)
        
return 0;

    
return 0;
}


//--------------------------------------------------------------------------------------
// Handle keybaord event
//--------------------------------------------------------------------------------------
void CALLBACK OnKeyboardProc(UINT charater, bool is_key_down, bool is_alt_down, void* user_context)
{
    
if(is_key_down)
    {
        
switch(charater)
        {
        
case VK_F1:
            g_show_help 
= !g_show_help;
            
break;
        }
    }
}

//--------------------------------------------------------------------------------------
// Handle events for controls
//--------------------------------------------------------------------------------------
void CALLBACK OnGUIEvent(UINT eventint control_id, CDXUTControl* control, void* user_context)
{
    
switch(control_id)
    {
    
case IDC_TOGGLE_FULLSCREEN:
        DXUTToggleFullScreen();
        
break;

    
case IDC_TOGGLE_REF:
        DXUTToggleREF();
        
break;

    
case IDC_CHANGE_DEVICE:
        g_settings_dlg.SetActive(
true);
        
break;
    }
}

//--------------------------------------------------------------------------------------
// Initialize dialogs
//--------------------------------------------------------------------------------------
void InitDialogs()
{
    g_settings_dlg.Init(
&g_dlg_resource_manager);
    g_button_dlg.Init(
&g_dlg_resource_manager);

    g_button_dlg.SetCallback(OnGUIEvent);

    
int x = 35, y = 10, width = 125, height = 22;

    g_button_dlg.AddButton(IDC_TOGGLE_FULLSCREEN, L
"Toggle full screen", x, y,         width, height);
    g_button_dlg.AddButton(IDC_TOGGLE_REF,          L
"Toggle REF (F3)",     x, y += 24, width, height);
    g_button_dlg.AddButton(IDC_CHANGE_DEVICE,      L
"Change device (F2)", x, y += 24, width, height, VK_F2);    
}

//--------------------------------------------------------------------------------------
// Initialize everything and go into a render loop
//--------------------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
    
// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF 
| _CRTDBG_LEAK_CHECK_DF );
#endif

    
// Set the callback functions
    DXUTSetCallbackDeviceCreated( OnCreateDevice );
    DXUTSetCallbackDeviceReset( OnResetDevice );
    DXUTSetCallbackDeviceLost( OnLostDevice );
    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackFrameRender( OnFrameRender );
    DXUTSetCallbackFrameMove( OnFrameMove );
    DXUTSetCallbackKeyboard(OnKeyboardProc);
   
    
// TODO: Perform any application-level initialization here
    InitDialogs();

    
// Initialize DXUT and create the desired Win32 window and Direct3D device for the application
    DXUTInit( truetruetrue ); // Parse the command line, handle the default hotkeys, and show msgboxes
    DXUTSetCursorSettings( truetrue ); // Show the cursor and clip it when in full screen
    DXUTCreateWindow( L"Vertex Blend" );
    DXUTCreateDevice( D3DADAPTER_DEFAULT, 
true640480, IsDeviceAcceptable, ModifyDeviceSettings );

    
// Start the render loop
    DXUTMainLoop();

    
// TODO: Perform any application-level cleanup here

    
return DXUTGetExitCode();
}

 

下載示例工程


posted on 2008-06-12 10:17 lovedday 閱讀(2804) 評論(0)  編輯 收藏 引用

公告

導航

統計

常用鏈接

隨筆分類(178)

3D游戲編程相關鏈接

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            午夜一区二区三视频在线观看| 精品动漫3d一区二区三区免费| 欧美精品激情在线观看| 国产精品美女久久久久aⅴ国产馆| 国产一区二区三区观看| 亚洲一区二区三区四区五区午夜| 欧美高清视频在线| 欧美一区二区视频在线| 国产精品www.| 日韩午夜在线视频| 欧美国产在线视频| 久久九九全国免费精品观看| 国产精品一区二区三区成人| 亚洲桃色在线一区| 日韩图片一区| 欧美区二区三区| 亚洲日韩欧美一区二区在线| 久久综合久色欧美综合狠狠| 午夜在线a亚洲v天堂网2018| 国产精品久久网| 亚洲午夜激情网站| 一本色道久久综合亚洲精品婷婷| 老牛影视一区二区三区| 欧美久久视频| av成人免费在线观看| 欧美激情亚洲视频| 欧美1区视频| 亚洲精品国产品国语在线app| 麻豆国产精品一区二区三区 | 国内精品久久久久久久影视麻豆| 亚洲一区自拍| 一区二区三区日韩精品| 欧美视频免费看| 亚洲天堂成人在线视频| 一区二区三区视频在线播放| 国产精品国产三级国产普通话蜜臀| 中文欧美日韩| 亚洲免费在线观看| 狠狠网亚洲精品| 欧美福利网址| 欧美日韩亚洲一区二区三区在线观看 | 老司机一区二区三区| 蜜桃av一区二区| 夜夜嗨av一区二区三区四季av| 日韩视频精品在线| 国产精品入口66mio| 久久久久久久高潮| 久久精品国产99精品国产亚洲性色| 在线看不卡av| 99精品国产在热久久| 国产嫩草一区二区三区在线观看| 久久先锋影音| 欧美日韩国产不卡| 久久久久久久国产| 欧美久久久久久蜜桃| 欧美中日韩免费视频| 噜噜爱69成人精品| 亚洲欧美日韩精品久久亚洲区 | 在线观看日韩精品| 亚洲精品社区| 国产日韩欧美夫妻视频在线观看| 欧美高清视频免费观看| 国产精品高精视频免费| 久久婷婷影院| 欧美日韩卡一卡二| 久久综合五月| 国产精品v欧美精品v日韩精品| 久久久久久久一区二区| 免费黄网站欧美| 欧美影院午夜播放| 欧美激情网友自拍| 久久精品夜色噜噜亚洲aⅴ| 欧美激情视频一区二区三区在线播放| 欧美一区二视频| 欧美伦理a级免费电影| 久久久久久久久一区二区| 欧美啪啪成人vr| 久久综合九色| 国产麻豆成人精品| 一区二区国产精品| 亚洲激情电影在线| 亚洲综合三区| 中国亚洲黄色| 欧美精品日韩一区| 亚洲电影天堂av| 国产精品免费aⅴ片在线观看| 亚洲成色777777女色窝| 欧美日韩一区二区精品| 欧美一区二区三区久久精品| 欧美激情一区二区三区成人| 久久午夜激情| 国产在线国偷精品产拍免费yy| 亚洲精品久久在线| 91久久精品国产91性色| 久久国产毛片| 欧美一区二区三区免费视频| 欧美婷婷在线| 欧美一区二区国产| 国产精品久久777777毛茸茸| 亚洲人午夜精品| 激情婷婷欧美| 久久久久久久久久久成人| 久久国产黑丝| 国产一区二区在线观看免费播放| 亚洲欧美日韩国产| 久久久亚洲一区| 伊人久久噜噜噜躁狠狠躁| 久久久久国产精品一区二区| 在线观看欧美日韩| 久久爱www| 久久久久在线| ●精品国产综合乱码久久久久| 久久久综合免费视频| 久久久久久亚洲精品中文字幕 | 亚洲丰满少妇videoshd| 免费成人av资源网| 亚洲国产日韩一区| 一区二区三区四区国产| 国产精品va| 午夜精品久久久久久久久久久久久 | 久久国产福利国产秒拍| 老牛嫩草一区二区三区日本 | 亚洲欧洲综合另类在线| 在线视频你懂得一区二区三区| 欧美日韩亚洲激情| 欧美一区二区三区在线视频| 美女脱光内衣内裤视频久久网站| 亚洲国产mv| 欧美三级小说| 欧美一区午夜精品| 亚洲国产精品精华液网站| 一本色道久久加勒比88综合| 国产精品激情av在线播放| 欧美一级午夜免费电影| 亚洲激情六月丁香| 性8sex亚洲区入口| 亚洲国产高清视频| 欧美体内谢she精2性欧美| 午夜精品999| 亚洲福利视频一区二区| 亚洲欧美日韩国产综合| 亚洲国产老妈| 国产精品一区二区你懂得| 牛牛影视久久网| 亚洲欧美国产一区二区三区| 欧美激情一区二区三区成人| 午夜精品在线| 亚洲精品一区二区三区蜜桃久| 国产精品人人做人人爽| 欧美fxxxxxx另类| 欧美日本韩国一区二区三区| 午夜伦欧美伦电影理论片| 国产一区二区三区精品久久久| 欧美成人精品福利| 午夜影视日本亚洲欧洲精品| 亚洲黄色片网站| 久久久噜噜噜久久中文字幕色伊伊 | 国产一区日韩欧美| 欧美日韩国产一级| 久久久久久久尹人综合网亚洲| 亚洲另类在线一区| 欧美激情视频给我| 久久久欧美一区二区| 午夜一区二区三区在线观看| 亚洲午夜久久久久久久久电影院| 亚洲国产日韩欧美| 18成人免费观看视频| 国产午夜亚洲精品不卡| 欧美性大战xxxxx久久久| 欧美国产欧美综合 | 日韩一区二区久久| 亚洲国产小视频| 伊人精品视频| 伊人久久亚洲美女图片| 国产在线日韩| 国内精品一区二区三区| 国产一区二区三区久久久| 国产日产欧美a一级在线| 国产精品日日摸夜夜添夜夜av| 欧美色欧美亚洲另类七区| 欧美色中文字幕| 欧美午夜无遮挡| 欧美日韩日日骚| 欧美日韩国产影片| 欧美日韩视频在线| 欧美伦理影院| 欧美日韩亚洲国产一区| 欧美日韩精品一二三区| 欧美伦理在线观看| aⅴ色国产欧美| 欧美黄色成人网| 亚洲成色777777在线观看影院| 久久成人免费| 久久综合图片| 老司机免费视频一区二区三区| 久久精品国产免费看久久精品| 1000部国产精品成人观看| 国产综合香蕉五月婷在线| 国产免费亚洲高清| 国产精品素人视频|