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

天行健 君子當自強而不息

坐標系與基本圖元(5)

使用索引緩沖區繪制圖形

當繪制一個比較復雜的圖形時,需要使用許多相互鄰接的三角形。如果為每個三角形準備三個頂點數據,顯然有許多數據是重復的,這樣會浪費大量的內存和系統帶寬。為了解決這一問題,可以先創建一個頂點緩沖區,將不重復的頂點數據寫入頂點緩沖區,然后創建一個頂點索引緩沖區(index buffer),存放各個三角形的頂點索引信息,最后通過頂點索引和頂點數據共同完成圖形繪制。

在Direct3D中一個頂點的索引只需要用一個16位或32位的整數表示,因此當多邊形的頂點有較多重復使用時,使用索引數組通常能夠比直接繪制頂點序列節省一部分內存空間和系統帶寬。同時,Direct3D渲染流水線避免了對相同頂點進行重復計算,從而可以相應地提高圖形程序的整體性能。

首先定義頂點結構和靈活頂點格式:

struct sCustomVertex
{
float x, y, z, rhw;
DWORD color;
};
#define D3DFVF_CUSTOM_VERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE) 

接著創建頂點緩沖區和索引緩沖區,各頂點位置如下圖所示:

void init_vertices()
{
sCustomVertex vertices[9];
	vertices[0].x	  = 300.0f;
vertices[0].y = 250.0f;
vertices[0].z = 0.5f;
vertices[0].rhw = 1.0f;
vertices[0].color = 0xffff0000;
	for(int i = 0; i < 8; i++)
{
vertices[i+1].x = (200 * sin(i * 3.14159f / 4.0f)) + 300;
vertices[i+1].y = -(200 * cos(i * 3.14159f / 4.0f)) + 250;
vertices[i+1].z = 0.5f;
vertices[i+1].rhw = 1.0f;
vertices[i+1].color = 0xff00ff00;
}
	WORD indices[] = { 0,1,2, 0,2,3, 0,3,4, 0,4,5, 0,5,6, 0,6,7, 0,7,8, 0,8,1 };
	// push vertex data into vertex buffer
	g_device->CreateVertexBuffer(sizeof(vertices), 0, D3DFVF_CUSTOM_VERTEX, D3DPOOL_DEFAULT, &g_vertex_buffer, NULL);
	void* ptr;
	g_vertex_buffer->Lock(0, sizeof(vertices), (void**)&ptr, 0);
memcpy(ptr, vertices, sizeof(vertices));
g_vertex_buffer->Unlock();
	// push vertex index into index buffer
	g_device->CreateIndexBuffer(sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &g_index_buffer, NULL);
	void* index_ptr;
	g_index_buffer->Lock(0, sizeof(indices), (void**)&index_ptr, 0);
memcpy(index_ptr, indices, sizeof(indices));
g_index_buffer->Unlock();
}

在上面的代碼段中,使用IDirect3DDevice9::CreateIndexBuffer()函數創建所需要的索引緩沖區,該函數的聲明如下:

Creates an index buffer.

HRESULT CreateIndexBuffer(
UINT Length,
DWORD Usage,
D3DFORMAT Format,
D3DPOOL Pool,
IDirect3DIndexBuffer9** ppIndexBuffer,
HANDLE* pSharedHandle
);

Parameters

Length
[in] Size of the index buffer, in bytes.
Usage
[in] Usage can be 0, which indicates no usage value. However, if usage is desired, use a combination of one or more D3DUSAGE constants. It is good practice to match the usage parameter in CreateIndexBuffer with the behavior flags in IDirect3D9::CreateDevice. For more information, see Remarks.
Format
[in] Member of the D3DFORMAT enumerated type, describing the format of the index buffer. For more information, see Remarks. The valid settings are the following:
D3DFMT_INDEX16
Indices are 16 bits each.
D3DFMT_INDEX32
Indices are 32 bits each.
Pool
[in] Member of the D3DPOOL enumerated type, describing a valid memory class into which to place the resource.
ppIndexBuffer
[out, retval] Address of a pointer to an IDirect3DIndexBuffer9 interface, representing the created index buffer resource.
pSharedHandle
[in] Reserved. Set this parameter to NULL.

Return Values

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

Remarks

