2017-02-14 7 views
0

Я храню материал объекта в текстуре массива 2D, состоящий из диффузного, рельефного, зеркального и т. Д. Затем дескриптор этого массива текстур сохраняется на вершине вдоль стороны вершины, uv, нормальных массивов в VAO, вместо того, чтобы использовать UBO или SSBO для достижения той же цели.Текстура текстуры без камней

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

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


Создание текстуры:

void TextureManager::FinishWorkOrders() 
{ 
    for (...) { 
     Material_WorkOrder *material = Mat_Work_Orders[x]; 
     glGenTextures(1, material->gl_array_ID); 
     glBindTexture(GL_TEXTURE_2D_ARRAY, *material->gl_array_ID); 
     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, material->size.x, material->size.y, 5, 0, GL_RGBA, GL_UNSIGNED_BYTE, material->textureData); 
     glGenerateMipmap(GL_TEXTURE_2D_ARRAY); 
     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_GENERATE_MIPMAP, GL_TRUE); 
     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 
     glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f); 

     // Material handle is of type GLuint64 
     *material->handle = glGetTextureHandleARB(*material->gl_array_ID); 
     glMakeTextureHandleResidentARB(*material->handle); 
    } 
} 

ВАО поколения:

GLuint ModelManager::genVAO(const vector<vec3> &vs, const vector<vec2> &uv, const vector<vec3> &nm, const vector<vec3> &tg, const vector<vec3> &bt, const vector<GLuint64*> &ts) 
{ 
    AttribBuffers b; 
    GLuint vao = 0; 
    size_t arraySize = vs.size(); 
    glGenVertexArrays(1, &vao); 
    glBindVertexArray(vao); 
    glGenBuffers(MAX_BUFFERS, b.buffers); 

    // Vertex array 
    glBindBuffer(GL_ARRAY_BUFFER, b.buffers[0]); 
    glBufferData(GL_ARRAY_BUFFER, arraySize * sizeof(vec3), &vs[0][0], GL_STATIC_DRAW); 
    glEnableVertexAttribArray(0); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 

    ... 

    // Texture Handle array 
    glBindBuffer(GL_ARRAY_BUFFER, b.buffers[5]); 
    glBufferData(GL_ARRAY_BUFFER, arraySize * sizeof(GLuint64), &ts[0], GL_STATIC_DRAW); 
    glEnableVertexAttribArray(5); 
    glVertexAttribLPointer(5, 1, GL_UNSIGNED_INT64_ARB, 0, 0); 

    glBindVertexArray(0); 
    return vao; 
} 

шейдера Использование:

Vertex:

#version 450 
#extension GL_ARB_bindless_texture : require 
#extension GL_ARB_gpu_shader5 : require 
#extension GL_ARB_gpu_shader_int64 : require 

layout (location = 0) in vec3 vertex; 

... 

layout (location = 5) in uint64_t texHandle; 

flat out uint64_t TextureHandle; 

void main(void) 
{ 
    TextureHandle   = texHandle; 

    ... 

    gl_Position    = worldMVP * v;   
} 

Фрагмент:

#version 450 
#extension GL_ARB_bindless_texture : require 
#extension GL_ARB_gpu_shader5 : require 
#extension GL_ARB_gpu_shader_int64 : require 

flat in uint64_t TextureHandle; 

layout (location = 0) out vec4 DiffuseOut; 

void main()         
{       
    sampler2DArray MaterialMap = sampler2DArray(TextureHandle); 

    ... 

    DiffuseOut = texture(MaterialMap, vec3(TexCoord0, 0)); 
} 
+0

"* Таким образом, с помощью обработчика текстуры, хранящегося на вершине, я мог бы просто отобразить всю модель в 1 обратном вызове. *« Есть лучшие способы сделать то, что не требует * каждой вершины *, чтобы иметь 8 дополнительных байтов в нем. Тем более, что большинство этих байтов будут одинаковыми. Намного лучше передать 1-байтовый индекс, который вы просматриваете в текстуре 2D-массива. Вот почему это текстура массива *, в конце концов. –

+0

В любом случае, самый простой способ узнать, что сломано, - это обеспечить дескриптор через унифицированный, а не VS-вход, а затем посмотреть, работает ли это. Если нет, то вы можете лучше локализовать проблему. –

+0

Да, я просто попробовал это и подобные методы. Проблема заключается в том, что я указываю указатели GLuint или что-то в этом роде. Но в любом случае я просто вместо этого поставлю дескрипторы в ssbo и задаю позиции массива с помощью атрибутов вершин – Yattabyte

ответ

0

Вопрос заключается в том, что glBufferData не может принять вектор указателей.

Я установил свои данные таким образом, чтобы последний массив атрибутов вершин был массивом Gluint64 * для двух причин: 1), чтобы соответствующая текстура на треугольник просто переходила из вершинного шейдера в шейдер фрагмента , 2), чтобы я мог создать массив раньше времени и дождаться создания текстуры и автоматически обновить массив, просто обновив базовые указатели отдельно.

Это может работать, но вектор необходимо изменить из типа GLuint * to GLuint (отбросить указатель).

Смежные вопросы