Shader compilation issue on Mac Mojave using Xcode and Eclipse

百般思念 提交于 2019-12-13 17:00:24

问题


The following code works fine on a Windows PC using Visual Studio, but fails to provide color to the triangles when running on a Mac. It seems that the fragment shader compiles without issue, but there is something about the way MacOS is compiling/using the shader that is not working.

I originally started with Xcode. After discovering that the code runs on a Windows PC, I then switched to Eclipse on the Mac. Same issue. No doubt I have a dependency problem, but I'm struggling to find it.

Using MacBook Air with Mojave 10.14.1. Xcode is 10.1(10861). Eclipse is 2018-09 (4.9.0).

GLFW is version 3.2.1. GLEW is 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;

}

The console output is as follows. Note the error at the beginning. According to this point it is known 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

Finally, here is the screen shot of the output on the Mac:


I don't have a screen shot for the PC, but it works without issue.


回答1:


Your shaders are setup to use OpenGL 3.3 Core profile but you do not specify the version in the GLFW initialization. This is probably causing a mismatch between the shaders and the version of OpenGL being initialized. Check out this link and specify 3 for both major and minor version.

Also, you might want to check that your shader program compiled with errors. Here is an example from the OpenGL wiki on how to do that.

If you are still having issues then add glGetError() after each OpenGL call to nail down where the error is occurring.




回答2:


If I had to guess, I would think your OpenGL-version is outdated on your Mac. This would cause certain functions to not behave as expected. The OpenGL-version can be obtained with glGetString(GL_VERSION).



来源:https://stackoverflow.com/questions/53385743/shader-compilation-issue-on-mac-mojave-using-xcode-and-eclipse

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!