Beispiel #1
0
Graphics::Graphics(Profile &profile)
: mMinAspect(0.0f), mMaxAspect(0.0f), mVSync(true), mFPSTime(0), mNumFrames(0), mFPS(0.0f), mBlendMode(BLEND_ALPHA)
{
	// setup the graphics settings
	CL_DisplayWindowDescription desc;
	desc.set_title("Balance");
	desc.set_size(CL_Size(profile.getInt("width", 1024), profile.getInt("height", 768)), true);
	desc.set_swap_interval(mVSync ? 1 : 0);
	if (profile.getBool("fullscreen", true))
	{
		desc.set_decorations(false);
		desc.set_fullscreen(true);
	}
	else
	{
		desc.set_allow_resize(true);
	}
	mWindow = CL_DisplayWindow(desc);

	// make window visible while debugging under SciTE
	mWindow.show();

	// connect window signals
	mSlots.connect(Application::getSingleton().getSigUpdate(), this, &Graphics::onUpdate);
	mSlots.connect(mWindow.get_ic().get_mouse().sig_key_down(), this, &Graphics::onMouseDown);
	mSlots.connect(mWindow.get_ic().get_mouse().sig_key_dblclk(), this, &Graphics::onMouseDown);
	mSlots.connect(mWindow.get_ic().get_mouse().sig_key_up(), this, &Graphics::onMouseUp);
	mSlots.connect(mWindow.sig_resize(), this, &Graphics::onResize);
	mSlots.connect(mWindow.sig_window_close(), this, &Graphics::onClose);

	// initialize the graphics settings
	mWindow.get_gc().set_map_mode(cl_user_projection);
	setScreenSize(1024.0f, 768.0f);
	setBlendMode(mBlendMode);

	// save the current settings
	profile.setBool("fullscreen", desc.is_fullscreen());
	profile.setInt("width", desc.get_size().width);
	profile.setInt("height", desc.get_size().height);
}
void CL_DisplayWindow_OpenGL::create_window(const CL_DisplayWindowDescription &desc)
{
	OSStatus result;

	const CL_OpenGLWindowDescription_Generic *gl_desc = 0;
	gl_desc = dynamic_cast<const CL_OpenGLWindowDescription_Generic*>(desc.impl.get());

	fullscreen_width = desc.get_size().width;
	fullscreen_height = desc.get_size().height;

	disp_ref_count++;

	GLint gl_attribs_single[] =
	{
		AGL_RGBA,
		AGL_RED_SIZE, 4,
		AGL_GREEN_SIZE, 4,
		AGL_BLUE_SIZE, 4,
		AGL_DEPTH_SIZE, 16,
		AGL_NONE
	};

	GLint gl_attribs[32];
	int i = 0;
	
	if( gl_desc )
	{
		if( gl_desc->rgba ) gl_attribs[i++] = AGL_RGBA;
		if( gl_desc->doublebuffer ) gl_attribs[i++] = AGL_DOUBLEBUFFER;
		//if( gl_desc->stereo ) gl_attribs[i++] = AGL_STEREO;
		gl_attribs[i++] = AGL_BUFFER_SIZE;
		gl_attribs[i++] = gl_desc->buffer_size;
		gl_attribs[i++] = AGL_LEVEL;
		gl_attribs[i++] = gl_desc->level;
		gl_attribs[i++] = AGL_AUX_BUFFERS;
		gl_attribs[i++] = gl_desc->aux_buffers;
		gl_attribs[i++] = AGL_RED_SIZE; 
		gl_attribs[i++] = gl_desc->red_size;
		gl_attribs[i++] = AGL_GREEN_SIZE;
		gl_attribs[i++] = gl_desc->green_size;
		gl_attribs[i++] = AGL_BLUE_SIZE;
		gl_attribs[i++] = gl_desc->blue_size;
		gl_attribs[i++] = AGL_DEPTH_SIZE;
		gl_attribs[i++] = gl_desc->depth_size;
		gl_attribs[i++] = AGL_STENCIL_SIZE;
		gl_attribs[i++] = gl_desc->stencil_size;
		gl_attribs[i++] = AGL_ACCUM_RED_SIZE;
		gl_attribs[i++] = gl_desc->accum_red_size;
		gl_attribs[i++] = AGL_ACCUM_GREEN_SIZE;
		gl_attribs[i++] = gl_desc->accum_green_size;
		gl_attribs[i++] = AGL_ACCUM_BLUE_SIZE;
		gl_attribs[i++] = gl_desc->accum_blue_size;
		gl_attribs[i++] = AGL_ACCUM_ALPHA_SIZE;
		gl_attribs[i++] = gl_desc->accum_alpha_size;
		gl_attribs[i++] = AGL_ACCUM_RED_SIZE;
		gl_attribs[i++] = gl_desc->accum_red_size;
//		gl_attribs[i++] = AGL_FULLSCREEN;
	}
	else
	{
		gl_attribs[i++] = AGL_RGBA;
		gl_attribs[i++] = AGL_NO_RECOVERY;
		gl_attribs[i++] = AGL_DOUBLEBUFFER;
		gl_attribs[i++] = AGL_DEPTH_SIZE;
		gl_attribs[i++] = 16;
	} 
/*	
	else
	{
		gl_attribs[i++] = AGL_RGBA;
		gl_attribs[i++] = AGL_DOUBLEBUFFER;
		gl_attribs[i++] = AGL_RED_SIZE;
		gl_attribs[i++] = 4;
		gl_attribs[i++] = AGL_GREEN_SIZE;
		gl_attribs[i++] = 4;
		gl_attribs[i++] = AGL_BLUE_SIZE;
		gl_attribs[i++] = 4;
		gl_attribs[i++] = AGL_DEPTH_SIZE;
		gl_attribs[i++] = 16;
//		gl_attribs[i++] = AGL_FULLSCREEN;
	}
*/

	gl_attribs[i] = AGL_NONE;

	CGDirectDisplayID display = CGMainDisplayID();
	GDHandle gdhDisplay, *pgdhDisplay;
	int numDisplay;

	pgdhDisplay = &gdhDisplay;
	
	if (noErr == DMGetGDeviceByDisplayID ((DisplayIDType)display, pgdhDisplay, false)) 
		numDisplay = 1;	
	else 
	{
		pgdhDisplay = 0;
		numDisplay = 0;
	}
		
	AGLPixelFormat pixelformat;	
	pixelformat = aglChoosePixelFormat(pgdhDisplay, numDisplay, gl_attribs);
	win_context = aglCreateContext(pixelformat, share_context);
	if (!share_context) share_context = win_context;
	aglDestroyPixelFormat(pixelformat);
	gl_attribs[i++] = AGL_FULLSCREEN;
	gl_attribs[i] = AGL_NONE;
	pixelformat = aglChoosePixelFormat(pgdhDisplay, numDisplay, gl_attribs);
	fs_context = aglCreateContext(pixelformat, win_context);
	aglDestroyPixelFormat(pixelformat);

	if (!(win_context && fs_context)) 
	{
		printf("Requested visual not supported by your OpenGL implementation. Falling back on singlebuffered Visual!\n");
		pixelformat = aglChoosePixelFormat(0, 0, gl_attribs_single);
		win_context = aglCreateContext(pixelformat, share_context);
		aglDestroyPixelFormat(pixelformat);
		fs_context = 0;
	}

	WindowAttributes style = kWindowCloseBoxAttribute | kWindowStandardHandlerAttribute;
	if (desc.get_allow_resize()) style |= kWindowResizableAttribute | kWindowFullZoomAttribute;
	Rect window_rect;
	SetRect(&window_rect, 50, 50, 50+desc.get_size().width, 50+desc.get_size().height);
	result = CreateNewWindow(kDocumentWindowClass, style, &window_rect, &window_ref);
	if (result != noErr)
		printf("Could not create window, due to error %d\n", (int)result);

	// set title of window:
	set_title(desc.get_title());

	// Set standard arrow cursor:
	InitCursor(); // do we need to do this? -- iMBN, 13. may 2004
	
	// Create input devices for window:
	keyboard = CL_InputDevice(new CL_InputDevice_MacKeyboard(this));
	mouse	= CL_InputDevice(new CL_InputDevice_MacMouse(this));

	get_ic()->clear();
	get_ic()->add_keyboard(keyboard);
	get_ic()->add_mouse(mouse);

//	buffer_front = CL_PixelBuffer(new CL_PixelBuffer_OpenGL_Frame(CL_FRONT, gc));
//	buffer_back = CL_PixelBuffer(new CL_PixelBuffer_OpenGL_Frame(CL_BACK, gc));

	if (!aglSetDrawable(win_context, GetWindowPort(window_ref)))
	{
		printf("Unable to set drawable");
	}
	
	if (desc.is_fullscreen())
		set_fullscreen(desc.get_size().width, desc.get_size().height, desc.get_bpp(), desc.get_refresh_rate());
	else {
		fullscreen = true;  // not really, but need to fool set_windowed
		set_windowed();
	}

	ShowWindow(window_ref);
}
void CL_DisplayWindow_OpenGL::create_window(const CL_DisplayWindowDescription &desc)
{
	const CL_OpenGLWindowDescription_Generic *gl_desc = 0;
	gl_desc = dynamic_cast<const CL_OpenGLWindowDescription_Generic*>(desc.impl.get());

	fullscreen_width  = desc.get_size().width;
	fullscreen_height = desc.get_size().height;

	XVisualInfo *vi;
	Colormap cmap;

	if (disp == 0)
	{
		disp = XOpenDisplay(0);
		if (disp == 0) throw CL_Error("Could not open X11 display!");
	}
	disp_ref_count++;

	int gl_attribs_single[] =
	{
		GLX_RGBA,
		GLX_RED_SIZE, 4,
		GLX_GREEN_SIZE, 4,
		GLX_BLUE_SIZE, 4,
		GLX_DEPTH_SIZE, 16,
		None
	};

	int gl_attribs[32];
	int i = 0;
	
	if( gl_desc )
	{
		if( gl_desc->rgba ) gl_attribs[i++] = GLX_RGBA;
		if( gl_desc->doublebuffer ) gl_attribs[i++] = GLX_DOUBLEBUFFER;
		if( gl_desc->stereo ) gl_attribs[i++] = GLX_STEREO;
		gl_attribs[i++] = GLX_BUFFER_SIZE;
		gl_attribs[i++] = gl_desc->buffer_size;
		gl_attribs[i++] = GLX_LEVEL;
		gl_attribs[i++] = gl_desc->level;
		gl_attribs[i++] = GLX_AUX_BUFFERS;
		gl_attribs[i++] = gl_desc->aux_buffers;
		gl_attribs[i++] = GLX_RED_SIZE; 
		gl_attribs[i++] = gl_desc->red_size;
		gl_attribs[i++] = GLX_GREEN_SIZE;
		gl_attribs[i++] = gl_desc->green_size;
		gl_attribs[i++] = GLX_BLUE_SIZE;
		gl_attribs[i++] = gl_desc->blue_size;
		gl_attribs[i++] = GLX_DEPTH_SIZE;
		gl_attribs[i++] = gl_desc->depth_size;
		gl_attribs[i++] = GLX_STENCIL_SIZE;
		gl_attribs[i++] = gl_desc->stencil_size;
		gl_attribs[i++] = GLX_ACCUM_RED_SIZE;
		gl_attribs[i++] = gl_desc->accum_red_size;
		gl_attribs[i++] = GLX_ACCUM_GREEN_SIZE;
		gl_attribs[i++] = gl_desc->accum_green_size;
		gl_attribs[i++] = GLX_ACCUM_BLUE_SIZE;
		gl_attribs[i++] = gl_desc->accum_blue_size;
		gl_attribs[i++] = GLX_ACCUM_ALPHA_SIZE;
		gl_attribs[i++] = gl_desc->accum_alpha_size;
		gl_attribs[i++] = GLX_ACCUM_RED_SIZE;
		gl_attribs[i++] = gl_desc->accum_red_size;
		gl_attribs[i++] = None;
	}
	else
	{
		gl_attribs[i++] = GLX_RGBA;
		gl_attribs[i++] = GLX_DOUBLEBUFFER;
		gl_attribs[i++] = GLX_RED_SIZE;
		gl_attribs[i++] = 4;
		gl_attribs[i++] = GLX_GREEN_SIZE;
		gl_attribs[i++] = 4;
		gl_attribs[i++] = GLX_BLUE_SIZE;
		gl_attribs[i++] = 4;
		gl_attribs[i++] = GLX_DEPTH_SIZE;
		gl_attribs[i++] = 16;
		gl_attribs[i++] = None;
	}

	// get an appropriate visual
	vi = glXChooseVisual(disp, DefaultScreen(disp), gl_attribs);
	
	if (vi == NULL)
	{
		vi = glXChooseVisual(disp, window, gl_attribs_single);
		printf("Requested visual not supported by your OpenGL implementation. Falling back on singlebuffered Visual!\n");
	}

	// create a GLX context
	context = glXCreateContext(disp, vi, share_context, True);

	if( share_context == NULL )
		share_context = context;

	glXGetConfig(disp, vi, GLX_BUFFER_SIZE, &glx_bpp);

	// create a color map
	cmap = XCreateColormap( disp, RootWindow(disp, vi->screen), vi->visual, AllocNone);

	attributes.colormap = cmap;
	attributes.border_pixel = 0;
	attributes.override_redirect = False;

	// create a window in window mode
	attributes.event_mask =
		ExposureMask |
		KeyPressMask |
		KeyReleaseMask |
		ButtonPressMask |
		ButtonReleaseMask |
		StructureNotifyMask |
		PointerMotionMask |
		EnterWindowMask |
		LeaveWindowMask |
		FocusChangeMask;

	window = XCreateWindow(disp, RootWindow(disp, vi->screen),
		0, 0, desc.get_size().width, desc.get_size().height, 0, vi->depth, InputOutput, vi->visual,
		CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask, &attributes);
	
	XSelectInput(disp, window,
		FocusChangeMask | KeyPressMask | KeyReleaseMask
		| PropertyChangeMask | StructureNotifyMask |
		KeymapStateMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask);

	// set title of window:
	set_title(desc.get_title());
	
	// setup size hints:
	XSizeHints size_hints;
	memset(&size_hints, 0, sizeof(XSizeHints));
	size_hints.width       = desc.get_size().width;
	size_hints.height      = desc.get_size().height;
	size_hints.base_width  = desc.get_size().width;
	size_hints.base_height = desc.get_size().height;
	size_hints.min_width   = size_hints.width;
	size_hints.min_height  = size_hints.height;
	size_hints.max_width   = size_hints.width;
	size_hints.max_height  = size_hints.height;
	size_hints.flags       = PSize|PBaseSize;
	if (!desc.get_allow_resize()) size_hints.flags |= PMinSize | PMaxSize;
	XSetWMNormalHints(disp, window, &size_hints);

	// handle wm_delete_events if in windowed mode:
	Atom wm_delete = XInternAtom(disp, "WM_DELETE_WINDOW", True);
	XSetWMProtocols(disp, window, &wm_delete, 1);

	// make window visible:
	XMapRaised(disp, window);

	if (!glXIsDirect(disp, context))
		printf("No hardware acceleration available. I hope you got a really fast machine..\n");

	// Create input devices for window:
	keyboard = CL_InputDevice(new CL_InputDevice_X11Keyboard(this));
	mouse    = CL_InputDevice(new CL_InputDevice_X11Mouse(this));

	get_ic()->clear();
	get_ic()->add_keyboard(keyboard);
	get_ic()->add_mouse(mouse);

	setup_joysticks();
// 	setup_usb_mice();
//	setup_xinput();
//	setup_event();

	XSync(disp, True);
	
	focus = true;
	
	system_cursor = XCreateFontCursor(disp, XC_left_ptr);
	char *data = (char*)malloc(64); // 8x8
	memset(data, 0, 64);

	XColor black_color;
	memset(&black_color, 0, sizeof(black_color));

	cursor_bitmap = XCreateBitmapFromData(disp, window, data, 8, 8);
	hidden_cursor = XCreatePixmapCursor(disp, cursor_bitmap, cursor_bitmap, &black_color, &black_color, 0,0 );
	
	if (desc.is_fullscreen())
		set_fullscreen(desc.get_size().width, desc.get_size().height, desc.get_bpp(), desc.get_refresh_rate());
}