2012-02-02 181 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 - 正是你想要的。

人体工程学,在总的每个间隙由三个三角形而这又使得它很容易看到当你收支平衡复杂明智炸毁你的顶点流。

无论如何,如果你需要建立一个缺口,只是你可以通过提供一个无效的三角形