繁体   English   中英

使用Mac OS X的OpenGL Red Book

[英]OpenGL Red Book with Mac OS X

我想在Mac OS X上使用Xcode,通过OpenGL红皮书, OpenGL编程指南,第8版

我无法运行第一个代码示例triangles.cpp。 我已经尝试了包含Xcode附带的GLUT和GL框架,我已经搜索了足够的内容,看到我不太可能自己解决这个问题。

假设我有一个全新的Mac OS X安装,并且我已经使用Xcode命令行工具新安装了Xcode, 那么在该环境中运行triangles.cpp的逐步说明是什么?

这个问题不同,我的偏好是使用Cocoa,Objective-C或Swift。 我的偏好只是留在C ++ / C中。 答案是正确的,如果我可以一步一步地遵循它并最终得到一个运行的triangles.cpp程序。

我的偏好是Mac OS X 10.9,但正确的答案可以假定10.9,10.10或10.11。

谢谢。

///////////////////////////////////////////////////////////////////////
//
// triangles.cpp
//
///////////////////////////////////////////////////////////////////////

#include <iostream>
using namespace std;

#include "vgl.h"
#include "LoadShader.h"

enum VAO_IDs { Triangles, NumVAOs };
enum Buffer_IDs { ArrayBuffer, NumBuffers };
enum Attrib_IDs { vPosition = 0 };

GLuint  VAOs[NumVAOs];
GLuint  Buffers[NumBuffers];

const GLuint  NumVertices = 6;

//---------------------------------------------------------------------
//
// init
//

void
init(void)
{
    glGenVertexArrays(NumVAOs, VAOs);
    glBindVertexArray(VAOs[Triangles]);

    GLfloat  vertices[NumVertices][2] = {
        { -0.90, -0.90 },  // Triangle 1
        {  0.85, -0.90 },
        { -0.90,  0.85 },
        {  0.90, -0.85 },  // Triangle 2
        {  0.90,  0.90 },
        { -0.85,  0.90 }
    };

    glGenBuffers(NumBuffers, Buffers);
    glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),
                 vertices, GL_STATIC_DRAW);

    ShaderInfo  shaders[] = {
        { GL_VERTEX_SHADER, "triangles.vert" },
        { GL_FRAGMENT_SHADER, "triangles.frag" },
        { GL_NONE, NULL }
    };

    GLuint program = LoadShaders(*shaders);
    glUseProgram(program);

    glVertexAttribPointer(vPosition, 2, GL_FLOAT,
                          GL_FALSE, 0, BUFFER_OFFSET(0));
    glEnableVertexAttribArray(vPosition);
}

//---------------------------------------------------------------------
//
// display
//

void
display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);

    glBindVertexArray(VAOs[Triangles]);
    glDrawArrays(GL_TRIANGLES, 0, NumVertices);

    glFlush();
}

//---------------------------------------------------------------------
//
// main
//

int
main(int argc, char** argv)
{



     glutInit(&argc, argv);
     glutInitDisplayMode(GLUT_RGBA);
     glutInitWindowSize(512, 512);
     glutInitContextVersion(4, 3);
     glutInitContextProfile(GLUT_CORE_PROFILE);
     glutCreateWindow(argv[0]);

     glewExperimental = GL_TRUE;

     if (glewInit()) {
         cerr << "Unable to initialize GLEW ... exiting" << endl;
         exit(EXIT_FAILURE);
     }

     init();

     glutDisplayFunc(display);

     glutMainLoop();
}

编辑1:在回应第一条评论时,这是天真的努力。

  • 在Mac OS X 10.9.5上打开Xcode 5.1.1
  • 创建一个新的C ++命令行项目。
  • 使用triangles.cpp的内容粘贴main.cpp的内容。
  • 单击项目 - > Build Phases - > Link Binary with Libraries
  • 添加OpenGL.framework和GLUT.framework

结果:“/ Users/xxx/Desktop/Triangles/Triangles/main.cpp:10:10:找不到'vgl.h'文件”

