MAC 下编写opengl3+程序

本文介绍了如何在MAC OS 10.7及更高版本上搭建OpenGL 3.2以上的开发环境,主要涉及使用glfw进行安装,并在Xcode中配置编译设置和链接库,以支持OpenGL 3+的程序编写。文章通过一个简单的示例程序展示如何创建窗口并避免使用固定管线函数。

mac os10.7 之后就开始支持opengl 3.2的语法,但opengl3.3+在10.9才开始支持,当然具体支持的扩展是何显卡有关的,可以参考Apple官方说明
最近在mac和windows两边写opengl代码,但由于mac原本只支持2.1,所以两边写不同的语法,让我很苦恼,而且在mac上无法学习一些较新的教程,在搜索了和踩了一些坑之后,终于实现在mac上编写opengl 3+ 程序.

正文

安装glfw

OSX对于GL 2.1以上只支持Core Profile.
GLFW支持创建Core Profile Context.

glfw 建议通过brew安装,在命令行界面:
执行以下命令:

brew update
brew tap homebrew/versions
brew install glfw3

安装成功后,头文件和库文件会分别在/usr/local/include 和/usr/local/lib

在xcode中使用

build setting的配置

在头文件路径中增加 /usr/local/include
这里写图片描述

在库路径中增加 /usr/local/Cellar/glfw3/3.1.1/lib
这里写图片描述

build pharse中使用glfw3动态链接库

这里写图片描述

opengl样例

如果仅仅按glfw官网教程框架是无法编写opengl3+的程序的,我们必须在创建glfw窗口之前加上以下4行:

  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);

而且不要使用glut框架
注意,一旦加了这4行,以前的固定管线函数就无效了,像glbegin,glend就无法使用了。
下面给一个示例程序:

#include <GLFW/glfw3.h>
#include <OpenGL/gl3.h>
#include <stdlib.h>
#include "initShader.h"
static void error_callback(int error, const char* description)
{
    fputs(description, stderr);
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GL_TRUE);
}


static const GLfloat g_vertex_buffer_data[] = {
    -1.0f, -1.0f, 0.0f,
    1.0f, -1.0f, 0.0f,
    0.0f, 1.0f, 0.0f,
};

#define printGlErr(func) err = glGetError(); if (err) fprintf(stderr, func " error: %u at line %d\n", err, __LINE__);
GLuint err =GL_INVALID_OPERATION;

void init()
{

    GLuint vaoId = 0;
    glGenVertexArrays(1, &vaoId);
    glBindVertexArray(vaoId);
    // Generate 1 buffer, put the resulting identifier in vertexbuffer
    GLuint vertexbuffer;
    glGenBuffers(1, &vertexbuffer);
    printGlErr("glGenBuffers()");
    // The following commands will talk about our 'vertexbuffer' buffer
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

    // Give our vertices to OpenGL.
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

    GLuint program = InitShader("/Users/dale/Documents/gameDevelop/opengl_learn/openGL/openGLproject/openGLproject/vertex.glsl","/Users/dale/Documents/gameDevelop/opengl_learn/openGL/openGLproject/openGLproject/fragment.glsl");
    GLuint loc = glGetAttribLocation(program, "vPosition");
    glEnableVertexAttribArray(loc);

    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glVertexAttribPointer(
                          loc,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
                          3,                  // size
                          GL_FLOAT,           // type
                          GL_FALSE,           // normalized?
                          0,                  // stride
                          (void*)0            // array buffer offset
                          );
    printGlErr("glVertexAttribPointer()");

}




void display()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glFlush();
}

int main(void)
{

    GLFWwindow* window;
    glfwSetErrorCallback(error_callback);
    if (!glfwInit())
        exit(EXIT_FAILURE);
     glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);


    window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);
    glfwSetKeyCallback(window, key_callback);
    init();
    while (!glfwWindowShouldClose(window))
    {
        float ratio;
        int width, height;
        glfwGetFramebufferSize(window, &width, &height);
        ratio = width / (float) height;
        glViewport(0, 0, width, height);
        glClear(GL_COLOR_BUFFER_BIT);

        display();
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwDestroyWindow(window);
    glfwTerminate();
    exit(EXIT_SUCCESS);
}

未给出的是initshader函数代码,这个网上很多实现,就不加在这里显的代码很长了
然后是vertex shader;

#version 330 core
layout(location =0 )in vec3 vPosition;
void main()
{
    gl_Position = vec4(vPosition,1.0);
}

fragment shader:

#version 330 core
out vec4 glcolor;
void main()
{
    glcolor = vec4(0.0, 1.0, 0.0, 1.0);
}

编译运行就看到一个绿色的三角形:
这里写图片描述
祝大家好运:)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值