java - LWJGL 2.9.0 GL20.glUniformMatrix4 导致随机卡顿

标签 java performance lwjgl opengl-3

我正在一个单独的线程中以 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/

相关文章:

java - 从java模块启动react-native Activity (android)

java - ArrayList快速查找自定义对象

javascript - jQuery 在循环期间非常慢,我可以改进什么?

java - LWJGL Tilerenderer 只渲染一种类型的图 block /一种纹理

shader - 如何使用shader绘制FBO lwjgl

java - 我们可以在android中使元素全局化吗

java - 使用 id 从 firebase 数据库获取节点到 textviex

java - 如何使用Hibernate和JPA注释保存外键值

c++ - OpenMP 并行线程

java - lwjgl,仅旋转屏幕上的一个对象?