【问题标题】:GLSL Uniforms will not be set不会设置 GLSL 制服
【发布时间】:2014-01-04 04:41:18
【问题描述】:

我想了解 GLSL 的工作原理,所以我一直在 youtube 上关注一个人:thebennybox。我一直在为我的节目设置制服。首先,这是我目前正在使用的 2 个着色器。

顶点着色器:

#version 430
layout (location = 0) in vec3 position;
out vec4 color;
uniform float uniformFloat;
void main(){

    color = vec4(clamp(position, 0.0, uniformFloat), 1.0);
    gl_Position = vec4(0.25 * position, 1.0); 
}

片段着色器:

#version 430
in vec4 color;
out vec4 fragColor;
void main(){

    fragColor = color;
}

它们都非常简单,但我似乎无法将 uniformFloat 变量设置为任何值。 在将这两个着色器链接并验证到着色器程序之后。我立即尝试将 1.0f 的值设置为 uniformFloat(仅用于测试目的)......当我这样做时,我只是得到一个黑屏,上面没有任何东西。如果我将 uniformFloat 替换为 1.0f(在着色器本身中),我将得到我所需要的。

添加和设置制服的代码如下:

public void addUniform(String uniform) {
    int uniformLocation = glGetUniformLocation(shaderProgram, uniform);

    if(uniformLocation == -1)
    {
            System.err.println("Error: Could not find uniform: " + uniform);
            new Exception().printStackTrace();
            System.exit(1);
    }
    uniforms.put(uniform, uniformLocation);

}

public void setUniformf(String uniformName, float value){
        glUniform1f(uniforms.get(uniformName), value);
}

(uniforms 是一个 HashMap,它为每个不同的统一值名称保存一个位置值) 我从字面上看,在验证程序是否已经过验证后立即放置 addUniform 和 setUniformf 方法。我在这里有什么遗漏吗?下面是添加创建着色器、链接它们、然后添加制服的代码。

public ProgramShader(String vertexShaderLocation, String fragmentShaderLocation) {
    shaderProgram = glCreateProgram();
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    vertexShaderSource = new StringBuilder();
    fragmentShaderSource = new StringBuilder();
    uniforms = new HashMap<String, Integer>();

    for (int i = 0; i < 2; i++) {
        try {
            BufferedReader reader;
            if (i == 0) {
                reader = new BufferedReader(new FileReader(
                        vertexShaderLocation));
            } else {
                reader = new BufferedReader(new FileReader(
                        fragmentShaderLocation));
            }
            String line;
            while ((line = reader.readLine()) != null) {
                if (i == 0) {
                    vertexShaderSource.append(line + "\n");
                } else {
                    fragmentShaderSource.append(line + "\n");
                }
            }
            reader.close();
        } catch (IOException e) {
            if (i == 0) {
                System.err
                        .println("Vertex Shader Source code was not found.");
            } else {
                System.err
                        .println("Fragment Shader Source code was not found.");
            }
        }
    }

    glShaderSource(vertexShader, vertexShaderSource);
    glCompileShader(vertexShader);
    if (glGetShaderi(vertexShader, GL_COMPILE_STATUS) == GL_FALSE) {
        System.err.println("Vertex Shader was not compiled correctly. Error log: ");
        System.err.println(glGetShaderInfoLog(vertexShader, 1024));
    }
    glShaderSource(fragmentShader, fragmentShaderSource);
    glCompileShader(fragmentShader);
    if (glGetShaderi(fragmentShader, GL_COMPILE_STATUS) == GL_FALSE) {
        System.err.println("Fragment Shader was not compiled correctly. Error log: ");
        System.err.println(glGetShaderInfoLog(fragmentShader, 1024));
    }
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    if (glGetProgrami(shaderProgram, GL_LINK_STATUS) == GL_FALSE) {
        System.err.println("Shader program wasn't linked correctly.");
        System.err.println(glGetProgramInfoLog(shaderProgram, 1024));
    }
    glValidateProgram(shaderProgram);
    addUniform("uniformFloat");
    setUniformf("uniformFloat", 1.0f);

    int error = glGetError();
    if(error != GL_NO_ERROR){
        System.out.println("ERROR: ");
        System.err.println(gluErrorString(error));
    }
}

出现错误,这是“无效操作”。有什么方法可以让我查明到底发生了什么?

【问题讨论】:

  • 您是否尝试过不经过哈希映射直接设置(排除哈希映射本身的问题)?
  • 设置制服时着色器程序是否处于活动状态?
  • 我确实尝试过让她摆脱哈希映射,但同样的事情仍然发生。并且着色器程序处于活动状态(据我所知)。当我在 Eclipse 上运行时会打开一个窗口,但除了黑屏之外什么都没有出现。我有编译状态错误,如果出现问题会弹出,但它们从未出现过。
  • glGetError() 有什么回报吗?
  • 我刚刚在原始帖子中添加了更多代码。但是,我确实实现了 glGetError() ,结果是“无效操作”。有什么不合适的地方吗?

标签: java opengl glsl lwjgl


【解决方案1】:

嗯...我让它工作了,但我仍然不知道它为什么工作。我将添加制服的代码保留在原处(在链接/验证着色器程序之后)。但是,我在 glUseProgram() 之后移动了用于设置统一值的代码,并且正确的三角形被绘制到了屏幕上。不过,我认为在着色器程序运行时不允许更改/设置统一变量。我想我还有一些阅读要做。

仍然感谢您的帮助!

【讨论】:

  • 程序没有“运行”仅仅因为你调用了glUseProgram (...)。这实际上只是告诉 OpenGL 在下一次某些东西(通常是顶点)沿着管道运行时,按字面意思使用程序。在您执行glDrawArrays (...) 之类的操作之前,它不会运行,即便如此,您也永远不会真正知道它何时“运行”。此外,与 OpenGL 中的大多数事情一样,该实现负责确保您在管道中的另一个命令正在使用它时不会更改某物的状态。 GL4 中的一些新特性改变了这一点,但您通常可以依赖这种行为。
  • 必须在能够设置制服之前调用 glUseProgram,除非您使用在 OpenGL 4.1 中引入的 glProgramUniform。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-29
  • 1970-01-01
  • 2011-07-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多