OSG Day006

1.文件的读写
支持的文件格式

  • 三维模型文件格式
  • 常见格式:.obj(Wavefront OBJ)、.fbx(Autodesk FBX)、.dae(Collada)、.gltf(GL Transmission Format)。
  • 特点:.obj格式简单易用,适合静态模型;.fbx支持动画和复杂场景,广泛用于游戏和影视;.gltf是现代Web应用中常用的格式,支持PBR(物理基础渲染)。
  • 图片及视频文件格式
  • 图片格式:.jpg(有损压缩,适合照片)、.png(无损压缩,支持透明)、.bmp(位图,未压缩)。
  • 视频格式:.mp4(广泛支持,良好的压缩比)、.avi(较老的格式,支持多种编码)、.mov(Apple的格式,常用于视频编辑)。
  • 打包及网络传输格式
  • 打包格式:.zip、.tar、.rar(数据压缩和归档)。
  • 网络传输格式:JSON、XML(用于数据交换),适用于API和网络通信。
  • 字体文件格式
  • 常见字体格式:.ttf(TrueType Font,广泛支持)、.otf(OpenType Font,支持更多功能)、.woff(Web Open Font Format,专为网页设计)。
  • 伪插件文件格式
  • 伪插件通常是为了兼容性和扩展性而设计的,允许开发者在不修改核心代码的情况下添加新功能。
  • .osg文件和.ive文件
  • .osg文件是OpenSceneGraph的场景描述文件,包含场景的几何和材质信息。
  • .ive文件是二进制格式,相比于.osg文件,加载速度更快,适合大场景的实时渲染。
    文件读写的流程
    在这里插入图片描述
  • osgDB库
  • osgDB是OpenSceneGraph的数据库接口,支持多种文件格式的读写,提供统一的API接口,简化了文件操作。
  • 文件的读取与保存
  • 读取文件时,首先通过osgDB库确定文件格式,然后解析文件内容并生成相应的场景图节点。
  • 保存文件时,需将场景图节点序列化为目标格式,确保数据完整性。
  • 文件读写示例
  • 文件读写进度
  • 可以通过回调函数或进度条来显示文件读写的进度,提升用户体验。
  • 文件读取进度示例
    插件的工作机制
  • 插件的搜索和注册
  • 插件通常放置在特定目录下,osgDB会在初始化时扫描这些目录并注册可用插件。
  • osgArchive读写流程
  • osgArchive用于处理打包文件,支持读取和写入,能够处理内部文件结构。
  • 自定义文件插件
  • 开发者可以根据需要实现自定义文件格式的读写插件,需实现特定的接口。
  • 自定义文件格式读写插件示例
    读写中文文件名及中文路径问题
  • 使用UTF-8编码处理中文文件名和路径,确保在不同操作系统上都能正确识别。
  • 在Windows平台上,可能需要使用特定的API(如_wfopen)来处理宽字符。
    osgEXP导出文件
  • osgEXP是OpenSceneGraph的导出工具,支持将场景导出为多种文件格式。
  • 使用osgEXP时,可以设置导出选项,如是否导出纹理、动画等。
    要点总结
  • 了解各种文件格式的特性及适用场景,有助于选择合适的格式进行数据交换。
  • 掌握文件的读写流程和示例代码,能够在项目中灵活运用。
  • 理解插件机制,能够扩展和自定义功能,提升系统灵活性。
  • 处理中文文件名和路径问题时,需注意编码方式,确保跨平台兼容性。
  • 熟悉osgEXP的使用,能够有效地导出场景数据,便于后续处理和共享。
    2.C++语法
osgDB::Registry::instance() 一个典型的单例模式实现
class Registry {
public:
    static Registry& instance() {
        static Registry instance; // 局部静态变量,保证只初始化一次
        return instance;
    }
private:
    Registry() {} // 构造函数私有化,防止外部创建实例
    Registry(const Registry&) = delete; // 禁止拷贝构造
    Registry& operator=(const Registry&) = delete; // 禁止赋值
};

// 拷贝构造函数的实现
class MyClass {
public:
    int data;
    // 默认构造函数
    MyClass(int value) : data(value) {}
    // 拷贝构造函数 浅拷贝
    MyClass(const MyClass& other) {
        data = other.data; // 复制状态
    }
};

// 深拷贝示例
class MyClass {
public:
    int* data;
    // 默认构造函数
    MyClass(int value) {
        data = new int(value);
    }
    // 拷贝构造函数(深拷贝)
    MyClass(const MyClass& other) {
        data = new int(*other.data); // 分配新的内存并复制值
    }
    // 析构函数
    ~MyClass() {
        delete data; // 释放内存
    }
};
std::deque<std::string> C++ 标准库中的一个双端队列(double-ended queue),可以存储 std::string 类型的元素。std::deque 是一个序列容器,允许在两端高效地插入和删除元素。
#include <iostream>
#include <deque>
#include <string>
int main() {
    std::deque<std::string> myDeque = {"Hello", "World", "C++"};
    for (const auto& str : myDeque) {
        // std::cout 被调用时,str 被解引用,输出的是 myDeque 中当前字符串的内容。
        std::cout << str << " "; // 输出每个字符串
    }
    std::cout << std::endl;
    return 0;
}