Index buffers are memory resources used to hold indices, they are similar to both surfaces and vertex buffers. The use of index buffers enables Direct3D to avoid unnecessary data copying and to place the buffer in the optimal memory type for the expected usage.

To use index buffers, create an index buffer, lock it, fill it with indices, unlock it, pass it to IDirect3DDevice9::SetIndices, set up the vertices, set up the vertex shader, and call IDirect3DDevice9::DrawIndexedPrimitive for rendering.

The MaxVertexIndex member of the D3DCAPS9 structure indicates the types of index buffers that are valid for rendering.

接著使用索引緩沖區繪制圖形:

void render()
{
g_device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_X#050505, 1.0f, 0);
	g_device->BeginScene();
	g_device->SetRenderState(D3DRS_FILLMODE, g_fill_mode);
g_device->SetStreamSource(0, g_vertex_buffer, 0, sizeof(sCustomVertex));
g_device->SetFVF(D3DFVF_CUSTOM_VERTEX);
g_device->SetIndices(g_index_buffer);
g_device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 9, 0, 8);
	g_device->EndScene();
	g_device->Present(NULL, NULL, NULL, NULL);
}

函數IDirect3DDevice9::DrawIndexedPrimitive()使用當前設置的索引緩沖區繪制圖形:

Based on indexing, renders the specified geometric primitive into an array of vertices.

HRESULT DrawIndexedPrimitive(
D3DPRIMITIVETYPE Type,
INT BaseVertexIndex,
UINT MinIndex,
UINT NumVertices,
UINT StartIndex,
UINT PrimitiveCount
);

Parameters

Type
[in] Member of the D3DPRIMITIVETYPE enumerated type, describing the type of primitive to render. D3DPT_POINTLIST is not supported with this method. See Remarks.
BaseVertexIndex
[in] Offset from the start of the vertex buffer to the first vertex. See Scenario 4.
MinIndex
[in] Minimum vertex index for vertices used during this call. This is a zero based index relative to BaseVertexIndex.
NumVertices
[in] Number of vertices used during this call. The first vertex is located at index: BaseVertexIndex + MinIndex.
StartIndex
[in] Index of the first index to use when accesssing the vertex buffer. Beginning at StartIndex to index vertices from the vertex buffer.
PrimitiveCount
[in] Number of primitives to render. The number of vertices used is a function of the primitive count and the primitive type. The maximum number of primitives allowed is determined by checking the MaxPrimitiveCount member of the D3DCAPS9 structure.

Return Values

If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be the following: D3DERR_INVALIDCALL.

Remarks

This method draws indexed primitives from the current set of data input streams. MinIndex and all the indices in the index stream are relative to the BaseVertexIndex.

The MinIndex and NumVertices parameters specify the range of vertex indices used for each IDirect3DDevice9::DrawIndexedPrimitive call. These are used to optimize vertex processing of indexed primitives by processing a sequential range of vertices prior to indexing into these vertices. It is invalid for any indices used during this call to reference any vertices outside of this range.

IDirect3DDevice9::DrawIndexedPrimitive fails if no index array is set.

The D3DPT_POINTLIST member of the D3DPRIMITIVETYPE enumerated type is not supported and is not a valid type for this method.

When converting a legacy application to Direct3D 9, you must add a call to either IDirect3DDevice9::SetFVF to use the fixed function pipeline, or IDirect3DDevice9::SetVertexDeclaration to use a vertex shader before you make any Draw calls.

 

完整源碼如下:

#include <d3d9.h>
#include 
<math.h>

#define CLASS_NAME    "GameApp"

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

IDirect3D9
*                g_d3d;
IDirect3DDevice9
*        g_device;
IDirect3DVertexBuffer9
* g_vertex_buffer;
IDirect3DIndexBuffer9
*    g_index_buffer;

DWORD                    g_fill_mode 
= D3DFILL_SOLID;

struct sCustomVertex
{
    
float x, y, z, rhw;
    DWORD color;
};

#define D3DFVF_CUSTOM_VERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE) 

