OpenGL/Libgdx: оптимизация рендеринга квадратной сетки

Рендеринг моего игрового фона занимает 1/4 всей продолжительности рендеринга, который я пытался улучшить, но все же я не думаю, что это нормально, что это занимает так много времени, зная, насколько это просто:

Фон представляет собой квадратную сетку (например, шахматную доску), где каждый квадрат имеет свой цвет, который меняется в каждом кадре. Положение квадратов по оси y также меняется в каждом кадре, но не по оси x.

Вот моя основная функция рендеринга

public void main.render() {
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    final float deltaS = Gdx.graphics.getDeltaTime();

    background.update(deltaS);
    updateTheGame(deltaS);

    background.render();

    spriteBatch.setProjectionMatrix(uiCamera.combined);
    spriteBatch.begin();
    renderTheGame(spriteBatch);
    spriteBatch.end();

}

Вот объявление сетки фона

mesh = new Mesh(true, nbVertices, nbIndices,
                new VertexAttribute(VertexAttributes.Usage.Position, 2, ShaderProgram.POSITION_ATTRIBUTE),
                new VertexAttribute(VertexAttributes.Usage.ColorUnpacked, 3, GL20.GL_FLOAT, false, ShaderProgram.COLOR_ATTRIBUTE));

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

void background.update(float deltaS) {
    for (BGSquareRow row : squareRows)
        row.update(deltaS);
    setupVerticesArray();
    mesh.updateVertices(0, verticesArray);
}


private final Color tmpColor = new Color();

private void setupVerticesArray() {
    int index = 0;
    for (BGSquareRow row : squareRows) {
        final float y0 = row.y;
        final float y1 = row.y + squareSize;
        for (int i=0; i<nbSquareX; i++) {
            row.getSquareColor(i, tmpColor);
            final float x0 = squareXs[i];
            final float x1 = squareXs[i+1];
            verticesArray[index++] = x0;
            verticesArray[index++] = y0;
            verticesArray[index++] = tmpColor.r;
            verticesArray[index++] = tmpColor.g;
            verticesArray[index++] = tmpColor.b;
            verticesArray[index++] = x1;
            verticesArray[index++] = y0;
            verticesArray[index++] = tmpColor.r;
            verticesArray[index++] = tmpColor.g;
            verticesArray[index++] = tmpColor.b;
            verticesArray[index++] = x1;
            verticesArray[index++] = y1;
            verticesArray[index++] = tmpColor.r;
            verticesArray[index++] = tmpColor.g;
            verticesArray[index++] = tmpColor.b;
            verticesArray[index++] = x0;
            verticesArray[index++] = y1;
            verticesArray[index++] = tmpColor.r;
            verticesArray[index++] = tmpColor.g;
            verticesArray[index++] = tmpColor.b;
        }
    }
}

Вот функция рендеринга фона, вызываемая каждый кадр после background.update() (это слишком дорого)

 void background.render() {
      shaderProgram.begin();
      shaderProgram.setUniformMatrix("u_projTrans", parent.uiCamera.combined);
      mesh.render(shaderProgram, GL20.GL_TRIANGLES);
      shaderProgram.end();
 }

Я постарался поставить только минимум, необходимый для понимания моей проблемы, поэтому, если я забыл что-то важное, сообщите мне, пожалуйста.

У меня есть некоторые идеи оптимизации, но я не знаю, как это сделать:

  • Можно ли нарисовать сетку фона на основном пакете спрайтов? Это привело бы к 1 вызову отрисовки в функции main.render() вместо 2, если я прав

  • Можно ли обновить только значения y, красного, синего и зеленого в буфере вершин сетки? Я нашел способы обновить часть буфера вершин, но только если это непрерывная часть.

  • Возможна ли оптимизация настройки verticesArray?

(Также пробовал использовать ColorPacked для буфера вершин, но лучше не стало)


person Xavier P    schedule 05.10.2017    source источник
comment
Сколько строк/столбцов?   -  person Tenfour04    schedule 05.10.2017
comment
Есть 17 рядов по 10 квадратов! Он заполняет экран   -  person Xavier P    schedule 05.10.2017
comment
И знаете ли вы, ограничены ли вы скорость заполнения или процессор, или что? Это выглядит очень тривиально, поэтому, если вам нужно его оптимизировать, может быть серьезная проблема в коде, который вы не показали.   -  person Tenfour04    schedule 05.10.2017


Ответы (1)


Вы можете создать свою сетку с помощью meshParts, где каждый meshPart представляет один квадрат сетки. Затем вы можете раскрасить каждый из квадратов разным цветом, используя шейдер GLSL. Это должно минимизировать время работы вашего процессора и использовать мощность графического процессора.

Вот пример раскрашивания шейдера с помощью libGDX. MeshPart Метод рендеринга поддерживает передавая ShaderProgram в качестве параметра и может содержать определенный материал.

person Michał Stochmal    schedule 08.10.2017