2016-11-21 122 views
1

我定義頂點的數據塊,像這樣:我應該如何爲我的文本設置屬性指針?

struct vertex { 
    float x, y, u, v; 
}; 

struct vertex_group { 
    vertex tl, bl, br, tr; 
    glm::vec4 color; 

    vertex_group(float x, float y, float width, float height, glm::vec4 c) { 
     tl.x = x;   tl.y = y + height; tl.u = 0; tl.v = 0; 
     bl.x = x;   bl.y = y;   bl.u = 0; bl.v = 1; 
     br.x = x + width; br.y = y;   br.u = 1; br.v = 1; 
     tr.x = x + width; tr.y = y + height; tr.u = 1; tr.v = 0; 
     color = c; 
    } 

    vertex_group(positioned_letter const& l) : 
    vertex_group(l.x, l.y, l.width, l.height, l.l.color) { 
    } 

    const float * data() const { 
     return &tl.x; 
    } 
}; 

屬性指針設置是這樣的:

glEnableVertexAttribArray(0); 
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), nullptr); 
glEnableVertexAttribArray(1); 
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)(4 * 4 * sizeof(GLfloat))); 

和拉伸代碼被調用像這樣:

vertex_group vertices(l); 
glBindTexture(GL_TEXTURE_2D, g.texture); 
glBindBuffer(GL_ARRAY_BUFFER, objects.rect_buffer); 
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices.data(), GL_STREAM_DRAW); 
glDrawArrays(GL_QUADS, 0, 4); 

基本思想是四元組的所有四個頂點都應該使用相同的顏色數據,即使它們需要不同的位置和紋理數據值。但是,當我將顏色設置爲紅色(1,0,0,1)時,屏幕上的結果是....不太正確。

Font rendered incorrectly

僅供參考緣故,如果*僅改變我做對代碼的前兩個部分,下面:

struct vertex { 
    float x, y, u, v; 
}; 

struct vertex_group { 
    vertex tl; 
    glm::vec4 color1; 
    vertex bl; 
    glm::vec4 color2; 
    vertex br; 
    glm::vec4 color3; 
    vertex tr; 
    glm::vec4 color4; 

    vertex_group(float x, float y, float width, float height, glm::vec4 c) { 
     tl.x = x;   tl.y = y + height; tl.u = 0; tl.v = 0; 
     bl.x = x;   bl.y = y;   bl.u = 0; bl.v = 1; 
     br.x = x + width; br.y = y;   br.u = 1; br.v = 1; 
     tr.x = x + width; tr.y = y + height; tr.u = 1; tr.v = 0; 
     color1 = color2 = color3 = color4 = c; 
    } 

    vertex_group(positioned_letter const& l) : 
    vertex_group(l.x, l.y, l.width, l.height, l.l.color) { 
    } 

    const float * data() const { 
     return &tl.x; 
    } 
}; 

(其他部分)

glEnableVertexAttribArray(0); 
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), nullptr); 
glEnableVertexAttribArray(1); 
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(4 * sizeof(GLfloat))); 

它呈現正確:

Font Renders Correctly

所以,總之,我的問題是:我想我的結構化數據(與它渲染)像xyuvxyuvxyuvxyuvrgba但我可以讓它開始工作的唯一方式是通過做xyuvrgbaxyuvrgbaxyuvrgbaxyuvrgba。如何設置我的指針/調用繪圖函數,以便我可以使用第一種方法?

回答

2

你不能那樣做。但是你可以使用實例化的渲染實現這一佈局:

xyuvxyuvxyuvxyuv    // <- only once 
whrgbawhrgbawhrgbawhrgba... // <- repeated per glyph 

其中W和H是在頂點着色器將應用於每個四邊形的大小。

這裏我把它分成兩個緩衝區,但你可以在技術上將它全部加載到一個緩衝區中。此外,我在這裏使用OpenGL 4.5無綁定API,因爲我認爲它更易於使用。如果您還沒有,則可以將其更改爲相應地使用舊的呼叫。

float quad[] = { 
    0, 1, 0, 0, 
    0, 0, 0, 1, 
    1, 1, 1, 0, 
    1, 0, 1, 1, 
}; 

struct Instance { 
    vec2 size; 
    // TODO: add index of the glyph you want to render 
    vec4 color; 
}; 

Instance inst[] = { ... }; 
int ninst = sizeof(inst)/sizeof(inst[0]); 

GLuint quad_buf = ... create buffer from quad[] ...; 
GLuint inst_buf = ... create buffer from inst[] ...; 

GLuint vao; 
glCreateVertexArrays(1, &vao); 

glEnableVertexArrayAttrib(vao, 0); 
glVertexArrayAttribFormat(vao, 0, 4, GL_FLOAT, GL_FALSE, 0); 
glVertexArrayAttribBinding(vao, 0, 0); // from 0th buffer 

glEnableVertexArrayAttrib(vao, 1); 
glVertexArrayAttribFormat(vao, 1, 2, GL_FLOAT, GL_FALSE, offsetof(Instance, size)); 
glVertexArrayAttribBinding(vao, 1, 1); // from 1st buffer 

glEnableVertexArrayAttrib(vao, 2); 
glVertexArrayAttribFormat(vao, 2, 4, GL_FLOAT, GL_FALSE, offsetof(Instance, color)); 
glVertexArrayAttribBinding(vao, 2, 1); // from 1st buffer 

glVertexArrayVertexBuffer(vao, 0, quad_buf, 0, sizeof(float)*4); // 0th buffer is the quad 
glVertexArrayVertexBuffer(vao, 1, inst_buf, 0, sizeof(Instance)); // 1th buffer for instances 
glVertexArrayBindingDivisor(vao, 1, 1); // 1st buffer advances once per instance 

// to draw: 
glBindTexture(...); 
glBindVertexArray(vao); 
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, ninst); 
+0

我使用兩臺測試計算機,其中一臺嚴格限制在OpenGL 4.3中,所以我不能使用DSA api。儘管我喜歡你的解決方案;我會看到它對我的作用。 – Xirema

相關問題