C++ Xcode没有使用最新版本运行OpenGL,这会导致编译错误

C++ Xcode没有使用最新版本运行OpenGL,这会导致编译错误,c++,xcode,opengl,C++,Xcode,Opengl,我正在使用OpenGL和GLSL。我正在遵循一个教程,确切地说是这一个:但他不使用xcode,这就是我正在使用的,它导致了这个问题 我将从我的系统信息开始,所有我认为足够相关的信息都将有助于解决这个问题。然后我会告诉你问题是什么,以及我所学到的我认为相关和有用的一切。之后,我将包含我使用的所有代码的副本,以便您可以查看其中的错误和真正的问题等等 系统信息: iMac(21.5英寸,2011年年中) OS X Yosesemite(第10.10.1节) 处理器:2.5 GHz Intel Core

我正在使用OpenGL和GLSL。我正在遵循一个教程,确切地说是这一个:但他不使用xcode,这就是我正在使用的,它导致了这个问题

我将从我的系统信息开始,所有我认为足够相关的信息都将有助于解决这个问题。然后我会告诉你问题是什么,以及我所学到的我认为相关和有用的一切。之后,我将包含我使用的所有代码的副本,以便您可以查看其中的错误和真正的问题等等

系统信息:

iMac(21.5英寸,2011年年中) OS X Yosesemite(第10.10.1节)

处理器:2.5 GHz Intel Core i5 内存:4 GB 1333 MHz DDR3

图形: OpenGL版本:4.1 ATI-1.28.29 GLSL版本:4.10 供应商:ATI技术公司。 渲染器:AMD Radeon HD 6750M OpenGL引擎

Xcode v 6.1.1

我的问题:

问题是着色器无法编译

fragment-shader.txt:

#version 130

out vec3 color;

void main() {

color = vec3(1.0, 0.0, 0.0);

}
vertex-shader.txt

#version 130

in vec2 vertexPosition;

void main() {
    //Set the x,y position on the screen
    gl_Position.xy = vertexPosition;
    //the z position is zero since we are in 2D
    gl_Position.z = 0.0;

    //Indicate that the coordinates are normalized
    gl_Position.w = 1.0;
}
这两个都无法编译。编译调用将在GLSLProgram.cpp中,更具体地说是void GLSLProgram::compileShader

我确实检查了错误,收到的错误消息是:“错误:0:1:”“:不支持版本“130”

我发现这个错误的典型原因是一个过时的图形卡。我知道情况并非如此,但是,我只是在运行时进行了检查。我检查了我的OpenGl版本和glsl版本,结果如下:

OpenGL版本:2.1 ATI-1.28.29 GLSL版本:1.20 供应商:ATI技术公司。 渲染器:AMD Radeon HD 6750M OpenGL引擎

它正在读取我的存储卡,但OpenGL和GLSL版本是错误的。我不知道为什么。我一直无法弄清楚为什么或者如何通过互联网自己解决这个问题,这就是我来这里的原因

我下载了一个随机的跨平台程序,它也使用GLSL,并且运行良好。我对openGL不是很熟悉,所以我无法查看代码并找出问题所在。我所能做的就是给我最好的猜测。我认为这是一个预处理器错误。我可能使用了不正确的预处理器,或者是过时的版本,或者我不知道。这就是问题所在。然而,运行的代码在运行时打印出正确的OpenGL版本和GLSL版本。所以我知道是什么原因导致我没有使用最新的版本。我不知道这是否是唯一的问题,但我知道这是问题之一

我在上一段中提到的代码来自,访问该代码的链接位于该教程第一段中

代码

我只打算包括cpp文件。转发声明在头文件中,但我认为没有必要包含它们。如果你真的需要它们,问一下,我会把它们贴出来

main.cpp

#include "MainGame.h"
#include "Sprite.h"

#include <iostream>

int main( int argc, char** argv) {
    MainGame mainGame;
    mainGame.run();

    return 0;
}
error.cpp(出错时退出)

