如何使用 bindless 指定 UBO 绑定?
Posted
技术标签:
【中文标题】如何使用 bindless 指定 UBO 绑定?【英文标题】:How to specify UBO binding with bindless? 【发布时间】:2016-11-01 00:43:04 【问题描述】:我用 vec4 colorA's 和 colorB's 像这样创建了 2+ 个简单的 UBO。使用 std140 的不必要复杂的 UBO 创建/绑定过程,我只会得到黑屏。如何在使用 glCreate 时指定哪个索引并让这个混乱工作,以便我可以选择 colorA 或 colorB?
//APP
glCreateBuffers(1, &testUBO);
glNamedBufferData(testUBO, sizeof(glm::vec4), 0, GL_DYNAMIC_DRAW);
glGetNamedBufferParameterui64vNV(testUBO, GL_BUFFER_GPU_ADDRESS_NV, &uboScene_64);
glMakeNamedBufferResidentNV(testUBO, GL_READ_ONLY);
glm::vec4 myVec4 = glm::vec4(0.f, 1.f, 0.f, 1.f); //add to structs.h
glNamedBufferSubData(testUBO, 0, sizeof(glm::vec4), &myVec4
//SHARED HEADER
typedef glm::vec4 vec4;
layout(std140, binding = 0) uniform sceneBuffer
vec4 colorA;
;
layout(std140, binding = 1) uniform objectBuffer
vec4 colorB;
;
//SHADER PROGRAM
void main()
Ci = colorA;
Ci = colorB;
【问题讨论】:
【参考方案1】:鉴于此着色器:
//GLSL
layout(std140, binding = 0) uniform sceneBuffer
vec4 colorA;
;
layout(std140, binding = 1) uniform objectBuffer
vec4 colorB;
;
还有这个 C++ 缓冲区初始化代码:
//Create scene buffer.
glCreateBuffers(1, &sceneUbo);
glNamedBufferStorage(sceneUbo, sizeof(glm::vec4), 0, GL_DYNAMIC_STORAGE_BIT);
glm::vec4 myVec4 = glm::vec4(0.f, 1.f, 0.f, 1.f);
glNamedBufferSubData(sceneUbo, 0, sizeof(glm::vec4), &myVec4);
//Create object buffer
glCreateBuffers(1, &objectUbo);
glNamedBufferStorage(objectUbo, sizeof(glm::vec4), 0, GL_DYNAMIC_STORAGE_BIT);
glm::vec4 myVec4 = glm::vec4(0.f, 1.f, 0.f, 1.f);
glNamedBufferSubData(objectUbo, 0, sizeof(glm::vec4), &myVec4);
NV_uniform_buffer_unified_memory
“bindless”代码如下所示:
//Get addresses
GLuint64 sceneUboAddr;
glGetNamedBufferParameterui64vNV(sceneUbo, GL_BUFFER_GPU_ADDRESS_NV, &sceneUboAddr);
glMakeNamedBufferResidentNV(sceneUbo, GL_READ_ONLY);
GLuint64 objectUboAddr;
glGetNamedBufferParameterui64vNV(objectUbo, GL_BUFFER_GPU_ADDRESS_NV, &objectUboAddr);
glMakeNamedBufferResidentNV(objectUbo, GL_READ_ONLY);
//You have to call this to turn on bindless buffers.
glEnableClientState(UNIFORM_BUFFER_UNIFIED_NV);
//0 represents the scene UBO's `binding` from GLSL:
glBufferAddressRangeNV(UNIFORM_BUFFER_ADDRESS_NV, 0, sceneUboAddr, sizeof(glm::vec4));
//1 represents the object UBO's `binding` from GLSL:
glBufferAddressRangeNV(UNIFORM_BUFFER_ADDRESS_NV, 1, objectUboAddr, sizeof(glm::vec4));
请注意,此扩展实际上需要glEnable/DisableClientState
,这是一个从核心配置文件中删除的函数。所以你需要使用兼容性配置文件来使用它。
为了证明非绑定代码几乎不是“不必要的复杂”,这里是:
//The first 0 represents the scene UBO's `binding` from GLSL:
glBindBufferRange(GL_UNIFORM_BUFFER, 0, sceneUbo, 0, sizeof(glm::vec4));
//1 represents the object UBO's `binding` from GLSL:
glBindBufferRange(GL_UNIFORM_BUFFER, 1, objectUbo, 0, sizeof(glm::vec4));
【讨论】:
谢谢,错过了对glBufferAddressRangeNV
的调用以上是关于如何使用 bindless 指定 UBO 绑定?的主要内容,如果未能解决你的问题,请参考以下文章
OpenGL Bindless Texture 函数 glMakeTextureHandleNonResident 究竟做了啥?
Angular Component:如何为父级中定义的输出绑定函数指定值?
OpenGL - 在没有 NV_gpu_shader5 的情况下访问 glMultiDrawElementsIndirect 内的无绑定纹理