Я немного новичок в OpenGL. Я пытаюсь нарисовать 3D динамический след c для самолета, используя Java OpenGL и WorldWind Java. Я могу нарисовать его с помощью glDrawArrays. Поскольку след самолета увеличивается с каждым кадром (25 кадров в секунду), я помещаю новые значения вершин в verticeBuffer. Я также использую rightFloatBuffer и leftFloatBuffer, чтобы нарисовать GL_LINE_STRIP по обеим сторонам следа, как вы можете видеть на прикрепленном первом изображении. Поскольку по мере полета самолет становится все длиннее и длиннее, я подумал, что мне нужно создать большой буфер FloatBuffer для треугольников (verticeBuffer) и 2 больших буфера FloatBuffer для левой и правой линий.
Мой первый вопрос: что такое самый эффективный способ нарисовать множество треугольников? Исходя из моего кода, я думаю, что через 5 часов полета FloatBuffers будет заполнен. Если я попытаюсь обновить значения с l oop в каждом кадре, и если у меня будет, скажем, 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();
}
}