顶点属性除数不适用于实例化渲染
Vertex Attrib Divisor not Working for Instanced Rendering
我有这段代码可以设置用于渲染的顶点属性指针:
glBindBuffer(GL_ARRAY_BUFFER, renderer->instancesBuffer);
enableFloatVertexAttribute(attributePosition, 2, sizeof(struct surfaceInstance), 0, 1);
enableFloatVertexAttribute(attributeSize, 2, sizeof(struct surfaceInstance), (void*) (2 * sizeof(float)), 1);
enableFloatVertexAttribute(attributeAngle, 1, sizeof(struct surfaceInstance), (void*) (4 * sizeof(float)), 1);
enableFloatVertexAttribute(attributeIdentifier, 1, sizeof(struct surfaceInstance), (void*) (5 * sizeof(float)), 1);
enableFloatVertexAttribute(attributeAtlasOffset, 2, sizeof(struct surfaceInstance), (void*) (6 * sizeof(float)), 1);
enableFloatVertexAttribute(attributeTextureSize, 2, sizeof(struct surfaceInstance), (void*) (8 * sizeof(float)), 1);
...
void enableFloatVertexAttribute(int32_t attribute, uint32_t size, uint32_t stride, void const *offset, uint32_t divisor) {
glEnableVertexAttribArray(attribute);
glVertexAttribPointer(attribute, size, GL_FLOAT, stride, GL_FALSE, offset);
if(divisor != 0) glVertexAttribDivisor(attribute, divisor);
}
...
layout(location = 0) in vec2 vertex;
layout(location = 1) in vec2 position;
layout(location = 2) in vec2 size;
layout(location = 3) in float angle;
layout(location = 4) in float identifierPass;
layout(location = 5) in vec2 atlasOffset;
layout(location = 6) in vec2 textureSize;
设置缓冲区的属性如下:
这是通过调用创建的:
surfaceRendererAppendSurface(renderer, 100, 100, 48, 48, glfwTime, 1);
surfaceRendererAppendSurface(renderer, 200, 100, 48, 48, glfwTime, 1);
如您所见,数据已正确发送到 GPU,第一个实例已正确绘制,GPU 正在绘制足够数量的实例,但是当我分析我的应用程序时,第二个、第三个或第四个实例完全错误,根本不遵循提供的缓冲区...这让我相信这是除法的问题,更奇怪的是,当我将除数切换为 2 时,第二个实例绘制得很好,并且然后是3,第三个画对了。。。很奇怪,不知道怎么回事。。。
例证:实例 1 = 完美复制!
Instance = 到底发生了什么???
(现在看...好像vertexAttribDivisor没有效果!)
(Looking at it right now... it looks like vertexAttribDivisor had no effect!)
对我来说,您的 stride
似乎完全关闭了。瞧,你交换了函数参数:
glVertexAttribPointer(attribute, size, GL_FLOAT, stride, GL_FALSE, offset);
^^^^^^^^ this is actually what you set as stride
由于 GL_FALSE
为 0,并且 GL 将 stride 0 解释为紧密排列的数组,因此屏幕截图中的数据非常有意义。
我有这段代码可以设置用于渲染的顶点属性指针:
glBindBuffer(GL_ARRAY_BUFFER, renderer->instancesBuffer);
enableFloatVertexAttribute(attributePosition, 2, sizeof(struct surfaceInstance), 0, 1);
enableFloatVertexAttribute(attributeSize, 2, sizeof(struct surfaceInstance), (void*) (2 * sizeof(float)), 1);
enableFloatVertexAttribute(attributeAngle, 1, sizeof(struct surfaceInstance), (void*) (4 * sizeof(float)), 1);
enableFloatVertexAttribute(attributeIdentifier, 1, sizeof(struct surfaceInstance), (void*) (5 * sizeof(float)), 1);
enableFloatVertexAttribute(attributeAtlasOffset, 2, sizeof(struct surfaceInstance), (void*) (6 * sizeof(float)), 1);
enableFloatVertexAttribute(attributeTextureSize, 2, sizeof(struct surfaceInstance), (void*) (8 * sizeof(float)), 1);
...
void enableFloatVertexAttribute(int32_t attribute, uint32_t size, uint32_t stride, void const *offset, uint32_t divisor) {
glEnableVertexAttribArray(attribute);
glVertexAttribPointer(attribute, size, GL_FLOAT, stride, GL_FALSE, offset);
if(divisor != 0) glVertexAttribDivisor(attribute, divisor);
}
...
layout(location = 0) in vec2 vertex;
layout(location = 1) in vec2 position;
layout(location = 2) in vec2 size;
layout(location = 3) in float angle;
layout(location = 4) in float identifierPass;
layout(location = 5) in vec2 atlasOffset;
layout(location = 6) in vec2 textureSize;
设置缓冲区的属性如下:
这是通过调用创建的:
surfaceRendererAppendSurface(renderer, 100, 100, 48, 48, glfwTime, 1);
surfaceRendererAppendSurface(renderer, 200, 100, 48, 48, glfwTime, 1);
如您所见,数据已正确发送到 GPU,第一个实例已正确绘制,GPU 正在绘制足够数量的实例,但是当我分析我的应用程序时,第二个、第三个或第四个实例完全错误,根本不遵循提供的缓冲区...这让我相信这是除法的问题,更奇怪的是,当我将除数切换为 2 时,第二个实例绘制得很好,并且然后是3,第三个画对了。。。很奇怪,不知道怎么回事。。。
例证:实例 1 = 完美复制!
Instance = 到底发生了什么???
(现在看...好像vertexAttribDivisor没有效果!)
(Looking at it right now... it looks like vertexAttribDivisor had no effect!)
对我来说,您的 stride
似乎完全关闭了。瞧,你交换了函数参数:
glVertexAttribPointer(attribute, size, GL_FLOAT, stride, GL_FALSE, offset); ^^^^^^^^ this is actually what you set as stride
由于 GL_FALSE
为 0,并且 GL 将 stride 0 解释为紧密排列的数组,因此屏幕截图中的数据非常有意义。