OpenGL/Libgdx : 方形网格渲染优化
OpenGL/Libgdx : Square grid rendering optimization
我的游戏背景渲染占用了所有渲染持续时间的 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));
这里是后台更新函数(每帧调用,在render()之前)
(这不是我要优化的)
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();
}
我试着只写了理解我的问题所需的最少内容,所以如果我忘记了重要的事情,请告诉我
我有一些优化的想法,但我不知道怎么做:
是否可以在主 spriteBatch 上绘制背景的网格?如果我是对的,这将导致 main.render() 函数中的 1 个绘制调用而不是 2 个
是否可以只更新网格顶点缓冲区中的 y、红色、蓝色和绿色值?我找到了更新顶点缓冲区的一部分的方法,但前提是它是连续的部分
verticesArray 设置是否有任何可能的优化?
(我也尝试过使用 ColorPacked 作为顶点缓冲区,但效果并不好)
您可以使用 meshParts 创建网格,其中每个 meshPart
将代表单个网格正方形。然后,您可以使用 GLSL 着色器为每个正方形着色不同的颜色。这应该可以最大限度地减少您的 CPU 工作时间,并且会利用 GPU 的能力。
Here's an example of colorizing shader with libGDX. MeshPart
渲染方法支持将 ShaderProgram
作为参数传递,并且可以包含特定的 material.
我的游戏背景渲染占用了所有渲染持续时间的 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));
这里是后台更新函数(每帧调用,在render()之前) (这不是我要优化的)
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();
}
我试着只写了理解我的问题所需的最少内容,所以如果我忘记了重要的事情,请告诉我
我有一些优化的想法,但我不知道怎么做:
是否可以在主 spriteBatch 上绘制背景的网格?如果我是对的,这将导致 main.render() 函数中的 1 个绘制调用而不是 2 个
是否可以只更新网格顶点缓冲区中的 y、红色、蓝色和绿色值?我找到了更新顶点缓冲区的一部分的方法,但前提是它是连续的部分
verticesArray 设置是否有任何可能的优化?
(我也尝试过使用 ColorPacked 作为顶点缓冲区,但效果并不好)
您可以使用 meshParts 创建网格,其中每个 meshPart
将代表单个网格正方形。然后,您可以使用 GLSL 着色器为每个正方形着色不同的颜色。这应该可以最大限度地减少您的 CPU 工作时间,并且会利用 GPU 的能力。
Here's an example of colorizing shader with libGDX. MeshPart
渲染方法支持将 ShaderProgram
作为参数传递,并且可以包含特定的 material.