我正在一个单独的线程中以 60FPS(16ms)的速度运行渲染器。
以下代码会产生随机口吃......
long testTime = System.nanoTime();
GL20.glUniformMatrix4(
GL20.glGetUniformLocation(getProgram(), "projectionMatrix"),
false,
matrix4fBuffer // holds projection matrix
);
testTime = System.nanoTime() - testTime;
if (testTime > 1000000) {
System.out.println("DELAY " + (testTime / 1000000) ); // 22-30ms
}
GL20.glUniformMatrix4 调用随机花费大约 22-30 毫秒(每 10 秒、30 秒、45 秒……),这会导致随机减速(卡顿)。通常需要 0 毫秒(几纳秒)。
我正在测试仅渲染一个对象(使用可编程管道 - 着色器,OpenGL >= 3.3)。
此示例的其他部分:
getProgram() // simply returns integer
// This is called before GL20.GLUniformMatrix4
FloatBuffer matrix4fBuffer = BufferUtils.createFloatBuffer(16);
projectionMatrix.store(matrix4fBuffer);
matrix4fBuffer.flip();
知道这里发生了什么吗?
编辑: 我忘了提及我正在单独的线程中运行渲染和更新。我想可能是 与线程调度有关?
编辑: 好吧,我也在单线程环境中测试了这个,问题仍然存在......我还发现对 glUnuformMatrix4 的其他调用不会导致问题,例如:
long testTime = System.nanoTime();
state.model.store(buffer);
buffer.flip();
GL20.glUniformMatrix4(
GL20.glGetUniformLocation(shader.getProgram(), "modelMatrix"),
false,
buffer
);
testTime = System.nanoTime() - testTime;
if (testTime > 16000000) {
System.out.println("DELAY MODEL" + (testTime / 1000000) );
}
最佳答案
停止这样做:
GL20.glUniformMatrix4(
GL20.glGetUniformLocation(getProgram(), "projectionMatrix"),
[...]
链接程序后,统一位置不会改变,并且从 OpenGL 查询任何内容是降低性能的好方法。
这个特定的Get
函数特别昂贵,因为它使用字符串来标识您正在搜索的位置。除非优化为字典树、哈希表等,否则字符串比较速度很慢......并且随着您向搜索字符串集添加更多潜在匹配项,费用也会增加。 OpenGL 和 GLSL 都没有定义如何实现这个函数,但是如果您担心性能,您应该假设您的实现是愚蠢的。
为您经常使用的命名制服准备一个GLint
。老实说,我建议编写一个封装 GLSL 程序对象的类,然后针对任何专门化对其进行子类化。专门的类将存储它们需要的所有统一位置,并且您永远不必查询 GL 来获取统一位置。
关于java - LWJGL 2.9.0 GL20.glUniformMatrix4 导致随机卡顿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20120610/