如何使用 Xcode 在 Mac 上运行 OpenGL 编程指南中的示例

How to run the examples in OpenGL Programming Guide on Mac with Xcode

我正在阅读 OpenGL 编程指南一书学习 OpenGL 编程。但是我不能用我的 Mac 书来运行书中的示例。即使是处理第一个示例三角形,在运行时总是会出现几十个错误。我想知道我应该怎么做才能用 Xcode.

运行 Red Book 中的示例

[平台信息]
Mac预订空气,OS X 10.10,Xcode 6.1

[我尝试了什么]
1.我删除了AppDelegate.*和main.m,然后创建一个cpp文件triangles.cpp,将源码复制进去。(源码会在最后附上)
2.我添加了OpenGL.framework.
3、我手动安装了glew,在Header Search Paths和Library Search Paths中添加了相应的路径。并将 -lGLEW 添加到其他链接器标志。
4.我手动安装了freeglut,在Header Search Paths和Library Search Paths中添加了相应的路径,并在Other Linker Flags中添加了-lGLUT,就在Lazy Foo的OpenGL教程的指导下。
5. 我在Header Search Paths 和Library Search Paths 中添加了红皮书附带的源代码目录,这样Xcode 就可以找到"vgl.h" 和"LoadShaders.h"。并且 LoadShaders.cpp 被添加到项目中。

我做第3步和第4步的原因是为了编译成功,否则,我会收到很多错误,例如:

Undefined symbols for architecture x86_64:
      "_glutInitContextProfile", referenced from:
          _main in main.o

但是这样编译是可以的,但是运行的时候就报错了:

X Error of failed request:  BadRequest (invalid request code or no such operation)
  Major opcode of failed request:  34 (X_UngrabKey)
  Serial number of failed request:  29
  Current serial number in output stream:  29
Program ended with exit code: 1

我真的很想知道在 Mac OS X!

上运行红皮书中示例的正确方法是什么

triangles.cpp:

#include <iostream>
using namespace std;

#include "vgl.h"
#include "LoadShaders.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;

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

    GLfloat vertices[NumVertices][2] = {
        {-0.90, -0.90},
        {0.85, -0.90},
        {-0.90, 0.85},
        {0.90, -0.85},
        {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);
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBindVertexArray(VAOs[Triangles]);
    glDrawArrays(GL_TRIANGLES, 0, NumVertices);

    glFlush();
}

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]);

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

    init();
    glutDisplayFunc(display);
    glutMainLoop();
}

如果您不介意在 C# 中工作,请查看 OpenTK,它是用于 Mono 和 .Net 的 OpenGL 包装器。我还没有用 Xcode 尝试过它,但它在 Xamarin Studio 中运行得很好。

如果走 Xamarin 路线,有两个选择:

1) 下载the latest OpenTK release并参考OpenTK.dll
2)使用Xamarin自带的OpenTK,说明here.

我建议下载外部版本,其中包含大量有用的示例。

但需要注意的是,在 MacOS 上,GameWindow 构造函数默认为 OpenGL 2.1(Windows 上没有),因此如果您想使用现代功能,则必须明确指定 OpenGL 版本构造函数中的数字。

public Game() : base(800, 600, new GraphicsMode(new ColorFormat(8), 3, 3, 4), "Welcome To Hell", GameWindowFlags.Default, DisplayDevice.Default, 3, 0, GraphicsContextFlags.Default)
{
}

红皮书的例子不会直接在OpenTK中运行,但是GL调用是一样的,只是语法需要修改。我发现 Neo Kabuto 的博客是 OpenTK 教程的最佳选择,很快,您就可以用 TK 重写红皮书代码了。

这可能不是您要找的答案,但这是我解决问题的方法。