使用JOML从LWJGL 2迁移到LWJGL 3时,3D投影丢失



我有一个小项目,它是用LWJGL2编写的,现在想转到版本3。我更改了主库,没有遇到更大的问题。但要循序渐进。所以我首先没有对Vector和Matrix类做任何更改。相反,在新项目中,我添加了旧的lwjgl_util.jar。我可以将所有内容渲染为正常。到目前为止,我唯一的损失是键盘和鼠标的输入,但这不是什么大问题。

下一步也是关键的一步是再次删除额外的.jar文件,并将所有导入更改为org.com.l.Vector2f、org.com.l.Vector2f和org.com.l.Matrix4f类,以及我的代码中所需的更改。Eclipse表示不再有错误,JVM也是如此。

如果我打印矢量或矩阵,代码就会运行。他们都有应该有的数据。

但是,它应该渲染的不是正常的世界,而是只有清晰的背景颜色(顺便说一句,正确的颜色(

我的想法是,我没有从Java获得任何数据到着色器,着色器将所有矩阵相乘为零,我看不到任何东西。

我在上找到了这条线https://github.com/JOML-CI/JOML/wiki/Migrating-from-LWJGL-2我知道这可能是我的问题,但我不明白它的确切含义:

一个重要的区别是从FloatBuffer获取值或将值写入FloatBuffer时对NIO Float缓冲区的处理。在LWJGL 2中,FloatBuffer的位置将通过加载和存储操作递增。在JOML中,位置不会改变!

所以我现在的问题是:

如何在不改变位置的情况下处理浮动缓冲器?

public abstract class ShaderProgram {
private static FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16);
...
protected void loadMatrix(int location, Matrix4f matrix) {
matrix.get(matrixBuffer);
matrixBuffer.flip();
GL20.glUniformMatrix4fv(location, false, matrixBuffer);
}
}

tl;dr

删除对matrixBuffer.flip()的调用

更长的解释

要知道你的代码为什么不起作用,你需要知道Buffer.flip()(通过你的FloatBuffer.flip()调用(到底做了什么:

翻转此缓冲区。限制设置为当前位置,然后位置设置为零。如果定义了标记,则会将其丢弃。

(我用粗体突出显示(。

你知道,NIO缓冲区有一个位置、标记、限制和容量。当您创建一个新的NIO缓冲区时,例如通过BufferUtils.createFloatBuffer(size),您将获得一个FloatBuffer,它是底层直接ByteBuffer的视图,其容量为size,限制为size,位置为0,并且没有标记集。

通常,JDK中的relativeNIO Buffer put操作会增加缓冲区的位置。然而,JOML的Matrix/Vector.get(Buffer)不会做到这一点,就像所有以NIO缓冲区为参数的LWJGL/OpenGL方法一样,比如GL15.glBufferData(...)

因此,当您调用Matrix4f.get(FloatBuffer)时,所提供的缓冲区的位置将不会被修改,因此,之后在该缓冲区上调用.flip()将把缓冲区的limit设置为缓冲区位置所在的位置(可能是0(。

接下来需要知道的是,采用NIO缓冲区的LWJGL方法将使用缓冲区的.remaining()(即.limit() - .position()(来确定底层本机OpenGL函数调用的任何大小/长度参数的参数值。在具有本机签名的glUniformMatrix4fv()的情况下:

void glUniformMatrix4fv(GLint位置、GLsizei计数、GLboolean转置、常量GLfloat*值(;

LWJGL将根据提供的NIO缓冲区的.remaining() / 16推断count参数的值。由于您的缓冲区可能有.remaining()对于0(由于当所述缓冲器具有0的位置时的.flip()调用-由于Matrix4f.get(FloatBuffer)没有增加该位置(,所提供的OpenGL函数自变量将是0,这将在这种情况下引起noop。

最新更新