500行纯C++代码实现软件渲染:展示3D图形API工作原理,附代码与示例

📅 2026/7/24 16:12:46 👁️ 阅读次数 📝 编程学习
500行纯C++代码实现软件渲染:展示3D图形API工作原理,附代码与示例

用500行纯C++代码实现软件渲染:展示3D图形API工作原理,附代码与示例

在这一系列文章里,打算通过从头编写简化版克隆程序,展示OpenGL、Vulkan、Metal和DirectX的工作原理。很多人学3D图形API会卡在入门阶段,为此准备简短系列讲座,讲座后学生能做出功能不错的渲染器。

任务目标

不使用任何第三方库(尤其是图形相关库),生成一张如下所示的图像:

需要注意,这是一份教学材料,大致遵循现代3D图形库结构,是个软件渲染器,并不打算展示如何编写GPU应用程序,而是展示其工作原理。理解这一点对用3D库编写高效应用程序很重要。

起点

最终代码约500行,学生通常花10到20个小时编程才能开始制作这样的渲染器。输入是由三角网格和纹理组成的3D模型,输出是渲染后的图像,程序无图形界面,仅简单生成一张图片。

为减少外部依赖,给学生提供处理 TGA 文件的类。TGA是支持RGB、RGBA和灰度图像的简单格式之一,是图像操作的基础。一开始,除加载和保存图像外,唯一可用功能是设置单个像素颜色。

没有内置绘制线段或三角形的函数,将手动实现所有功能。虽会和学生一起编写源代码,但不建议直接使用,亲自动手实践对理解概念很重要。完整代码可在 GitHub 上找到,给学生的初始源代码可在 这里 找到。下面是起点代码:

main.cpp

#include "tgaimage.h" constexpr TGAColor white = {255, 255, 255, 255}; // 注意,BGRA 顺序 constexpr TGAColor green = { 0, 255, 0, 255}; constexpr TGAColor red = { 0, 0, 255, 255}; constexpr TGAColor blue = {255, 128, 64, 255}; constexpr TGAColor yellow = { 0, 200, 255, 255}; int main(int argc, char** argv) { constexpr int width = 64; constexpr int height = 64; TGAImage framebuffer(width, height, TGAImage::RGB); int ax = 7, ay = 3; int bx = 12, by = 37; int cx = 62, cy = 53; framebuffer.set(ax, ay, white); framebuffer.set(bx, by, white); framebuffer.set(cx, cy, white); framebuffer.write_tga_file("framebuffer.tga"); return 0; }

这段代码会生成一个64x64的图像 `framebuffer.tga`,为便于阅读,对其进行了缩放:

编译

git clone https://github.com/ssloy/tinyrenderer.git && cd tinyrenderer && cmake -Bbuild && cmake --build build -j && build/tinyrenderer obj/diablo3_pose/diablo3_pose.obj obj/floor.obj

渲染后的图像会保存为 `framebuffer.tga`。

预览:渲染器生成的几个示例




评论

使用 Material for MkDocs 制作

导航目录

  • 主页
  • tinyrenderer
    • 主页
    • 布雷森汉姆直线绘制算法
    • 三角形光栅化
    • 重心坐标
    • 隐藏面消除
    • 简易相机处理
    • 优化相机
    • 着色
    • 更多数据!
    • 切线空间
    • 阴影映射
    • 环境光遮蔽
    • 额外内容:卡通着色
    • 后记
  • tinycompiler
    • 主页
    • 抽象语法树
    • SLY:词法分析器和语法分析器
    • 符号表
    • 显示
    • 汇编代码生成
    • 自制词法分析器
    • 自制语法分析器
    • 后记
  • tinyoptimizer
    • 主页
    • mem2reg
  • tinyfloat
    • 主页
    • 计算机与数字
    • 浮点数打印
    • 加法与误差
    • 除法
  • 香蕉投掷项目
    • 主页
    • 猿猴计算秒数
    • 猿猴买了块更好的手表
    • 猿猴没碰到地面
    • 猿猴从错误中学习
    • 猿猴击中目标
    • 猿猴扔得更远
    • 懒惰的猿猴
    • 丛林起风了
    • 猿猴了解丛林法则
    • 两秒之间,事情发生了
  • 奇闻趣事
    • 诅咒之火或 #define 黑魔法
    • 门多西诺电机与恩绍定理