向AI许了个愿:CodeBuddy帮我用c++开发了一个Obj Viewer

AI 工具使用心得

现在在外网开发时,我基本离不开AI了,也不会用搜索引擎了。基本都是先问AI,对AI的回答不满意或质疑答案时,才会去搜索。像一些简单的代码段,基本主流的大模型都能正确回答。

目前我是这么用大模型的

  • Qwen 解决编程语言的基础问题,比如Java的一些基础问题
  • ChatGPT优化提示词,具有全局记忆功能,能记住以前的聊天记录,提供更个性化的回答
  • Claude写代码主力,没法直接用,通过CodeBuddy使用,一般都是完整demo级别的任务
  • Gemini研究论文或实现算法,如果写代码最终还是会用Claude优化
  • Kimi总结网页内容,水文章😁
  • 豆包生成图片(配个图啥的)或新闻,总结新闻来龙去脉,设置了定时任务每天下午五点半推送新闻热点
  • 元宝手机端使用,日常搜索一些问题,分享公众号文章链接让它总结核心内容等。

提示词优化流程

如果是完成一项比较正式的任务,我会:

  1. 首先写一段基础的提示词
  2. 让ChatGPT帮我优化
  3. 审核优化后的提示词
  4. 如果觉得有不全的或需要修改的,直接告诉ChatGPT
  5. ChatGPT会一条一条帮我记录
  6. 最后让它输出完整的提示词

因为我对渲染不熟悉,但又想做个viewer,所以我让ChatGPT帮我优化了一段提示词,最后让Claude帮我实现了一个简单的OBJ Viewer,后续我实现几何相关算法就可以用这个Viewer查看或操作模型了。

原始提示词

