2012-02-02 176 views
1

我執行與GL_TRIANGLE_STRIPS和LWJGL OpenGL的Java綁定,一個高度圖。當我使用'GL_BEGIN/GL_END'繪製'直接'時,它可以很好地工作,但是當高度圖大時,它的運行速度會變慢。OpenGL的頂點數組和GL_TRIANGLE_STRIP繪製錯誤

正如我希望使用移動VBO的,我現在正在學習如何使用頂點數組的。這是我遇到問題的地方,繪圖是錯誤的。看起來,該帶的最後一個三角形返回到第一個。 Perheps圖片更好:

好圖紙: Good direct drawing

壞頂點數組繪製: Bad vertex array drawing

我的代碼是正常繪製如下:

public void renderDirect() { 
    //adapt the camera to the map 
    float scale = 5.0f/Math.max(w - 1, l - 1); 
    GL11.glScalef(scale, scale, scale); 
    GL11.glTranslatef(-(float) (w - 1)/2, 0.0f, -(float) (l - 1)/2); 

    //choose map color 
    GL11.glColor3f(0.3f, 0.9f, 0.0f); 

    for (int z = 0; z < l - 1; z++) { 
     //Makes OpenGL draw a triangle at every three consecutive vertices 
     GL11.glBegin(GL11.GL_TRIANGLE_STRIP); 
     for (int x = 0; x < w; x++) { 
      Vector3f normal = getNormal(x, z); 
      GL11.glNormal3f(normal.getX(), normal.getY(), normal.getZ()); 
      GL11.glVertex3f(x, getHeight(x, z), z); 
      normal = getNormal(x, z + 1); 
      GL11.glNormal3f(normal.getX(), normal.getY(), normal.getZ()); 
      GL11.glVertex3f(x, getHeight(x, z + 1), z + 1); 
     } 
     glEnd(); 
    } 
} 

我的代碼是以下爲頂點陣列圖:

private void loadArrays(){ 
    //calculate the length of the buffers 
    bLength = (l-1) * w * 6; 
    //create the normal and vertex buffer array's 
    dataBuffer = BufferUtils.createFloatBuffer(bLength*2); 
    cBuffer = BufferUtils.createFloatBuffer(bLength); 

    for (int z = 0; z < l - 1; z++) { 
     //Fill up the buffers 
     for (int x = 0; x < w; x++) { 
      Vector3f normal = getNormal(x, z); 
      dataBuffer.put(x).put(getHeight(x,z)).put(z); 
      dataBuffer.put(normal.getX()).put(normal.getY()).put(normal.getZ()); 
      normal = getNormal(x, z + 1); 
      dataBuffer.put(x).put(getHeight(x,z+1)).put(z+1); 
      dataBuffer.put(normal.getX()).put(normal.getY()).put(normal.getZ());    
     } 
    } 
} 

int stride = 6*4; 
public void renderDirect() { 
    //adapt the camera to the map 
    float scale = 5.0f/Math.max(w - 1, l - 1); 
    GL11.glScalef(scale, scale, scale); 
    GL11.glTranslatef(-(float) (w - 1)/2, 0.0f, -(float) (l - 1)/2); 

    //choose map color 
    GL11.glColor3f(0.3f, 0.9f, 0.0f); 

    //Draw the vertex arrays 
    glEnableClientState(GL_VERTEX_ARRAY);  
    glEnableClientState(GL_NORMAL_ARRAY); 

    dataBuffer.position(0); 
    glVertexPointer(3, stride, dataBuffer); 
    dataBuffer.position(3); 
    glNormalPointer(stride,dataBuffer); 

    glDrawArrays(GL_TRIANGLE_STRIP, 0, bLength/3);  

    glDisableClientState(GL_VERTEX_ARRAY);  
    glDisableClientState(GL_NORMAL_ARRAY); 
}  

我在做什麼錯?如你預期

回答

3

串聯三角形帶回來到後端這樣是行不通的。

要麼調用glDrawArrays()在一個循環中調節firstcount參數提請原始N三角形條帶,或添加到degenerate triangles每行的末端復位條起始位置。

或者只是使用GL_TRIANGLES :)

+3

@OP想想吧,你需要一個'glDrawArrays'呼籲每個'在glBegin/glEnd'的方式這樣做您以前的代碼塊。在這種情況下,考慮索引原語(因此'glDrawElements'而不是'glDrawArrays')可能是一個好主意,因爲每個頂點基本上都是兩個條的一部分。 – 2012-02-02 16:02:12

0

,可以安全你很多的時間,如果連續繪製的三角形在你帶的數量是足夠高的是下面的另一種解決方案:

當渲染三角形帶你向OpenGL提供頂點信息流,併爲每個新頂點渲染一個三角形(例如,序列ABCDEF爲您提供三角形ABC,BCD,CDE,DEF)。現在,這將始終是單條(這就是爲什麼它被稱爲GL_TRIANGLE_STRIP,而不是常見的複數名稱)。

無論如何,如果你需要給你介紹可以使用多次打電話給你繪製函數的間隙(儘管這是你要避免什麼,右),但你也可以使用無效的多邊形。

無效的多邊形是沒有曲面的多邊形。您可以通過提供相同的點(如ABB或ABA)來創建無效的多邊形。據我所知,這樣一個多邊形將在流水線的早期被拒絕,因此它不會給你帶來太多的開銷。現在到你的特定問題。假設您有一個類似於「ABC | DEF」的間隙(由豎線表示)。修改你的流,看起來像這樣的「ABCCEEDEF」。這種憎惡給你三角形ABC,BCC,CCE,CEE,EDE,DEF。如果你考慮早期拒絕無效的ABC ABC和DEF - 正是你想要的。

人體工程學,在總的每個間隙由三個三角形而這又使得它很容易看到當你收支平衡複雜明智炸燬你的頂點流。

無論如何,如果你需要建立一個缺口,只是你可以通過提供一個無效的三角形