예제 #1
0
OSErr SetupPickMonitorPane(ControlRef inPane, DisplayIDType inDefaultMonitor)
{
	GDHandle dev = GetDeviceList();
	OSErr err = noErr;
	
	// make the default monitor the selected device
	if (inDefaultMonitor)
		DMGetGDeviceByDisplayID(inDefaultMonitor, &sSelectedDevice, true);
	else
		sSelectedDevice = GetMainDevice();

	// build the list of monitors
	sNumMonitors = 0;
	while (dev && sNumMonitors < kMaxMonitors)
	{
		if (TestDeviceAttribute(dev, screenDevice) && TestDeviceAttribute(dev, screenActive))
		{
			sMonitors[sNumMonitors].device = dev;
			sMonitors[sNumMonitors].origRect = (**dev).gdRect;
			sMonitors[sNumMonitors].isMain = (dev == GetMainDevice());
			sNumMonitors++;
		}
		dev = GetNextDevice(dev);
	}

	// calculate scaled rects
	if (sNumMonitors)
	{
		Rect origPaneRect, paneRect;
		Rect origGrayRect, grayRect, scaledGrayRect;
		float srcAspect, dstAspect, scale;
		int i;
		
		GetControlBounds(inPane, &origPaneRect);
		paneRect = origPaneRect;
		OffsetRect(&paneRect, -paneRect.left, -paneRect.top);
		
		GetRegionBounds(GetGrayRgn(), &origGrayRect);
		grayRect = origGrayRect;
		OffsetRect(&grayRect, -grayRect.left, -grayRect.top);
		
		srcAspect = (float)grayRect.right / (float)grayRect.bottom;
		dstAspect = (float)paneRect.right / (float)paneRect.bottom;
		
		scaledGrayRect = paneRect;
		
		if (srcAspect < dstAspect)
		{
			scaledGrayRect.right = (float)paneRect.bottom * srcAspect;
			scale = (float)scaledGrayRect.right / grayRect.right;
		}
		else
		{
			scaledGrayRect.bottom = (float)paneRect.right / srcAspect;
			scale = (float)scaledGrayRect.bottom / grayRect.bottom;
		}
		
		for (i = 0; i < sNumMonitors; i++)
		{
			Rect r = sMonitors[i].origRect;
			Rect r2 = r;
			
			// normalize rect and scale
			OffsetRect(&r, -r.left, -r.top);
			r.bottom = (float)r.bottom * scale;
			r.right = (float)r.right * scale;
			
			// offset rect wrt gray region
			OffsetRect(&r, (float)(r2.left - origGrayRect.left) * scale, 
							(float)(r2.top - origGrayRect.top) * scale);

			sMonitors[i].scaledRect = r;
		}
		
		// center scaledGrayRect in the pane
		OffsetRect(&scaledGrayRect, (paneRect.right - scaledGrayRect.right) / 2,
					(paneRect.bottom - scaledGrayRect.bottom) / 2);

		// offset monitors to match
		for (i = 0; i < sNumMonitors; i++)
			OffsetRect(&sMonitors[i].scaledRect, scaledGrayRect.left, scaledGrayRect.top);
	}
	else
		return paramErr;
		
	// setup the procs for the pick monitor user pane
	err = SetupUserPaneProcs(inPane, drawProc, hitTestProc, trackingProc);
	return err;
}
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);
}
예제 #3
0
qboolean VID_InitMode(viddef_mode_t *mode)
{
	const EventTypeSpec winEvents[] =
	{
		{ kEventClassWindow, kEventWindowClosed },
		{ kEventClassWindow, kEventWindowCollapsing },
		{ kEventClassWindow, kEventWindowExpanded },
	};
	OSStatus carbonError;
	Rect windowBounds;
	CFStringRef windowTitle;
	AGLPixelFormat pixelFormat;
	GLint attributes [32];
	GLenum error;

	if (!GL_OpenLibrary())
	{
		Con_Printf("Unable to load GL driver\n");
		return false;
	}

	if ((qaglChoosePixelFormat = (AGLPixelFormat (*) (const AGLDevice *gdevs, GLint ndev, const GLint *attribList))GL_GetProcAddress("aglChoosePixelFormat")) == NULL
	 || (qaglCreateContext = (AGLContext (*) (AGLPixelFormat pix, AGLContext share))GL_GetProcAddress("aglCreateContext")) == NULL
	 || (qaglDestroyContext = (GLboolean (*) (AGLContext ctx))GL_GetProcAddress("aglDestroyContext")) == NULL
	 || (qaglDestroyPixelFormat = (void (*) (AGLPixelFormat pix))GL_GetProcAddress("aglDestroyPixelFormat")) == NULL
	 || (qaglErrorString = (const GLubyte* (*) (GLenum code))GL_GetProcAddress("aglErrorString")) == NULL
	 || (qaglGetError = (GLenum (*) (void))GL_GetProcAddress("aglGetError")) == NULL
	 || (qaglSetCurrentContext = (GLboolean (*) (AGLContext ctx))GL_GetProcAddress("aglSetCurrentContext")) == NULL
	 || (qaglSetDrawable = (GLboolean (*) (AGLContext ctx, AGLDrawable draw))GL_GetProcAddress("aglSetDrawable")) == NULL
	 || (qaglSetFullScreen = (GLboolean (*) (AGLContext ctx, GLsizei width, GLsizei height, GLsizei freq, GLint device))GL_GetProcAddress("aglSetFullScreen")) == NULL
	 || (qaglSetInteger = (GLboolean (*) (AGLContext ctx, GLenum pname, const GLint *params))GL_GetProcAddress("aglSetInteger")) == NULL
	 || (qaglSwapBuffers = (void (*) (AGLContext ctx))GL_GetProcAddress("aglSwapBuffers")) == NULL
	)
	{
		Con_Printf("AGL functions not found\n");
		ReleaseWindow(window);
		return false;
	}

	qCGLEnable = (CGLError (*) (CGLContextObj ctx, CGLContextEnable pname)) CGL_GetProcAddress("CGLEnable");
	qCGLDisable = (CGLError (*) (CGLContextObj ctx, CGLContextEnable pname)) CGL_GetProcAddress("CGLDisable");
	qCGLGetCurrentContext = (CGLContextObj (*) (void)) CGL_GetProcAddress("CGLGetCurrentContext");
	if(!qCGLEnable || !qCGLDisable || !qCGLGetCurrentContext)
		Con_Printf("CGL functions not found; disabling multithreaded OpenGL\n");

	// Ignore the events from the previous window
	AsyncEvent_Quitting = false;
	AsyncEvent_Collapsed = false;

	// Create the window, a bit towards the center of the screen
	windowBounds.left = 100;
	windowBounds.top = 100;
	windowBounds.right = mode->width + 100;
	windowBounds.bottom = mode->height + 100;
	carbonError = CreateNewWindow(kDocumentWindowClass, kWindowStandardFloatingAttributes | kWindowStandardHandlerAttribute, &windowBounds, &window);
	if (carbonError != noErr || window == NULL)
	{
		Con_Printf("Unable to create window (error %u)\n", (unsigned)carbonError);
		return false;
	}

	// Set the window title
	windowTitle = CFSTR("DarkPlaces AGL");
	SetWindowTitleWithCFString(window, windowTitle);

	// Install the callback function for the window events we can't get
	// through ReceiveNextEvent (i.e. close, collapse, and expand)
	InstallWindowEventHandler (window, NewEventHandlerUPP (MainWindowEventHandler),
							   GetEventTypeCount(winEvents), winEvents, window, NULL);

	// Create the desired attribute list
	VID_BuildAGLAttrib(attributes, mode->bitsperpixel == 32, mode->fullscreen, mode->stereobuffer, mode->samples);

	if (!mode->fullscreen)
	{
		// Output to Window
		pixelFormat = qaglChoosePixelFormat(NULL, 0, attributes);
		error = qaglGetError();
		if (error != AGL_NO_ERROR)
		{
			Con_Printf("qaglChoosePixelFormat FAILED: %s\n",
					(char *)qaglErrorString(error));
			ReleaseWindow(window);
			return false;
		}
	}
	else  // Output is fullScreen
	{
		CGDirectDisplayID mainDisplay;
		CFDictionaryRef refDisplayMode;
		GDHandle gdhDisplay;

		// Get the mainDisplay and set resolution to current
		mainDisplay = CGMainDisplayID();
		CGDisplayCapture(mainDisplay);

		// TOCHECK: not sure whether or not it's necessary to change the resolution
		// "by hand", or if aglSetFullscreen does the job anyway
		refDisplayMode = CGDisplayBestModeForParametersAndRefreshRateWithProperty(mainDisplay, mode->bitsperpixel, mode->width, mode->height, mode->refreshrate, kCGDisplayModeIsSafeForHardware, NULL);
		CGDisplaySwitchToMode(mainDisplay, refDisplayMode);
		DMGetGDeviceByDisplayID((DisplayIDType)mainDisplay, &gdhDisplay, false);

		// Set pixel format with built attribs
		// Note: specifying a device is *required* for AGL_FullScreen
		pixelFormat = qaglChoosePixelFormat(&gdhDisplay, 1, attributes);
		error = qaglGetError();
		if (error != AGL_NO_ERROR)
		{
			Con_Printf("qaglChoosePixelFormat FAILED: %s\n",
						(char *)qaglErrorString(error));
			ReleaseWindow(window);
			return false;
		}
	}

	// Create a context using the pform
	context = qaglCreateContext(pixelFormat, NULL);
	error = qaglGetError();
	if (error != AGL_NO_ERROR)
	{
		Con_Printf("qaglCreateContext FAILED: %s\n",
					(char *)qaglErrorString(error));
	}

	// Make the context the current one ('enable' it)
	qaglSetCurrentContext(context);
	error = qaglGetError();
	if (error != AGL_NO_ERROR)
	{
		Con_Printf("qaglSetCurrentContext FAILED: %s\n",
					(char *)qaglErrorString(error));
		ReleaseWindow(window);
		return false;
	}

	// Discard pform
	qaglDestroyPixelFormat(pixelFormat);

	// Attempt fullscreen if requested
	if (mode->fullscreen)
	{
		qaglSetFullScreen (context, mode->width, mode->height, mode->refreshrate, 0);
		error = qaglGetError();
		if (error != AGL_NO_ERROR)
		{
			Con_Printf("qaglSetFullScreen FAILED: %s\n",
						(char *)qaglErrorString(error));
			return false;
		}
	}
	else
	{
		// Set Window as Drawable
		qaglSetDrawable(context, GetWindowPort(window));
		error = qaglGetError();
		if (error != AGL_NO_ERROR)
		{
			Con_Printf("qaglSetDrawable FAILED: %s\n",
						(char *)qaglErrorString(error));
			ReleaseWindow(window);
			return false;
		}
	}

	if ((qglGetString = (const GLubyte* (GLAPIENTRY *)(GLenum name))GL_GetProcAddress("glGetString")) == NULL)
		Sys_Error("glGetString not found in %s", gl_driver);

	gl_platformextensions = "";
	gl_platform = "AGL";

	multithreadedgl = false;
	vid_isfullscreen = mode->fullscreen;
	vid_usingmouse = false;
	vid_usinghidecursor = false;
	vid_hidden = false;
	vid_activewindow = true;
	sound_active = true;
	GL_Init();

	SelectWindow(window);
	ShowWindow(window);

	return true;
}
예제 #4
0
static int RLXAPI CreateSurface(int numberOfSparePages)
{
	static GLint          attrib[32];
	GLint		*pAttrib =  attrib;

	*pAttrib = AGL_RGBA; pAttrib++;
	*pAttrib = AGL_DOUBLEBUFFER; pAttrib++;
	*pAttrib = AGL_NONE; pAttrib++;

    AGLPixelFormat fmt;
    GLboolean      ok;

    g_pRLX->pGX->View.lpBackBuffer   = NULL;

    /* Choose an rgb pixel format */
    GDHandle gdhDisplay;
    ok = DMGetGDeviceByDisplayID((DisplayIDType)g_cgDisplayID, &gdhDisplay, false);
    SYS_ASSERT(ok == noErr);
    fmt = aglChoosePixelFormat(&gdhDisplay, 1, attrib);
	SYS_AGLTRACE(0);
    if(fmt == NULL)
    {
        ok = SYS_AGLTRACE(aglGetError());
		return -1;
    }
    /* Create an AGL context */
    g_pAGLC = aglCreateContext(fmt, NULL);
    SYS_AGLTRACE(0);
	if(g_pAGLC == NULL)
		return -2;

    /* Attach the window to the context */
    ok = SYS_AGLTRACE(aglSetDrawable(g_pAGLC, GetWindowPort(g_hWnd)));
    if(!ok)
		return -3;

    /* Make the context the current context */
    ok = SYS_AGLTRACE(aglSetCurrentContext(g_pAGLC));
    if(!ok)
		return -4;

	SizeWindow(g_hWnd, gl_lx, gl_ly, true);
	if ((g_pRLX->Video.Config & RLXVIDEO_Windowed))
		CenterWindow(g_hWnd);
    ShowWindow(g_hWnd);

	// copy portRect
	GetPortBounds(GetWindowPort(g_hWnd), g_pRect);

    /* Pixel format is no more needed */
    aglDestroyPixelFormat(fmt);

    if (!(g_pRLX->Video.Config & RLXVIDEO_Windowed))
    {
		HideMenuBar();
        aglSetFullScreen(g_pAGLC, 0, 0, 0, 0);
	    GLint swap = !!(g_pRLX->pGX->View.Flags & GX_CAPS_VSYNC);
        aglSetInteger(g_pAGLC, AGL_SWAP_INTERVAL, &swap);
		SYS_AGLTRACE(0);
	}

    // Reset engine
    GL_InstallExtensions();
	GL_ResetViewport();

	g_pRLX->pGX->Surfaces.maxSurface = numberOfSparePages;;

	if (g_pRLX->pGX->View.Flags & GX_CAPS_MULTISAMPLING)
	{
		glEnable(GL_MULTISAMPLE_ARB);
	}

    return 0;
}
예제 #5
0
static AGLContext createContext(WindowRef window) {
    AGLPixelFormat pf;
    AGLContext ctx;
    GDHandle gdh;
    CFDictionaryRef refMode;
    GLenum error;

    CGDirectDisplayID mainDisplay = CGMainDisplayID();

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

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

    g_Window.double_buffered = true;

    if (!g_Window.fs) {
        pf = aglChoosePixelFormat(NULL, 0, attrs);
    } else {
        CGDisplayCapture(mainDisplay);
        refMode = CGDisplayBestModeForParameters(mainDisplay, 32,
                                                 g_Window.width, g_Window.height, NULL);
        CGDisplaySwitchToMode(mainDisplay, refMode);
        DMGetGDeviceByDisplayID(mainDisplay, &gdh, false);
        pf = aglChoosePixelFormat(&gdh, 1, fullscreen_attrs);

        error = aglGetError();
        if (error != AGL_NO_ERROR) {
            printf("%s\n", aglErrorString(error));
            return 0;
        }
    }

    if (!pf) {
        printf("Error choosing pixel format\n");
        return 0;
    }

    ctx = aglCreateContext(pf, 0);
    if (!ctx) {
        printf("%s\n", aglErrorString(aglGetError()));
        return 0;
    }

    aglDestroyPixelFormat(pf);
    aglSetCurrentContext(ctx);

    if (g_Window.fs) {
        aglSetFullScreen(ctx, g_Window.width, g_Window.height, 0, 0);
    } else {
        aglSetWindowRef(ctx, window);
    }

    return ctx;
}