Xcode 没有运行最新版本的 OpenGL,这会导致编译错误

Xcode is not running OpenGL with most up to date version, which is causing compilation errors

本文关键字:错误 编译 OpenGL 运行 最新版 新版本 Xcode      更新时间:2023-10-16

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

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

系统信息:

iMac(21.5 英寸,2011 年中(OS X 优塞米蒂 (V 10.10.1(

处理器: 2.5 GHz 英特尔酷睿 i5内存: 4 GB 1333 MHz DDR3

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

Xcode v 6.1.1

我的问题:

问题是着色器无法编译。

片段着色器.txt:

#version 130
out vec3 color;
void main() {
color = vec3(1.0, 0.0, 0.0);
}

顶点着色器.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.29GLSL 版本:1.20供应商: ATI技术公司渲染器:AMD Radeon HD 6750M OpenGL 引擎

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

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

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

法典

我只会包含 cpp 文件。前向声明在头文件中,但我认为没有必要包含它们。如果你确实需要它们,请询问,我会发布它们。

主.cpp

#include "MainGame.h"
#include "Sprite.h"
#include <iostream>
int main( int argc, char** argv) {
    MainGame mainGame;
    mainGame.run();
    return 0;
}

主游戏.cpp(将所有内容联系在一起(

#include "MainGame.h"
#include <iostream>
#include <string>

MainGame::MainGame(){
    _window = nullptr;
    _screenHeight = 768;
    _screenWidth = 1024;
    _gameState = PLAY;
}
MainGame::~MainGame(){
}
void MainGame::run(){
    initSystems();

    _sprite.init(-1.0f, -1.0f, 1.0f, 1.0f);
    gameLoop();
}
void MainGame::initSystems(){
    SDL_Init(SDL_INIT_EVERYTHING);
    _window = SDL_CreateWindow("Game Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, _screenWidth, _screenHeight, SDL_WINDOW_OPENGL);
    if (_window == nullptr) {
        fatalError("SDL Window could not be created. :(");
    }
    SDL_GLContext glContext = SDL_GL_CreateContext(_window);
    if (glContext == nullptr) {
        fatalError("SDL_GL context could not be created. :(");
    }
    std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl;
    std::cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
    std::cout << "Vendor: " << glGetString(GL_VENDOR) << std::endl;
    std::cout << "Renderer: " << glGetString(GL_RENDERER) << std::endl;

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    glClearColor(0.0f, 0.0f, 1.0f, 1.0);


    initShaders();
}

void MainGame::initShaders(){
    _colorProgram.compileShaders("/Users/user/filepath.../vertex-shader.txt", "/Users/user/filepath.../fragment-shader.txt");
    _colorProgram.addAttribute("vertexPosition");
    _colorProgram.linkShaders();
}

void MainGame::gameLoop(){
    while (_gameState != GameState::EXIT) {
        processInput();
        drawGame();
    }
}

void MainGame::processInput(){
    SDL_Event evnt;
    while (SDL_PollEvent(&evnt))
        switch (evnt.type) {
            case SDL_QUIT:
                _gameState = EXIT;
                break;
            case SDL_MOUSEMOTION:
                std::cout << evnt.motion.x << " " << evnt.motion.y << std::endl;
                break;
        }
}

void MainGame::drawGame(){
    glClearDepth(1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    _colorProgram.use();
    _sprite.draw();
    _colorProgram.unuse();
    SDL_GL_SwapWindow(_window);
}

GLSLProgram.cpp(处理大多数与GLSL相关的事情(

#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("%sn", &(errorLog[0]));
        fatalError("Shader " + filePath + " failed to compile");
    }
    // Shader compilation is successful.

}

精灵.cpp(绘制一个简单的三角形(

#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);
}

错误.cpp(出错时退出(

#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();
}

此外,此代码至少在Windows上确实有效。几乎所有内容都取自上面的youtube链接,只是略有修改以与Xcode配合使用。在youtube视频的描述中有一个指向该代码的链接。

您需要在创建窗口之前调用SDL_GL_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);