【发布时间】:2020-08-19 18:02:08
【问题描述】:
我对 OpenGL 有点陌生。我正在尝试使用 Java OpenGL 和 WorldWind Java 为飞机绘制 3D 动态轨迹,我可以使用 glDrawArrays 绘制它。由于飞机的轨迹在每一帧(25fps)中都会增加,因此我将新的顶点值放入 verticeBuffer。我还使用 rightFloatBuffer 和 leftFloatBuffer 将 GL_LINE_STRIP 绘制到路径的两侧,正如您在附加的第一张图片中看到的那样。由于随着飞机飞行轨迹变得越来越长,我认为我需要为三角形(verticeBuffer)创建一个大的 FloatBuffer,为左右线创建 2 个大的 FloatBuffer。
我的第一个问题:绘制多个三角形最有效的方法是什么?根据我的代码,我认为在飞行 5 小时后,FloatBuffers 将已满。如果我尝试在每帧中使用 for 循环更新值,并且如果我同时有 50-75 架飞机,这将降低性能。因此,我在每一帧更新一个三角形。
第二个问题:我想像第二张图片那样画一条小路。如您所见,随着距离飞机越来越近,轨迹变得更加透明。当飞机变颜色时,轨迹的底部似乎有所不同。我该怎么做?
第三个问题:我使用gl.DepthMask(false) 和draw 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();
}
}
【问题讨论】:
-
请将您的帖子编辑为仅一个问题。您可以在多个帖子中提出多个问题。它使其他人更容易回答您的问题或找到问题。
-
为什么要禁用平滑线的深度缓冲区?我认为您想使用 MSAA。