我正在研究使用无绑定纹理来快速显示一系列图像。我的参考是OpenGL 4.5红皮书。这本书说我可以使用这个片段着色器在着色器中对无绑定纹理进行采样:
#version 450 core
#extension GL_ARB_bindless_texture : require
in FS_INPUTS {
vec2 i_texcoord;
flat int i_texindex;
};
layout (binding = 0) uniform ALL_TEXTURES {
sampler2D fs_textures[200];
};
out vec4 color;
void main(void) {
color = texture(fs_textures[i_texindex], i_texcoord);
};
我创建了一个顶点着色器,如下所示:
#version 450 core
in vec2 vert;
in vec2 texcoord;
uniform int texindex;
out FS_INPUTS {
vec2 i_texcoord;
flat int i_texindex;
} tex_data;
void main(void) {
tex_data.i_texcoord = texcoord;
tex_data.i_texindex = texindex;
gl_Position = vec4(vert.x, vert.y, 0.0, 1.0);
};
正如你可能注意到的,我对发生的事情的把握有点弱。
在我的OpenGL代码中,我创建了一组纹理,获取它们的句柄,并使它们常驻。我用来获取纹理句柄的函数是“glGetTextureHandleARB”。还有另一个可以替代的函数“glGetTextureSamplerHandleARB”,我可以在其中传递一个采样器位置。以下是我所做的:
Texture* textures = new Texture[load_limit];
GLuint64* tex_handles = new GLuint64[load_limit];
for (int i=0; i<load_limit; ++i)
{
textures[i].bind();
textures[i].data(new CvImageFile(image_names[i]));
tex_handles[i] = glGetTextureHandleARB(textures[i].id());
glMakeTextureHandleResidentARB(tex_handles[i]);
textures[i].unbind();
}
我的问题是如何将我的纹理句柄绑定到片段着色器的ALL_TEXTURES统一属性?此外,我应该使用什么来更新顶点属性“texindex”——我的纹理句柄数组或纹理句柄的实际索引?
这是无绑定纹理。你不会将这样的纹理“绑定”到任何东西上。
在无粘合剂纹理中,采样器的数据值是一个数字。具体来说,glGetTextureHandleARB
返回的数字。纹理句柄是64位无符号整数。
在着色器中,缓冲区支持的接口块(UBO和SSBO)中的采样器
类型的值是64位无符号整数。因此采样器数组在结构上等价于64位无符号整数数组。
因此,在C中,与所有_纹理
块等效的结构应该是:
struct AllTextures
{
GLuint64 textures[200];
};
当然,假设你正确使用了std140。否则,您必须查询结构的布局。
此时,您将缓冲区视为与任何其他UBO用法没有什么不同。通过将AllTexas
粘贴到缓冲区对象中来构建着色器的数据,然后将该缓冲区作为UBO绑定到绑定0。您只需要用实际的纹理句柄填充数组。
此外,我应该使用什么来更新顶点属性“texindex”——纹理句柄数组或纹理句柄中的实际索引?
嗯,两个都不行。不是你写的方式。
看,ARB_bindless_texture不允许您在任何时候从任何着色器调用以任何方式访问您想要的任何纹理。除非您使用NV_gpu_shader5,否则导致纹理访问的代码必须基于动态统一的表达式。
因此,除非渲染命令中的每个顶点都获得相同的索引或句柄......否则您无法使用它们来选择要使用的纹理。即使实例化也救不了你,因为动态统一表达式不关心实例化。
如果您想渲染一组四边形,而不必在它们之间更换制服(也不必依赖NVIDIA扩展),那么您有几个选项。大多数支持无绑定纹理的硬件也支持ARB_shader_draw_参数。这使您可以访问gl_DrawID
,它表示glMultiDraw
样式命令中渲染命令的当前索引。该扩展明确声明,gl_DrawID
是动态统一的。
所以你可以用它来选择要渲染的纹理。只需发出“多重绘制”命令,反复渲染相同的网格数据,但在每种情况下都会得到不同的gl_DrawID
索引。
我正在尝试将多个纹理绑定到片段着色器中的采样器。加载代码似乎运行良好。ATI的CodeXL显示正确加载的纹理。 但是,当我将模型的纹理绑定到活动纹理0和1时,我无法让它将值发送到我的着色器。当我将着色器统一标记为usampler2D并使用uvec4存储颜色时,就像我应该做的那样,因为我的纹理是以无符号字节提供的,我得到了一个全白色的模型。当我将着色器统一更改为sampler2D并使用vec4存储颜
我对如何将纹理绑定到GLSL中的插槽有点困惑。以下是我的着色器: 当我设置矩阵时,我需要查询统一位置,然后手动设置该位置的值,执行如下操作: 然而,据我所知,我不需要这样做来初始化我的纹理采样器。在设置时,我似乎只需要这样做: 所以,我的问题是,为什么我不需要对纹理进行与矩阵相同的处理?OpenGL运行时如何“知道”我绑定的纹理应该是我定义的采样器?如果我想拥有多种纹理,我该怎么做呢?
在我的程序中,我使用了2种纹理:t0和t1。t1是附加的,仅在某些情况下需要: 绘图着色器: 它的工作原理很好:第二个纹理在需要时首先重叠。假设使用glBindTexture(..,0)返回零纹理(0,0,0,0),但在将NVidia驱动程序更新到314.07后,我的代码会出现黑屏,比如glBindTexture(..,0)返回(0,0,0,1)纹理。 我做了一些测试:使用着色器 我在旧驱动程序(
我是OpenGL的新手,在整理如何将纹理和着色器绑定到VBOs时遇到了困难。 我正在使用Cinder的纹理和着色器类。以下是我绘制方法的一部分: 在上面的代码中,如果我注释掉对mShader的调用。bind(),我的球体VBO将显示纹理(myImage)。我的着色器适用于普通(无纹理)形状,但当我在绘制任何带有包裹纹理的形状之前绑定着色器时,它会阻止纹理显示。 这是我使用的着色器的问题,还是我不理
我有一个用于OpenGL中模型渲染的纹理数组。此数组包含漫反射和镜面纹理。由于某些网格没有镜面纹理,因此我在每次渲染后简单地将NULL纹理绑定到我的镜面采样器,并且只有当网格具有镜面纹理时,我才绑定一个。但是,我仍然在没有镜面纹理的网格上看到镜面纹理。 这是我的渲染代码 材质索引保存数组中纹理的索引,如果网格没有镜面纹理 索引为-1 纹理单元0用于漫反射 纹理单元2用于镜面
OpenGL标准是否要求应该给一个程序没有绑定到纹理单元的统一采样器2D给出一个texture 2d操作的结果? 例如在像素着色器中: 在该计划中: 对于上下文,我想知道是否可以对纹理实体和非纹理实体使用相同的着色器,其中(希望如此),我只需要确保没有任何东西绑定到GL_TEXTURE_2D,以便texture2d()返回0,0,0,1。否则,我需要为每个置换使用一个着色器。