示例#1
0
extern struct gl_platform *gl_platform_create(gs_device_t *device,
		uint32_t adapter)
{
	/* There's some trickery here... we're mixing libX11, xcb, and GLX
	   For an explanation see here: http://xcb.freedesktop.org/MixingCalls/
	   Essentially, GLX requires Xlib. Everything else we use xcb. */
	struct gl_platform * plat = bmalloc(sizeof(struct gl_platform));
	Display * display = open_windowless_display();

	if (!display) {
		goto fail_display_open;
	}

	XSetEventQueueOwner(display, XCBOwnsEventQueue);
	XSetErrorHandler(x_error_handler);

	/* We assume later that cur_swap is already set. */
	device->plat = plat;

	plat->display = display;

	if (!gl_context_create(plat)) {
		blog(LOG_ERROR, "Failed to create context!");
		goto fail_context_create;
	}

	if (!glXMakeContextCurrent(plat->display, plat->pbuffer, plat->pbuffer,
				plat->context)) {
		blog(LOG_ERROR, "Failed to make context current.");
		goto fail_make_current;
	}

	if (!gladLoadGL()) {
		blog(LOG_ERROR, "Failed to load OpenGL entry functions.");
		goto fail_load_gl;
	}

	blog(LOG_INFO, "OpenGL version: %s\n", glGetString(GL_VERSION));

	goto success;

fail_make_current:
	gl_context_destroy(plat);
fail_context_create:
fail_load_gl:
	XCloseDisplay(display);
fail_display_open:
	bfree(plat);
	plat = NULL;
success:
	UNUSED_PARAMETER(adapter);
	return plat;
}
示例#2
0
Handle
gl_context_create( Handle widget, GLRequest * request)
{
	int attr_list[64], *attr = attr_list;
	XVisualInfo * visual;
	GLXContext context;
	Context * ret;

	if ( pguts == NULL )
		pguts = (UnixGuts*) apc_system_action("unix_guts");

	CLEAR_ERROR;
	XCHECKPOINT;

#define ATTR(in,out) \
	if ( request-> in) { \
		*(attr++) = out; \
		*(attr++) = request-> in; \
	}

	*(attr++) = GLX_USE_GL;
	if ( request-> pixels         == GLREQ_PIXEL_RGBA) *(attr++) = GLX_RGBA;
	if ( request-> double_buffer  == GLREQ_TRUE) *(attr++) = GLX_DOUBLEBUFFER;
	if ( request-> stereo         == GLREQ_TRUE) *(attr++) = GLX_STEREO;
	ATTR( layer           , GLX_LEVEL            )
	ATTR( color_bits      , GLX_BUFFER_SIZE      )
	ATTR( aux_buffers     , GLX_AUX_BUFFERS      )
	ATTR( red_bits        , GLX_RED_SIZE         )
	ATTR( green_bits      , GLX_GREEN_SIZE       )
	ATTR( blue_bits       , GLX_BLUE_SIZE        )
	ATTR( alpha_bits      , GLX_ALPHA_SIZE       )
	ATTR( depth_bits      , GLX_DEPTH_SIZE       )
	ATTR( stencil_bits    , GLX_STENCIL_SIZE     )
	ATTR( accum_red_bits  , GLX_ACCUM_RED_SIZE   )
	ATTR( accum_green_bits, GLX_ACCUM_GREEN_SIZE )
	ATTR( accum_blue_bits , GLX_ACCUM_BLUE_SIZE  )
	ATTR( accum_alpha_bits, GLX_ACCUM_ALPHA_SIZE )
	*(attr++) = 0;

	if ( request-> target == GLREQ_TARGET_WINDOW && sys-> flags. layered) {
		visual = sys-> visual;
	} else if ( !( visual = glXChooseVisual( DISP, SCREEN, attr_list ))) {
		if ( request-> pixels != GLREQ_PIXEL_RGBA) {
			/* emulate win32 which does it softly, i.e. if RGBA fails, it proposes PALETTED */
			request-> pixels = GLREQ_PIXEL_RGBA;
			return gl_context_create( widget, request);
		}
		if ( request-> double_buffer == GLREQ_DONTCARE) {
			request-> double_buffer = GLREQ_TRUE;
			return gl_context_create( widget, request );
		}
		SET_ERROR( ERROR_CHOOSE_VISUAL );
		return (Handle) 0;
	}

	XCHECKPOINT;
	if ( !( context = glXCreateContext( DISP, visual, 0, request-> render != GLREQ_RENDER_XSERVER))) {
		SET_ERROR( ERROR_CREATE_CONTEXT );
		return (Handle) 0;
	}

	ret = malloc( sizeof( Context ));
	memset( ret, 0, sizeof( Context));
	ret-> context  = context;

	switch ( request-> target) {
	case GLREQ_TARGET_WINDOW:
		ret-> drawable   = var-> handle;
		break;
	case GLREQ_TARGET_APPLICATION:
		/* doesn't work with gnome and kde anyway */
		ret-> drawable   = RootWindow( DISP, SCREEN);
		break;
	case GLREQ_TARGET_BITMAP:
	case GLREQ_TARGET_IMAGE: 
	{
		GLXContext  old_context;
		GLXDrawable old_drawable;
		Bool success;
		XCHECKPOINT;

		ret-> drawable = glXCreateGLXPixmap( DISP, visual, sys-> gdrawable);
		ret-> pixmap   = 1;

		/* check if pixmaps are supported on this visual at all */
		old_context  = glXGetCurrentContext();
		old_drawable = glXGetCurrentDrawable();
		success = glXMakeCurrent( DISP, ret-> drawable, ret-> context);
		glXMakeCurrent( DISP, old_drawable, old_context);
		if ( !success ) {
			SET_ERROR( ERROR_NO_PIXMAPS );
			glXDestroyGLXPixmap( DISP, ret-> drawable);
			glXDestroyContext( DISP, ret-> context );
			free(ret);
			return 0;
		}


		break;
	}
	case GLREQ_TARGET_PRINTER:
		SET_ERROR(ERROR_NO_PRINTER);
		free(ret);
		return 0;
	}

	return (Handle) ret;
}
示例#3
0
extern struct gl_platform *gl_platform_create(gs_device_t *device,
		const struct gs_init_data *info)
{
	/* There's some trickery here... we're mixing libX11, xcb, and GLX
	   For an explanation see here: http://xcb.freedesktop.org/MixingCalls/
	   Essentially, GLX requires Xlib. Everything else we use xcb. */
	struct gl_windowinfo *wi = gl_windowinfo_create(info);
	struct gl_platform * plat = bmalloc(sizeof(struct gl_platform));
	Display * display;

	print_info_stuff(info);

	if (!wi) {
		blog(LOG_ERROR, "Failed to create window info!");
		goto fail_wi_create;
	}

	display = XOpenDisplay(XDisplayString(info->window.display));
	if (!display) {
		blog(LOG_ERROR, "Unable to open new X connection!");
		goto fail_display_open;
	}

	XSetEventQueueOwner(display, XCBOwnsEventQueue);
	XSetErrorHandler(x_error_handler);

	/* We assume later that cur_swap is already set. */
	device->cur_swap = &plat->swap;
	device->plat = plat;

	plat->display = display;
	plat->swap.device = device;
	plat->swap.info = *info;
	plat->swap.wi = wi;

	if (!gl_platform_init_swapchain(&plat->swap)) {
		blog(LOG_ERROR, "Failed to initialize swap chain!");
		goto fail_init_swapchain;
	}

	if (!gl_context_create(plat)) {
		blog(LOG_ERROR, "Failed to create context!");
		goto fail_context_create;
	}

	if (!glXMakeCurrent(plat->display, wi->window, plat->context)) {
		blog(LOG_ERROR, "Failed to make context current.");
		goto fail_make_current;
	}

	if (!gladLoadGL()) {
		blog(LOG_ERROR, "Failed to load OpenGL entry functions.");
		goto fail_load_gl;
	}

	blog(LOG_INFO, "OpenGL version: %s\n", glGetString(GL_VERSION));

	goto success;

fail_make_current:
	gl_context_destroy(plat);
fail_context_create:
fail_load_gl:
fail_init_swapchain:
	XCloseDisplay(display);
fail_display_open:
fail_wi_create:
	gl_windowinfo_destroy(wi);
	free(plat);
	plat = NULL;
success:
	return plat;
}
示例#4
0
文件: opengl.c 项目: AgentD/sgui
static sgui_context* gl_context_create_share( sgui_context* super )
{
    sgui_context_gl* this = (sgui_context_gl*)super;
    return gl_context_create( this->wnd, this->wnd->backend, super );
}