编辑2:添加了vgh翻译单元和LoadShaders翻译单元,还将libFreeGlut.a和libGlew32.a添加到我的项目编译/链接中。 将所有OpenGL Book的Include内容移动到我的项目源目录中。 不得不改变几个include语句来使用quoted包括而不是有角度的包含。 感觉这更接近工作,但它无法找到LoadShader.h。 请注意,OpenGL下载中的翻译单元称为LoadShaders(复数)。 更改triangles.cpp以引用LoadShaders.h修复了包含问题,但该转换单元的内容似乎与从triangles.cpp调用的签名不匹配。

源和oglpg-8th-edition.zip中的文件存在一些问题:

triangles.cpp使用未包含在glut中的非标准GLUT函数,而只是freeglut实现的一部分( glutInitContextVersionglutInitContextProfile )。 freeglut并不真正支持OS X,而是依赖于额外的X11支持来构建它。 而不是告诉你如何做到这一点我只是修改源代码来构建OS X的GLUT框架。

代码依赖于glew,本书的源代码下载显然不包含您可以使用的二进制文件,因此您需要自己构建它。

使用以下命令构建GLEW:

git clone git://git.code.sf.net/p/glew/code glew
cd glew
make extensions
make

现在:

  • 创建一个C ++命令行Xcode项目

  • 将可执行文件设置为与OpenGL和GLUT框架以及刚刚构建的glew dylib链接。

  • 修改项目“标题搜索路径”以包含您构建的库的glew标题的位置,然后是oglpg-8th-edition / include的路径

  • 将oglpg-8th-edition / lib / LoadShaders.cpp添加到您的xcode项目中

  • 将triangles.cpp源粘贴到Xcode项目的main.cpp中

  • 修改源:将#include "vgl.h"替换为:

     #include <GL/glew.h> #include <OpenGL/gl3.h> #include <GLUT/glut.h> #define BUFFER_OFFSET(x) ((const void*) (x)) 

    还要确保你的问题中包含的triangle.cpp版本中的拼写错误是固定的:当它应该是“LoadShaders.h”和LoadShaders(*shaders);时包含“LoadShader.h” LoadShaders(*shaders); 应该是LoadShaders(shaders) (我的书副本中印刷的代码不包含这些错误。)

  • 删除对glutInitContextVersionglutInitContextProfile的调用。

  • 将参数更改为glutInitDisplayModeGLUT_RGBA | GLUT_3_2_CORE_PROFILE GLUT_RGBA | GLUT_3_2_CORE_PROFILE

此时代码构建,链接和运行,但是运行程序会为我显示一个黑色窗口而不是预期的三角形。

您可以使用此链接中的示例。 它几乎是一样的。 它使用glfw而不是过剩。

http://www.tomdalling.com/blog/modern-opengl/01-getting-started-in-xcode-and-visual-cpp/