void init_vertices()
{
    sCustomVertex vertices[
9];
    
    vertices[
0].x      = 300.0f;
    vertices[
0].y      = 250.0f;
    vertices[
0].z      = 0.5f;
    vertices[
0].rhw      = 1.0f;
    vertices[
0].color = 0xffff0000;

    
for(int i = 0; i < 8; i++)
    {
        vertices[i
+1].x        =  (200 * sin(i * 3.14159f / 4.0f)) + 300;
        vertices[i
+1].y        = -(200 * cos(i * 3.14159f / 4.0f)) + 250;
        vertices[i
+1].z        = 0.5f;
        vertices[i
+1].rhw    = 1.0f;
        vertices[i
+1].color = 0xff00ff00;
    }

    WORD indices[] 
= { 0,1,20,2,30,3,40,4,50,5,60,6,70,7,80,8,1 };

    
// push vertex data into vertex buffer

    g_device
->CreateVertexBuffer(sizeof(vertices), 0, D3DFVF_CUSTOM_VERTEX, D3DPOOL_DEFAULT, &g_vertex_buffer, NULL);

    
void* ptr;

    g_vertex_buffer
->Lock(0sizeof(vertices), (void**)&ptr, 0);
    memcpy(ptr, vertices, 
sizeof(vertices));
    g_vertex_buffer
->Unlock();

    
// push vertex index into index buffer

    g_device
->CreateIndexBuffer(sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &g_index_buffer, NULL);

    
void* index_ptr;
    
    g_index_buffer
->Lock(0sizeof(indices), (void**)&index_ptr, 0);
    memcpy(index_ptr, indices, 
sizeof(indices));
    g_index_buffer
->Unlock();
}

bool init_d3d(HWND hwnd)
{
    g_d3d 
= Direct3DCreate9(D3D_SDK_VERSION);

    
if(g_d3d == NULL)
        
return false;

    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(
&d3dpp, sizeof(d3dpp));

    d3dpp.Windowed            
= TRUE;
    d3dpp.SwapEffect        
= D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat    
= D3DFMT_UNKNOWN;

    
if(FAILED(g_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                  
&d3dpp, &g_device)))
    {
        
return false;
    }

    init_vertices();
    
    g_device
->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

    
return true;
}

void cleanup()
{
    release_com(g_index_buffer);
    release_com(g_vertex_buffer);
    release_com(g_device);
    release_com(g_d3d);
}

void render()
{
    g_device
->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(555), 1.0f0);

    g_device
->BeginScene();

    g_device
->SetRenderState(D3DRS_FILLMODE, g_fill_mode);
    g_device
->SetStreamSource(0, g_vertex_buffer, 0sizeof(sCustomVertex));
    g_device
->SetFVF(D3DFVF_CUSTOM_VERTEX);
    g_device
->SetIndices(g_index_buffer);
    g_device
->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 00908);       

    g_device
->EndScene();

    g_device
->Present(NULL, NULL, NULL, NULL);
}

LRESULT WINAPI WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    
switch(msg)
    {
    
case WM_KEYDOWN:
        
switch(wParam)
        {    
        
case VK_SPACE:
            g_fill_mode 
= (g_fill_mode == D3DFILL_WIREFRAME) ? D3DFILL_SOLID : D3DFILL_WIREFRAME;
            
break;
        
case VK_ESCAPE:
            DestroyWindow(hwnd);
            
break;
        }    
        
break;

    
case WM_DESTROY:        
        PostQuitMessage(
0);
        
return 0;
    }

    
