假设我只想渲染四边形并且可以重复使用我的网格,我希望能够在一次绘制调用中渲染许多实例。
我想通过将转换矩阵放入缓冲区来实现纹理缓冲区对象。
我理解如何在C ++中设置纹理缓冲区对象,但我对如何在GLSL中从中获取转换感到困惑。
uniform samplerBuffer sampler;
...
... = texelFetch( sampler, index );
在上面的代码中(在顶点着色器中)我不确定samplerBuffer
关键字是如何工作的(并且在查找文档时遇到了很多麻烦)。我想知道给定顶点与纹理缓冲区中的哪个索引相关联,这样就可以进行转换查找。我怎么能这样做,GLSL语法是什么样的?
可以假设变换矩阵是4×4矩阵。我希望能够将OpenGL版本要求保持在2.XX范围内。
编辑:所以我发现了这个:http://www.opengl.org/registry/specs/ARB/draw_instanced.txt。我可以处理3.0限制。但是当我查找如何使用它的示例时,我会感到困惑。使用GLEW,我想我会调用glDrawElementsInstanced,但互联网上的一些地方说这需要OpenGL 3.3或更高版本。我如何利用我链接的3.0要求?
答案 0 :(得分:3)
嗯,缓冲区纹理本质上是存储在缓冲区对象(TEXTURE_BUFFER
)数据存储中的一维数据数组。您提供一个整数,它本质上是缓冲区的偏移量,并从该偏移量开始从texelFetch
获取单个纹素。偏移始终指的是纹素,而不是指纹素的单个分量(例如R
- vec4
的分量)。因此,如果使用内部格式GL_R
设置缓冲区纹理,则会查找仅存储单个值的单个纹理元素 - 但是,如果您使用GL_RGBA
,则纹理元素将包含四个组成部分。
例如,假设您选择将带有RGBA
组件的两个规范化颜色向量放入数据存储区,选择内部格式GL_RGBA
并使用0和1索引,您将获得第一个和缓冲区纹理中的第二个纹素,根据核心OpenGL 4.4规范的第8.9节:
[..]附加缓冲区对象的数据存储被解释为与 internalformat 对应的GL数据类型的元素数组。每个纹素由一到四个元素组成,这些元素映射到纹理组件(R,G,B和A)。
请注意,texelFetch
将总是返回gvec4
,即ivec4
,uivec4
或vec4
,具体取决于内部格式。如果您选择的内部格式指定少于四个组件,例如GL_R32F
,结果将是非标准化(< - 这很重要!)vec4(R, 0, 0, 1)
- 其余GB
个组件设置为零,A
设置为1.请参阅上述规范的表8.15 以获取完整概述。
另请注意,texelFetch
不执行任何过滤或LOD钳位。
答案 1 :(得分:2)
texelFetch的所有版本都返回gvec4,因此我假设你应该执行4次查找,每行1次。但这取决于你对矩阵的编码方式。
uniform samplerBuffer sampler;
...
mat4 transform( texelFetch( sampler, RowIndex0 ), texelFetch( sampler, RowIndex1 ), texelFetch( sampler, RowIndex2 ), texelFetch( sampler, RowIndex3 ) );
请记住,GLSL中的mat4
会在构造函数中使用列,因此如果您使用的是基于列的矩阵,则需要转置它。