Отправка одного незаявленного int в VBO - PullRequest
0 голосов
/ 09 октября 2018

Я пытаюсь отправить одно беззнаковое 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;
}

Я должен войти во второй if, но это не так: \

1 Ответ

0 голосов
/ 09 октября 2018

Вы должны использовать glVertexAttribIPointer (фокус на I) при определении массива общих данных атрибута вершины для атрибута вершины in int in_textureId;.
Данные атрибута вершины, определяемые какglVertexAttribPointer будет преобразовано в число с плавающей запятой.

См. Спецификация профиля ядра API OpenGL 4.6;10,2.ТЕКУЩИЕ ЗНАЧЕНИЯ VERTEX ATTRIBUTE;стр. 344

Команды VertexAttribI* указывают значения со знаком или без знака с фиксированной точкой , которые хранятся как целые числа со знаком или без знака соответственно.Такие значения называются чистыми целыми числами.

...

Все остальные команды VertexAttrib* указывают значения, которые преобразуются непосредственно во внутреннее плавающеепредставление точек .


Обратите внимание, вы должны использовать либо Qualifier Layout , чтобы указать индекс атрибута в вершинном шейдере:

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 );

Edit :

Конечно, glBindAttribLocation также является правильным решением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...