我正在使用GL_TRIANGLE_STRIPS和LWJGL OpenGL Java Bindings实现高度图。当我使用'GL_BEGIN / GL_END'绘制'直接'时,它可以很好地工作,但是当高度图很大时它会很慢。
由于我想继续使用VBO,我现在正在学习如何使用Vertex Array。这是我遇到问题的地方,图纸是错误的。似乎条带的最后一个三角形返回到第一个三角形。 Perheps图片更好:
好画:
Bad Vertex数组绘图:
正常绘图的代码如下:
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);
}
我做错了什么?
答案 0 :(得分:3)
背靠背连接三角形条似乎无法按预期工作。
在循环中调用glDrawArrays()
调整first
和count
参数以绘制原始N
三角形条带,或将degenerate triangles添加到结尾每一行重置条带起始位置。
或者只使用GL_TRIANGLES
:)
答案 1 :(得分:0)
如果条带中连续绘制的三角形数量足够高,另一种可以节省大量时间的解决方案如下:
渲染三角形条带时,您向OpenGL提供顶点信息流,并为每个新顶点渲染一个三角形(例如,序列ABCDEF为您提供三角形ABC,BCD,CDE,DEF)。现在,这将始终是一个单一的条带(这就是为什么它被称为GL_TRIANGLE_STRIP而不是常见的复数命名)。
无论如何,如果你需要引入一个间隙,你可以使用几次调用你的绘图功能(虽然这是你想要避免的,对吧),但你也可以使用无效的多边形。
无效多边形是没有曲面的多边形。您可以通过提供相同的点(如ABB或ABA)来创建无效多边形。据我所知,这样的多边形将在管道中很早就被拒绝,因此它不会给你带来太多的开销。现在针对你的特殊问题。假设你有一个间隙(由垂直条表示),如“ABC | DEF”。将您的信息流修改为“ABCCEEDEF”。这种憎恶给你三角形ABC,BCC,CCE,CEE,EDE,DEF。如果你考虑到早期拒绝无效的那些,你会得到ABC和DEF - 正是你想要的。
因此,总的来说,每个间隙会使你的顶点流被三个三角形炸掉,这反过来又很容易让你看到它在复杂性方面的突破。
无论如何,如果你需要建立一个差距,你可以通过提供一个无效的三角形
来实现