I would like to render instanced geometry with a per-instance texture. To do so, I want to create a Vertex Attrib (that is consumed in a per-instance basis) containing the texture handler and create the sampler2D in the shader using the bindless_texture NVIDIA extension. I want to do so because the number of instances is dynamic and they are created an destroyed during runtime so I cannot allocate an statically allocated array of textureHandles as in the example in the extension specification.
//Create the textures and obtain the handles
foreach instance
glGenTextures(1, &this->gpuTextureId);
glBindTexture(GL_TEXTURE_2D, this->gpuTextureId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ResX, ResY, 0, GL_RGBA, GL_UNSIGNED_BYTE, info);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); // Linear Filtering
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); // Linear Filtering
// Get a handle for the texture.
this->gpuTextureHandlerId = glGetTextureHandleNV(this->gpuTextureId);
// Make the handle resident before using it.
glMakeTextureHandleResidentNV(this->gpuTextureHandlerId);
endfor
//Pass the handle to the buffer
#define INSTANCE_TEXTURE_LOCATION 6
glGenBuffers(1, &this->instanceTextureHandlerVboId);
glBindBuffer(this->instanceTextureHandlerVboId);
glEnableVertexAttribArray(INSTANCE_TEXTURE_LOCATION);
glVertexAttribPointer(INSTANCE_TEXTURE_LOCATION, 1, GL_UNSIGNED_INT64_NV, GL_FALSE, sizeof(GLuint64), 0);
glVertexAttribDivisor(INSTANCE_TEXTURE_LOCATION, 1);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLuint64) * this->numElements, instanceTextureHandle, GL_DYNAMIC_DRAW); //instanceTextureHandle contains the texture handles for all the instances.
As for the shader:
#version 430
#extension GL_NV_bindless_texture : require
#extension GL_NV_gpu_shader5 : require
in vec2 ex_textCoord;
layout(location = 6) in uint64_t in_textHandler;
out vec4 out_Color;
void main(void)
{
sampler2D s = sampler2D(in_textHandler);
out_Color = texture(s, ex_textCoord);
}
The problem is that I cannot send the 64-bit pointer to the shader. If it was a Uniform I could use “glUniformHandleui64NV(location, instanceTextureHandle[i]);” I use GL_UNSIGNED_INT64_NV or GL_DOUBLE in the glVertexAttribPointer without success.
Can it be done?
Thanks in advance.
Nicolau