2017-02-14 1 views
0

Je stocke le matériau d'un objet dans une texture de tableau 2D composée de diffuse, bump, spéculaire, etc. Le handle de ce tableau de texture est ensuite stocké par vertex, le long du vertex, uv, rangées normales dans un VAO, au lieu d'utiliser UBO ou SSBO pour atteindre le même but.La texture de tableau sans Bindless ne fonctionne pas

Mon objectif est de compresser un modèle complet en un seul objet tableau de sommet, car un modèle peut avoir plusieurs maillages et chaque maillage peut avoir sa propre texture. De cette façon, avec la poignée de texture stockée par sommet, je pourrais juste rendre le modèle entier dans l'appel 1 draw.

Le problème est que tous les objets sont noirs, ce qui suggère que l'échantillonneur ne fonctionne pas ou que la poignée n'est pas transmise tout le long. Le programme shader se compile avec succès et la géométrie est correctement rendue (c'est-à-dire que je peux remplacer la couleur diffuse finale par une couleur fixe et voir la scène).


Texture Création:

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

génération VAO:

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

Shader Utilisation:

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

Fragment:

#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

"De cette façon, avec la poignée de texture stockée par vertex, je pourrais juste rendre le modèle entier en 1 tirage. *" Il y a de meilleures façons de faire cela qui ne nécessite pas * chaque vertex * octets en elle. Surtout que la plupart de ces octets seront les mêmes. Il est préférable de passer un index de 1 octet que vous recherchez dans la texture du tableau 2D. C'est pourquoi c'est une texture * array, après tout. –

+0

Dans tous les cas, le moyen le plus simple de savoir ce qui est cassé est de fournir le handle via une entrée uniforme plutôt que VS, puis voir si cela fonctionne. Si non, alors vous pouvez mieux localiser le problème. –

+0

Oui, j'ai juste essayé cela et des méthodes similaires. Le problème semble être que je spécifie des pointeurs GLuint ou quelque chose. Mais dans tous les cas, je vais simplement placer les poignées dans un ssbo et spécifier les positions du tableau via les attributs de vertex – Yattabyte

Répondre

0

Le problème est que glBufferData ne peut pas accepter un vecteur de pointeurs.

J'ai paramétré mes données de telle façon que le dernier tableau d'attributs de vertex était un tableau de poignées Gluint64 * pour 2 raisons: 1) pour que la texture appropriée par triangle passe juste du vertex shader au fragment shader , 2) pour que je puisse créer le tableau à l'avance et attendre que la texture soit créée et mettre à jour le tableau automatiquement en mettant à jour les pointeurs sous-jacents séparément

Cela peut fonctionner, mais le vecteur doit être changé de type GLuint * à GLuint (dépose le pointeur).