Opengl VBO和着色器的性能不佳
我尝试用VBOs和着色器在现代OpenGL中渲染2048个四边形。但是表演很糟糕。通过使用下面的代码,我只获得了大约50 FPS。我想,我每帧都会调用一些东西,是什么减慢了应用程序的速度,但我不知道它是什么 我还认为,如果只是改变了对象的位置,那么每帧向着色器发送位置、视图和投影矩阵的速度非常慢 我可以做些什么来更快地获取此代码 型号代码:Opengl VBO和着色器的性能不佳,opengl,glsl,lwjgl,Opengl,Glsl,Lwjgl,我尝试用VBOs和着色器在现代OpenGL中渲染2048个四边形。但是表演很糟糕。通过使用下面的代码,我只获得了大约50 FPS。我想,我每帧都会调用一些东西,是什么减慢了应用程序的速度,但我不知道它是什么 我还认为,如果只是改变了对象的位置,那么每帧向着色器发送位置、视图和投影矩阵的速度非常慢 我可以做些什么来更快地获取此代码 型号代码: import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.util.Arra
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.util.Arrays;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;
public abstract class Model
{
private TexturedVertex[] vertices;
private byte[] indices;
private FloatBuffer verticesBuffer;
private ByteBuffer indicesBuffer;
private Vector3f position;
private Vector3f angle;
private Vector3f scale;
int shaderProgram;
int indicesCount;
private int projectionMatrixLocation;
private int viewMatrixLocation;
private int modelMatrixLocation;
int vaoID;
int vboID;
int vboiID;
public void load (TexturedVertex[] vertices, byte[] indices, Shader shader)
{
this.position = new Vector3f(0, 0, -1);
this.angle = new Vector3f(0, 0, 0);
this.scale = new Vector3f(1, 1, 1);
this.vertices = vertices;
this.indices = indices;
this.shaderProgram = shader.getProgramID();
this.generateBuffer();
this.generateArrayBufferObjects();
this.configureShader();
}
private void generateBuffer()
{
// === Vertices Buffer === //
this.verticesBuffer = BufferUtils.createFloatBuffer(vertices.length * TexturedVertex.elementCount);
for (int i = 0; i < vertices.length; i++)
{
verticesBuffer.put(vertices[i].getElements());
System.out.print ("XYZW: " + Arrays.toString(vertices[i].getXYZW()));
System.out.print (" RGBA: " + Arrays.toString(vertices[i].getRGBA()));
System.out.println (" ST: " + Arrays.toString(vertices[i].getST()));
}
verticesBuffer.flip();
// === Generate Indices Buffer === //
this.indicesCount = indices.length;
this.indicesBuffer = BufferUtils.createByteBuffer(indicesCount);
indicesBuffer.put(indices);
indicesBuffer.flip();
}
private void generateArrayBufferObjects()
{
// === Generate VAO & VBO === //
this.vaoID = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vaoID);
this.vboID = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer, GL15.GL_STATIC_DRAW);
this.vboiID = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiID);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL15.GL_STATIC_DRAW);
System.out.println ();
System.out.println ("VAO-ID: #" + vaoID);
System.out.println ("VBO-ID: #" + vboID);
System.out.println ("VBOI-ID: #" + vboiID);
// === Put informations to shader === //
GL20.glVertexAttribPointer(0, TexturedVertex.positionElementCount, GL11.GL_FLOAT, false, TexturedVertex.stride, TexturedVertex.positionByteOffset);
GL20.glVertexAttribPointer(1, TexturedVertex.colorElementCount, GL11.GL_FLOAT, false, TexturedVertex.stride, TexturedVertex.colorByteOffset);
GL20.glVertexAttribPointer(2, TexturedVertex.textureElementCount, GL11.GL_FLOAT, false, TexturedVertex.stride, TexturedVertex.textureByteOffset);
// === Unbind Buffers === //
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0);
}
private void configureShader()
{
// === Bind shader === //
GL20.glUseProgram(shaderProgram);
// === Get matrix location === //
this.projectionMatrixLocation = GL20.glGetUniformLocation(shaderProgram, "projectionMatrix");
this.viewMatrixLocation = GL20.glGetUniformLocation(shaderProgram, "viewMatrix");
this.modelMatrixLocation = GL20.glGetUniformLocation(shaderProgram, "modelMatrix");
// === Update the matrix === //
this.updateMatrix();
// === Unbind shader === //
GL20.glUseProgram(0);
}
void updateMatrix()
{
// === Bind shader === //
GL20.glUseProgram(shaderProgram);
// === Load matrix === //
Matrix4f projectionMatrix = GameManager.camera.getProjectionMatrix();
Matrix4f viewMatrix = GameManager.camera.getViewMatrix();
Matrix4f modelMatrix = new Matrix4f();
// === Scale, translate and rotate matrix === //
Matrix4f.scale(scale, modelMatrix, modelMatrix);
Matrix4f.translate(position, modelMatrix, modelMatrix);
Matrix4f.rotate(Util.degreesToRadians(angle.z), new Vector3f(0, 0, 1), modelMatrix, modelMatrix);
Matrix4f.rotate(Util.degreesToRadians(angle.y), new Vector3f(0, 1, 0), modelMatrix, modelMatrix);
Matrix4f.rotate(Util.degreesToRadians(angle.x), new Vector3f(1, 0, 0), modelMatrix, modelMatrix);
// === Apply uniform matrix to shader === //
FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16);
projectionMatrix.store(matrixBuffer);
matrixBuffer.flip();
GL20.glUniformMatrix4(projectionMatrixLocation, false, matrixBuffer);
viewMatrix.store(matrixBuffer);
matrixBuffer.flip();
GL20.glUniformMatrix4(viewMatrixLocation, false, matrixBuffer);
modelMatrix.store(matrixBuffer);
matrixBuffer.flip();
GL20.glUniformMatrix4(modelMatrixLocation, false, matrixBuffer);
// === Unbind shader === //
GL20.glUseProgram(0);
}
public void setPosition (Vector3f newPosition)
{
this.position = newPosition;
this.updateMatrix();
}
public void setAngle (Vector3f newAngle)
{
this.angle = newAngle;
this.updateMatrix();
}
public void setScale (Vector3f newAngle)
{
this.scale = newAngle;
this.updateMatrix();
}
}
着色器:
#version 150 core
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
in vec4 in_Position;
in vec4 in_Color;
in vec2 in_TextureCoord;
out vec4 pass_Color;
out vec2 pass_TextureCoord;
void main(void) {
gl_Position = projectionMatrix * viewMatrix * modelMatrix * in_Position;
pass_Color = in_Color;
pass_TextureCoord = in_TextureCoord;
}
不知道?我需要帮助;)停止不正确地使用VAO。在绑定启用的顶点属性集时,它们已经存储并设置了这些属性集。除了在绘图时更改边界VAO之外,您还可以通过自己执行此操作来增加开销。如果使用正确,VAOs甚至可以存储绑定的
元素\u数组\u缓冲区
。您可以通过调用glBindVertexArray(…)
来替换大量代码。这些冗余API调用可能不是主要的性能瓶颈,但它们肯定不会对您的情况有任何帮助。如果合并索引缓冲区,您可能可以将2048个draw调用合并为1。@AndonM.Coleman您可以给我一个代码示例,如何正确使用VBO吗。如果我删除glEnableVertexAttribArray,四元组将不会被渲染。我没有说删除它,我说的是正确使用VAOs。我建议您寻找VAO教程。@AndonM.Coleman但我在本教程中使用的VAO如下:
import org.lwjgl.opengl.Display;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;
public class Camera extends Worker
{
private Matrix4f projectionMatrix;
private Matrix4f viewMatrix;
private Vector3f position;
private Vector3f angle;
private float fieldOfView;
private float aspectRatio;
private float nearPlane;
private float farPlane;
private float xScale;
private float yScale;
private float frustumLength;
@Override
protected void onInitialize()
{
// Apply default settings
this.fieldOfView = 60f;
this.aspectRatio = (float) Display.getWidth() / (float) Display.getHeight();
this.nearPlane = 0.1f;
this.farPlane = 100f;
this.position = new Vector3f(0, 0, -1);
this.angle = new Vector3f(0, 0, 0);
// Calculate scale and furstum length
this.yScale = Util.coTangent(Util.degreesToRadians(fieldOfView / 2f));
this.xScale = yScale / aspectRatio;
this.frustumLength = farPlane - nearPlane;
// Projection Matrix
projectionMatrix = new Matrix4f();
projectionMatrix.m00 = xScale;
projectionMatrix.m11 = yScale;
projectionMatrix.m22 = -((farPlane + nearPlane) / frustumLength);
projectionMatrix.m23 = -1;
projectionMatrix.m32 = -((2 * nearPlane * farPlane) / frustumLength);
projectionMatrix.m33 = 0;
// View Matrix
viewMatrix = new Matrix4f();
Matrix4f.translate(position, viewMatrix, viewMatrix);
Matrix4f.rotate(Util.degreesToRadians(angle.z), new Vector3f(0, 0, 1),
viewMatrix, viewMatrix);
Matrix4f.rotate(Util.degreesToRadians(angle.y), new Vector3f(0, 1, 0),
viewMatrix, viewMatrix);
Matrix4f.rotate(Util.degreesToRadians(angle.x), new Vector3f(1, 0, 0),
viewMatrix, viewMatrix);
}
public Matrix4f getProjectionMatrix()
{
return this.projectionMatrix;
}
public Matrix4f getViewMatrix()
{
return this.viewMatrix;
}
public void setPosition (Vector3f newPosition)
{
Matrix4f.translate(newPosition, viewMatrix, viewMatrix);
}
public void setPosition (float x, float y, float z)
{
setPosition(new Vector3f (x, y, z));
}
public void setAngle (Vector3f newAngle)
{
Matrix4f.rotate(Util.degreesToRadians(newAngle.z), new Vector3f(0, 0, 1),
viewMatrix, viewMatrix);
Matrix4f.rotate(Util.degreesToRadians(newAngle.y), new Vector3f(0, 1, 0),
viewMatrix, viewMatrix);
Matrix4f.rotate(Util.degreesToRadians(newAngle.x), new Vector3f(1, 0, 0),
viewMatrix, viewMatrix);
}
public void setAngle (float x, float y, float z)
{
setAngle(new Vector3f (x, y, z));
}
@Override
protected void onDestroy()
{
;
}
@Override
protected void onTick()
{
;
}
}
#version 150 core
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
in vec4 in_Position;
in vec4 in_Color;
in vec2 in_TextureCoord;
out vec4 pass_Color;
out vec2 pass_TextureCoord;
void main(void) {
gl_Position = projectionMatrix * viewMatrix * modelMatrix * in_Position;
pass_Color = in_Color;
pass_TextureCoord = in_TextureCoord;
}