gpt4 book ai didi

java - 绘制大量三角形的有效方法 (OpenGL)

转载 作者:行者123 更新时间:2023-12-01 16:54:52 24 4
gpt4 key购买 nike

我对 OpenGL 有点陌生。我正在尝试使用 Java OpenGL 和 WorldWind Java 为飞机绘制 3D 动态轨迹,我可以使用 glDrawArrays 来绘制它。由于飞机的尾迹在每一帧(25fps)中都会增加,因此我将新的顶点值放入verticeBuffer中。我还使用 rightFloatBuffer 和 leftFloatBuffer 将 GL_LINE_STRIP 绘制到路径的两侧,正如您在所附的第一张图片中看到的那样。由于随着飞机飞行,轨迹变得越来越长,我认为我需要为三角形(verticeBuffer)创建一个大的 FloatBuffer,并为左右线创建 2 个大的 FloatBuffer。

我的第一个问题:绘制多个三角形最有效的方法是什么?根据我的代码,我认为飞行 5 小时后 FloatBuffer 将满。如果我尝试在每一帧中使用 for 循环更新值,并且如果我同时拥有 50-75 架飞机,这会降低性能。因此,我在每一帧更新一个三角形。

第二个问题:我想画一条像第二张图一样的轨迹。正如您所看到的,随着距离飞机越来越近,踪迹变得更加透明。当飞机变色时,轨迹的底部看起来会有所不同。我该怎么做?

第三个问题:我使用gl.DepthMask(false)并绘制line_strip和gl.DepthMask(true)来绘制平滑的线条,线条之间没有间隙。但这次首先添加到场景中的飞机尾迹总是显示在顶部,无论它是否在另一条尾迹下。我可以做什么来克服这个问题?或者考虑到顶点的数量,我该怎么做才能绘制没有间隙的平滑线条?

我绘制轨迹的代码如下:


private final FloatBuffer verticeBuffer = GLBuffers.newDirectFloatBuffer(3000000);
private final FloatBuffer rightFloatBuffer = GLBuffers.newDirectFloatBuffer(1500000);
private final FloatBuffer leftFloatBuffer = GLBuffers.newDirectFloatBuffer(1500000);

protected void drawTrail() {

gl.glPushAttrib(GL2.GL_CURRENT_BIT | GL2.GL_COLOR_BUFFER_BIT | GL2.GL_LINE_BIT | GL2.GL_ENABLE_BIT
| GL2.GL_DEPTH_BUFFER_BIT);
try {
gl.glEnable(GL.GL_BLEND);
gl.glBlendFunc(GL2.GL_SRC_ALPHA, GL2.GL_ONE_MINUS_SRC_ALPHA);
gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);

doDrawTrail(dc);

gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
gl.glDisable(GL.GL_BLEND);
} finally {
gl.glPopAttrib();
}
}

protected void doDrawTrail() {

updateTrailVertices();

float[] colors = new float[]{trailColor.getRed() / 255.f, trailColor.getGreen() / 255.f, trailColor.getBlue() / 255.f};
gl.glColor4f(colors[0], colors[1], colors[2], 0.6f);

gl.glEnable(GL2.GL_LINE_SMOOTH);
gl.glHint(GL2.GL_LINE_SMOOTH_HINT, GL2.GL_NICEST);

gl.glVertexPointer(3, GL.GL_FLOAT, 0, verticeBuffer.rewind());
gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, verticeBuffer.limit() / 3);

gl.glColor3f(colors[0], colors[1], colors[2]);

gl.glLineWidth(3f);

//To draw smooth lines
gl.glDepthMask(false);

gl.glVertexPointer(3, GL.GL_FLOAT, 0, rightFloatBuffer.rewind());
gl.glDrawArrays(GL.GL_LINE_STRIP, 0, rightFloatBuffer.limit() / 3);

gl.glVertexPointer(3, GL.GL_FLOAT, 0, leftFloatBuffer.rewind());
gl.glDrawArrays(GL.GL_LINE_STRIP, 0, leftFloatBuffer.limit() / 3);

gl.glDepthMask(true);

}

protected void updateTrailVertices() {

// In each frame when the aircraft position changes this function updates the last vertices
if (positionChange) {

positionChange = false;

//I need to set the position and the limit of the buffers to draw only updated parts
verticeBuffer.position(lastIndex * 2);

rightFloatBuffer.position(lastIndex);
leftFloatBuffer.position(lastIndex);

verticeBuffer.limit((lastIndex * 2) + 6);

rightFloatBuffer.limit(lastIndex + 3);
leftFloatBuffer.limit(lastIndex + 3);

List<Vec4> pointEdges = computeVec4(this.currentPosition, this.currentHeading, this.currentRoll, this.span);

verticeBuffer.put((float) pointEdges.get(0).x).put((float) pointEdges.get(0).y).put((float) pointEdges.get(0).z);
verticeBuffer.put((float) pointEdges.get(1).x).put((float) pointEdges.get(1).y).put((float) pointEdges.get(1).z);

rightFloatBuffer.put((float) pointEdges.get(0).x).put((float) pointEdges.get(0).y).put((float) pointEdges.get(0).z);
leftFloatBuffer.put((float) pointEdges.get(1).x).put((float) pointEdges.get(1).y).put((float) pointEdges.get(1).z);

lastIndex = rightFloatBuffer.position();

}
}

First Picture

Second Picture

最佳答案

如果可以使用几何着色器,显示飞行轨迹的最有效方法是使用一个顶点缓冲区并将其渲染为一条线带。顶点缓冲区包含早期位置和法线 vector (平面向上方向)。使用这两个值,几何着色器可以将其转换为四边形。这些四边形应该包含纹理坐标,可以在片段着色器中使用它来显示边框。

您只需要一次绘制调用,并将 GPU 上存储的数据减少到绝对最小值。

飞行轨迹的淡入淡出可以通过使用带有平面坐标的制服来完成。您的其中一种阴影可以计算到平面的距离以及像素的 alpha 值。

关于java - 绘制大量三角形的有效方法 (OpenGL),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61607004/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com