return DefWindowProc(hwnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE inst, HINSTANCE, LPSTR, INT)
{
    WNDCLASSEX wc;

    wc.cbSize            
= sizeof(WNDCLASSEX);
    wc.style            
= CS_CLASSDC;
    wc.lpfnWndProc        
= WinProc;
    wc.cbClsExtra        
= 0;
    wc.cbWndExtra        
= 0;
    wc.hInstance        
= inst;
    wc.hIcon            
= NULL;
    wc.hCursor            
= NULL;
    wc.hbrBackground    
= NULL;
    wc.lpszMenuName        
= NULL;
    wc.lpszClassName    
= CLASS_NAME;
    wc.hIconSm            
= NULL;

    
if(! RegisterClassEx(&wc))
        
return -1;

    HWND hwnd 
= CreateWindow(CLASS_NAME, "Direct3D App", WS_OVERLAPPEDWINDOW, 200100600500,
                             NULL, NULL, wc.hInstance, NULL);

    
if(hwnd == NULL)
        
return -1;

    
if(init_d3d(hwnd))
    {
        ShowWindow(hwnd, SW_SHOWDEFAULT);
        UpdateWindow(hwnd);

        MSG msg;
        ZeroMemory(
&msg, sizeof(msg));

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

    cleanup();

    UnregisterClass(CLASS_NAME, wc.hInstance);    

    
return 0;
}


運行截圖:

實體模式

線框模式

也可以只使用頂點緩沖區通過三角扇形圖元來繪制,改動init_vertices()和render()即可,需要增加一個頂點使多邊形封閉(即,使v9==v1)。

void init_vertices()
{
sCustomVertex vertices[10];
	vertices[0].x	  = 300.0f;
vertices[0].y = 250.0f;
vertices[0].z = 0.5f;
vertices[0].rhw = 1.0f;
vertices[0].color = 0xffff0000;
	for(int i = 0; i < 9; i++)
{
vertices[i+1].x = (200 * sin(i * 3.14159f / 4.0f)) + 300;
vertices[i+1].y = -(200 * cos(i * 3.14159f / 4.0f)) + 250;
vertices[i+1].z = 0.5f;
vertices[i+1].rhw = 1.0f;
vertices[i+1].color = 0xff00ff00;
}
	// push vertex data into vertex buffer
	g_device->CreateVertexBuffer(sizeof(vertices), 0, D3DFVF_CUSTOM_VERTEX, D3DPOOL_DEFAULT, &g_vertex_buffer, NULL);
	void* ptr;
	g_vertex_buffer->Lock(0, sizeof(vertices), (void**)&ptr, 0);
memcpy(ptr, vertices, sizeof(vertices));
g_vertex_buffer->Unlock();
}
void render()
{
g_device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_X#050505, 1.0f, 0);
	g_device->BeginScene();
	g_device->SetRenderState(D3DRS_FILLMODE, g_fill_mode);
g_device->SetStreamSource(0, g_vertex_buffer, 0, sizeof(sCustomVertex));
g_device->SetFVF(D3DFVF_CUSTOM_VERTEX);
	g_device->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 8);	
	g_device->EndScene();
	g_device->Present(NULL, NULL, NULL, NULL);
}

