使用Xcode和Eclipse的Mac Mojave上的着色器编译问题

时间:2018-11-20 03:21:45

标签: c++ macos opengl glfw glew

以下代码在使用Visual Studio的Windows PC上正常运行,但是在Mac上运行时无法为三角形提供颜色。似乎片段着色器可以毫无问题地进行编译,但是MacOS编译/使用无法使用的着色器的方式有些问题。

我最初是从Xcode开始的。发现代码可以在Windows PC上运行后,我随后在Mac上切换到Eclipse。同样的问题。毫无疑问,我有一个依赖问题,但是我很难找到它。

在Mojave 10.14.1中使用MacBook Air。 Xcode是10.1(10861)。 Eclipse是2018-09(4.9.0)。

GLFW是版本3.2.1。 GLEW是2.1.0。

#include <iostream>
#include <string>

// GLEW
#define GLEW_STATIC
#include <GL/glew.h>

// GLFW
#include <GLFW/glfw3.h>

const GLint WIDTH = 800, HEIGHT = 600;

// Draw primative(s)
void draw() {

    GLenum mode = GL_TRIANGLES;
    GLint first = 0;
    GLsizei count = 6;

    glDrawArrays(mode, first, count);

}

// Create and compile shaders
static GLuint CompileShader(const std::string& source, GLuint shaderType) {

    // Create shader object
    GLuint shaderID = glCreateShader(shaderType);
    const char* src = source.c_str();

    // Attach source code to shader object
    glShaderSource(shaderID, 1, &src, nullptr);

    // Compile shader
    std::cout << "Compiling shader..." << std::endl;
    glCompileShader(shaderID);

    // Return ID of compiled shader
    return shaderID;
}

// Create program object
static GLuint CreateShaderProgram(const std::string& vertexShader, const std::string& fragmentShader) {

    // Compile vertex shader
    std::cout << "***** Compiling Vertex Shader *****" << std::endl;
    GLuint vertexShaderComp = CompileShader(vertexShader, GL_VERTEX_SHADER);

    // Compile fragment shader
    std::cout << "***** Compiling Fragment Shader *****" << std::endl;
    GLuint fragmentShaderComp = CompileShader(fragmentShader, GL_FRAGMENT_SHADER);

    // Create program object
    std::cout << "***** Create program object *****" << std::endl;
    GLuint shaderProgram = glCreateProgram();

    // Attach vertex and fragment shaders to program object
    glAttachShader(shaderProgram, vertexShaderComp);
    glAttachShader(shaderProgram, fragmentShaderComp);
    std::cout << "***** Attached both Shaders *****" << std::endl;

    // Link shaders to create executable
    glLinkProgram(shaderProgram);

    // Delete compiled shaders
    glDeleteShader(vertexShaderComp);
    glDeleteShader(fragmentShaderComp);

    // Return shaderProgram
    return shaderProgram;

}


