2

对于 OpenGL 的学习,我指的是openglbook。目前在第 2 章中,我正在尝试运行粘贴在此处以供参考的代码。

我面临的问题是以下功能:

void CreateShaders(void)
{
    GLenum ErrorCheckValue = glGetError();

    VertexShaderId = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(VertexShaderId, 1, &VertexShader, NULL);
    glCompileShader(VertexShaderId);

    FragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(FragmentShaderId, 1, &FragmentShader, NULL);
    glCompileShader(FragmentShaderId);

    ProgramId = glCreateProgram();
        glAttachShader(ProgramId, VertexShaderId);
        glAttachShader(ProgramId, FragmentShaderId);
    glLinkProgram(ProgramId);
    glUseProgram(ProgramId);

    ErrorCheckValue = glGetError(); // =====> returns GL_INVALID_OPERATION
    if (ErrorCheckValue != GL_NO_ERROR)
    {
        fprintf(
            stderr,
            "ERROR: Could not create the shaders: %s \n",
            gluErrorString(ErrorCheckValue)
        );

        exit(-1);
    }
}

如上function( glew.h)所示,为什么会返回"GL_INVALID_OPERATION"
如果我评论这些行,那么它可以工作,但只会打印一个空白窗口。

这是我的glxinfo。由于我的版本是 2.2 并且此代码适用于 3.3+,因此我删除了以下代码以避免失败:

  glutInitContextVersion(4, 0); 
  glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
  glutInitContextProfile(GLUT_CORE_PROFILE);

更新:在遵循@Tim 的回答建议后,我能够成功运行该程序;似乎这些行是创建问题:

“#version 400\n”(替换为“#version 130”)

布局(位置 = 0)(已删除)。布局(位置 = 1)(已删除)。

然而,由于这个原因,预期的三角形并不完全相同。可能本教程会考虑到最新的 opengl 版本,而我没有,这会产生问题。

有没有办法在不改变输出的情况下将代码从最新的 OpenGL (4.0+) 兼容代码修改为较低版本 (例如 < 3.0)?我将无法升级图形硬件。

4

1 回答 1

6

您没有对着色器编译和链接进行正确的错误检查。您的着色器中可能存在某种语法错误,导致无法编译,因此您的 useProgram 调用尝试使用无效程序。

对于每个着色器,在调用之后,glCompileShader您需要调用glGetShaderiv(shader, GL_COMPILE_STATUS, compile_status)which 返回 atruefalsecompile_status 来告诉您编译是否成功。如果不是,您可以调用glGetShaderiv(shader, GL_INFO_LOG_LENGTH, length)以获取 infoLog 的大小,然后调用glGetShaderInfoLog()以获取一个字符串,该字符串告诉您在编译期间发生的任何错误。

总之,编译器/链接器错误检查应该是这样的:

void CheckError (GLuint shaderId, uint LINE)
{
  GLint bCompiled;
  glGetShaderiv(shaderId, GL_COMPILE_STATUS, &bCompiled);
  if(bCompiled == false)
  {
    GLint length;
    glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &length);
    GLchar *pInfo = new GLchar[length + 1];
    glGetShaderInfoLog(shaderId, length, &length, pInfo);
    fprintf(stderr, "called at line-%u: Compiler/Linker error: %s", LINE, pInfo);
    delete[] pInfo;
  }
}

如果两个着色器都编译成功,那么在链接程序后,你想在程序对象上测试相同的glGetProgramiv/GL_LINK_STATUS东西glGetProgramInfoLog

于 2012-09-07T03:08:17.733 回答