2014-01-20 4 views
1

Я занимаюсь учебным упражнением OpenGL, которое включает использование glGenFramebuffers(). Однако, когда я вызываю функцию, кажется, что ничего не происходит. Я создал следующую простую программу, чтобы воспроизвести проблему:MacOS X: неожиданное поведение glGenFramebuffers()

#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] и фб [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 256 МБ

$ 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

+1

Возможный дубликат [Почему может ли glGetString (GL \ _VERSION) вызвать причину Seg Fault?] (Http://stackoverflow.com/questions/6288759/why-could-glgetstringgl-version-be-causing-a-seg -fault) – genpfault

ответ

3

После вызова этой функции проверьте значение glGetError (...). Это очень вероятно GL_INVALID_OPERATION в контексте 2.1. Вы можете вызвать функции GL 3.x из контекста GL 2.1 в OS X, но они всегда будут генерировать GL_INVALID_OPERATION.

Ситуация сильно отличается от большинства других платформ, где указатели на функции настраиваются во время выполнения. В OS X вы ссылаетесь на одну и ту же библиотеку, есть ли у вас GL 2.1-контекст или GL 3.2+-ядро, которое содержит функции для каждой версии GL, которые Apple реализует. Это позволяет вам вызывать функции, которые не реализованы в вашей версии контекста. Однако любая попытка вызова этих функций не будет влиять на время выполнения, отличное от установки GL_INVALID_OPERATION.

Чтобы исправить это, вам нужно либо использовать форму FBOs EXT, либо получить базовый контекст 3.2+. Поскольку нет способа сделать более позднюю версию с использованием X11 в OS X, вам, вероятно, придется использовать расширение. Я должен пояснить, что, когда я говорю использовать форму расширения FBOs, все это на самом деле invosles на OS X заменяет glGenFramebuffers (...) на glGenFramebuffersEXT (...). Вам не нужно вызывать функции *GetProcAddress (...).

В качестве альтернативы вы можете использовать фреймворк, например SDL или GLFW3, или перейти от X11/GLX к NSOpenGL (Obj-C) или CGL (C/C++). Использование родных интерфейсов вместо устаревших вещей, таких как AGL или X11/GLX на OS X, является единственным способом получить 3,2-х основных контекстов.

+0

glGetError() фактически возвращает 0, но после того, как я изменил код, чтобы использовать функции * EXT, и все началось с работы :) Очень странно, как OS X обрабатывает версии opengl. Я ожидал бы получить ошибку компиляции, но библиотека просто терпит неудачу во время выполнения. – martinkunev

+1

Обычно это выполняется довольно грациозно на OS X. Если вы используете фреймворк OpenGL и включаете , он включает только функции, предоставляемые контекстом 2.1. Вы должны использовать , чтобы получить определения функций, typedefs и константы из ядра 3.2+. Но поскольку вы используете X11/GLX/Mesa вместо обычной OpenGL-структуры, он не ведет себя так. –

+0

Я хотел иметь возможность запускать тот же код в Linux, поэтому я решил, что это путь. – martinkunev

1

Вам нужен контекст OpenGL, но вы его не создаете.

3

FBOs - это только ядро ​​в OpenGL 3.0+. Вы получаете контекст 2.1.

Check для EXT_framebuffer_object поддержка и использование glGenFramebuffersEXT().

Смежные вопросы