使用Xcode和Eclipse的Mac

使用Xcode和Eclipse的Mac

本文介绍了使用Xcode和Eclipse的Mac Mojave上的着色器编译问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码在使用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第一响应者错误

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上输出的屏幕截图:


我没有PC的屏幕截图,但没有问题.

解决方案

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

此外,您可能需要检查着色器程序是否编译有错误. 这是OpenGL Wiki中的示例. >

如果您仍然遇到问题,请添加 glGetError() 在每次OpenGL调用后确定错误发生的位置.

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.

解决方案

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.

这篇关于使用Xcode和Eclipse的Mac Mojave上的着色器编译问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 01:33