/*
 main

 Copyright 2012 Thomas Dalling - http://tomdalling.com/

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

//#include "platform.hpp"

// third-party libraries
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>

// standard C++ libraries
#include <cassert>
#include <iostream>
#include <stdexcept>
#include <cmath>

// tdogl classes
#include "Program.h"

// constants
const glm::vec2 SCREEN_SIZE(800, 600);

// globals
GLFWwindow* gWindow = NULL;
tdogl::Program* gProgram = NULL;
GLuint gVAO = 0;
GLuint gVBO = 0;


// loads the vertex shader and fragment shader, and links them to make the global gProgram
static void LoadShaders() {
    std::vector<tdogl::Shader> shaders;
    shaders.push_back(tdogl::Shader::shaderFromFile("vertex-shader.txt", GL_VERTEX_SHADER));
    shaders.push_back(tdogl::Shader::shaderFromFile("fragment-shader.txt", GL_FRAGMENT_SHADER));
    gProgram = new tdogl::Program(shaders);
}


// loads a triangle into the VAO global
static void LoadTriangle() {
    // make and bind the VAO
    glGenVertexArrays(1, &gVAO);
    glBindVertexArray(gVAO);

    // make and bind the VBO
    glGenBuffers(1, &gVBO);
    glBindBuffer(GL_ARRAY_BUFFER, gVBO);

    // Put the three triangle verticies into the VBO
    GLfloat vertexData[] = {
        //  X     Y     Z
         0.0f, 0.8f, 0.0f,
        -0.8f,-0.8f, 0.0f,
         0.8f,-0.8f, 0.0f,
    };
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);

    // connect the xyz to the "vert" attribute of the vertex shader
    glEnableVertexAttribAxrray(gProgram->attrib("vert"));
    glVertexAttribPointer(gProgram->attrib("vert"), 3, GL_FLOAT, GL_FALSE, 0, NULL);

    // unbind the VBO and VAO
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}


// draws a single frame
static void Render() {
    // clear everything
    glClearColor(0, 0, 0, 1); // black
    glClear(GL_COLOR_BUFFER_BIT);

    // bind the program (the shaders)
    glUseProgram(gProgram->object());

    // bind the VAO (the triangle)
    glBindVertexArray(gVAO);

    // draw the VAO
    glDrawArrays(GL_TRIANGLES, 0, 3);

    // unbind the VAO
    glBindVertexArray(0);

    // unbind the program
    glUseProgram(0);

    // swap the display buffers (displays what was just drawn)
    glfwSwapBuffers(gWindow);
}

void OnError(int errorCode, const char* msg) {
    throw std::runtime_error(msg);
}

// the program starts here
void AppMain() {
    // initialise GLFW
    glfwSetErrorCallback(OnError);
    if(!glfwInit())
        throw std::runtime_error("glfwInit failed");

    // open a window with GLFW
    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);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    gWindow = glfwCreateWindow((int)SCREEN_SIZE.x, (int)SCREEN_SIZE.y, "OpenGL Tutorial", NULL, NULL);
    if(!gWindow)
        throw std::runtime_error("glfwCreateWindow failed. Can your hardware handle OpenGL 3.2?");

    // GLFW settings
    glfwMakeContextCurrent(gWindow);

    // initialise GLEW
    glewExperimental = GL_TRUE; //stops glew crashing on OSX :-/
    if(glewInit() != GLEW_OK)
        throw std::runtime_error("glewInit failed");

    // print out some info about the graphics drivers
    std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl;
    std::cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
    std::cout << "Vendor: " << glGetString(GL_VENDOR) << std::endl;
    std::cout << "Renderer: " << glGetString(GL_RENDERER) << std::endl;

    // make sure OpenGL version 3.2 API is available
    if(!GLEW_VERSION_3_2)
        throw std::runtime_error("OpenGL 3.2 API is not available.");

    // load vertex and fragment shaders into opengl
    LoadShaders();

    // create buffer and fill it with the points of the triangle
    LoadTriangle();

    // run while the window is open
    while(!glfwWindowShouldClose(gWindow)){
        // process pending events
        glfwPollEvents();

        // draw one frame
        Render();
    }

    // clean up and exit
    glfwTerminate();
}


int main(int argc, char *argv[]) {
    try {
        AppMain();
    } catch (const std::exception& e){
        std::cerr << "ERROR: " << e.what() << std::endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

关于解决马修和Bames53评论中提到的黑窗问题

  1. 按照bames53的回答
  2. 将着色器定义为字符串

    const char * pTriangleVert =“vec4 vPosition中的#version 410 core \\ n \\ layout(location = 0); \\ n \\ void \\ n \\ main()\\ n \\ {\\ n \\ \\ n \\ gl_Position = vPosition; \\ n \\}”;

    const char * pTriangleFrag =“#version 410 core \\ n \\ out vec4 fColor; \\ n \\ void \\ n \\ main()\\ n \\ {\\ n \\ fColor = vec4(0.0,0.0,1.0,1.0); \\ n \\ }“;

我的iMac支持OpenGl 4.1,因此我将版本更改为410

ShaderInfo  shaders[] = {
    { GL_VERTEX_SHADER, pTriangleVert},
    { GL_FRAGMENT_SHADER, pTriangleFrag },
    { GL_NONE, NULL }
};
  1. 修改ShaderInfo结构略有变化

typedef struct { GLenum type; const char* filename; GLuint shader; } ShaderInfo;

typedef struct { GLenum type; const char* source; GLuint shader; } ShaderInfo;

  1. 修改loadShader函数稍微注释一下从文件中读取着色器的代码

      /* const GLchar* source = ReadShader( entry->filename ); if ( source == NULL ) { for ( entry = shaders; entry->type != GL_NONE; ++entry ) { glDeleteShader( entry->shader ); entry->shader = 0; } return 0; } glShaderSource( shader, 1, &source, NULL ); delete [] source;*/ 

    glShaderSource(着色器,1,&entry-> source,NULL);