// 模板定义
#include <iostream>
#include <string>
#include <cstring>
#include <type_traits>
template<typename Elem, typename Tr = std::char_traits<Elem>> // 属于模板参数
class MyString {
public:
    MyString(const Elem* str) {
        size = Tr::length(str); // 使用 Tr 来获取字符串长度
        data = new Elem[size + 1];
        Tr::copy(data, str, size); // 使用 Tr 来复制字符串
        data[size] = Tr::to_char_type(0); // 添加字符串结束符
    }
    ~MyString() {
        delete[] data;
    }
    void print() const {
        std::cout << data << std::endl;
    }
private:
    Elem* data;
    size_t size;
};
int main() {
    MyString<char> myStr("Hello, World!");
    myStr.print(); // 输出: Hello, World!
    return 0;
}

// 函数模板
#include <iostream>
// 定义一个函数模板
template<typename T>
T add(T a, T b) {
    return a + b;
}
int main() {
    std::cout << add(5, 3) << std::endl;       // 输出: 8
    std::cout << add(5.5, 3.2) << std::endl;   // 输出: 8.7
    return 0;
}

// 类模板
#include <iostream>
template<typename T>
class Box {
public:
    Box(T value) : value(value) {}
    T getValue() const {
        return value;
    }
private:
    T value;
};
int main() {
    Box<int> intBox(123);
    Box<std::string> strBox("Hello, Templates!");
    std::cout << intBox.getValue() << std::endl;       // 输出: 123
    std::cout << strBox.getValue() << std::endl;       // 输出: Hello, Templates!
    return 0;
}

// 模板参数
#include <iostream>
template<typename T, int size>
class Array {
public:
    Array() {
        std::cout << "Array size: " << size << std::endl;
    }
private:
    T arr[size]; // 使用非类型参数定义数组大小
};
int main() {
    Array<int, 10> intArray; // 创建一个大小为 10 的整数数组
    return 0;
}

// 模板特化
#include <iostream>
template<typename T>
class Printer {
public:
    void print(T value) {
        std::cout << "Value: " << value << std::endl;
    }
};
// 针对 std::string 类型的特化
template<>
class Printer<std::string> {
public:
    void print(std::string value) {
        std::cout << "String Value: " << value << std::endl;
    }
};
int main() {
    Printer<int> intPrinter;
    intPrinter.print(42); // 输出: Value: 42
    Printer<std::string> strPrinter;
    strPrinter.print("Hello, World!"); // 输出: String Value: Hello, World!
    return 0;
}

总结
函数模板 允许你定义通用函数,接受多种数据类型。
类模板 允许你定义通用类,处理不同类型的对象。
模板参数 可以是类型参数和非类型参数。
模板特化 允许你为特定类型提供不同的实现。
### CISSP OSG 第十版 资料 教材 内容 关于CISSP OSG(Official Study Guide)第十版的具体内容和特点,虽然当前的信息主要集中在第九版和其他版本上,但从已有信息可以推测出一些通用特征。 #### 版本更新趋势 通常情况下,新版教材会基于前一版本进行改进和完善。例如,在第八版至第九版之间,OSG保持了其简洁精炼的特点,同时增加了更多实用性的考试准备材料[^3]。因此,预计第十版将继续沿袭这些优点,并可能引入最新的信息安全标准和技术发展动态。 #### 主要特性 - **结构紧凑**:相比其他同类书籍如AIO,OSG倾向于提供更为集中和重点突出的内容覆盖。 - **章节设置合理**:尽管具体数量未知,但以往各版次中,OSG的章节安排能够有效地映射到CISSP所涉及的安全领域,有助于考生全面理解和记忆知识点。 - **辅助工具完善**:每章结尾处配备详细的考点提示以及练习题目,便于读者自我检测学习效果并加深印象。 #### 学习建议 对于打算使用OSG第十版作为备考资源的人来说,制定科学合理的复习计划至关重要。可以根据个人情况调整每日或每周的学习量,比如每天花大约1.5小时左右的时间深入研读指定章节,并配合参加线上线下的培训课程来强化理解[^4]。 ```python # Python代码示例用于模拟如何规划学习进度 def plan_study_schedule(total_days, daily_hours=1.5): chapters = ["Chapter_{}".format(i+1) for i in range(21)] # 假设有21个章节 schedule = {} current_day = 0 chapter_index = 0 while chapter_index < len(chapters): if current_day >= total_days: break study_time_left_today = min(daily_hours * (total_days - current_day), sum([len(c) / 100 for c in chapters[chapter_index:]])) while study_time_left_today > 0 and chapter_index < len(chapters): time_spent_on_chapter = min(study_time_left_today, len(chapters[chapter_index]) / 100) if "Day_" + str(current_day + 1) not in schedule: schedule["Day_" + str(current_day + 1)] = [] schedule["Day_" + str(current_day + 1)].append((chapters[chapter_index], round(time_spent_on_chapter, 2))) study_time_left_today -= time_spent_on_chapter if study_time_left_today <= 0 or chapter_index == len(chapters)-1: current_day += 1 elif sum([len(c) / 100 for c in chapters[chapter_index:]]) <= study_time_left_today: chapter_index += 1 return schedule ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值