int main() {

    glfwInit();  // Initialize the glfw library

    // Setup properties for the window
    // THESE OPTIONS CAUSED THE TRIANGLE TO FAIL RENDERING; NOT SURE WHY
    /*glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint( GLFW_RESIZABLE, GL_FALSE);*/

    // Create instance of the window
    GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "Kevin Tooley", nullptr, nullptr);

    int screenWidth, screenHeight;
    glfwGetFramebufferSize(window, &screenWidth, &screenHeight);

    // Handle the case that the window was not initialized
    if ( nullptr == window ) {
        std::cout << "Failed to create OpenGL Window" << std::endl;
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent( window );  // Make the window active

    glewExperimental = GL_TRUE;

    // Handle the case where glew failed to init
    if ( GLEW_OK != glewInit() ) {
        std::cout << "Failed to initialize GLEW" << std::endl;

        return -1;
    }

    // Parameters used to display the window in relation to my screen
    glViewport( 0, 0, screenWidth, screenHeight );

    GLfloat vertices[] = {

        // Triangle 1
        0.0, 0.0, 0.0, // vert 0
        1.0, 0.0, 0.0, // Red

        -0.5, 0.0, 0.0, // vert 1
        0.0, 1.0, 0.0, // Green

        -0.5, 0.5, 0.0, // vert2
        0.0, 0.0, 1.0, // Blue

        // Triangle 2
        0.0, 0.0, 0.0, // vert 0
        1.0, 1.0, 0.0, // Red

        0.5, 0.0, 0.0, // vert 1
        0.0, 1.0, 1.0, // Green

        0.5, -0.5, 0.0, // vert2
        1.0, 0.0, 1.0 // Blue

    };

    GLuint VBO;
    glGenBuffers(1, &VBO);  // Create VBO
    glBindBuffer(GL_ARRAY_BUFFER, VBO);  // Select buffer ( VBO )
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);  // Load vertex attributes

    // Specify location and layout to GPU
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(1);

    // Vertex Shader source code
    std::string vertexShaderSource =
    "#version 330 core\n"
    "layout(location = 0) in vec4 aPosition;\n"
    "layout(location = 1) in vec4 aColor;\n"
    "out vec4 oColor;\n"
    "void main()\n"
    "{\n"
    "gl_Position = aPosition;\n"
    "oColor = aColor;\n"
    "}\n";

    // Fragment shader source code
    std::string fragmentShaderSource =
    "#version 330 core\n"
    "in vec4 oColor;\n"
    "out vec4 fragColor;\n"
    "void main()\n"
    "{\n"
    "fragColor = oColor;\n"
    "}\n";


    // Create shader program
    GLuint shaderProgram = CreateShaderProgram(vertexShaderSource, fragmentShaderSource);

    // Use shader program
    glUseProgram(shaderProgram);

    // Loop to process while window is open
    while ( !glfwWindowShouldClose( window ) ) {

        glfwPollEvents();

        // Resize window and drawing simultaneously
        //glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
        //glViewport( 0, 0, screenWidth, screenHeight );

        //glClearColor( 0.2f, 0.3f, 0.3f, 1.0f );
        //glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
        glClear( GL_COLOR_BUFFER_BIT );

        // Draw primative
        draw();

        //glEnable(GL_DEPTH_TEST);

        glfwSwapBuffers( window );

        //glfwPollEvents();

    }

    // The window has been closed, so terminate glfw
    glfwTerminate();

    return 0;

}

控制台输出如下。请注意开头的错误。根据这一点,它是已知的bug? GLFW first responder error

2018-11-19 22:04:14.669523-0500 GLFW OpenGL[30749:3605032] [General] ERROR: Setting <GLFWContentView: 0x1005d0e60> as the first responder for window <GLFWWindow: 0x1005aa770>, but it is in a different window ((null))! This would eventually crash when the view is freed. The first responder will be set to nil.
(
    0   AppKit                              0x00007fff48427a8b -[NSWindow _validateFirstResponder:] + 530
    1   AppKit                              0x00007fff48427835 -[NSWindow _setFirstResponder:] + 31
    2   AppKit                              0x00007fff484fa114 -[NSWindow _realMakeFirstResponder:] + 448
    3   libglfw.3.dylib                     0x00000001003619f7 _glfwPlatformCreateWindow + 644
    4   libglfw.3.dylib                     0x000000010035d71e glfwCreateWindow + 443
    5   GLFW OpenGL                         0x00000001000015bd main + 77
    6   libdyld.dylib                       0x00007fff7803508d start + 1
)
***** Compiling Vertex Shader *****
Compiling shader...
***** Compiling Fragment Shader *****
Compiling shader...
***** Create program object *****
***** Attached both Shaders *****
Program ended with exit code: 0

最后,这是Mac上输出的屏幕截图:

Triangles shown, but they have no color

我没有PC的屏幕截图,但是可以正常使用。

2 个答案:

答案 0 :(得分:0)

如果我不得不猜测,我会认为您的OpenGL-version在Mac上已经过时了。这将导致某些功能无法正常工作。可以使用glGetString(GL_VERSION)获得OpenGL版本。

答案 1 :(得分:0)

您的着色器已设置为使用OpenGL 3.3核心配置文件,但未在GLFW初始化中指定版本。这可能会导致着色器与正在初始化的OpenGL版本之间不匹配。 Check out this link并为主要和次要版本指定3。

此外,您可能需要检查着色器程序是否编译有错误。 Here is an example from the OpenGL wiki上的说明。

如果仍然有问题,请在每个OpenGL调用之后添加glGetError(),以查明发生错误的位置。