#包括“Errors.h”
#包括
#包括
void fatalError(标准::字符串errorString){

std::cout在创建窗口之前,您需要调用SDL\u GL\u SetAttribute来设置所需的最低OpenGL版本

SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

我认为您特别需要创建一个支持OpenGL 4(或您需要的最低版本)的OpenGL上下文。查看此链接了解如何使用SDL:好的。这很有意义。今晚我有时间时,我会尝试这样做。感谢您的回复。这与Xcode无关。如果您不想在运行时使用OpenGL 2.1上下文,您只需要在OS X上使用核心配置文件上下文。好的,所以我确认了我需要的最低版本,它确实是3。0.我将代码放在SDL_Init(SDL_Init_EVERYTHING)之后,在创建窗口之前。但是现在SDL_GLContext=nullptr(这以前没有发生过,它被设置为其他值,这意味着它正在工作)我不知道着色器是否已编译,当我注释掉导致它结束的错误时,程序没有完成那么远。这不会起作用。OS X不支持OpenGL 3.0。它支持2.1、3.2、3.3和4.1(取决于操作系统版本)。但要获得除2.1之外的任何内容,您需要一个核心配置文件。@AndonM.Coleman根据我找到的文档,
GL\u SetAttribute
是minimums@ratchetfreak:没错,但这里的问题是OS X如何处理上下文版本。它没有实现3.0上下文,而是直接从2.1(旧版)跳到3.2(核心版)。如果您不请求core,您将无法获得3.2上下文。有些框架对此非常挑剔,除非您请求3.2完全向前兼容(例如GLFW),否则不会提供core配置文件。
#include "GLSLProgram.h"
#include "Errors.h"

#include <fstream>
#include <vector>
#include <iostream>



GLSLProgram::GLSLProgram() : _numAttributes(0), _programID(0), _vertexShaderID(0), _fragmentShaderID(0)
{

}

GLSLProgram::~GLSLProgram(){

}

void GLSLProgram::compileShaders(const std::string& vertexShaderFilePath, const std::string& fragmentShaderFilePath){
    _vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
    if (_vertexShaderID == 0){
        fatalError("Vertex Shader failed to be created");
    }

    _fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
    if (_fragmentShaderID == 0){
        fatalError("Fragment Shader failed to be created");
    }

    compileShader(vertexShaderFilePath, _vertexShaderID);

    compileShader(fragmentShaderFilePath, _fragmentShaderID);


}



void GLSLProgram::addAttribute(const std::string& attributeName){
    glBindAttribLocation(_programID, _numAttributes++, attributeName.c_str());
}



void GLSLProgram::linkShaders(){
    //Vertex and fragment shaders are successfully compiled.
    //Now time to link them together into a program.
    //Get a program object.
    _programID = glCreateProgram();

    //Attach our shaders to our program
    glAttachShader(_programID, _vertexShaderID);
    glAttachShader(_programID, _fragmentShaderID);

    //Link our program
    glLinkProgram(_programID);

    //Note the different functions here: glGetProgram* instead of glGetShader*.
    GLint isLinked = 0;
    glGetProgramiv(_programID, GL_LINK_STATUS, (int *)&isLinked);
    if(isLinked == GL_FALSE)
    {
        GLint maxLength = 0;
        glGetProgramiv(_programID, GL_INFO_LOG_LENGTH, &maxLength);

        //The maxLength includes the NULL character
        std::vector<char> errorLog(maxLength);
        glGetProgramInfoLog(_programID, maxLength, &maxLength, &errorLog[0]);

        //We don't need the program anymore.
        glDeleteProgram(_programID);
        //Don't leak shaders either.
        glDeleteShader(_vertexShaderID);
        glDeleteShader(_fragmentShaderID);

        std::printf("%s/n", &(errorLog[0]));
        fatalError("Shaders failed to link");        //In this simple program, we'll just leave


    }

    //Always detach shaders after a successful link.
    glDetachShader(_programID, _vertexShaderID);
    glDetachShader(_programID, _fragmentShaderID);
    glDeleteShader(_vertexShaderID);
    glDeleteShader(_fragmentShaderID);

}






void GLSLProgram::use(){
    glUseProgram(_programID);
    for (int i = 0; i < _numAttributes; i++) {
        glEnableVertexAttribArray(i);
    }
}



void GLSLProgram::unuse(){
    glUseProgram(0);
    for (int i = 0; i < _numAttributes; i++) {
        glDisableVertexAttribArray(i);
    }
}







void GLSLProgram::compileShader(const std::string& filePath, GLuint id){
    std::ifstream shaderFile(filePath);
    if (shaderFile.fail()){
        perror(filePath.c_str());
        fatalError("Failed to open " + filePath);
    }

    std::string fileContents ="";
    std::string line;

    while (std::getline(shaderFile, line)) {
        fileContents += line + "\n";
    }

    shaderFile.close();



    const char* contentsPtr = fileContents.c_str();
    glShaderSource(id, 1, &contentsPtr, nullptr);


    glCompileShader(id);

    GLint success = 0;
    glGetShaderiv(id, GL_COMPILE_STATUS, &success);


    if(success == GL_FALSE)
    {
        GLint maxLength = 0;
        glGetShaderiv(id, GL_INFO_LOG_LENGTH, &maxLength);

        // The maxLength includes the NULL character
        std::vector<char> errorLog(maxLength);
        glGetShaderInfoLog(id, maxLength, &maxLength, &errorLog[0]);

        // Provide the infolog in whatever manor you deem best.
        // Exit with failure.
        glDeleteShader(id); // Don't leak the shader.


        std::printf("%s\n", &(errorLog[0]));
        fatalError("Shader " + filePath + " failed to compile");
    }

    // Shader compilation is successful.


}
#include "Sprite.h"



Sprite::Sprite(){
    _vboID = 0;
}


Sprite::~Sprite(){
    if (_vboID != 0){
        glDeleteBuffers(1, &_vboID);
    }
}


void Sprite::init(float x, float y, float width, float height){
    _x = x;
    _y = y;
    _width = width;
    _height = height;

    if (_vboID == 0){
        glGenBuffers(1, &_vboID);
    }

    float vertexData[12];

    //first triangle
    vertexData[0] = x + width;
    vertexData[1] = y + height;

    vertexData[2] = x;
    vertexData[3] = y + height;

    vertexData[4] = x;
    vertexData[5] = y;

    //second triangle
    vertexData[6] = x + width;
    vertexData[7] = y + height;

    vertexData[8] = x;
    vertexData[9] = y;

    vertexData[10] = x + width;
    vertexData[11] = y;

    glBindBuffer(GL_ARRAY_BUFFER, _vboID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
}


void Sprite::draw(){
    glBindBuffer(GL_ARRAY_BUFFER, _vboID);

    glEnableVertexAttribArray(0);

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);

    glDrawArrays(GL_TRIANGLES, 0, 6);

    glDisableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

}
#include "Errors.h"

#include <iostream>
#include <SDL2/SDL.h>


void fatalError(std::string errorString) {
    std::cout << errorString << std::endl;
    std::cout << "Enter any key to quit...";
    int tmp;
    std::cin >> tmp;
    SDL_Quit();
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);