【问题标题】:Opengl uniform variable not working?Opengl统一变量不起作用?
【发布时间】:2015-04-02 18:53:48
【问题描述】:

好的。我正在进入opengl 2.1(没有固定功能的东西)并且我在使用着色器时遇到了麻烦。我在我的着色器上声明了我的统一变量,在我的程序中我得到了统一的位置并用 gluniform 为其分配了一个值,但它似乎不起作用。

这些是我的着色器

片段着色器: #版本 120

varying float color;

void
main ()
{
    gl_FragColor = vec4(color, 0, 0, 1);
}

还有我的顶点着色器: #版本 120

attribute vec2 position;
varying float color;
uniform float pr_color;

void
main () 
{
    color = pr_color;
    gl_Position = vec4(position, 0.0, 1.0);
}

这就是我将数据传递给着色器的方式:

void 
display () 
{
     glClear(GL_COLOR_BUFFER_BIT);

     glUseProgram(g_program);

     pos_loc = glGetAttribLocation(g_program, "position");

     col_loc = glGetUniformLocation(g_program, "pr_color");

     glUniform1f(col_loc, 1.0);

     glBindBuffer(GL_ARRAY_BUFFER, vbo);
     glEnableVertexAttribArray(pos_loc);
     glVertexAttribPointer(pos_loc, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));

     glDrawArrays(GL_TRIANGLES, 0, 3);

    glutPostRedisplay();
    glutSwapBuffers();
 }

我不认为这是必要的,但无论如何,我的 initgl 函数

void 
init () 
{
     // Set clear color to black
     glClearColor(0.0,0.0,0.0,0.0);

     vshader = createShader(GL_VERTEX_SHADER, "vertex.glsl");
     fshader = createShader(GL_FRAGMENT_SHADER, "fragment.glsl");

     g_program = createProgram(vshader, fshader);

     // Create vbo and send it the vertex data
     glGenBuffers(1, &vbo);
     glBindBuffer(GL_ARRAY_BUFFER, vbo);
     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
}

问题是,我的着色器正在工作,如果我将颜色硬编码到片段 sahder 中,则绘制三角形,但如果我将颜色传递给顶点着色器,它不起作用,三角形被绘制到黑色,这很奇怪,因为我的位置属性有效,但我的颜色统一设置为 0。如您所见,我在传递统一值之前设置了 useprogram()。

编辑:我将 gluniform1i(col_loc, 1) 更改为 glUniformif(col_loc, 1.0)。还是不行

编辑:我将添加我的着色器加载功能以确保问题不在着色器中

GLuint
createShader (GLenum type, char* filename)
{
    GLuint shader;

    // Load file
    FILE* file;
    file = fopen(filename, "r");
    if (file == NULL)
    {
        printf("Error reading file \n");
    }

    // Get Length
    fseek(file, 0, SEEK_END);
    long length = ftell(file);
    fseek(file, 0, SEEK_SET);

    // Get source
    char* source;
    source = malloc( (size_t) length + 1);
    if (source == NULL)
    {
        printf("Error alocating space for shader\n");
    }

    // Read file
    fread(source, 1, length, file);

    // Close file
    fclose(file);
    source[length] = '\n';

    // Create shader, attach it's source and compile it
    shader = glCreateShader(type);
    glShaderSource(shader, 1, (const GLchar*)&source, &length);
    free(source); // Free shader source, once it's attached
    glCompileShader(shader);

    // Check for errors
    GLint shader_status;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_status);
    if (!shader_status) {
        fprintf(stderr, "Failed to compile %s:\n", filename);

        GLint log_length;
        char *log;

        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
        log = malloc(log_length);

        glGetShaderInfoLog(shader, log_length, NULL, log);
        fprintf(stderr, "%s", log);
        free(log);

        glDeleteShader(shader);
        return 0;
    }
    return shader;
}

当着色器出现错误时,程序实际上会打印错误日志,所以我不认为错误在这里,但无论如何,它是。

编辑:程序链接器代码

GLuint
createProgram (GLuint vertexs, GLuint fragments)
{
    GLint program_ok;

    // Create program and attach to shaders
    GLuint program = glCreateProgram();
    glAttachShader(program, vertexs);
    glAttachShader(program, fragments);
    glLinkProgram(program);

    glGetProgramiv(program, GL_LINK_STATUS, &program_ok);
    if (!program_ok) {
        fprintf(stderr, "Failed to link shader program:\n");
        GLint log_length;
        char *log;

        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
        log = malloc(log_length);
        glGetProgramInfoLog(program, log_length, NULL, log);
        fprintf(stderr, "%s", log);
        free(log);

        glDeleteProgram(program);
        return 0;
    }

    return program;
}

如果我的着色器/程序有什么问题,请告诉我,我刚刚开始了解可编程管道的基础知识,现在我什至无法渲染三角形

【问题讨论】:

  • 如果制服是浮点数,为什么要传递整数值?
  • 只是在做了一些更改后复制了代码,但是我尝试了1.0f,1.0,但没有成功。我也无法传递矢量数据,这就是我尝试使用简单浮点数的原因
  • 您确定您的着色器链接正确吗?看不到您检查 GL_LINK_STATUS。
  • 我添加了程序代码。也许错误在那里?

标签: c opengl shader


【解决方案1】:

你正在使用

glUniform1i(col_loc, 1);

设置值

uniform float pr_color;

1i 代表 1 个整数。将 1f 用于 1 个浮点数。

glUniform1f(col_loc, 1.0f);

【讨论】:

  • 哦,我太愚蠢了,正如我所说,我一直在玩代码,看看我是否可以让它工作,并尝试使用整数,但我尝试使用 glUniform1f 和它也没有用。代码似乎没问题,可能问题出在其他地方。
  • 那么在这种情况下,可能值得从 OpenGL 中打印出着色器和程序日志。有一些很好的例子说明如何在 C++ 中做到这一点,问题可能只是你的着色器没有正确编译/链接。
  • 我添加了着色器加载功能。但是如果问题出在这里,那么属性位置也不应该起作用,但它确实起作用。此外,如果着色器中出现错误(例如拼写错误或分配不兼容的类型),则会将错误打印到控制台。
【解决方案2】:

好的,我可以使用 glUnifrom4fv()。我现在将 vec4 传递给着色器的颜色变量,它可以工作!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-12
    • 1970-01-01
    • 2015-09-27
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 2012-03-13
    • 1970-01-01
    相关资源
    最近更新 更多