【问题标题】:Passing matrices to glsl just won't work?将矩阵传递给 glsl 不起作用?
【发布时间】:2011-12-08 03:06:38
【问题描述】:

我目前正在使用 lwjgl 并编程 glsl 1.20。

尝试将 4x4 浮点矩阵发送到着色器的代码如下所示:

    int normalMatrixLocation = ARBShaderObjects.glGetUniformLocationARB(handlers.ShaderHandler.get().getShader("sphere"), "normalMatrix");
    tempFloatBuffer = BufferUtils.createFloatBuffer(16);
    tempFloatBuffer.put(helpers.Matrix.doubleToFloat4x4(normalMatrix.getArray()));
    tempFloatBuffer.rewind();
    ARBShaderObjects.glUniformMatrix4ARB(normalMatrixLocation, false, tempFloatBuffer);

辅助函数如下所示:

    public static float[] doubleToFloat4x4(double[][] dArray) {
        float[] newFloat = new float[16];
        for(int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                newFloat[j+4*i] = (float)dArray[i][j];
            }
        }
        return newFloat;
    }

在着色器中我有以下内容,以便我能够在着色器的不同功能中使用它:

uniform mat4 normalMatrix;

虽然这件制服始终是一个空的 4x4 矩阵...

我做错了什么?

【问题讨论】:

  • 您是否检查过normalMatrixLocation 是一个合法值? rewind 是做什么的?在调用glUniformMatrix4ARB 之前,您是否确认tempFloatBuffer 不是空矩阵?
  • 您没有使用 GLSL 1.20。我知道这一点是因为您所有的调用都以 ARB 结尾,这意味着您使用的是 ARB_shader_objects 扩展,它不允许 GLSL 1.20。或者,如果确实如此,它只是偶然起作用。不要使用 GLSL 作为扩展;将其用作核心功能(无 ARB 后缀)。
  • 感谢您的回答! @JimBuck normalMatrixLocation 等于0,接缝很好,倒带将内部迭代器指针指向位置0。当我调用glUniformMatrix4ARB时,我已经确认tempFloatBuffer中确实有数据。 @NicolBolas 我在我的着色器文件的顶部指定了#version 120,你是说在使用库 org.lwjgl.opengl.ARBShaderObjects 中的类时,我应该使用库中的相应函数而不是使用 arb surfix org.lwjgl.opengl.GL20?
  • 好吧,这很奇怪,在我测试了 normalMatrixLocation 并在没有 ARB 的情况下进行了测试之后,我将代码恢复到以前的样子(我认为),现在它可以正常工作了......不要不知道我改变了什么,但现在它显然可以工作了!感谢您的帮助,很抱歉我找不到错误所在,以免其他人遇到此问题。
  • @Nicol Bolas:你在哪里发现 ARB_shader_objects 不允许 GLSL 1.20?规范只说明它是针对 GLSL 1.10 编写的,但没有说明何时适用!

标签: opengl glsl lwjgl


【解决方案1】:
uniform mat4x4 matrixName;

据我所知,它是“mat4x4”而不是“mat4”。

此外,发送浮点缓冲区需要使用字节缓冲区和 ByteOrder 类。我的代码如下:

 qbuffer.rewind();

    ByteBuffer temp = ByteBuffer.allocateDirect(64);
    temp.order(ByteOrder.nativeOrder());

    int qLocation = ARBShaderObjects.glGetUniformLocationARB(shaderProgram, "q");
    ARBShaderObjects.glUniformMatrix4ARB(qLocation, 
false, (FloatBuffer)temp.asFloatBuffer().put(qbuffer).flip());

令人费解,是的,但它确保了原生顺序。

【讨论】:

  • 'mat4' 是正确的。只有非方阵描述这两个维度。
  • 我说 mat4x4 因为它确实是我一直在使用的。如果你说的是真的,这很好。如果适合您,您可以编辑我的答案。
【解决方案2】:

glUniform 函数影响当前程序。确保在调用 glUniform 之前调用 glUseProgramARB(myProgramObj)。

【讨论】:

  • 没有实际的 glUniform 函数,我说 glUniform 包含 glUniform 的所有变体(1f/4f/Matrix4f/等)。显然,如果您使用的是 ARB_shader_objects,您将使用 glUniform 函数的 ARB 版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-12
  • 1970-01-01
  • 2019-12-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多