我有一个小项目,它是用LWJGL 2编写的,现在我想转到第3版,我没有遇到更大的问题就修改了主库。但步子很小。所以我首先没有对向量和矩阵类做任何修改。相反,在新项目中,我添加了旧的lwjgl_util.jar。我可以把一切都恢复正常。到目前为止,我唯一的损失是键盘和鼠标的输入,但这不是什么大问题。
下一个关键步骤是再次删除额外的.jar文件,并将所有导入更改为org.joml.Vector2f、org.joml.Vector2f和org.joml.Matrix4f类,以及我的代码中所需的更改。Eclipse说不再有错误,JVM也是这样说的。
如果我打印向量或矩阵,代码就会运行。他们都有他们应该有的数据。
但是它不应该渲染正常的世界,只有清晰的背景颜色(正确的颜色)。
我的想法是,我没有从Java到着色器的数据,着色器将所有矩阵乘以零,我什么也看不见。
我在https://github.com/JOML-CI/JOML/wiki/Migrating-from-LWJGL-2上找到了这一行,并认为这可能是我的问题,但我不明白它到底意味着什么:
的一个重要区别是在从FloatBuffer获取值或将值写入FloatBuffer时对NIO FloatBuffer的处理。在LWJGL 2中,FloatBuffer的位置将随着加载和存储操作的增加而增加。在JOML中,这个位置不会改变!
所以我现在的问题是:
如何处理不改变位置的FloatBuffers?
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);
}
}发布于 2022-01-21 08:21:29
tl;dr
删除对matrixBuffer.flip()的调用
较长解释
要知道为什么您的代码不能工作,需要您知道Buffer.flip() (通过您的FloatBuffer.flip()调用)到底做了什么:
翻转这个缓冲区。限制设置为当前位置,然后将位置设置为零。如果定义了标记,那么它就会被丢弃。
(我用粗体突出)。
你知道,NIO缓冲区有一个位置,标记,限制和容量。当您创建一个新的NIO缓冲区时,例如通过BufferUtils.createFloatBuffer(size),您将得到一个FloatBuffer,它是一个底层直接ByteBuffer的视图,它具有size的容量、size的限制、0的位置以及没有标记集。
通常,JDK中的相对NIO缓冲区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转座子,const GLfloat *值);
LWJGL将根据提供的NIO缓冲区的count参数的.remaining() / 16推断值。由于缓冲区可能具有.remaining() of 0 (当所述缓冲区的位置为0时,由于.flip()调用--由于Matrix4f.get(FloatBuffer)没有增加位置),所提供的OpenGL函数参数将是0,在本例中将导致noop。
https://stackoverflow.com/questions/70793756
复制相似问题