c++ - 向 VBO 发送单个 unsigned int

标签 c++ opengl

我正在尝试向 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;
}

我应该进入第二个 if,但它没有:\

最佳答案

在定义通用顶点属性数据数组时,必须使用glVertexAttribIPointer(重点放在I),对于顶点属性in int in_textureId;.
glVertexAttribPointer 定义的顶点属性数据将被转换为 float 。

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

The VertexAttribI* commands specify signed or unsigned fixed-point values that are stored as signed or unsigned integers, respectively. Such values are referred to as pure integers.

...

All other VertexAttrib* commands specify values that are converted directly to the internal floating-point representation.


请注意,您应该使用 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也是妥妥的解决办法。

关于c++ - 向 VBO 发送单个 unsigned int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52726660/

相关文章:

c++ - OpenGL 纹理颜色问题

c++ - Python 和 C++ 构造函数之间的差异

c++ - 空时访问索引0处的 vector

c++ - 检测与子弹的碰撞

c++ - 条件表达式中的常量值

opengl - Nvidia Flex 数据传输

opengl - 如何在OpenGL中有效地实现 "point-on-heightmap"拾取?

c++ - 错误修复。 OpenGL、GLSL Sprite 网格渲染问题

c++ - Opengl 游戏循环多线程

c++ - 关于 C 和 C++ 中的 offsetof 用法?