posted on 2008-04-30 17:39 lovedday 閱讀(1624) 評論(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>
            久久精品在这里| 久久成人精品视频| 亚洲午夜国产一区99re久久| 好看的av在线不卡观看| 欧美日韩国产首页| 欧美黄色成人网| 欧美日韩中文字幕日韩欧美| 麻豆免费精品视频| 欧美岛国激情| 欧美日韩激情小视频| 欧美日韩亚洲另类| 国产精品一区二区在线观看不卡| 欧美日韩精品二区第二页| 欧美日韩国产小视频| 欧美日韩在线视频一区二区| 欧美精品久久久久久久免费观看| 欧美黑人一区二区三区| 国产精品男女猛烈高潮激情 | 亚洲国产视频一区二区| 国产日韩欧美三级| 一色屋精品视频在线观看网站| 在线播放豆国产99亚洲| 亚洲男人av电影| 欧美专区在线观看| 欧美电影在线| 亚洲系列中文字幕| 久久一二三四| 国产精品v亚洲精品v日韩精品| 国产一区再线| 一本久久a久久精品亚洲| 久久精品一本| 中文日韩欧美| 欧美日韩国产一区二区| 国内外成人在线视频| 亚洲一区二区四区| 日韩天堂av| 欧美日韩一区二区三区免费看| 精品1区2区3区4区| 蜜桃久久精品一区二区| 欧美一区二区在线播放| 国产亚洲欧美色| 午夜精品久久久久久久白皮肤| 亚洲精品一二| 欧美日韩亚洲视频| 亚洲一区二区伦理| 日韩一区二区电影网| 欧美日韩视频专区在线播放 | 欧美淫片网站| 国产一级揄自揄精品视频| 亚洲专区在线| 午夜欧美视频| 亚洲一二三区视频在线观看| 亚洲狼人精品一区二区三区| 亚洲毛片在线看| 亚洲一区二区视频在线| 久久久久久黄| 亚洲图片欧美一区| 亚洲午夜三级在线| 亚洲国产成人精品视频| 久久精品成人| 91久久嫩草影院一区二区| 欧美一级片在线播放| 欧美色大人视频| 亚洲精品欧美激情| 亚洲一区二区三区精品动漫| 裸体歌舞表演一区二区| 亚洲视频精品| 午夜精品久久久久久久99樱桃 | 亚洲欧美日韩国产另类专区| 在线视频日本亚洲性| 亚洲日本精品国产第一区| 亚洲与欧洲av电影| 日韩午夜av在线| 日韩视频久久| 欧美激情一区二区三区在线视频观看 | 99视频在线精品国自产拍免费观看 | 亚洲肉体裸体xxxx137| 午夜视频久久久| 欧美激情视频一区二区三区免费| 欧美一二三区在线观看| 欧美区高清在线| 99精品欧美一区二区三区综合在线| 亚洲欧洲美洲综合色网| 欧美xart系列高清| 最新高清无码专区| 一个人看的www久久| 欧美日韩精品系列| 亚洲在线播放电影| 欧美亚洲综合网| 激情av一区| 欧美区日韩区| 欧美在线视频播放| 欧美激情一区二区三区不卡| 国产精品99久久久久久有的能看| 欧美精品久久久久久| 亚洲欧美区自拍先锋| 麻豆免费精品视频| 亚洲图片在线观看| 国产主播精品在线| 欧美精品免费视频| 久久国产精品久久久久久| 亚洲国产精品t66y| 欧美在线网址| 亚洲香蕉在线观看| 一区二区在线免费观看| 国产精品jvid在线观看蜜臀| 奶水喷射视频一区| 久久精品欧美| 亚洲一区二区三区高清| 欧美激情一区在线| 久久久久久一区二区| 亚洲主播在线播放| 亚洲欧美日韩一区在线观看| av不卡在线观看| 亚洲精品社区| 欧美一级理论片| 亚洲精品中文字幕在线| 欧美成人午夜免费视在线看片| 久久福利毛片| 久久精品在线免费观看| 欧美专区中文字幕| 久久成人精品一区二区三区| 午夜激情综合网| 欧美综合国产| 久久综合99re88久久爱| 免费在线观看成人av| 牛人盗摄一区二区三区视频| 久久亚洲精品中文字幕冲田杏梨| 久久av最新网址| 毛片av中文字幕一区二区| 欧美激情视频一区二区三区在线播放 | 亚洲电影免费观看高清完整版| 免费视频一区| 一区二区三区四区精品| 亚洲欧美日韩在线不卡| 久久综合五月天婷婷伊人| 欧美日韩国产精品一卡| 国产亚洲欧美一区| 99精品欧美一区二区三区综合在线| 午夜精品久久久久久久白皮肤| 欧美成人资源网| 亚洲一二三区在线| 欧美大片18| 91久久久亚洲精品| 老牛嫩草一区二区三区日本| 艳妇臀荡乳欲伦亚洲一区| 美国十次成人| 亚洲福利视频三区| 久久久99久久精品女同性| 99精品视频免费观看| 欧美美女bbbb| 欧美影院视频| 国产精品婷婷午夜在线观看| 91久久精品一区二区三区| 久久不射中文字幕| 亚洲网站啪啪| 国产精品在线看| 欧美一级视频| 欧美在线综合| 影音欧美亚洲| 欧美福利在线| 欧美高清在线视频| 99riav久久精品riav| 亚洲精品乱码视频| 欧美午夜欧美| 久久综合伊人77777蜜臀| 欧美另类专区| 国产精品视频99| 亚洲高清网站| 亚洲欧洲一区二区在线观看| 亚洲欧洲av一区二区三区久久| 亚洲另类黄色| 亚洲夜晚福利在线观看| 国产精品视频一区二区三区| 国产精品一区二区三区四区| 欧美亚韩一区| 国产免费一区二区三区香蕉精| 国产精品久久久久久亚洲毛片| 国产精品国产三级国产a| 国产亚洲免费的视频看| 亚洲高清一区二区三区| 久久婷婷国产综合国色天香| 亚洲国产毛片完整版| 亚洲综合丁香| 亚洲综合三区| 国产精品五月天| 久久在线视频| 中文在线不卡| 亚洲电影专区| 欧美一区午夜精品| 亚洲午夜电影网| 欧美日韩福利在线观看| 久久综合九色综合欧美狠狠| 欧美日韩亚洲高清| 亚洲另类一区二区| 一区二区欧美激情| 亚洲国产一区二区三区a毛片| 亚洲欧美日产图| 小嫩嫩精品导航| 国产精品任我爽爆在线播放|