OpenGL纹理用法

时间:2015-05-18 13:08:28

标签: c++ opengl

Picture

最近我开始阅读OpenGL维基文章。这就是我从here描述OpenGL纹理的方式。虽然,有几点尚不清楚。

以下陈述是真的,假的还是取决于?

  1. 将两个纹理绑定到相同的纹理单元是不可能的。
  2. 将两个采样器绑定到相同的纹理单元是不可能的。
  3. 将一个纹理绑定到两个不同的纹理单元是不可能的。
  4. 将一个采样器绑定到两个不同的纹理单元是不可能的。
  5. 明确将采样器类型传递给哪个统一变量是应用程序的责任。
  6. 着色程序有责任确保将采样器作为正确的统一变量类型。
  7. 纹理单元的数量足够大。让每个加载到应用程序的网格占用尽可能多的纹理单元。
  8. 某些Sampler参数与纹理参数重复。它们将覆盖纹理参数设置。
  9. 某些Sampler参数与着色器程序中的采样器描述重复。着色器程序的描述将覆盖采样器参数。

1 个答案:

答案 0 :(得分:3)

我将在下面介绍您的陈述。有时我会争论OpenGL 4.5 core profile specification的引用。这些都不是GL 4.5特有的,我只是选择它,因为那是最新的版本。

  

<强> 1。将两个纹理绑定到相同的纹理单元是   不可能的。

如果我说&#34;假&#34;,那可能会产生误导。确切的说法是&#34;将两个纹理绑定到同一纹理单元的同一目标是不可能的。&#34;从技术上讲,您可以说,将2D纹理和3D纹理绑定到同一个单元。但是你不能在同一个绘图调用中使用。请注意,这是一个动态错误条件,取决于您设置采样器制服的值。引自第7.10节和第34节;采样器&#34; GL规范:

  

不允许使用不同采样器类型的变量   指向程序对象中的相同纹理图像单元。这个   只能在下一个发出的渲染命令中检测到情况   它会触发着色器调用,并会出现INVALID_OPERATION错误   然后生成。

因此,当您实际尝试使用该着色器绘制某些内容(或以其他方式触发着色器调用)时,GL将检测此错误情况,同时配置它以使两个采样器制服引用同一单元的不同目标。但这不是一个错误。如果您暂时将两个制服设置为相同的值但不尝试绘制该状态,则不会生成任何错误。

  

<强> 2。将两个采样器绑定到相同的纹理单元是不可能的。

你可能意味着Sampler Objects(而不仅仅是&#34;采样器&#34; GLSL中的类型),所以这是真的。

  

第3。将一个纹理绑定到两个不同的纹理单元是不可能的。

假。您可以将相同的纹理对象绑定到可用的单元数。然而,这是一个非常无用的操作。在固定功能管道的时代,有一些极端情况,这是有限的使用。例如,我看到有人将相同的纹理绑定两次并使用寄存器组合器将两者相乘,因为他需要一些方形操作。但是,使用着色器,您可以对纹理进行一次采样并对结果执行任何操作,因此实际上没有任何用例。

  

<强> 4。将一个采样器绑定到两个不同的纹理单元是不可能的。

假。单个采样器对象可以由多个纹理单元引用。您可以为所需的每个采样状态创建一个采样器对象,而无需创建冗余采样状态。

  

<强> 5。应用程序有责任明确将采样器类型传递给哪个统一变量。

     

<强> 6。着色程序的责任是确保将采样器作为正确的均匀变量类型。

我不确定你在这里问的是什么。着色器中的sampler变量选择纹理目标,并且还必须匹配要使用的纹理对象的内部数据(即isamplerusampler,您需要非标准化的整数纹理格式,否则结果是未定义的。)

但我不知道&#34;什么样的采样器类型被传递给什么样的统一变量&#34;应该在这里意味着什么。就GL客户端而言,不透明的采样器制服只是可以设置为要使用的纹理单元的索引的东西,并且可以通过glUniform1i之类的整数来完成。 。没有&#34;采样器类型&#34;传递给统一变量。

  

<强> 7。纹理单元的数量足够大。让加载到应用程序的每个网格占用尽可能多的纹理单元。

不是一般情况。 GL 4.5规范要求的GL_MAX_TEXTURE_IMAGE_UNITS(定义片段着色器可以访问多少个不同的纹理单元)只有16个。(每个shder阶段有单独的限制,因此有GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,{{ 1}}等等。在当前规范中,它们都必须至少为16。)

通常,您必须在绘制调用之间切换纹理。 array texturestexture atlasses的使用可能允许进一步减少必要状态切换的数量(并最终减少绘制调用)。

非常现代的GPU也支持GL_ARB_bindless_texture,它完全绕过&#34;纹理单元&#34;间接层,允许着色器通过一些不透明的句柄直接引用纹理对象(基本上归结为在引擎盖下引用一些虚拟GPU内存地址)。但是,该功能尚未成为OpenGL标准的一部分。

  

<强> 8。一些Sampler参数是纹理参数的副本。它们将覆盖纹理参数设置。

是。传统上,GL中没有单独的采样器对象。相反,采样器状态如过滤或包裹模式是纹理对象本身的一部分。但现代硬件不以这种方式运行,因此采样器对象API已作为GL_ARB_sampler_objects扩展引入(现在是GL的核心功能)。如果采样器对象绑定到纹理单元,则其设置将覆盖纹理对象中存在的采样器状态。

  

<强> 9。某些Sampler参数与着色器程序中的采样器描述重复。着色器程序的描述将覆盖采样器参数。

我不确定你的意思。什么&#34;采样器描述&#34;着色器程序定义了什么?通过GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS只有统一的声明和可能的初始化。但是,这只是初始值。客户端可以通过将制服设置为另一个值来随时更新,因此实际上并不是'#34;覆盖&#34;任何东西。但我不确定你的意思。