OpenGL ES 3 (iOS) 纹理奇特 - 想知道为什么
OpenGL ES 3 (iOS) texturing oddness - want to know why
我有一个正常运行的OpenGL ES 3程序(iOS(,但我很难理解OpenGL纹理。 我正在尝试将几个四边形渲染到屏幕上,所有四边形都有不同的纹理。 纹理都是 256 张带有调色板的彩色图像。
这是将纹理发送到着色器C++代码
// THIS CODE WORKS, BUT I'M NOT SURE WHY
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, _renderQueue[idx]->TextureId);
glUniform1i(_glShaderTexture, 1); // what does the 1 mean here
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, _renderQueue[idx]->PaletteId);
glUniform1i(_glShaderPalette, 2); // what does the 2 mean here?
glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0);
这是片段着色器
uniform sampler2D texture; // New
uniform sampler2D palette; // A palette of 256 colors
varying highp vec2 texCoordOut;
void main()
{
highp vec4 palIndex = texture2D(texture, texCoordOut);
gl_FragColor = texture2D(palette, palIndex.xy);
}
正如我所说,代码有效,但我不确定它为什么有效。 几个看似微小的变化打破了它。 例如,在C++代码中使用 GL_TEXTURE0
和 GL_TEXTURE1
会破坏它。 将 glUniform1i
中的数字更改为 0,1 会中断它。 我猜我不了解OpenGL 3+(也许是纹理单位???(中的纹理,但需要一些指导来弄清楚是什么。
由于它经常让新的OpenGL程序员感到困惑,我将尝试在非常基本的层面上解释纹理单元的概念。一旦你学会了术语,它就不是一个复杂的概念。
整个事情的动机是提供在着色器中采样多个纹理的可能性。由于 OpenGL 传统上对绑定glBind*()
调用的对象进行操作,这意味着需要绑定多个纹理的选项。因此,具有一个绑定纹理的概念扩展到具有绑定纹理表。OpenGL所说的纹理单元是此表中的一个条目,由索引指定。
如果要用 C/C++ 样式表示法描述此状态,可以将绑定纹理表定义为纹理 ID 数组,其中大小是实现支持的最大绑定纹理数(使用 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, ...)
查询(:
GLuint BoundTextureIds[MAX_TEXTURE_UNITS];
如果绑定纹理,它将绑定到当前活动的纹理单元。这意味着对glActiveTexture()
的最后一次调用决定了修改绑定纹理表中的哪个条目。在将纹理绑定到纹理单元的典型调用序列中i
:
glActiveTexture(GL_TEXTUREi);
glBindTexture(GL_TEXTURE_2D, texId);
这相当于通过以下方式修改我们的虚构数据结构:
BoundTextureIds[i] = texId;
这涵盖了设置。现在,着色器可以访问此表中的所有纹理。类型 sampler2D
的变量用于访问 GLSL 代码中的纹理。要确定每个变量访问sampler2D
纹理,我们需要指定每个变量使用的表条目。这是通过将统一值设置为表索引来完成的:
glUniform1i(samplerLoc, i);
指定采样器在位置均匀samplerLoc
从表条目i
读取,这意味着它使用 id BoundTextureIds[i]
对纹理进行采样。
在问题的特定情况下,第一个纹理绑定到纹理单元 1,因为glActiveTexture(GL_TEXTURE1)
是在 glBindTexture()
之前调用的。要从着色器访问此纹理,着色器制服也需要设置为 1。第二个纹理也是如此,纹理单元为 2。
(上面的描述略有简化,因为它没有考虑不同的纹理目标。实际上,具有不同目标的纹理,例如 GL_TEXTURE_2D
和GL_TEXTURE_3D
,可以绑定到同一个纹理单元。
GL_TEXTURE1和GL_TEXTURE2指的是纹理单位。 glUniform1i 为采样器的第二个参数获取纹理单元 ID。这就是为什么它们是 1 和 2。
从OpenGL网站:
程序中采样器制服的值不是纹理对象, 而是纹理图像单位索引。因此,您设置了纹理单位索引 程序中的每个采样器。
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- 我想知道长双倍和双倍之间的区别
- 有人知道为什么在开关中使用stoi函数会返回恒定的错误吗
- 我是 C++ 的初学者,我想知道如何在 2D 矢量中获取重复值
- C++新手,想知道如何使用VS code 2019播放音频文件
- 可能我知道为什么这段代码没有给出任何输出吗?
- 我不知道为什么这段代码会让核心被转储?
- 有谁知道为什么会这样?C++"正在初始化":无法从
- 反转字符串.不知道为什么这个逻辑是错误的.C++
- 我是C++新手,我想知道,为什么在c ++中使用纯虚函数?为什么要使用纯虚函数?
- 我想知道为什么"std::unique_ptr<int> foo(新 int)"是合法的,因为"std::<int>unique_ptr"要求输入参数类型应该是"int"?
- 没有函数模板的实例与我不知道为什么的参数列表匹配
- if-else 语句仅按特定顺序工作,我不知道为什么
- DirectX 11 引擎在第三次代码改进后没有突然运行,我不知道为什么
- VS为我提供了对构造函数的另一个解决方案,但我想知道为什么我的工作不起作用
- 想知道为什么我不能只捕获协程的 asio::handler_type 的引用
- 我想知道为什么Asset_manager(Android NDK)没有界面目录的接口
- OpenGL ES 3 (iOS) 纹理奇特 - 想知道为什么
- 想知道我为什么会有隔离故障
- 几个模板问题(已经解决了…只是想知道为什么)