Данные не отправляются в буфер правильно? - PullRequest
0 голосов
/ 16 февраля 2019

Я пытаюсь создать систему, в которой я передаю данные из буферов в вершинные шейдеры, используя атрибуты, у меня уже есть некоторые, но эта новая система не работает.Я пытаюсь передать единственное целое число в мой вершинный шейдер.Я точно знаю, что все мои другие системы работают, и данные, поступающие в буфер, верны.Матрицы работают правильно, когда я помещаю int вместо атрибута, поэтому я знаю, что это как-то связано с буферами.

Я проверил ВСЕ мои системы.Это буквально до того факта, что когда я вставляю атрибут integer в оператор моего массива в вершинном шейдере, он НЕ будет работать, даже если он не находится непосредственно в нем, и я установил другое целое число в int.и я получаю полностью белый экран, по какой-то причине, когда я делаю атрибут 3 вместо 4, экран становится красным.если я сделаю это 1, это все еще становится белым.Значение данных, поступающих в glbufferdata, равно 1, и я убедился, что это правильная длина и пара для КАЖДОЙ вершины.

        if (reload == 1)
        {
            char scenepath[32] = "Gamedata\\Scenes\\Scene01.map";

            LoadScene(scenepath);

            for (size_t i = 0; i < ObjNames.size(); i++)
            {
                loadobj(modelloc[i]);
            }

            reorder_index();

            //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
            //glBufferData(GL_ELEMENT_ARRAY_BUFFER, index.size() * sizeof(int), &index[0], GL_STATIC_DRAW);




            glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
            glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);


            glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
            glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_STATIC_DRAW);

            glBindBuffer(GL_ARRAY_BUFFER, objbuffer);
            glBufferData(GL_ARRAY_BUFFER, model_index.size() * sizeof(int), &model_index[0], GL_STATIC_DRAW); 



            glEnableVertexAttribArray(0);

            glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

            glEnableVertexAttribArray(2);

            glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
            glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

            glEnableVertexAttribArray(3);

            glBindBuffer(GL_ARRAY_BUFFER, objbuffer);  //not workinngggg
            glVertexAttribPointer(3, 1, GL_INT, GL_FALSE, 0, (void*)0);


        }

}

#version 430
layout(location = 0) in vec3 v_pos;
//layout (location = 1) in vec3 uv;
layout (location = 2) in vec3 v_Normal;
layout (location = 3) in int object;
out vec3 FragPos;  
out vec3 Normalout;
uniform mat4 outmatrix[];
uniform mat4 model;
void main() {

gl_Position = outmatrix[object] * vec4(v_pos, 10.0f);
FragPos = vec3(model * vec4(v_pos , 0.0));

Normalout =  v_Normal;

}

Я ожидаю, что целое число из атрибута 3 войдет во внешнюю матрицу [interger_here], чтобы получить желаемые результаты наличия нескольких матриц в моей игре.

Я с нетерпением жду вашей поддержки, потому что я действительно невежественен, и экран имеет разные цвета в зависимости от местоположения.

1 Ответ

0 голосов
/ 16 февраля 2019

Если вы хотите определить массив общих целочисленных данных атрибутов вершин, вам нужно использовать glVertexAttribIPointer (фокус на I), а не glVertexAttribPointer:

glBindBuffer(GL_ARRAY_BUFFER, objbuffer); 
glVertexAttribIPointer(3, 1, GL_INT, 0, (void*)0);

Примечание. glVertexAttribPointer в сочетании с целочисленным типом данных (например, GL_INT) преобразует интегральные атрибуты в значения с плавающей запятой.


Недопустимо, чтобы массив единообразных переменных индексировался атрибутом!

См. Язык затенения OpenGL 4.30 Спецификация - 4.3.9 Интерфейсные блоки;страница 53

Унифицированный или шейдерный массив блочный массив может быть проиндексирован только с помощью динамически однородного интегрального выражения , в противном случае результаты не определены.

(в самой последней версии 4.60 GLSL это остается прежним)

Обратите внимание, что унифицированные переменные хранятся в унифицированном блоке по умолчанию, и атрибут не является "динамически однородным", потому что онможет отличаться для каждого запуска вершинного шейдера.

Это означает, что согласно спецификации результат вашего кода не определен.

#version 430

// [...]
layout (location = 3) in int object;
uniform mat4 outmatrix[];

void main()
{
    // [...]
    gl_Position = outmatrix[object] * vec4(v_pos, 10.0f);
}

Обходной путь может заключаться в кодировании матриц в 2-мерную (4 * N) текстуру с внутренним форматом GL_RGBA32F:

const int N = ...;
std::vector<glm::mat4> outmatrix(N);

GLuint tbo;
glGenTextures(1, tbo);
glBindTexture(GL_TEXTURE_2D, tbo);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 4, N, 0, GL_RGBA, GL_FLOAT, outmatrix.data()); 

Получить значения матрицы из текстурыиспользуя texelFetch:

#version 430

 layout(location = 3) in int object;

 layout(binding=0) uniform sampler2D outmatrix;

 // [...]

 void main()
 {
    mat4 outMat = mat4(
        texelFetch(outmatrix, ivec2(0, object), 0),
        texelFetch(outmatrix, ivec2(1, object), 0),
        texelFetch(outmatrix, ivec2(2, object), 0),
        texelFetch(outmatrix, ivec2(3, object), 0)
    );

    // [...]

}
...