2017-02-14 129 views
0

我將對象的材質存儲在由漫反射,凹凸,鏡面反射等構成的數組紋理2D中。然後將此紋理數組的句柄存儲在每個頂點,沿着頂點,uv,法線數組在VAO中,而不是使用UBO或SSBO來實現相同的目的。Bindless array texture not working

我的目標是將整個模型壓縮成單個頂點數組對象,因爲模型可能有很多網格,並且每個網格可能都有自己的紋理。通過這種方式,每個頂點存儲紋理句柄,我可以在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); 
    } 
} 

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

着色用途:

頂點:

#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個額外字節在裏面。特別是因爲這些字節的大部分將是相同的。傳遞在2D陣列紋理中查找的1字節索引要好得多。畢竟,這就是爲什麼它是一個*數組紋理*。 –

+0

在任何情況下,找出哪些是壞了最簡單的方法是通過一個統一的,而不是VS輸入提供的句柄,然後看看是否能工程。如果沒有,那麼你可以更好地本地化問題。 –

+0

是的,我只是去嘗試和類似的方法。 問題似乎是我指定GLuint指針或其他東西。但無論如何,我只是把柄放在ssbo中,並通過頂點屬性指定數組的位置 – Yattabyte

回答

0

的問題是,glBufferData不能接受指針的載體。

我這樣設置我的數據,以便最後的頂點屬性數組是一個數組Gluint64 *手柄,原因有兩個: 1),以便每個三角形的恰當紋理從頂點着色器流向片段着色器,2)以便我可以提前創建陣列並等待紋理創建並通過單獨更新底層指針來自動更新陣列

這可以工作,但是需要將矢量從類型GLuint *到GLuint(放下指針)。