发送单个未初始化的int到VBO

时间:2018-10-09 17:45:30

标签: c++ opengl

我试图将单个无符号int发送给vbo,但是当我在顶点着色器中测试其值(应该为1)时,该值与预期值不同。

包含我的无符号整数的变量是textureIds

加载vbo的代码:

std::vector<unsigned int> textureIds;
glGenBuffers(1, &vboID_m);
glBindBuffer(GL_ARRAY_BUFFER, vboID_m);
{
    glBufferData(GL_ARRAY_BUFFER,
            (vertices.size() + texture.size() + normals.size())
                    * sizeof(float) + textureIds.size() * sizeof(unsigned int), 0,
            GL_STATIC_DRAW);
    glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(float),
            vertices.data());
    glBufferSubData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float),
            texture.size() * sizeof(float), texture.data());
    glBufferSubData(GL_ARRAY_BUFFER,
            (vertices.size() + texture.size()) * sizeof(float),
            normals.size() * sizeof(float), normals.data());
    glBufferSubData(GL_ARRAY_BUFFER,
            (vertices.size() + texture.size() + normals.size()) * sizeof(float),
            textureIds.size() * sizeof(unsigned int), textureIds.data());
}
glBindBuffer(GL_ARRAY_BUFFER, 0);

绘制vbo的代码:

void Chunck::draw() const {
    glBindBuffer(GL_ARRAY_BUFFER, vboID_m);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float),
            BUFFER_OFFSET(0));
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float),
            BUFFER_OFFSET(verticeSize_m * sizeof(float)));
    glEnableVertexAttribArray(1);

    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float),
            BUFFER_OFFSET(
                    (verticeSize_m + textureSize_m) * sizeof(float)));
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(3, 1, GL_UNSIGNED_INT, GL_FALSE, sizeof(unsigned int),
                BUFFER_OFFSET(
                        (verticeSize_m + textureSize_m + normalSize_m) * sizeof(float)));
    glEnableVertexAttribArray(3);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, grassTexture_m.getID());

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, dirtTexture_m.getID());
    glDrawArrays(GL_TRIANGLES, 0, verticeSize_m / 3);
    glBindTexture(GL_TEXTURE_2D, 0);

    glDisableVertexAttribArray(2);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

顶点着色器:

#version 330 core

in vec3 in_Vertex;
in vec2 in_TexCoord0;
in vec3 in_normal;

in int in_textureId;

uniform mat4 projection;
uniform mat4 model;
uniform mat4 view;

out vec2 coordTexture;
out vec3 normal;
out vec3 FragPos;
out vec3 rayDir;

out float grassAmount;
out float dirtAmount;


void main()
{
    vec4 pos = model * vec4(in_Vertex, 1.0);
    vec2 mu = vec2(0., 0.);
    //pos.y = max(pos.y, 10 * exp(-((pos.x - mu.x) * (pos.x - mu.x) + (pos.z - mu.y) * (pos.z - mu.y)) / 100.));

    gl_Position = projection * view * pos;
    FragPos = vec3(pos);
    coordTexture = in_TexCoord0;
    normal = in_normal;
    rayDir = (view * model * vec4(FragPos, 1.)).xyz;

    grassAmount = 0;
    dirtAmount = 0;

    if (in_textureId == 0)
        grassAmount = 1;
    else if (in_textureId == 1)
        dirtAmount = 1;
}

如果不是,我应该输入第二个,但不是:\

1 个答案:

答案 0 :(得分:1)

在定义通用顶点属性数据的数组时,必须为顶点属性glVertexAttribIPointer使用I(着重于 in int in_textureId; )。< br /> 由glVertexAttribPointer定义的顶点属性数据将转换为浮点。

请参见OpenGL 4.6 API Core Profile Specification; 10.2. CURRENT VERTEX ATTRIBUTE VALUES; page 344

  

VertexAttribI* 命令指定有符号或无符号定点值   分别存储为有符号或无符号整数。这样的值称为纯整数。

     

...

     

所有其他 VertexAttrib* 命令指定直接转换为内部浮点表示形式的值


请注意,您应该使用Layout Qualifier来在顶点着色器中指定属性索引:

layout(location = 0) in vec3 in_Vertex;
layout(location = 1) in vec2 in_TexCoord0;
layout(location = 2) in vec3 in_normal;
layout(location = 3) in int in_textureId;

或者您应该在程序链接后的glGetAttribLocation之前请求属性索引:

例如:

GLuint progObj = ...;
glLinkProgram( progObj );

GLint texIdInx = glGetAttribLocation( progObj, "in_textureId" );

glVertexAttribIPointer(
    texIdInx, 1, GL_UNSIGNED_INT, GL_FALSE, sizeof(unsigned int),
    BUFFER_OFFSET((verticeSize_m + textureSize_m + normalSize_m) * sizeof(float)));
glEnableVertexAttribArray(texIdInx );

修改

当然,glBindAttribLocation也是合适的解决方案。