简体   繁体   English

顶点着色器属性位置中的数据损坏

[英]Corrupted data in vertex shader attribute location

My model looks stretched because of corrupted data in vertex shader attribute location由于顶点着色器属性位置中的数据损坏,我的 model 看起来被拉伸了

Here's the vertex shader code:这是顶点着色器代码:

#version 330 core

layout (location = 0) in vec3 vertPos;
layout (location = 1) in vec3 vertNormal;
layout (location = 2) in vec2 texCoord;
layout (location = 3) in vec4 boneWeigths;
layout (location = 4) in ivec4 boneIDs;

out vec3 vNormal;
out vec3 fragPos;
out vec2 fragTexCoord;

const int MAX_BONES = 100;

uniform mat4 MVP;
uniform mat4 M;
uniform mat4 boneTransforms[MAX_BONES];

void main()
{
    mat4 boneTx = boneTransforms[boneIDs[0]] * boneWeigths[0]
                + boneTransforms[boneIDs[1]] * boneWeigths[1]
                + boneTransforms[boneIDs[2]] * boneWeigths[2]
                + boneTransforms[boneIDs[3]] * boneWeigths[3];
    vec4 pos = boneTx * vec4(vertPos, 1.0f);
    gl_Position = MVP * pos;
    vec4 normal = boneTx * vec4(vertNormal, 0.0f);
    vNormal = normalize(vec3(M * normal));
    fragPos = vec3(M * pos);
    fragTexCoord = vec2(texCoord.x, texCoord.y);
}

The problem seems to be corrupted data in boneIDs (boneIDs data is fine on CPU, but getting corrupted data in shader).问题似乎是 boneIDs 中的数据损坏(boneIDs 数据在 CPU 上很好,但在着色器中获取损坏的数据)。 I tried hard-coding boneIDs data in shader, and that works fine.我尝试在着色器中硬编码 boneIDs 数据,效果很好。

Here's the code for VAO:这是 VAO 的代码:

    // create buffers/arrays
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);

    glBindVertexArray(VAO);
    // load data into vertex buffers
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    unsigned int sz = sizeof(BoneVertex);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(BoneVertex), &vertices[0], GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);

    // set the vertex attribute pointers
    // vertex Positions
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(BoneVertex), (void*)0);
    // vertex normals
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(BoneVertex), (void*)(3 * sizeof(float)));
    // vertex texture coords
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(BoneVertex), (void*)(6 * sizeof(float)));
    // bone weights
    glEnableVertexAttribArray(3);
    glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(BoneVertex), (void*)(8 * sizeof(float)));
    // bone ids
    glEnableVertexAttribArray(4);
    glVertexAttribPointer(4, 4, GL_INT, GL_FALSE, sizeof(BoneVertex), (void*)(12 * sizeof(float)));

    glBindVertexArray(0);

BoneVertex structure: BoneVertex 结构:

struct BoneVertex
{
    glm::vec3 position;
    glm::vec3 normal;
    glm::vec2 textureCoords;
    glm::vec4 boneWeights;
    glm::ivec4 boneIDs;
}

This is weird, because the first 3 attributes data seems fine.这很奇怪,因为前 3 个属性数据看起来不错。 The problem is with boneIDs and boneWeights Is this somehow related to padding, and how data is arranged in a structure?问题在于 boneIDs 和 boneWeights 这是否与填充有关,以及数据如何在结构中排列? Or am I missing something else?还是我错过了其他东西?

Thanks谢谢

boneIDs is a vertex shader input with an integral data type: boneIDs是具有整数数据类型的顶点着色器输入:

 layout (location = 4) in ivec4 boneIDs;

If you want to specify the generic vertex attribute data for an integral attribute, then you have to use glVertexAttribIPointer (focus on I ) rather than glVertexAttribPointer (see glVertexAttribPointer ).如果要为整体属性指定通用顶点属性数据,则必须使用glVertexAttribIPointer (关注I )而不是glVertexAttribPointer (请参阅glVertexAttribPointer )。
Note, the type argument doesn't specify the type of the target attribute, it specifies the element type of the source data array.注意,type 参数没有指定目标属性的类型,它指定了源数据数组的元素类型。 glVertexAttribPointer converts the source data array to floating point values, but glVertexAttribIPointer specifies the array for integral target attributes. glVertexAttribPointer将源数据数组转换为浮点值,但glVertexAttribIPointer指定整数目标属性的数组。

glVertexAttribPointer(4, 4, GL_INT, GL_FALSE, sizeof(BoneVertex), (void*)(12 * sizeof(float)));

glVertexAttribIPointer(4, 4, GL_INT, sizeof(BoneVertex), (void*)(12 * sizeof(float)));   

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM