c - MacOS X : unexpected behavior of glGenFramebuffers()

标签 c macos opengl

我正在做一个涉及使用 glGenFramebuffers() 的 OpenGL 学习练习。但是,当我调用该函数时,似乎什么也没有发生。我创建了以下简单程序来重现该问题:

#define GL_GLEXT_PROTOTYPES
#include <stdio.h>
#include <GL/gl.h>
#include <GL/glext.h>

static GLuint fb[2];

int main(void)
{
    glGenFramebuffers(2, fb);
    printf("result: %u %u\n", fb[0], fb[1]);
    return 0;
}

$ gcc -std=c99 -I/usr/X11/include test.c -o test -L/usr/X11/lib -lGL -lOSMesa

$./test

输出是result: 0 0

根据 http://www.opengl.org/wiki/GLAPI/glGenFramebuffers glGenFramebuffers() 应该设置 fb[0] 和 fb[1]。在我的例子中,我找不到解释实际结果的引用资料。我的真实代码的行为方式相同,所以我想这不是这里缺少某些初始化的问题。

我是做错了什么还是这是某种错误?


编辑:即使我有上下文,同样的事情也会发生。这是代码的更完整版本。

#define GL_GLEXT_PROTOTYPES

#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/glext.h>
#include <xcb/xcb.h>
#include <X11/Xlib-xcb.h>
#include <stdio.h>

static Display *display;
static xcb_connection_t *connection;
static xcb_window_t window;
static GLXDrawable drawable;
static GLXContext context;

static GLuint fb[2];

int main(void)
{
    display = XOpenDisplay(0);
    if (!display) return 0;

    int default_screen = XDefaultScreen(display);

    connection = XGetXCBConnection(display);
    if (!connection) goto error;

    int visualID = 0;

    XSetEventQueueOwner(display, XCBOwnsEventQueue);

    // find XCB screen
    xcb_screen_iterator_t screen_iter = xcb_setup_roots_iterator(xcb_get_setup(connection));
    int screen_num = default_screen;
    while (screen_iter.rem && screen_num > 0)
    {
        screen_num -= 1;
        xcb_screen_next(&screen_iter);
    }
    xcb_screen_t *screen = screen_iter.data;

    // query framebuffer configurations
    GLXFBConfig *fb_configs = 0;
    int num_fb_configs = 0;
    fb_configs = glXGetFBConfigs(display, default_screen, &num_fb_configs);
    if (!fb_configs || num_fb_configs == 0) goto error;

    // select first framebuffer config and query visualID
    GLXFBConfig fb_config = fb_configs[0];
    glXGetFBConfigAttrib(display, fb_config, GLX_VISUAL_ID , &visualID);

    // create OpenGL context
    context = glXCreateNewContext(display, fb_config, GLX_RGBA_TYPE, 0, True);
    if (!context) goto error;

    // create XID's for colormap and window
    xcb_colormap_t colormap = xcb_generate_id(connection);
    window = xcb_generate_id(connection);

    xcb_create_colormap(connection, XCB_COLORMAP_ALLOC_NONE, colormap, screen->root, visualID);

    uint32_t eventmask = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE;
    uint32_t valuelist[] = {eventmask, colormap, 0};
    uint32_t valuemask = XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;

    // TODO set window parameters
    xcb_create_window(connection, XCB_COPY_FROM_PARENT, window, screen->root, 100, 0, 400, 300, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visualID, valuemask, valuelist);

    // NOTE: window must be mapped before glXMakeContextCurrent
    xcb_map_window(connection, window); 

    drawable = glXCreateWindow(display, fb_config, window, 0);

    if (!window)
    {
        xcb_destroy_window(connection, window);
        glXDestroyContext(display, context);
        goto error;
    }

    // make OpenGL context current
    if (!glXMakeContextCurrent(display, drawable, drawable, context))
    {
        xcb_destroy_window(connection, window);
        glXDestroyContext(display, context);
        goto error;
    }

    glGenFramebuffers(2, fb);

    printf("%s\n", glGetString(GL_VERSION));
    printf("%d %d\n", fb[0], fb[1]);

    return 0;

error:
    XCloseDisplay(display);
}

输出:

2.1 NVIDIA-7.32.12
0 0

MacOS X 10.7.5

NVIDIA GeForce 320M 256MB

$ gcc --version
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)

glGetString(GL_VERSION): 2.1 NVIDIA-7.32.12

最佳答案

调用该函数后检查 glGetError (...) 的值。在 2.1 上下文中很可能是 GL_INVALID_OPERATION。您可以从 OS X 上的 GL 2.1 上下文调用 GL 3.x 函数,但它们将始终生成 GL_INVALID_OPERATION

情况与大多数其他平台截然不同,在其他平台中,函数指针是在运行时设置的。在 OS X 上,无论您拥有 GL 2.1 上下文还是 GL 3.2+ 核心,您都链接到同一个库,它包含 Apple 实现的每个 GL 版本的函数。这允许您调用未在您的上下文版本中实现的函数。但是,除了设置 GL_INVALID_OPERATION 之外,任何调用这些函数的尝试都不会在运行时产生任何影响。

要解决此问题,您需要使用 FBO 的 EXT 形式,或者获取 3.2+ 核心上下文。由于以后无法在 OS X 上使用 X11,因此您可能不得不使用扩展。我应该澄清一下,当我说使用 FBO 的扩展形式时,所有这些在 OS X 上实际上涉及的是将 glGenFramebuffers (...) 替换为 glGenFramebuffersEXT (...) .您不必调用任何 *GetProcAddress (...) 函数。

或者,您可以使用 SDL 或 GLFW3 之类的框架,或者从 X11/GLX 迁移到 NSOpenGL (Obj-C) 或 CGL (C/C++)。在 OS X 上使用 native 接口(interface)而不是弃用的东西,如 AGL 或 X11/GLX 是获得 3.2 核心上下文的唯一方法。

关于c - MacOS X : unexpected behavior of glGenFramebuffers(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21240036/

相关文章:

c - ubuntu 上的段错误,在 debian 上运行

c - 排列的矩阵和子矩阵

c - 指针&字符段错误

java - JDialog 小程序在 Mac OSX 中未正确隐藏

c++ - 将 OpenGL 1.x 代码移植到 WebGL

c++ - OpenCV-OpenGL 互操作性

c - 数组函数只返回第一个元素,我需要整个数组。请帮助

swift - 如何在 Mac OS X 中向 SpriteKit 游戏添加窗口(首选项窗口)?

xcode - 段错误 : 11 when attempting to codesign . 应用程序

opengl - 延迟渲染 vs 前向渲染 + early-z