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

天行健 君子當自強而不息

坐標系與基本圖元(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 閱讀(1625) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


公告

導航

統計

常用鏈接

隨筆分類(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>
            国产精品超碰97尤物18| 亚洲久久视频| 美女露胸一区二区三区| 亚洲精品国产欧美| 亚洲欧美国产毛片在线| 久久久久国产精品厨房| 欧美国产欧美亚州国产日韩mv天天看完整| 欧美成在线观看| 黄色成人精品网站| 欧美影院在线播放| 欧美一区二区三区在线| 香蕉国产精品偷在线观看不卡| 久久全球大尺度高清视频| 亚洲尤物视频在线| 久久久噜噜噜久久久| 亚洲一区在线播放| 国产精品美女主播| 午夜电影亚洲| 夜夜精品视频一区二区| 亚洲免费高清| 欧美日韩在线一二三| 一区二区三区久久| 欧美va亚洲va香蕉在线| 欧美一区成人| 国产精品久久久久久五月尺| 亚洲综合激情| 久久久久久欧美| 最近看过的日韩成人| 亚洲六月丁香色婷婷综合久久| 欧美午夜性色大片在线观看| 久久综合五月天婷婷伊人| 国产精品国产三级国产aⅴ浪潮| 免费永久网站黄欧美| 欧美日韩免费精品| 欧美日韩精品在线观看| 亚洲综合首页| 欧美日韩国产黄| 亚洲承认在线| 亚洲国产日本| 久久免费视频这里只有精品| 欧美在线啊v| 国产目拍亚洲精品99久久精品 | 亚洲一区二区三区精品在线观看| 免费不卡视频| 亚洲国产日韩一级| 一二三四社区欧美黄| 久久国产精品网站| 久久大综合网| 国内外成人免费激情在线视频网站 | 欧美日韩国产综合在线| 亚洲免费大片| 久久久久久综合| 久久久噜噜噜久噜久久| 欧美/亚洲一区| 国产精品毛片| 久久综合伊人77777蜜臀| 精品99一区二区三区| 久久久欧美精品sm网站| 欧美不卡视频一区发布| 一区二区三区视频在线观看| 欧美日韩高清在线观看| 午夜精品久久久久久久99水蜜桃 | 欧美一区激情视频在线观看| 国产欧美日韩激情| 女生裸体视频一区二区三区| 在线视频欧美一区| 亚洲第一在线综合在线| 久久久久欧美| 免费在线国产精品| 欧美激情一区二区三区成人| 亚洲网站啪啪| 亚洲国产精品免费| 国产精品影片在线观看| 欧美精品日韩三级| 欧美大片91| 久久亚洲一区| 久久久成人精品| 欧美在线关看| 欧美一区免费视频| 亚洲女同同性videoxma| 亚洲欧美视频在线| 性色av一区二区三区| 亚洲天天影视| 亚洲永久网站| 午夜精品久久久99热福利| 亚洲午夜小视频| 亚洲欧美日韩精品在线| 香蕉久久精品日日躁夜夜躁| 国产精品99久久久久久人| 亚洲国产天堂网精品网站| 1000精品久久久久久久久 | 久久裸体艺术| 久久久久国色av免费看影院| 久久视频国产精品免费视频在线| 久久精品视频播放| 免费黄网站欧美| 国产精品久久久久久五月尺| 国产精品无码专区在线观看 | 亚洲午夜一二三区视频| 国产亚洲欧洲997久久综合| 最新日韩在线视频| 午夜精品久久久久久久| 久久九九电影| 洋洋av久久久久久久一区| 久久综合图片| 欧美日韩国产首页| 亚洲综合日本| 亚洲午夜黄色| 欧美顶级大胆免费视频| 亚洲视频图片小说| 黑人巨大精品欧美一区二区| 亚洲综合欧美| 亚洲午夜精品视频| 亚洲视频二区| 一区二区三区www| 亚洲第一中文字幕| 狠狠色伊人亚洲综合成人| 久久精品一区二区| 99视频精品全部免费在线| 亚洲人午夜精品免费| 欧美激情国产高清| 久久国产精品一区二区三区四区| 欧美在线高清视频| 亚洲人成绝费网站色www| 欧美日韩综合视频| 欧美jizzhd精品欧美巨大免费| 一区精品在线播放| 亚洲第一视频网站| 欧美大片91| 久久免费的精品国产v∧| 韩国av一区二区| 欧美中文字幕久久| 亚洲欧美精品中文字幕在线| 国产精品中文字幕欧美| 欧美一级视频| 久久国产精品99国产精| 在线观看一区视频| 亚洲精品极品| 欧美性猛片xxxx免费看久爱 | 欧美大片免费久久精品三p | 国内精品久久久久久久果冻传媒 | 欧美性做爰猛烈叫床潮| 亚洲欧美国产另类| 久久精品国产成人| 日韩午夜在线视频| 欧美一区二区三区在线看| 亚洲国产精品小视频| 亚洲性视频h| 亚洲精品一二三区| 新67194成人永久网站| 亚洲精品影视| 一本久久综合| 亚洲国产mv| 亚洲免费一级电影| 99在线观看免费视频精品观看| 久久爱www久久做| 欧美淫片网站| 国产精品国产三级国产aⅴ入口 | 亚洲国产成人tv| 亚洲精品中文字幕有码专区| 午夜天堂精品久久久久| 亚洲精品影院| 欧美精品www在线观看| 久久精品欧洲| 国产一区99| 午夜精品一区二区三区电影天堂 | 亚洲尤物视频网| 欧美三级日韩三级国产三级| 亚洲电影在线观看| 国产最新精品精品你懂的| 亚洲天堂av图片| 久久精品国产亚洲5555| 国产精品一区免费在线观看| 99国产精品| 欧美一区二区成人| 国产一级久久| 欧美gay视频激情| 日韩性生活视频| 久久成人18免费观看| 一区二区在线观看视频在线观看| 欧美va日韩va| 一区二区三区欧美在线观看| 欧美在线观看你懂的| 国产一区二区黄| 欧美国产日韩免费| 亚洲你懂的在线视频| 亚洲电影在线播放| 一区二区三区免费看| 国产亚洲精品久久飘花| 欧美国产丝袜视频| 欧美一区二区三区视频在线| 亚洲国产一区二区精品专区| 性欧美videos另类喷潮| 亚洲黄色成人网| 精久久久久久久久久久| 欧美午夜精品一区| 欧美日韩国产91| 久久综合伊人77777尤物| 午夜精品福利一区二区蜜股av| 91久久在线观看|