【问题标题】:GLSL shaders not working. No compile errors, and used glUseProgramGLSL 着色器不工作。没有编译错误,并且使用了 glUseProgram
【发布时间】:2017-08-24 00:31:19
【问题描述】:

我想出了渲染矩形的代码,但着色器不起作用。它仍然是空白的白色。

这里我将包含重要的代码

主要:

float verts[] = {
    -.5f, -.5f, .0f,
    -.5f,  .5f, .0f,
     .5f,  .5f, .0f,
     .5f,  .5f, .0f,
     .5f, -.5f, .0f,
    -.5f, -.5f, .0f
};

Shader shader("basicVert.glsl", "basicFrag.glsl");

GLuint VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), &verts, GL_STATIC_DRAW);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);

shader.enable();

Shader.cpp(类函数)

Shader::Shader(const string vpath, const string fpath) {
    Shader();
    current_vpath = vpath;
    current_fpath = fpath;
    shaderID = init();
}

Shader::Shader(const char *vpath, const char *fpath) {
    Shader(string(vpath), string(fpath));
}

Shader::~Shader() {
    shaderID = NULL;
    glDeleteProgram(shaderID);
}

void Shader::enable() {
    glUseProgram(shaderID);
}

GLuint Shader::makeVertextShader(const char* source) {
    GLuint vertShaderID = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertShaderID, 1, &source, NULL);
    glCompileShader(vertShaderID);
    GLint r;
    glGetShaderiv(vertShaderID, GL_COMPILE_STATUS, &r);
    if (r == GL_FALSE) {
        GLint l;
        glGetShaderiv(vertShaderID, GL_INFO_LOG_LENGTH, &l);
        cout << l << endl;
        char *bfer = new char[l];
        glGetShaderInfoLog(vertShaderID, l, &l, bfer);
        cerr << "Failed to compile VERTEXT SHADER! FILE NAME: " << 
        current_vpath << endl;
        cerr << bfer << endl;
        glDeleteShader(vertShaderID);
        delete[] bfer;
        return NULL;
    }
    return vertShaderID;
}

GLuint Shader::makeFragmentShader(const char* source) {
  GLuint fragShaderID = glCreateShader(GL_FRAGMENT_SHADER);
  glShaderSource(fragShaderID, 1, &source, NULL);
  glCompileShader(fragShaderID);
  GLint r;
  glGetShaderiv(fragShaderID, GL_COMPILE_STATUS, &r);
  if (r == GL_FALSE) {
      GLint l;
      glGetShaderiv(fragShaderID, GL_INFO_LOG_LENGTH, &l);
      char *bfer = new char[l];
      glGetShaderInfoLog(fragShaderID, l, &l, bfer);
      cerr << "Failed to compile FRAGMENT SHADER! FILE NAME: " << 
              current_fpath << endl;
      cerr << bfer << endl;
      glDeleteShader(fragShaderID);
      delete[] bfer;
      return NULL;
  }
  return fragShaderID;
}

GLuint Shader::init() {
    GLuint program = glCreateProgram();
    const string vs = readFile(current_vpath);
    const string vf = readFile(current_fpath);

    const char *vertexsrc = vs.c_str();
    const char *fragmentsrc = vf.c_str();

    GLuint vertShaderID = this->makeVertextShader(vertexsrc);
    GLuint fragShaderID = this->makeFragmentShader(fragmentsrc);

    glAttachShader(program, vertShaderID);
    glAttachShader(program, fragShaderID);
    glLinkProgram(program);
    glValidateProgram(program);
    glDeleteShader(vertShaderID);
    glDeleteShader(fragShaderID);
    return program;
}

GLSL 顶点着色器

#version 330 core

layout(location = 0) in vec3 position;

void main(){

    gl_Position = position;

}

GLSL 片段着色器

#version 330 core

layout(location = 0) out vec4 color;

void main(){

    color = vec4(1.0, 0.0, 1.0, 1.0);
    gl_FragColor = color;

}

【问题讨论】:

  • 你在某处打电话给glDrawArrays吗?此外,如果没有看到您的着色器,也很难知道问题是否存在
  • 你的两个着色器都不应该编译。你真的检查过你的程序的输出吗?此外,您的代码缺少对链接故障的检查。
  • 它编译,如果有错误,它会输出错误。
  • GLSL 300 中没有 gl_FragColor
  • 除非它发生在你的 make*shader 方法中,你在哪里检查着色器编译的结果?检查着色器编译和链接日志会帮助您找到此错误

标签: c++ opengl glsl


【解决方案1】:

现代版本的 GLSL 不再支持gl_FragColor

所以它会在顶点着色器中,

layout(location = 0) in vec4 position;

void main()
{
  gl_Position = position;
}

在 FS 中,

layout(location = 0) out vec4 color;

void main()
{
color = vec4(1.0, 0.0, 1.0, 1.0);
//gl_FragColor is no longer supported in modern versions of GLSL  
}

【讨论】:

  • @Rabbid76 谢谢。我不知道布局限定符也用于输出。
【解决方案2】:

顶点和片段着色器必须如下所示:

#version 330 core

layout(location = 0) in vec3 position;

void main()
{
    gl_Position = vec4( position.xyz, 1.0 );
}
#version 330 core

layout(location = 0) out vec4 color;

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

解释:

您的代码中有两个问题:

1.) 虽然顶点属性 position,但在 Vertex Shader 的类型为 vec3Built-in Variable (GLSL) gl_Position 的类型为 vec4
必须更改顶点属性的类型:

layout(location = 0) in vec4 position;

或者必须调整分配给gl_Position

gl_Position = vec4( position.xyz, 1.0 );

2.) 在Fragment Shader 中可以使用Built-in output Variable (GLSL) gl_FragColor

void main()
{
    gl_FragColor = [...];
}

或者必须声明一个显式的输出变量:

out vec4 color;

void main()
{
    color = [...];
}

【讨论】:

    【解决方案3】:

    问题似乎出在顶点着色器上:您将 vec3 position 传递给 vec4 gl_Position,这实际上将 w 坐标设置为 0。正确渲染所需的是齐次坐标 1(否则除以 w 是除以 0)。尝试将您的代码更改为

    gl_Position = vec4(position, 1.0);
    

    【讨论】:

    • 我刚刚添加了它,但它不起作用。无论如何感谢您的帮助
    • 附带说明:您正在检查着色器的编译状态,而不是程序的链接状态。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多