Sau khi bạn có vertex buffer, bạn cần đưa dữ liều vecto vào đó. Nhưng trước đó, bạn phải khóa vùng nhớ mà buffer đang dùng. Sau khi vùng nhớ này được khóa, bạn mới có thể
nạp dữ liệu vào đó.
Khóa Vertex Buffer
Khóa vùng nhớ cho vertex buffer cho phép ứng dụng của bạn ghi dữ liệu lên đó. Tại thời
điểm này, bạn đã định nghĩa xong vertex buffer và kiểu của vecto mà nó chứa. Bước tiếp theo là khóa buffer và nạp dữ liệu vecto. Khóa buffer thông qua lời gọi hàm:
HRESULT Lock( UINT OffsetToLock, UINT SizeToLock, VOID **ppbData, DWORD Flags ); Hàm Lockfunction có bốn đối số:
■OffsetToLock. Vùng buffer bạn muốn khóa. Nếu bạn muốn khóa toàn bộ thì gán giá trị này là 0.
■SizeToLock. Kích thước dạng byte bạn muốn khóa. Nếu bạn muốn khóa toàn bộ buffer thì gán giá trị này là 0.
■ppbData. Con trỏ dạng void trỏ tới buffer chứa vecto.
■Flags. Cờ quy định kiểu khóa. Đưa vào một trong các giá trị sau:
• D3DLOCK_DISCARD. Ghi đè toàn bộ buffer.
• D3DLOCK_NO_DIRTY_UPDATE. Không ghi dữ liệu lên các vùng bẩn!!!
• D3DLOCK_NO_SYSLOCK. Cho phép hệ thống tiếp tục xử lý các sự kiện trong suôt quá trình khóa.
• D3DLOCK_READONLY. Chỉ cho phép đọc.
• D3DLOCK_NOOVERWRITE. Không cho ghi đè dữ liệu cũ.
Đoạn code sau cho thấy cách gọi thông thường của hàm Lock:
HRESULT hr; VOID* pVertices; // Khóa vertex buffer
hr = g_pVB->Lock( 0, 0, ( void** ) &pVertices, 0 ); // Kiểm tra giá trị trả về
if FAILED (hr) return false;
Hàm Lock thừa nhận rằng bạn đã tạo thành công vertex buffer. Biến g_pVB trỏ tới buffer này.
Sao chép dữ liệu vào vertex buffer
Sau khi khóa vertex buffer, bạn có thể tự do copy dữ liệu vào buffer. Bạn vừa có thể copy các vecto mới vào buffer, vừa có thể sửa đổi những vecto đã nằm trong buffer. Ví dụ tiếp theo cho thấy cách sử dụng memcpy để copy một mảng vecto vào trong vertex buffer.
// cấu trúc CUSTOMVERTEX struct CUSTOMVERTEX {
FLOAT x, y, z, rhw; // vị trí 3D đã qua biến đổi của vecto DWORD color; // màu vecto
};
// định nghĩa các vecto dùng trong vertex buffer CUSTOMVERTEX g_Vertices [ ] = { {320.0f, 50.0f, 0.5f, 1.0f, D3DCOLOR_ARGB (0, 255, 0, 0),}, {250.0f, 400.0f, 0.5f, 1.0f, D3DCOLOR_ARGB (0, 0, 255, 0),}, {50.0f, 400.0f, 0.5f, 1.0f, D3DCOLOR_ARGB (0, 0, 0, 255),}, };
// Copy dữ liệu vào vertex buffer
memcpy( pVertices, g_Vertices, sizeof( g_Vertices ) );
Đầu tiên ta khai báo cấu trúc CUSTOMVERTEX. Nhưđã đề cập trước đây, cấu trúc này chứa cả vị trí và màu của vecto. Tiếp theo, ta tạo ra một mảng vecto. Nó được trỏđến bởi
g_Vertices và nó chứa những vecto sẽ được copy vào buffer. Cuối cùng, lời gọi tới memcpy sẽ copy những vecto này vào buffer. Đối số thứ nhất cho memcpy là pVertices, là con trỏ kiểu void đã được tạo ra qua lời gọi Lock.
Mở khóa Vertex Buffer
Sau khi những vecto trên đã đươc copy vào buffer, bạn phải mở khóa buffer. Mở khóa buffer cho phép Direct3D tiếp tục quá trình bình thường. Bạn mở khóa buffer thông qua hàm Unlock được định nghía dưới đây:
HRESULT Unlock (VOID);
Hàm Unlock không đòi hỏi đối số và giá trị trả về của nó là D3D_OK nếu thành công. Sau khi nạp dữ liệu vào vertex buffer, ta có thể biểu diễn nó trên màn hình.
Hàm SetupVB dưới đây tổng hợp toàn bộ các bước đã nêu ở trên: // con trỏ tới vertex buffer
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;
/****************************************************************************** * SetupVB * SetupVB
******************************************************************************/ HRESULT SetupVB() HRESULT SetupVB()
{
HRESULT hr;
// Khởi tạo giá trị cho 3 vecto của tam giác CUSTOMVERTEX g_Vertices[] = { {320.0f, 50.0f, 0.5f, 1.0f, D3DCOLOR_ARGB (0, 255, 0, 0), }, {250.0f, 400.0f, 0.5f, 1.0f, D3DCOLOR_ARGB (0, 0, 255, 0), }, {50.0f, 400.0f, 0.5f, 1.0f, D3DCOLOR_ARGB (0, 0, 0, 255), }, };
// tạo một vertex buffer
hr = pd3dDevice->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX), 0, D3DFVF_XYZRHW|D3DFVF_DIFFUSE, D3DPOOL_DEFAULT, &g_pVB, NULL );
// Kiểm tra xem vertex buffer đã được tạo ra chưa if FAILED ( hr )
return NULL; VOID* pVertices; // Khóa vertex buffer
hr = g_pVB->Lock( 0, sizeof(g_Vertices), (void**)&pVertices, 0 ); // Kiểm tra xem lời gọi hàm có thành công không
if FAILED (hr)
return E_FAIL; // Copy các vecto vào buffer
memcpy( pVertices, g_Vertices, sizeof(g_Vertices) ); // Mở khóa vertex buffer
g_pVB->Unlock(); return S_OK; }
Hàm SetupVBđòi hỏi biến chứa vertex buffer phải được khai báo bên ngoài phạm vi của hàm này. Biến g_pVB tham chiếu tới biến này. Nếu vertex buffer được tạo và nạp dữ liệu thành công, hàm SetupVB trả về một giá trị kiểu HRESULT là S_OK.