| 系统 | API | 作用 |
|---|---|---|
| 纹理采样系统 | glActiveTexture + glBindTexture | Shader 里 sampler2D 用 |
| 帧缓冲系统 | glBindFramebuffer + glFramebufferTexture2D | 决定渲染往哪画 |
| 纹理对象管理 | glGenTextures + glBindTexture | 配置/上传纹理属性数据 |
三种纹理 一种是上传到GPU的数据,一种是Fbo的渲染对象,一种是属性
OpenGL 有 多个 Texture Unit(纹理单元)
比如:
1 | GL_TEXTURE0 |
每个 Texture Unit 里, 才有 它自己的 GL_TEXTURE_2D 绑定槽位:
1 | Texture Unit 0 : 绑定一个 GL_TEXTURE_2D |
1 | glActiveTexture(GL_TEXTURE0); |
意思是:
“把 texture 绑定给 Texture Unit 0 的 GL_TEXTURE_2D 槽”
Pipeline 用纹理时 不是看“当前 GL_TEXTURE_2D 指向谁” 而是:
Shader 的 sampler2D —— 指向哪个 Texture Unit Texture Unit —— 绑定哪个 GL_TEXTURE_2D 纹理对象
它跟 FBO 是完全独立的系统
FBO 有自己的:
1 | GL_COLOR_ATTACHMENT0 = renderTexture |
跟 Texture Units 完全不冲突, 跟
glBindTexture(GL_TEXTURE_2D …) 也不冲突。
不是只有一个 GL_TEXTURE_2D 指针。 每个 Texture Unit 都有一个 GL_TEXTURE_2D 绑定指针, Shader 用的是 Texture Unit, 不是“当前唯一 GL_TEXTURE_2D”。
而:
- Texture Unit 系统 —— 负责 采样
- FBO 系统 —— 负责 渲染输出
- Unbind 只是把某个 Texture Unit 的绑定清掉 ✔ 数据仍然在 GPU ✔ 其它 Unit / FBO 完全不受影响
如果没有调用 glActiveTexture(...),那么
glBindTexture(GL_TEXTURE_2D, …)
绑定的是当前“活动纹理单元(Active Texture Unit)”,而 OpenGL
默认的活动单元就是 GL_TEXTURE0。
Shader 怎么知道用哪个 Texture Unit?取决于 uniform:
1 | // 表示: |
它必须被设置:
1 | glUniform1i(location, 0); |
表示:
1 | u_texture 使用 Texture Unit 0 |
任何时刻,Active Texture Unit 只有 1 个,渲染时可用 Texture Unit
可以很多个,Shader 能同时采样多少,取决于
GL_MAX_TEXTURE_IMAGE_UNITS,glBindTexture 只影响当前 Active
Unit
GPU Pipeline 其实同时有很多个 Texture Unit,比如:
1 | GL_TEXTURE0 |
你可以:
1 | glActiveTexture(GL_TEXTURE0); |
然后在 shader 里同时用:
1 | vec4 a = texture(u_tex0, uv); |
👉 Pipeline 同时使用 texA + texB,没有任何问题。 并不是只有一个 unit 被“激活”在工作。
FBO = OpenGL 内部“渲染目标对象” WindowSurface = 用来“显示到屏幕”的表面 PBuffer = EGL 早期的“离屏 Surface”,现在多数被 FBO 取代