我正在进行涉及使用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 256 MB
$ 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
答案 0 :(得分:3)
FBO只是OpenGL 3.0+的核心。你获得了2.1背景。
Check支持EXT_framebuffer_object
并使用glGenFramebuffersEXT()
代替。
答案 1 :(得分:3)
调用该函数后检查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
之外,任何调用这些函数的尝试都不会在运行时产生任何影响。
要解决此问题,您需要使用EXT
形式的FBO,或获得3.2+核心上下文。由于在OS X上无法使用X11进行后续操作,因此您可能必须使用该扩展。我应该澄清一下,当我说使用FBO的扩展形式时,所有这些实际上在OS X上的invovles正在用glGenFramebuffers (...)
替换glGenFramebuffersEXT (...)
。您无需调用任何*GetProcAddress (...)
函数。
或者你可以使用像SDL或GLFW3这样的框架,或者从X11 / GLX转移到NSOpenGL(Obj-C)或CGL(C / C ++)。在OS X上使用本机接口而不是AGL或X11 / GLX等弃用的东西是获得3.2核心上下文的唯一方法。
答案 2 :(得分:1)
您需要一个OpenGL上下文,但不创建一个。