2012-03-15 18 views
0

我試圖用「n」個紋理(示例中爲6)繪製任意對象,並且每個面都有一個(但可能不同)紋理。如何在使用VBO的OpenGL上使用GL_TEXTURE_2D_ARRAY

當使用單個紋理時,它一切正常,但我很難使2D紋理陣列工作。

這裏的對象:

struct Vertex3f { float x, y, z; }; 
struct ObjectVertexfMT { // MT stands for Multi Texture 
    struct Vertex3f coord; 
    struct Vertex3f texcoord; 
    struct Vertex3f normal; 
}; 
struct ObjectVertexfMT GLEngine_CubeMT[] = { 
    // x,  y,  v, u, v, r, nx, ny, nz 
    // Front 
    { -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }, 
    { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }, 
    { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }, 
    { -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }, 
    // Back 
    { -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f }, 
    { 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f }, 
    { 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f }, 
    { -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f }, 
    // Top 
    { -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 2.0f, 0.0f, 1.0f, 0.0f }, 
    { -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 2.0f, 0.0f, 1.0f, 0.0f }, 
    { 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 2.0f, 0.0f, 1.0f, 0.0f }, 
    { 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 2.0f, 0.0f, 1.0f, 0.0f }, 
    // Bottom 
    { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 3.0f, 0.0f, -1.0f, 0.0f }, 
    { -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 3.0f, 0.0f, -1.0f, 0.0f }, 
    { 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 3.0f, 0.0f, -1.0f, 0.0f }, 
    { 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 3.0f, 0.0f, -1.0f, 0.0f }, 
    // Right 
    { 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 4.0f, 1.0f, 0.0f, 0.0f }, 
    { 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 4.0f, 1.0f, 0.0f, 0.0f }, 
    { 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 4.0f, 1.0f, 0.0f, 0.0f }, 
    { 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 4.0f, 1.0f, 0.0f, 0.0f }, 
    // Left 
    { -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 5.0f, -1.0f, 0.0f, 0.0f }, 
    { -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 5.0f, -1.0f, 0.0f, 0.0f }, 
    { -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 5.0f, -1.0f, 0.0f, 0.0f }, 
    { -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 5.0f, -1.0f, 0.0f, 0.0f } 
}; 

注意,「R」參數針對每一個四(表明我想在那個特定的四紋理的索引)不同。

我註冊的紋理就像這樣:

struct texInfo { 
    int width, height; 
    unsigned char *data; 
}; 

// Loads texture from filename in a texInfo structure -- always 32 bit depth 
struct texInfo *loadTexture(const char* filename); 

unsigned int register3DTexture(const char *filenames[], unsigned int texcount) { 
    unsigned int ret; 
    unsigned int i; 
    struct texInfo *tex; 
    glGenTextures(1, &ret); 
    glBindTexture(GL_TEXTURE_2D_ARRAY, ret); 
    glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, 4, 256, 256, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 
    for (i = 0; i < texcount; i++) { 
    tex = loadTexture(filenames[i]); 
    glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, tex->width, tex->height, 1, GL_RGBA, GL_UNSIGNED_BYTE, tex->data); 
    free(tex); 
    } 

    return(ret); 
} 

...然後我得出:

glPushMatrix(); 

    glClientActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D_ARRAY, textures[0]); // Same behaviour if I change to GL_TEXTURE_2D 

    glTranslatef(pos.x, pos.y, pos.z); 
    glRotatef(rot_angle, rot.x, rot.y, rot.z); 

    glBindBuffer(GL_ARRAY_BUFFER, VobObject[0]); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VobObject[1]); 

    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_NORMAL_ARRAY); 

    glVertexPointer(3, GL_FLOAT, sizeof(struct ObjectVertexfMT), 0); 
    glNormalPointer(GL_FLOAT, sizeof(struct ObjectVertexfMT), (void*)(sizeof(float) * 6)); 

    // Textures 
    glClientActiveTexture(GL_TEXTURE0); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glTexCoordPointer(2, GL_FLOAT, sizeof(struct ObjectVertexfMT), (void*)(sizeof(float) * 3)); 

    glDrawElements(GL_QUADS, m_vertexcount, GL_UNSIGNED_SHORT, 0); 

    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_NORMAL_ARRAY); 
    glPopMatrix(); 

對象繪製正確,但沒有紋理。

另外幾個問題:

  • 假設它的工作原理,這是實現我目標的最佳方式是什麼?

  • 的「subtextures」可以具有的「主」紋理的不同尺寸(寬度和高度的 參數上glTexImage3D()可以是從glTexSubImage3D()從那些不同 )?

回答

1

您必須使用着色器來使用數組紋理。你不能在固定功能渲染中使用它們。

「subtextures」可以具有「主」紋理的不同尺寸(glTexImage3D()上的寬度和高度參數可能與glTexSubImage3D()中的參數不同)?

這個問題很混亂。就像使用C++數組一樣,紋理數組的元素都是相同的。如果你在C++中有一個int[30]的數組,那麼每個元素的大小將是30個整數。數組紋理也是如此。二維數組紋理作爲一個整體具有寬度和高度,這對陣列中的所有紋理都是相同的。

glTexSubImage3D(以及類似的功能)不是會影響貼圖的尺寸。它所做的只是將像素數據上傳到紋理中的某個位置。只有glTexImage3D(以及類似的功能)會影響紋理的尺寸。

+0

因此......根本不可能使用帶有GL_TEXTURE_2D_ARRAY的VBO,對吧?現在我需要一個關於着色器的教程...... – 2012-03-16 12:15:36

+0

@SergioMoura:緩衝區對象和着色器與對方沒有任何關係。您可以使用固定功能渲染的緩衝區對象。您可以使用帶客戶端頂點數組的着色器。它們交互時的* only *時間是當你使用緩衝對象作爲各種着色器相關活動(提供屬性,制服,變換反饋等)的源數據時。 – 2012-03-16 17:22:55