C++ Mac上的OpenGL GLSL着色器不编译

C++ Mac上的OpenGL GLSL着色器不编译,c++,macos,opengl,glsl,glew,C++,Macos,Opengl,Glsl,Glew,当我尝试在Mac上为我的应用程序编译GLSL着色器时,由于着色器的版本冲突错误而失败: Error compiling vertex shader: ERROR: 0:1: '' : version '130' is not supported Error compiling shader: ERROR: 0:1: '' : version '130' is not supported 着色器如下所示: 顶点着色器: #version 130 in vec2 in_vPos; in v

当我尝试在Mac上为我的应用程序编译GLSL着色器时,由于着色器的版本冲突错误而失败:

Error compiling vertex shader:
ERROR: 0:1: '' :  version '130' is not supported

Error compiling shader:
ERROR: 0:1: '' :  version '130' is not supported
着色器如下所示:

顶点着色器:

#version 130

in vec2 in_vPos;
in vec2 in_vTexCoord;

out vec2 s_vTexCoord;

void main()
{
    gl_Position = vec4(in_vPos, 0, 1);
    s_vTexCoord = (in_vTexCoord + vec2(1, 1)) / 2;
}
片段着色器:

#version 130

in vec2 s_vTexCoord;

out vec4 s_colOut;

uniform sampler2DRect s_texSampler;
uniform vec4 s_colBlend;

void main()
{
    vec4 pixel = texture(s_texSampler, s_vTexCoord * textureSize(s_texSampler));
    s_colOut = s_colBlend * pixel;
}
以下是初始化SDL渲染器和Glew的方式:

  ren_pRenderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

  SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
  SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
  glEnable(GL_MULTISAMPLE);

  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE | SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);

  SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");

  static bool _bInitializedGlew = false;
  if(!_bInitializedGlew) {
    glewExperimental = GL_TRUE;
    GLenum err = glewInit();
    if(err != GLEW_OK) {
      printf("Glew initialization error: %d\n", err);
    }
    _bInitializedGlew = true;
  }
这就是我编译着色器的方式:

unsigned int CShader::CompileShader(const char* str, int type, bool &bSuccess)
{
    // create a new shader
    GLuint iShader = glCreateShader(type);
    const GLchar* aSourceVertex[] = { str };
    glShaderSource(iShader, 1, aSourceVertex, NULL);
    glCompileShader(iShader);

    // check if compiling went okay
    GLint bShaderCompiled = GL_FALSE;
    glGetShaderiv(iShader, GL_COMPILE_STATUS, &bShaderCompiled);
    if(bShaderCompiled != GL_TRUE) {
        // it did not.
        printf("Error compiling %sshader:\n", (type == GL_VERTEX_SHADER ? "vertex " : ""));
        int iLogLength = 0;
        int iMaxLength = 0;
        glGetShaderiv(iShader, GL_INFO_LOG_LENGTH, &iMaxLength);
        char* buffer = new char[iMaxLength];
        glGetShaderInfoLog(iShader, iMaxLength, &iLogLength, buffer);
        if(iLogLength > 0) {
            printf("%s\n", buffer);
        }
        delete[] buffer;

        // report it back
        bSuccess = false;
        // and delete the shader
        glDeleteShader(iShader);
    } else {
        // it worked!
        bSuccess = true;
    }

    // return shader
    return iShader;
}
之前我四处寻找答案,但没有找到一个可以帮助我的结论性答案,尽管它确实为我指明了正确的方向,即使用
SDL\u GL\u SetAttribute
设置GL版本和核心配置文件。因此,在上面的代码中,我将其设置为3.1 Core,即
#version 140
,但即使我使用它,也会得到相同的错误:

Error compiling vertex shader:
ERROR: 0:1: '' :  version '140' is not supported

Error compiling shader:
ERROR: 0:1: '' :  version '140' is not supported
编辑:我将attributes中的版本更改为3.2 Core+Forward Compat,现在使用
#version 150
我遇到了同样的问题,说150不受支持

当我打印
glGetString(GL\u SHADING\u LANGUAGE\u版本)
的结果时,我得到
1.20

即使在创建SDL窗口后显式创建了上下文,它仍然报告
1.20

win_pWindow = SDL_CreateWindow(strTitle, iX, iY, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | ulFlags);
win_pContext = SDL_GL_CreateContext(win_pWindow);
printf("GLSL version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));

嗯,那个错误消息呢:

这正是你的问题所在。GLSL版本1.30与OpenGL-3.0相关;由于该版本中没有核心/兼容性配置文件,所以MacOS X不支持它


说到现代OpenGL MacOS X,它只支持核心配置文件。因此,您需要一个核心配置文件上下文,并且必须使用核心配置文件版本编写着色器。OpenGL-3核心配置文件仅在OpenGL-3.2中引入,相应的GLSL版本为1.50。因此,您必须在那里编写
#version 150

您并不是在创建您认为正在创建的上下文版本:

SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE | SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG)
只是无效,
SDL\u GL\u CONTEXT\u FORWARD\u COMPATIBLE\u标志
不属于标志,而是属于

实际上,
SDL\u GL\u CONTEXT\u FORWARD\u COMPATIBLE\u FLAG
的值与
SDL\u GL\u CONTEXT\u PROFILE\u COMPATIBILITY
的值相同,因此您确实同时请求了核心配置文件和兼容配置文件。我怀疑您有一个遗留上下文,它仅限于GL
  • 我听说使用SDL_渲染器会将OpenGL版本降低到兼容配置文件/不使用核心配置文件的OpenGL版本(因此,低于3.2的OpenGL版本)
  • 确保在使用
    SDL\u GLSetAttribute
    设置版本等后,同时窗口和上下文。因此,您的代码应该如下所示:

    SDL_GLSetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GLSetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
    SDL_GLSetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    
    //create window
    
    //create context
    

这就是我如何在mac上获得3.3上下文的方法。从您的代码中,我看不出您是否在属性之后创建了上下文和窗口。

我还是OpenGL和GLFW新手,我不确定问题出在哪里,但在macOS上有同样的问题,但将下面的代码块放在这个位置修复了问题

glfwInit();

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif

GLFWwindow *window = glfwCreateWindow( ... );

作为一个次要的补充说明:由于某些原因,到目前为止,所有的核心配置文件版本都需要支持GLSL回到1.40,所以将其升级到
#version 140
就足够了。实际上,OP不应该试图将SDL#U渲染器与OpenGL进行交互。API中没有保存/恢复SDL_渲染器状态的规定,即使它使用的是OpenGL后端。
glfwInit();

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif

GLFWwindow *window = glfwCreateWindow( ... );