最小加载obj文件的viewer(可以依赖tinyobjloader读取obj文件,https://github.com/tinyobjloader/tinyobjloader)支持显示纹理、ui用最简单的,帮我列举下,显示模型时可以显示线框模式、线框+填充、顶点模式、显示法线、场景常规操作,旋转、平移、缩放,选择就暂时不需要了,ui需要有菜单栏,菜单下文件,文件下有打开和退出,打开文件会默认清空当前场景,加载新的模型对象,然后默认用打开的模型boundingbox定位,菜单栏需要有视图菜单,视图底下有重置相机,重置相机就是用模型boundingbox定位场景。

优化后的完整提示词

目标 实现一个最小化、可扩展的 OBJ 文件 Viewer,专注运算与渲染解耦,代码结构简单明了,便于后续扩展绘制与几何运算功能。

一、功能需求

  1. 文件加载
    • 新模型加载时追加到场景,不覆盖已有模型
    • 提供清空场景功能
    • 使用 tinyobjloader 解析 OBJ 文件
    • 支持纹理加载与显示
    • 多模型支持
    • 加载完成后,可根据该模型或整个场景的 Bounding Box 自动定位相机
    • 文件路径和文件名可能包含中文或其他 Unicode 字符,读取时使用 UTF-8 编码,确保解析成功并提供异常处理
  2. 文件保存
    • 支持保存 OBJ 文件,路径和文件名可包含 Unicode(中文或特殊字符)
    • 保存时使用 UTF-8 编码,确保 OBJ 格式兼容标准
    • 提供覆盖或新建文件选项,与场景数据一致
  3. 显示模式
    • 线框模式
    • 线框 + 填充模式
    • 顶点模式
    • 显示法线
  4. 场景元素
    • X/Y/Z 坐标轴显示,默认 Y 轴向上
    • 坐标轴绘制独立于模型缩放
  5. 鼠标交互
    • 左键:旋转相机
    • 右键:平移相机
    • 中键滚轮:缩放相机视距
  6. UI
    • 文件
    • 视图
    • 打开(Open)→ 追加到场景
    • 清空场景(Clear Scene)
    • 退出(Exit)
    • 重置相机(根据 Bounding Box 定位)
    • 使用简单 UI 库(推荐 ImGui)
    • 菜单栏可扩展:
    • 菜单代码需支持后续新增子菜单项(如"编辑""分析"等)

二、数据与渲染精度

  1. 运算层(double 精度)
    • 存储所有模型对象原始数据(顶点、法线、纹理坐标)
    • 每个模型对象独立管理 m_modelMatrix(双精度 Model Matrix)
    • 用于后续几何运算(布尔运算、法线重建等)
  2. 渲染层(float 精度)
    • 每次渲染前,将运算层数据转换为 float 缓冲区(VBO/VAO)供 OpenGL 渲染
    • 渲染与运算层解耦,互不影响
  3. 模型对象示例结构structMeshDataDouble
    {
        std::vector<Eigen::Vector3d> m_vertices;
        std::vector<Eigen::Vector3d> m_normals;
        std::vector<Eigen::Vector2d> m_texcoords;
    };

    structMeshDataFloat
    {
        std::vector<Eigen::Vector3f> m_vertices;
        std::vector<Eigen::Vector3f> m_normals;
        std::vector<Eigen::Vector2f> m_texcoords;
    };

    structModelObject
    {
        MeshDataDouble m_dataDouble;
        MeshDataFloat m_dataFloat;
        Eigen::Matrix4d m_modelMatrix; // 双精度变换矩阵
    };

三、扩展预留

  • 绘制接口DrawPoints()DrawLines()DrawFaces(),可对单个模型或全场景调用
  • 几何运算可在 double 层对单个模型或多模型进行布尔运算、测量、法线计算等
  • 菜单扩展菜单栏通过注册机制或配置驱动添加功能

四、代码规范

  • 成员变量统一使用 m_ 前缀
  • 大括号风格Allman 风格({ 换行)
  • 缩进使用 Tab
  • 编码UTF-8
  • 代码字符集除注释外不得出现中文或非 ASCII 特殊字符
  • 文件目录结构
    • include/存放头文件(.h/.hpp)
    • src/存放源文件(.cpp)
    • 头文件与源文件一一对应,类/函数声明放头文件,定义放源文件

五、限制条件

  • 实现最基础 Viewer 功能,UI 与渲染逻辑保持最小化
  • 不实现模型选择或高级编辑功能
  • 保持结构清晰、易于维护

功能覆盖清单: 

✅ 多模型管理
✅ Y-Up 坐标轴
✅ 鼠标左旋右移中缩
✅ 显示模式切换
✅ Unicode 文件读写/保存
✅ 运算层 double,渲染层 float 解耦
✅ 代码风格规范(Allman + Tab + m_ 前缀)
✅ 头文件和源文件目录结构

可以说以上提示词完全覆盖了我的基本要求。


项目结构

在CodeBuddy内新建文件夹,通常我会按照以下方式组织:

├── images/                     # 存放图片
├── src/                        # cpp源文件,这里通常会按照类别组织代码,比如core、UI、Render等
│   └── main.cpp                
├── include/                    # 和src对应
│   └── test.h
├── Third/                      # 第三方库
│   ├── GLFW/                   # 窗口管理库
│   └── glad/                   # OpenGL加载库
├── projects/                   # 项目文件
├── Docs/                       # 项目涉及文档等
│   └── viewer_提示词.md         # 提示词
├── README.md                   # 一般会写项目文档综述
└── .codebuddy/                 # codebuddy目录
    └── actorus.mdc             # 项目规则文件

注意: 一般情况下我会把提示词拆分出来,把一般规则放到项目规则文件内,比如一些代码规范等。一般来说这个文件不宜太长,因为这个规则文件可能每次对话都需要(根据Rule Type确定),太长会占用太多上下文。

项目成果

在经过长达十轮对话后,Claude帮我完整实现了这个项目,中间我提了额外的需求,比如日志、设置、视图切换等。目前这个软件基本能满足我个人使用(我甚至让Claude帮我实现了shader管理,虽然我不懂😂),后续我会在这个基础上实现一些几何算法。

软件界面

很简洁,支持快捷键切换视图:

功能说明

基本操作

  1. 加载模型
    • 菜单: File → Open (Ctrl+O)
    • 支持OBJ格式文件
  2. 保存模型
    • 菜单: File → Save (Ctrl+S)
  3. 清空场景
    • 菜单: File → Clear Scene (Ctrl+N)

相机控制

  • 旋转鼠标左键拖动
  • 平移鼠标右键拖动
  • 缩放鼠标滚轮
  • 重置相机菜单 View → Reset Camera (F键)

标准视图

通过菜单 View → Standard Views 可以快速切换到标准视图:

  • Front (前视图) - 快捷键: 1
  • Back (后视图) - 快捷键: 2
  • Left (左视图) - 快捷键: 3
  • Right (右视图) - 快捷键: 4
  • Top (顶视图) - 快捷键: 5
  • Bottom (底视图) - 快捷键: 6

显示模式

通过View菜单可以切换不同的显示模式:

  • Fill Mode标准填充模式
  • Wireframe Mode线框模式
  • Points Mode点模式
  • Wireframe+Fill Mode线框和填充混合模式

其他功能

  • 显示法线View → Show Normals
  • 坐标轴右上角实时显示3D坐标轴
  • 状态栏底部显示模型数量和当前显示模式

技术架构

项目规模

  • 类数量9个核心类
  • 文件数量25个文件
  • 可执行文件大小不到900KB

依赖库

  • tinyobjloaderOBJ文件解析
  • eigen数学运算库
  • gladOpenGL加载库
  • GLFW窗口管理库
  • imgui用户界面库

核心类说明

Application类

  • 应用程序主类,负责初始化和主循环
  • 管理窗口、输入处理和各模块协调

Camera类

  • 轨道相机实现
  • 支持旋转、平移、缩放操作
  • 提供六个标准视图方向

ModelObject类

  • 3D模型对象封装
  • 支持OBJ文件加载和保存
  • 材质和纹理管理

Renderer类

  • OpenGL渲染器
  • 支持多种显示模式
  • 着色器管理和渲染管线

ShaderManager类

  • 着色器管理器,应该没实现完整,不重要,能正确加载纹理就行了😂

UIManager类

  • ImGui界面管理
  • 菜单系统和状态栏
  • 用户交互处理

Scene类

  • 场景管理器
  • 模型集合管理
  • 包围盒计算

SettingsManager类

  • 应用程序配置管理(单例模式)
  • 设置的保存和加载(JSON格式)
  • 支持背景颜色和日志级别配置
  • 配置文件:actorusLab.json

Logger类

  • 完整的日志系统(单例模式)
  • 多级别日志记录(DEBUG、INFO、WARN、ERROR)
  • 同时支持文件和控制台输出
  • 线程安全的日志记录
  • 日志文件格式:yyyy_mm_dd_pid.log

FileUtils类

  • File相关工具类
  • 包含基本文件IO和文件路径操作