为什么从顶点缓冲区传递到顶点着色器的 GLSL 整数属性变得太大?

问题描述 投票:0回答:1

我正在尝试按以下方式渲染 GL_POINTS:

  • 使用uniform来传递viewProjectionMatrix
  • 使用着色器存储缓冲区对象(SSBO)来存储世界中游戏对象的所有 glm::mat4 转换。游戏引擎中的所有内容都使用此 SSBO。
  • 每个 OpenGLPointD 都有自己的顶点着色器对象(VSO)来存储以下结构:
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
来修复它。

c++ opengl glsl glm-math shader-storage-buffer
1个回答
0
投票

我找到了答案。

glVertexAttribPointer
用于浮点数。
glVertexAttribIPointer
用于整数。当
glVertexAttribPointer
用于整数值时,会将其转换为浮点数,反之亦然。因此,任何类型的转换都会被误解,因为数据本身从一开始就被误解了。

© www.soinside.com 2019 - 2024. All rights reserved.