Hiển thị nội dung Buffer

Một phần của tài liệu Beginning DirectX 9 doc (Trang 66 - 69)

Sau khi bỏ thời gian để tạo vertex buffer và nạp dữ liệu vecto cho nó, chắc bạn sẽ tự hỏi nó sẽ xuất hiện trên màn hình thế nào. Để render những vecto trong vertex buffer đòi hỏi ba bước. Bước thứ nhất là cài đặt luồng nguồn, tiếp theo là thiết lập cho chếđộ shader (đổ

bóng), cuối cùng là vẽ những vecto đó lên màn hình. Những bước trên được giải thích chi tiết ở phần sau.

Cài đặt luồng nguồn

Luồng trong Direct3D là mảng của những thành phần dữ liệu có bao gồm nhiều thành tố. Vertex buffer bạn tạo ra ở trên chính là một luồng. Trước khi Direct3D có thể render một vertex buffer, bạn phải gắn liền buffer đó với một luồng dữ liệu. Điều đó đuợc thực hiện với hàm SetStreamSource được định nghĩa dưới đây:

HRESULT SetStreamSource( UINT StreamNumber,

IDirect3DVertexBuffer9 *pStreamData, UINT OffsetInBytes,

UINT Stride );

SetStreamSource cần 4 đối số:

■ StreamNumber. Số của luồng dữ liệu. Nếu bạn chỉ tạo một vertex buffer thì đối số này là 0

■ pStreamData. Con trỏ tới biến chứa vertex buffer.

■ OffsetInBytes. Số byte tính từđiểm bắt đầu của buffer nới chứa dữ liệu. Giá trị

này thường để là 0.

■ Stride. Kích thước của mỗi vecto trong. Một ví dụ về lời gọi tới SetStreamSource:

pd3dDevice->SetStreamSource ( 0, buffer, 0, sizeof(CUSTOMVERTEX) );

Trong lời gọi tới hàm SetStreamSource, đối số thứ nhất biểu diễn số của luồng được gán là 0. Đối số thứ hai là con trỏ tới vertex buffer hợp lệ. Đối số thứ ba được gán là 0, thông báo cho Direct3D vị trí bắt đầu là từđầu luồng. Đối số cuối cùng là bước của luồng. Nó

được gán cho kích thước bằng byte của cấu trúc CUSTOMVERTEX. Hàm sizeof sẽ tính toán số byte cho bạn.

Cài đặt đổ bóng

Sau khi đặt nguồn cho luồng, bạn phải đặt chếđộ đổ bóng vecto. Chế độ này thông báo cho Direct3D kiểu đổ bóng được dùng. Hàm SetFVF, định nghĩa dưới đây, cài đặt cho Direct3D sử dụng định dạng vecto bổ sung.

HRESULT SetFVF( DWORD FVF );

Hàm SetFVFchỉ cần một đối số là FVF. Đối sốFVFgồm các giá trịđịnh nghĩa bởi D3DFVF.

Đoạn code sau cho thấy cách dùng FVF. HRESULT hr;

hr = pd3dDevice->SetFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE); // Kiểm tra kết quả trả về từ SetFVF

if FAILED (hr) return false;

Đoạn code trên đưa vào giá trị D3DFVF_XYZRHWvà D3DFVF_DIFFUSEcho FVF. Khi cấu trúc CUSTOMVERTEXđược xây dựng, nó dùng hai giá trị trên khi tạo vertex buffer. Bạn cũng phải tạo một (Direct3D device) hợp lệ. Nó được tham chiếu qua biến

pd3dDevice.

Render Vertex Buffer

Sau khi bạn tạo luồng và gắn nó với một vertex buffer, bạn có thể render những vecto trong đó lên màn hình. Hàm cần dùng là DrawPrimitive được định nghĩa dưới đây.

Hàm DrawPrimitive sẽ duyệt qua vertex buffer và render dữ liệu của nó lên màn hình. HRESULT DrawPrimitive( D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount ); Hàm DrawPrimitive cần ba đối số:

■ PrimitiveType. Kiểu gốc dùng để vễ vecto của luồng.

■ StartVertex. Vị trí của vecto đầu tiên trong.

■ PrimitiveCount. Số kiểu gốc cần render. Kiểu gốc có thể là một trong các giá trị: (adsbygoogle = window.adsbygoogle || []).push({});