如果某些着色器编译错误,你最好打开DEBUG

我在这里修改了MAC项目: https//github.com/badousuan/openGLredBook9th

该项目可以成功构建,大多数演示可以按预期运行。 但是原始代码基于openGL 4.5,而MAC仅支持4.1版,一些新的API调用可能会失败。 如果某些目标不能正常工作,您应该考虑此版本问题并进行一些调整

我使用本教程中的代码: http//antongerdelan.net/opengl/hellotriangle.html ,它可以在我的mac上运行。 这是我运行的代码。

#include <GL/glew.h> // include GLEW and new version of GL on Windows
#include <GLFW/glfw3.h> // GLFW helper library
#include <stdio.h>

int main() {
    // start GL context and O/S window using the GLFW helper library
    if (!glfwInit()) {
        fprintf(stderr, "ERROR: could not start GLFW3\n");
        return 1;
    }

    // uncomment these lines if on Apple OS X
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow* window = glfwCreateWindow(640, 480, "Hello Triangle", NULL, NULL);
    if (!window) {
        fprintf(stderr, "ERROR: could not open window with GLFW3\n");
        glfwTerminate();
        return 1;
    }
    glfwMakeContextCurrent(window);

    // start GLEW extension handler
    glewExperimental = GL_TRUE;
    glewInit();

    // get version info
    const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string
    const GLubyte* version = glGetString(GL_VERSION); // version as a string
    printf("Renderer: %s\n", renderer);
    printf("OpenGL version supported %s\n", version);

    // tell GL to only draw onto a pixel if the shape is closer to the viewer
    glEnable(GL_DEPTH_TEST); // enable depth-testing
    glDepthFunc(GL_LESS); // depth-testing interprets a smaller value as "closer"

    /* OTHER STUFF GOES HERE NEXT */

    float points[] = {
        0.0f,  0.5f,  0.0f,
        0.5f, -0.5f,  0.0f,
        -0.5f, -0.5f,  0.0f
    };

    GLuint vbo = 0; // vertex buffer object
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), points, GL_STATIC_DRAW);

    GLuint vao = 0; // vertex array object
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);

    const char* vertex_shader =
    "#version 400\n"
    "in vec3 vp;"
    "void main() {"
    "  gl_Position = vec4(vp, 1.0);"
    "}";

    const char* fragment_shader =
    "#version 400\n"
    "out vec4 frag_colour;"
    "void main() {"
    "  frag_colour = vec4(0.5, 0.0, 0.5, 1.0);"
    "}";

    GLuint vs = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vs, 1, &vertex_shader, NULL);
    glCompileShader(vs);
    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fs, 1, &fragment_shader, NULL);
    glCompileShader(fs);

    GLuint shader_programme = glCreateProgram();
    glAttachShader(shader_programme, fs);
    glAttachShader(shader_programme, vs);
    glLinkProgram(shader_programme);

    while(!glfwWindowShouldClose(window)) {
        // wipe the drawing surface clear
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glUseProgram(shader_programme);
        glBindVertexArray(vao);
        // draw points 0-3 from the currently bound VAO with current in-use shader
        glDrawArrays(GL_TRIANGLES, 0, 3);
        // update other events like input handling
        glfwPollEvents();
        // put the stuff we've been drawing onto the display
        glfwSwapBuffers(window);
    }

    // close GL context and any other GLFW resources
    glfwTerminate();
    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM