Skip to content

zuoco/learn-opengl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

learn-opengl-slint

一个从零开始构建的 C++ 软件光栅化渲染器(Software Renderer / CPU Rasterizer),模拟类似 OpenGL ES 的 GPU 图形管线。本项目包含 23 个循序渐进的章节,从基础窗口创建逐步推进到 3D 模型加载、光照计算和相机系统。


项目特点

  • 纯 CPU 渲染:不依赖 OpenGL、DirectX、Vulkan 等任何硬件图形 API
  • 模拟 OpenGL 风格 API:VAO、VBO、EBO、Shader、Texture、FrameBuffer
  • 完整图形管线:顶点着色 → 裁剪 → 透视除法 → 背面剔除 → 屏幕映射 → 光栅化 → 片元着色 → 深度测试 → 混合
  • 跨平台 UI:使用 Slint UI 框架作为窗口和显示层
  • 自研数学库:向量、矩阵、变换函数等基础数学工具
  • 循序渐进:23 个独立章节,每章聚焦一个核心图形学概念

技术栈

层级 技术
语言 C++17
构建系统 CMake
目标平台 Linux (x86_64)
UI 框架 Slint C++ SDK v1.15.1
数学库 项目内自建 header-only 库
图像加载 stb_image.h
模型加载 Assimp (第 23 章)

章节概览

章节 目录 内容
01 01-窗口 基础窗口与 Slint 集成
02 02-视口 视口与帧缓冲概念
03 03-直线光栅化 Bresenham 直线算法
04 04-向量计算 向量数学库
05 05-三角形光栅化-颜色插值 三角形光栅化与颜色插值
06 06-混合-透明度 Alpha 混合
07 07-纹理 纹理映射
08 08-最临近插值-双线性插值 纹理过滤
09 09-纹理寻址 纹理环绕模式
10 10-矩阵 矩阵数学
11 11-空间变换 3D 空间变换
12 12-顶点对象 顶点数组/缓冲区对象抽象
13 13-数据重构 数据结构重构
14 14-绘制管线 绘制管线
15 15-裁剪 视锥体裁剪
16 16-透视校正 透视校正插值
17 17-面剔除 背面剔除
18 18-深度测试 深度测试(Z-Buffer)
19 19-混合 混合管线完善
20 20-高级纹理 高级纹理
21 21-相机 相机系统
22 22-光照 光照计算
23 23-模型 模型加载(Assimp)

知识点总结

本项目循序渐进地覆盖了计算机图形学从数学基础到完整渲染管线的核心知识,可分为数学基础图形学核心两大板块。

数学基础

知识点 对应章节 说明
向量代数 04-向量计算 向量表示、加减、标量乘、点乘(投影与夹角)、叉乘(法向量与方向判断)、归一化、长度计算
矩阵运算 10-矩阵 矩阵乘法、转置、逆矩阵、行列式;列主序存储方式
空间变换 11-空间变换 平移、旋转、缩放矩阵;模型矩阵(Model)、视图矩阵(View / lookAt)、投影矩阵(正交 / 透视);NDC 与视口变换;屏幕空间变换矩阵
插值与采样 05-三角形光栅化-颜色插值 08-最临近插值-双线性插值 16-透视校正 线性插值(Lerp);重心坐标插值;透视校正插值(Perspective-Correct Interpolation,对 1/w 插值后恢复属性);纹理采样中的最邻近插值与双线性插值
基础几何 04-向量计算 17-面剔除 平面法向量;利用叉积符号判断三角形朝向(顺时针 / 逆时针)

图形学核心

知识点 对应章节 说明
窗口与显示 01-窗口 02-视口 窗口系统集成、事件循环、帧缓冲(FrameBuffer)概念、视口(Viewport)变换
直线光栅化 03-直线光栅化 Bresenham 直线算法,利用整数步进高效绘制直线
三角形光栅化 05-三角形光栅化-颜色插值 三角形扫描线光栅化、边界方程、重心坐标计算、顶点属性插值
顶点数据管理 12-顶点对象 13-数据重构 模拟 OpenGL 的 VAO(顶点数组对象)、VBO(顶点缓冲对象)、EBO(索引缓冲对象);顶点属性描述(BindingDescription)与数据布局
纹理映射 07-纹理 08-最临近插值-双线性插值 09-纹理寻址 20-高级纹理 UV 坐标映射、二维纹理采样器、纹理过滤(Nearest / Bilinear)、纹理寻址模式(Repeat / Clamp / Mirror)
裁剪 15-裁剪 视锥体裁剪(Frustum Clipping)、Sutherland-Hodgman 多边形裁剪算法
透视除法 16-透视校正 齐次坐标除法(除以 w),从裁剪空间转换到 NDC(Normalized Device Coordinates)
背面剔除 17-面剔除 根据三角形法向量与视线方向的点积判断正面 / 背面;CULL_FACEFRONT_FACE 状态控制
深度测试 18-深度测试 Z-Buffer(深度缓冲)原理、深度值计算、深度比较函数(DEPTH_LESSDEPTH_EQUAL 等)
颜色混合 06-混合-透明度 19-混合 Alpha 混合原理、混合方程(SrcAlpha / OneMinusSrcAlpha)、预乘 Alpha、混合管线开关控制
着色器模型 14-绘制管线 22-光照 顶点着色器(Vertex Shader)与片元着色器(Fragment Shader);Uniform 变量;varying 插值数据;可编程 Shader 抽象基类
相机系统 21-相机 FPS 风格相机(WASD 移动 + 鼠标视角控制)、欧拉角(俯仰角 / 偏航角)、LookAt 矩阵、视图与投影矩阵分离管理
光照模型 22-光照 方向光、环境光(Ambient)、漫反射(Diffuse / Lambert)、镜面反射(Specular / Phong 与 Blinn-Phong)、法向量、半角向量(Halfway Vector)
模型加载 23-模型 使用 Assimp 加载层级 3D 模型、网格(Mesh)与材质、漫反射纹理、节点变换层级、多网格渲染

快速开始

依赖安装(Fedora/RHEL)

sudo dnf install cmake clang pkg-config ninja-build
sudo dnf install freetype-devel fontconfig-devel
sudo dnf install libinput-devel libxkbcommon-devel systemd-devel gbm-devel libseat-devel
sudo dnf install assimp-devel  # 仅第 23 章需要

构建与运行

每章都是独立的 CMake 工程,进入对应目录后构建:

cd 23-模型  # 或任意章节

cmake -B build -G Ninja
cmake --build build
./build/softRenderer

注意:早期章节(01~02)可能需要显式指定编译器为 Clang,并开启 SLINT_FEATURE_BACKEND_LINUXKMS 等选项。参考 编译.md 中的完整配置。


渲染管线

GPU::drawElement() 按以下顺序执行软件图形管线:

  1. 顶点着色 — 运行用户提供的 Shader::vertexShader()
  2. 裁剪 — 视锥体裁剪
  3. 透视除法 — 除以 w 得到 NDC
  4. 背面剔除 — 根据叉积符号剔除背面/正面
  5. 屏幕映射 — 将 NDC 转换为像素坐标
  6. 光栅化 — 生成逐片元数据
  7. 透视恢复 — 恢复被 w 除过的属性
  8. 片元着色 — 运行 Shader::fragmentShader()
  9. 深度测试 — 与深度缓冲比较
  10. 混合 — Alpha 混合
  11. 写入帧缓冲 — 将最终颜色写入颜色缓冲

项目结构(中后期章节示例)

<章节>/
├── CMakeLists.txt          # 根 CMake
├── main.cpp                # 程序入口
├── ui/
│   └── app-window.slint    # Slint UI 定义
├── application/            # 应用层(输入、相机、模型加载)
├── gpu/                    # 软件 GPU(渲染管线、着色器、光栅化)
├── math/                   # 自研数学库(header-only)
├── global/                 # 基础类型与常量
└── assets/                 # 运行时资源(纹理、模型)

编码规范

  • 类名:大写驼峰(GPU, FrameBuffer
  • 成员变量:m 前缀(mModelMatrix
  • 函数名:大写驼峰(initSurface, drawElement
  • 矩阵存储:列主序(Column-Major),与 OpenGL 一致
  • 单例:sglGPU::getInstance(), appApplication::getInstance()

许可证

本项目为学习/教学用途的图形学工程。

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors