c++ - 使用 Xcode 和 Eclipse 在 Mac Mojave 上编译着色器问题

标签 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;

}

控制台输出如下。注意开头的错误。根据这一点它是已知的错误? 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 的屏幕截图,但它可以正常工作。

最佳答案

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

另外,您可能想检查您的着色器程序编译时是否有错误。 Here is an example from the OpenGL wiki关于如何做到这一点。

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

关于c++ - 使用 Xcode 和 Eclipse 在 Mac Mojave 上编译着色器问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53385743/

相关文章:

c++ - 多屏幕/窗口 QT QML C++ 应用程序

C++ 11 线程 API : is there a free implementation for MSVC 2010?

objective-c - 在没有 doubleClick 的情况下为 IKImageView 调用 IKImageEditPanel 非常慢

java - java swing 应用程序中 mac os x 上的功能键

c - 在 C 中使用 OpenGL 3 动画场景

opengl - 使用 premake4 构建项目文件 - 如何?

c - 模拟绘画应用的笔触

c++ - 通过 shared_ptr 访问 calloc 的数据

bash - 从 zsh 进入 bash 时如何加载 ~/.bash_profile?

c++ - 为什么 opengl 着色器没有编译?