Здоровый способ рисования линий сетки в LibGdx

#java #opengl #libgdx #rendering #game-engine

#java #opengl #libgdx #визуализация #игровой движок

Вопрос:

Итак, я хотел нарисовать сетку в своей игре, и когда я ее писал, это показалось невероятно необычным (по крайней мере, мне) с точки зрения эффективности. У меня есть два цикла for внутри метода рендеринга, который используется для рендеринга игры, поэтому он вызывается очень часто и быстро.

Является ли эта часть ShapeRenderer красным флагом?

 public void render(float deltaTime) {
    Gdx.gl.glClearColor(Color.GRAY.r, Color.GRAY.g, Color.GRAY.b, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);       

    batch.begin();
    this.world.getPlayer().render(deltaTime, batch);
    batch.end();

    // Gridlines
    shape.begin(ShapeType.Line);
    shape.setColor(Color.BLACK);
    for (int i = 0; i < Gdx.graphics.getHeight() / 32; i  ) {
        shape.line(0, i * 32, Gdx.graphics.getWidth(), i * 32);
    }
    for (int i = 0; i < Gdx.graphics.getWidth() / 32; i  ) {
        shape.line(i * 32, 0, i * 32, Gdx.graphics.getHeight());
    }
    shape.end();
}
  

Комментарии:

1. На самом деле это не так плохо, как могло бы быть… вместо этого у вас может быть два вложенных цикла O(N^2) O(2*N) . Однако, если shape функция этого line (...) объекта преобразуется в вызов рисования для каждого вызова, это не так эффективно, как могло бы быть. Базовый GL_LINES примитив рисует несвязанные отрезки линий в виде пар точек. Вы можете легко упростить это до одного вызова рисования, используя списки вершин (индексированный чертеж), если это действительно вас беспокоит.

2. Честно говоря, даже если вы использовали примитив подключенной строки, например GL_LINE_STRIP , вы все равно могли бы свернуть это в один вызов рисования. Это просто потребует немного большей сложности в порядке рисования линий.

3. Если он не отображается в тестах или профилировании, вам не нужно беспокоиться об этом.

4. Хорошо, спасибо всем! Я рассмотрю варианты.

Ответ №1:

Вы могли бы использовать быстрый, простой и мощный ImmediateModeRenderer20. Пожалуйста, взгляните на следующий код с помощью PerspectiveCamera:

 // init primitive renderer
ImmediateModeRenderer20 lineRenderer = new ImmediateModeRenderer20(false, true, 0);

// create atomic method for line
public static void line(float x1, float y1, float z1,
                        float x2, float y2, float z2,
                        float r, float g, float b, float a) {
    lineRenderer.color(r, g, b, a);
    lineRenderer.vertex(x1, y1, z1);
    lineRenderer.color(r, g, b, a);
    lineRenderer.vertex(x2, y2, z2);
}

// method for whole grid
public static void grid(int width, int height) {
    for (int x = 0; x <= width; x  ) {
        // draw vertical
        line(x, 0, 0,
                x, 0, -height,
                0, 1, 0, 0);
    }

    for (int y = 0; y <= height; y  ) {
        // draw horizontal
        line(0, 0, -y,
                width, 0, -y,
                0, 1, 0, 0);
    }
}

// init 3d camera
PerspectiveCamera perspectiveCamera = new PerspectiveCamera(55, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());

// your render loop {
perspectiveCamera.update();
lineRenderer.begin(perspectiveCamera.combined, GL30.GL_LINES);
//... lineRenderer works a lot
grid(10, 10);
//... lineRenderer works a lot
lineRenderer.end();
//}
  

Надеюсь, это поможет!