我正在尝试按以下方式渲染 GL_POINTS:
struct OpenGLPointDData {
int transformIndex = -1;
float size = 40.0f;
glm::vec3 offset = glm::vec3(0.0f, 0.0f, 0.0f);
glm::vec4 color = glm::vec4(1.0f, 0.0f, 0.0f, 0.25f);
};
这是我将引用的代码:
顶点着色器:
// Vertex shader
#version 460 core
// Attributes
layout(location = 0) in int transformIndex;
layout(location = 1) in float size;
layout(location = 2) in vec3 offset;
layout(location = 3) in vec4 color;
// Uniforms
layout(location = 4) uniform mat4 uProjectionView;
// Shader storage buffers
layout(std430, binding = 3) buffer ssboTransform {
mat4 transforms[];
};
out vec4 outVertVarColor;
void main() {
mat4 selectedMatrix = transforms[transformIndex];
gl_Position = uProjectionView * selectedMatrix * vec4(offset, 1.0);
gl_PointSize = size;
outVertVarColor = color;
if (transformIndex > 0) {
outVertVarColor = vec4(transformIndex,transformIndex,transformIndex,0.5);
gl_PointSize = transformIndex;
}
}
C++
void OpenGLPointD::render(GLSLBuffer* transformBuffer, glm::mat4* viewProjectionMatrix) {
if (!isInit)
return;
for (OpenGLPointD* point : points) {
glslProgram->bind();
point->glslBuffer->bind();
point->glslBuffer->subwrite(0, sizeof(OpenGLPointDData), &point->gpuData);
// transformBuffer->bindToBindingPoint(0);
transformBuffer->bind();
transformBuffer->bindToBindingPoint(glslProgram->ssbos[0].bindingPoint);
// glslProgram->setUniformLocationArray(0, 1, false, viewProjectionMatrix);
glm::mat4 matrix = glm::mat4(1);
glslProgram->setUniformLocationArray(glslProgram->uniforms[0].location, 1, false, viewProjectionMatrix);
glslProgram->enableAttributes();
{
OpenGLPointDData data;
point->glslBuffer->getData(0, sizeof(OpenGLPointDData), &data);
glm::mat4 matrix = glm::mat4(1);
transformBuffer->getData(0, sizeof(glm::mat4), &matrix);
Transform transform = Transform();
transform.setLoca`enter code here`lMatrix(matrix);
transformBuffer->getData(sizeof(glm::mat4), sizeof(glm::mat4), &matrix);
transform = Transform();
transform.setLocalMatrix(matrix);
}
glDrawArrays(GL_POINTS, 0, 1);
}
}
我遇到的问题是,唯一正确渲染的 OpenGLPointD 是着色器存储缓冲区索引 0 处的 OpenGLPointD。其他所有点都会渲染在屏幕中心。运行一些测试后,我跟踪问题如下。
transformationIndex
在顶点着色器中变得太大了。我添加了一个 if
条件来跟踪 transformationIndex
的值。无论值变成什么,都在 1000 以上。
我写这篇文章是为了检查我的缓冲区是否正确,它们是:
{
OpenGLPointDData data;
point->glslBuffer->getData(0, sizeof(OpenGLPointDData), &data);
glm::mat4 matrix = glm::mat4(1);
transformBuffer->getData(0, sizeof(glm::mat4), &matrix);
Transform transform = Transform();
transform.setLocalMatrix(matrix);
transformBuffer->getData(sizeof(glm::mat4), sizeof(glm::mat4), &matrix);
transform = Transform();
transform.setLocalMatrix(matrix);
}
有谁知道为什么整数属性在顶点着色器中的值会改变?以下是我启用属性的方法。我正在传递基本数据类型,并且规范化默认为 false。
for (unsigned int i = 0; i < attributes.size(); i++) {
GLSLAttribute attribute = attributes[i];
unsigned int location = (unsigned int)attribute.location;
unsigned int componentCount = (unsigned int)GLSLProgram::getComponentCount(attribute.dataType);
unsigned int baseDataType = (unsigned int)attribute.baseDataType;
bool normalize = attributes[i].normalize;
int size = attributes[i].arraySize * getDataTypeSize(attribute.dataType);
glEnableVertexAttribArray(location);
glVertexAttribPointer(location, componentCount, baseDataType, normalize, size, (const void*)offset);
offset += size;
}
我想我几年前就遇到过这个问题,我通过传递
float
并将其转换为顶点着色器中的 int
来修复它。
我找到了答案。
glVertexAttribPointer
用于浮点数。 glVertexAttribIPointer
用于整数。当 glVertexAttribPointer
用于整数值时,会将其转换为浮点数,反之亦然。因此,任何类型的转换都会被误解,因为数据本身从一开始就被误解了。