■ D3DPT_POINTLIST. Vẽ các điểm riêng lẻ.

■ D3DPT_LINELIST.Vẽ những đường thẳng riêng lẻ.

■ D3DPT_LINESTRIP. Vẽ những line liên tiếp nối đuôi nhau.

■ D3DPT_TRIANGLELIST. Vẽ những tam giác riêng lẻ gồm 3 vecto.

■ D3DPT_TRIANGLESTRIP. Vẽ một loạt tam giác liên tiếp nối đuôi nhau (từ tam giác thứ 2 trởđi chỉ cần 1 vecto để xác định).

■ D3DPT_TRIANGLEFAN. Vẽ một loạt tam giác có chung 1 vecto (đỉnh).

Đoạn code sau sử dụng DrawPrimitive ở chếđộ vẽ D3DPT_TRIANGLESTRIP. HRESULT hr; // Gọi DrawPrimitive hr = pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 1 ); // Kiểm tra kết quả trả về if FAILED (hr) return false;

Đoạn code trên thông báo với Direct3D để render những vecto chứa trong vertex buffer sử dụng chế độ vẽ D3DPT_TRIANGLESTRIP cho tham số thứ nhất. Tham số thứ hai

được gán là 0, thông báo cho DrawPrimitive bắt đầu với vecto đầu tiên trong buffer. Đối số cuối được gán là 1 bởi vì số vecto trong bộđệm chỉ đủđể tạo ra một tam giác.

Ta cần có thiết bị một Direct3D được khai báo chuẩn. Nó được tham chiếu đến thông qua biến pd3dDevice.

Mã nguồn chi tiết cho phần tạo và render một vertex buffer có thể tìm thấy ở thư mục chapter4\example1 trên đĩa CD-ROM.

Hình 4.8: Kết quả hiển thị từ ví dụ 1.

Render một khung cảnh (scene)

Trước khi bạn có thể render, bạn phải chuẩn bị Direct3D để render. Hàm BeginScene thông báo cho Direct3D chuẩn bị cho render. Sử dụng hàm BeginScene, Direct3D cần

chắc chắn rằng vùng render hợp lệ và sẵn sàng. Nếu hàm BeginScene bị lỗi, code của bạn sẽ bỏ qua đoạn gọi render.

Sau khi render xong, bạn cần gọi tới hàm EndScene. Hàm EndScene thông báo với Direct3D rằng bạn đã kết thúc quá trình gọi render và khung cảnh (scene) đã sẵn sàng để

chuyển sang back buffer.

Đoạn code sau đây xác nhận mã trả về từ khối BeginScene và EndScene. HRESULT hr;

if ( SUCCEEDED( pDevice->BeginScene( ) ) ) {

// Chỉ thực hiện render khi việc gọi BeginScene thành công // Đóng khung cảnh (scene)

hr = pDevice->EndScene( ); if ( FAILED ( hr ) )

return hr; }

Đoạn code ở trên xác nhận sư thành công của lời gọi tới BeginScene trước khi cho phép quá trình render diễn ra bằng cách sử dụng lệnh SUCCEEDED. Khi quá trình render hoàn thành, bạn gọi tới hàm EndScene. Đoạn code sau là một ví dụ: /****************************************************************************** * render ******************************************************************************/ void render() {

// Xóa back buffer bằng màu đen

pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );

// Thông báo bắt đầu scene tới Direct3D pd3dDevice->BeginScene();

// Vẽ những vecto chứa trong vertex buffer // Trước hết cần đặt luồng dữ liệu

pd3dDevice->SetStreamSource( 0, buffer, 0, sizeof(CUSTOMVERTEX) ); // Đặt định dạng vecto cho luồng

pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); // Vẽ những vecto trong vertex buffer dùng triangle strips pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 1 ); // Thông báo với Direct3D rằng quá trình vẽđã kết thúc

pd3dDevice->EndScene(); (adsbygoogle = window.adsbygoogle || []).push({});

// chuyển từ back buffer sang front buffer

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

Hàm render là tập hợp tất cả các bước đã nói ở trên. Biến pd3dDevice thể hiện một thiết bị Direct3D hợp lệđược tạo ra ở bên ngoài hàm này.

Một phần của tài liệu Beginning DirectX 9 doc (Trang 66 - 69)