CHƯƠNG 1: CÔNG NGHỆ VR VỚI THƯƠNG MẠI ĐIỆN TỬ VÀ QUẢNG BÁ SẢN PHẨM TRÊN NỀN WEB
1.4. Giới thiệu OpenSceneGraph (OSG)
1.4.5. Quản lý bộ nhớ và các lớp quản lý trạng thái
Trước khi bắt đầu xây dựng một scene graph, cần hiểu OSG quản lý bộ nhớ đang sử dụng như thế nào bởi các node và dữ liệu scene graph. Nắm chắc khái niệm này sẽ dễ dàng viết mã và tránh dư thừa bộ nhớ và các con trỏ thừa.
Trong cách dùng thông thường kịch bản điển hình một cách rõ ràng, ứng dụng giữ một con trỏ trỏ tới một nút gốc nhưng không phải là các node khác
Group
Geode Geode
Drawable Drawable
Geode
Drawable Drawable
hết các node trong scene graph. Hình 20 minh họa kịch bản điển hình này. Khi ứng dụng hoàn thành việc sử dụng scene graph này, bộ nhớ đang sử dụng bởi mỗi node phải được xóa để tránh lãng phí bộ nhớ. Viết mã để đi qua toàn bộ scene graph và xóa mỗi node (và dữ liệu của nó) trên đường đi sẽ dài dòng và dễ xảy ra lỗi. May thay, OSG cung cấp một hệ thống thu gom các dữ liệu vô nghĩa hoặc không phù hợp do đó bộ nhớ được sử dụng một cách hiệu quả hơn. Hầu hết các node được tính lại, và khi tính lại nếu số lượng của chúng giảm đến 0 thì đối tượng quản lý bộ nhớ sẽ xóa chúng. Để xóa hình scene graph, đơn giản chương trình sẽ xóa con trỏ trỏ tới node gốc. Điều này gây ra một hiệu ứng phân tầng, xóa hết các node và dữ liệu trong scene graph, được biểu diễn ở hình 20.
Hình 20 – Việc tham chiếu một scene graph
Đặc biệt, một ứng dụng tham chiếu một scene graph cùng với một con trỏ đơn lưu trữ địa chỉ của node gốc. Ứng dụng không lưu trữ con trỏ trỏ tới các node khác trong scene graph. Hầu hết các node khác đều được tham chiếu, trực tiếp hoặc không trực tiếp, từ node gốc.
Hình 21 – Xóa scene graph nhiều tầng
Hệ thống quản lý bộ nhớ của OSG xóa toàn bộ scene graph khi con trỏ trỏ tới node gốc cuối cùng được xóa.
OSG định nghĩa một lớp con trỏ thông minh tạm thời được gọi là osg::ref_ptr<> mà sử dụng như một con trỏ C++ thông thường. Sử dụng các biến ref_ptr<> để lưu trữ các địa chỉ OSG node và địa chỉ dữ liệu scene graph được cấp phát trên bộ nhớ heap. Khi mã gắn địa chỉ đối tượng Referenced tới một biến ref_ptr<>, tính thử lại trong Referenced tự động tăng.
Bất kỳ đoạn mã lưu trữ một con trỏ trỏ tới một đối tượng được lấy từ Referenced phải lưu trữ con trỏ trong một ref_ptr<> đúng hơn là biến con trỏ C++ thông thường. Nếu tất cả các mã đều tuân thủ theo quy tắc này, thì bộ nhớ sẽ xóa đi một cách tự động khi biến ref_ptr<> liên quan đến nó tiến hành.
Ref_ptr<> sử dụng thao tác nạp chồng, với mục đích là các biến ref_ptr<>
hoạt động tương tự nhu các biến con trỏ C + + thông thường. Ví dụ, biến ref_ptr<> nạp chồng operator->() và con trỏ operator*() truy cập vào vùng nhớ mà con trỏ địa chỉ trỏ tới.
Khi tạo bất kỳ node hoặc dữ liệu scene graph nào lấy từ Referenced, mã ứng dụng không thế xóa bộ nhớ đó một cách dứt khoát. Cùng với một vài ngoại lệ, hầu hết các lớp con Referenced đều được bảo vệ khỏi sự phá hoại. Điều này đảm bảo rằng các đối tượng được lấy từ Referenced chỉ có thể được xóa kết quả của việc giảm số lượng sự tham chiếu của chúng đến 0.
1.4.5.2. Các lớp quản lý trạng thái
OSG cung cấp một cơ chế lưu trữ sự phân loại trạng thái biểu diễn khi OpenGL yêu cầu trong đồ thị cảnh. Trong quá trình quét chọn lọc, hình học cùng với các trạng thái giống nhau được nhóm lại với nhau để giảm thiểu sự thay đổi trạng thái. Trong thời gian duyệt cảnh, mã quản lý trạng thái theo dõi trạng thái hiện thời để loại trừ những thay đổi trạng thái dư thừa. Thư viện cho phép trạng thái kết hợp với bất kỳ trạng thái của nút đồ thị khác, và trạng thái này được kế thừa có thứ bậc trong suốt quá trình tạo cảnh.
StateSet: OSG lưu trữ một tập các giá trị của state (được gọi là các phương thức và các thuộc tính) trong lớp StateSet. Bất kỳ osg::Node trong scene graph có thể có StateSet liên kết với nó.
Các phương thức (Modes): Tương tự đối với OpenGL gọi tới các hàm glEnable() và glDisable(). Các phương thức cho phép mở và ngắt các tính năng trong OpenGL. Sử dụng phương thức osg::StateSet::setMode() để lưu trữ một mode trong một StateSet.
Các thuộc tính (Attribute): Các thuộc tính lưu trữ các tham số trạng thái, như hàm trộn, màu sương mù. Sử dụng phương thức osg::StateSet::setAttribute() để lưu trữ một thuộc tính trong một StateSet.
Các phương thức và các thuộc tính texture: Các phương thức và các thuộc tính đó áp dụng đối với một đơn vị texture cụ thể trong sự kiến tạo đa nhiệm OpenGL. Không giống với OpenGL, ở đó không có đơn vị texture mặc định; ứng dụng phải cung cấp đơn vị texture khi thiết lập các phương thức và các thuộc tính texture. Để thiết lập các giá trị state đó và xác định đơn vị texture của chúng sử dụng các phương thức StateSet là setTextureMode() và setTextureAttribute().
Sự kế thừa các flag: OSG cung cấp các flag cho việc điều chỉnh trạng thái được kế thừa trong lúc một scene graph giao nhau. Theo mặc định, stateset trong một nút con quan trọng hơn cùng stateset trong một nút cha. Tuy nhiên có thể buộc trạng thái node cha ghi đè lên trạng thái node con và có thể xác định rõ trạng thái node con được bảo vệ từ sự ưu tiên của node cha.
Hệ thống trạng này đã được chứng minh bản thân hệ thống đó rất linh hoạt. Hầu hết các đặc tính mới được thêm vào sự đặc tả OpenGL trong thời gian tồn tại của OSG, bao gồm cả việc bổ sung ngôn ngữ tô bóng OpenGL, dễ dàng thích hợp với hệ thống trạng thái OSG.