Ejemplo n.º 1
0
static int GLW_MakeContext( PIXELFORMATDESCRIPTOR *pPFD )
{
	//
	// don't putz around with pixelformat if it's already set (e.g. this is a soft
	// reset of the graphics system)
	//
	if ( !glw_state.pixelFormatSet )
	{
        int pixelformat;

		//
		// choose, set, and describe our desired pixel format.  If we're
		// using a minidriver then we need to bypass the GDI functions,
		// otherwise use the GDI functions.
		//
		if (glw_state.nPendingPF)
			pixelformat = glw_state.nPendingPF;
		else
		if ( ( pixelformat = GLW_ChoosePFD( glw_state.hDC, pPFD ) ) == 0 )
		{
			ri.Printf( PRINT_ALL, "...GLW_ChoosePFD failed\n");
			return TRY_PFD_FAIL_SOFT;
		}
		ri.Printf( PRINT_DEVELOPER, "...PIXELFORMAT %d selected\n", pixelformat );

		DescribePixelFormat( glw_state.hDC, pixelformat, sizeof( *pPFD ), pPFD );

		if ( SetPixelFormat( glw_state.hDC, pixelformat, pPFD ) == FALSE )
		{
			ri.Printf( PRINT_ALL, "...SetPixelFormat failed\n", glw_state.hDC );
			return TRY_PFD_FAIL_SOFT;
		}

		glw_state.pixelFormatSet = qtrue;
	}

	//
	// startup the OpenGL subsystem by creating a context and making it current
	//
	if ( !glw_state.hGLRC )
	{
		if ( ( glw_state.hGLRC = qwglCreateContext( glw_state.hDC ) ) == 0 )
		{
			ri.Printf( PRINT_ALL, "...GL context creation failure\n" );
			return TRY_PFD_FAIL_HARD;
		}
		ri.Printf( PRINT_DEVELOPER, "...GL context created\n" );

		if ( !qwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ) )
		{
			qwglDeleteContext( glw_state.hGLRC );
			glw_state.hGLRC = NULL;
			ri.Printf( PRINT_ALL, "...GL context creation currency failure\n" );
			return TRY_PFD_FAIL_HARD;
		}
		ri.Printf( PRINT_DEVELOPER, "...GL context creation made current\n" );
	}

	return TRY_PFD_SUCCESS;
}
Ejemplo n.º 2
0
static int GLW_MakeContext( PIXELFORMATDESCRIPTOR* pPFD ) {
	//
	// don't putz around with pixelformat if it's already set (e.g. this is a soft
	// reset of the graphics system)
	//
	if ( !pixelFormatSet ) {
		//
		// choose, set, and describe our desired pixel format.
		//
		int pixelformat = GLW_ChoosePFD( maindc, pPFD );
		if ( pixelformat == 0 ) {
			common->Printf( "...GLW_ChoosePFD failed\n" );
			return TRY_PFD_FAIL_SOFT;
		}
		common->Printf( "...PIXELFORMAT %d selected\n", pixelformat );

		DescribePixelFormat( maindc, pixelformat, sizeof ( *pPFD ), pPFD );

		if ( SetPixelFormat( maindc, pixelformat, pPFD ) == FALSE ) {
			common->Printf( "...SetPixelFormat failed\n" );
			return TRY_PFD_FAIL_SOFT;
		}

		pixelFormatSet = true;
	}

	//
	// startup the OpenGL subsystem by creating a context and making it current
	//
	if ( !baseRC ) {
		common->Printf( "...creating GL context: " );
		if ( ( baseRC = wglCreateContext( maindc ) ) == 0 ) {
			common->Printf( "failed\n" );
			return TRY_PFD_FAIL_HARD;
		}
		common->Printf( "succeeded\n" );

		common->Printf( "...making context current: " );
		if ( !wglMakeCurrent( maindc, baseRC ) ) {
			wglDeleteContext( baseRC );
			baseRC = NULL;
			common->Printf( "failed\n" );
			return TRY_PFD_FAIL_HARD;
		}
		common->Printf( "succeeded\n" );
	}

	return TRY_PFD_SUCCESS;
}
Ejemplo n.º 3
0
static int GLW_GetDisplayLevel( HDC dc )
{
	int i;
	PIXELFORMATDESCRIPTOR pfd;
	
	pfd = GLW_DEFAULT_PFD;
	i = GLW_ChoosePFD( dc, &pfd );

	if( !i )
		return 0;

	pfd.nSize = sizeof( pfd );
	DescribePixelFormat( dc, i, sizeof( PIXELFORMATDESCRIPTOR ), &pfd );

	if( (pfd.dwFlags & PFD_SUPPORT_OPENGL) == 0 )
		return 0;

	if( pfd.dwFlags & PFD_GENERIC_FORMAT )
		return 1; //software GL

	return 2; //full GL
}
Ejemplo n.º 4
0
HGLRC GL_GenerateRC(HDC hDC, bool bDoubleBuffer/* = true*/)
{
	HGLRC hRC = NULL;

	if (1/*RunningNT() || bCalledFromMainCellView*/)
	{
		static PIXELFORMATDESCRIPTOR pfd = 
		{
			sizeof(PIXELFORMATDESCRIPTOR),	// size of this struct
			1,								// struct version
			PFD_DRAW_TO_WINDOW |			// draw to window (not bitmap)
	//		PFD_DOUBLEBUFFER   |			// double buffered mode
			PFD_SUPPORT_OPENGL,				// support opengl in window
			PFD_TYPE_RGBA,					// RGBA colour mode
			24,								// want 24bit colour
			0,0,0,0,0,0,					// not used to select mode
			0,0,							// not used to select mode
			0,0,0,0,0,						// not used to select mode
			32,								// size of depth buffer
			0,								// not used to select mode
			0,								// not used to select mode
			PFD_MAIN_PLANE,					// draw in main plane
			0,								// not used to select mode
			0,0,0							// not used to select mode
		};
		if (bDoubleBuffer)
		{
			pfd.dwFlags |= PFD_DOUBLEBUFFER;			
		}

		// choose a pixel format that best matches the one we want...
		//
		int iPixelFormat = GLW_ChoosePFD(hDC,&pfd);	// try and choose best hardware mode
		if (iPixelFormat == 0)
		{
			// nothing decent found, fall bac to whatever crap the system recommends...
			//
			iPixelFormat = ChoosePixelFormat(hDC,&pfd);
		}

		//
		// set the pixel format for this device context...
		//
		//JAC FIXME - assertion failed
		//VERIFY(SetPixelFormat(hDC, iPixelFormat, &pfd));
		SetPixelFormat(hDC, iPixelFormat, &pfd);
		//
		// create the rendering context...
		//
		hRC = wglCreateContext(hDC);

		if (hRC)
		{
			//
			// make the rendering context current, init, then deselect...
			//
			VERIFY(wglMakeCurrent(hDC,hRC));

			// first one in creates the global RC, everyone else shares lists with it...
			//
			if (g_hRC)
			{
				ASSERT_GL;
				VERIFY(wglShareLists(g_hRC,hRC));
				ASSERT_GL;
			}
			else
			{
				g_hRC = hRC;
				g_hDC = hDC;
			
				// record vendor strings for later display...
				//
				csGLVendor		= glGetString (GL_VENDOR);
				csGLRenderer	= glGetString (GL_RENDERER);
				csGLVersion		= glGetString (GL_VERSION);
				csGLExtensions	= glGetString (GL_EXTENSIONS);	
				
				//
				// for the moment I'll insist on 24 bits and up (texture loading reasons, plus GL issues)
				//
				{
					HDC _hDC = GetDC( GetDesktopWindow() );
					int iDesktopBitDepth = GetDeviceCaps( _hDC, BITSPIXEL );
					if (iDesktopBitDepth == 8)
					{
						WarningBox(va("Your desktop is only %d bit!,\n\nChange the bitdepth to 16 or more (65536 colours or over) and re-run.",iDesktopBitDepth));
					}
					ReleaseDC( GetDesktopWindow(), _hDC );
				}
			}
//			VERIFY(wglMakeCurrent(NULL,NULL));	// leave context running!
		}	
	}

	return hRC;
}
Ejemplo n.º 5
0
static void GLW_CreateGLWnd( void )
{
	int x, y, w, h;
	HWND hParent;
	float aspect;
	DWORD s, es;
	skinDef_t *skin;

	int refresh = 0;
	int colorDepth = 0;

	WinVars_t *winVars = (WinVars_t*)ri.PlatformGetVars();

	if( winVars->hWnd )
		return;

	x = 0;
	y = 0;

	if( r_fullscreen->integer )
	{
		int mode_id;

		char * res = r_fsmode->string;
		w = atoi( COM_Parse( &res ) );
		h = atoi( COM_Parse( &res ) );
		aspect = (float)w / (float)h;

		sql_prepare( &com_db, "SELECT x, y FROM monitors SEARCH dev_name ?" );
		sql_bindtext( &com_db, 1, r_fsmonitor->string );
		if( sql_step( &com_db ) )
		{
			x = sql_columnasint( &com_db, 0 );
			y = sql_columnasint( &com_db, 1 );
		}
		sql_done( &com_db );

		//find the settings mode id
		mode_id = -1;
		sql_prepare( &com_db, "SELECT id FROM fsmodes SEARCH dev_name ?1 WHERE w=?2 AND h=?3" );
		sql_bindtext( &com_db, 1, r_fsmonitor->string );
		sql_bindint( &com_db, 2, w );
		sql_bindint( &com_db, 3, h );
		if( sql_step( &com_db ) )
			mode_id = sql_columnasint( &com_db, 0 );
		sql_done( &com_db );

		//get a matching color mode
		sql_prepare( &com_db, "SELECT bpp FROM fsmodes_ext SEARCH id ?1" );
		sql_bindint( &com_db, 1, mode_id );

		while( sql_step( &com_db ) )
		{
			int bpp = sql_columnasint( &com_db, 0 );
			if( r_colorbits->integer )
			{
				if( bpp == r_colorbits->integer )
				{
					//take an exact match
					colorDepth = bpp;
					break;
				}

				if( bpp > r_colorbits->integer )
				{
					if( colorDepth < r_colorbits->integer || bpp < colorDepth )
						//if we must go over, take the smallest value that goes over
						colorDepth = bpp;
				}
				else if( bpp > colorDepth )
					colorDepth = bpp;
			}
			else if( bpp > colorDepth )
				colorDepth = bpp;
		}

		sql_done( &com_db );

		//get a matching refresh rate
		sql_prepare( &com_db, "SELECT hz FROM fsmodes_ext SEARCH id ?1 WHERE bpp=?2" );
		sql_bindint( &com_db, 1, mode_id );
		sql_bindint( &com_db, 2, colorDepth );

		while( sql_step( &com_db ) )
		{
			int hz = sql_columnasint( &com_db, 0 );
			if( r_displayRefresh->integer )
			{
				if( hz == r_displayRefresh->integer )
				{
					//take an exact match
					refresh = hz;
					break;
				}

				if( hz > r_displayRefresh->integer )
				{
					if( refresh < r_displayRefresh->integer || hz < refresh )
						//if we must go over, take the smallest value that goes over
						refresh = hz;
				}
				else if( hz > refresh )
					refresh = hz;
			}
			else if( hz > refresh )
				//take the highest refresh rate
				refresh = hz;
		}

		sql_done( &com_db );
	}
	else
	{
		if( !R_GetModeInfo( &w, &h, &aspect, r_mode->integer ) )
		{
			//fall back to special modes
			w = 0;
			h = 0;
		}
	}

	/*
		Clean out old display mode changes.

		Note that we *don't* skip this when we're going back into fullscreen
		as it tends to produce some aweful bugs on some Windows installations.
	*/
	if( glw_state.cdsFullscreen )
		ChangeDisplaySettings( NULL, 0 );

	//window style bits
	es = 0;
	s = 0;

	skin = NULL;

	if( r_fullscreen->integer )
	{
		//go into full screen mode

		RECT rc;
		HMONITOR monitor;
		MONITORINFOEX monitorInfo;

		hParent = 0;

		//make sure we're set up for multimon goodness
		if( winVars->hWndHost )
		{
			GetWindowRect( winVars->hWndHost, &rc );
		}
		else
		{
			rc.left = x;
			rc.top = y;
			rc.right = x + w;
			rc.bottom = y + h;
		}

		monitor = MonitorFromRect( &rc, MONITOR_DEFAULTTONEAREST );

		monitorInfo.cbSize = sizeof( monitorInfo );
		GetMonitorInfo( monitor, (LPMONITORINFO)&monitorInfo );

		//if we got an invalid mode then use desktop resolution
		if( w == 0 )
			w = monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left;
		if( h == 0 )
			h = monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top;

		//change that monitor's display size to <w, h>
		//set the window rect to cover the display
		//skip the festival of desktop flickering if not changing resolution
		if( (monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left) != w ||
			(monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top) != h )
		{
			DEVMODE dm;
			memset( &dm, 0, sizeof( dm ) );

			dm.dmSize = sizeof( dm );
			
			dm.dmPelsWidth = w;
			dm.dmPelsHeight = h;
			dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;

			if( refresh != 0 )
			{
				dm.dmDisplayFrequency = refresh;
				dm.dmFields |= DM_DISPLAYFREQUENCY;
			}

			if( colorDepth != 0 )
			{
				dm.dmBitsPerPel = colorDepth;
				dm.dmFields |= DM_BITSPERPEL;
			}

			if( ChangeDisplaySettingsEx( monitorInfo.szDevice, &dm, NULL, CDS_FULLSCREEN, NULL )
				!= DISP_CHANGE_SUCCESSFUL )
			{
				//try again without color bits and frequency
				dm.dmFields &= ~(DM_BITSPERPEL | DM_DISPLAYFREQUENCY);
				dm.dmBitsPerPel = 0;
				dm.dmDisplayFrequency = 0;

				if( ChangeDisplaySettingsEx( monitorInfo.szDevice, &dm, NULL, CDS_FULLSCREEN, NULL )
					!= DISP_CHANGE_SUCCESSFUL )
					//failed...
					ri.Printf( PRINT_WARNING, "Invalid fullscreen resolution, running at desktop resolution" );
			}
		}

		//get the new monitor info
		monitorInfo.cbSize = sizeof( monitorInfo );
		GetMonitorInfo( monitor, (LPMONITORINFO)&monitorInfo );

		x = monitorInfo.rcMonitor.left;
		y = monitorInfo.rcMonitor.top;
		w = monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left;
		h = monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top;

		s = WS_POPUP;
		es = WS_EX_APPWINDOW | WS_EX_TOPMOST;

		glw_state.cdsFullscreen = qtrue;
	}
	else if( winVars->hWndHost )
	{
		RECT rc;

		hParent = winVars->hWndHost;

		GetClientRect( winVars->hWndHost, &rc );
		x = rc.left;
		y = rc.top;
		w = rc.right - rc.left;
		h = rc.bottom - rc.top;

		s = WS_CHILD;
		es = WS_EX_NOPARENTNOTIFY;
	}
	else
	{
		RECT rc;
		HMONITOR monitor;
		MONITORINFO monitorInfo;
		qboolean usedefault = qfalse;

		if( w == 0 )
			w = 640;
		if( h == 0 )
			h = 480;

		vid_xpos = ri.Cvar_Get( "vid_xpos", va("%d",CW_USEDEFAULT), CVAR_ARCHIVE );
		vid_ypos = ri.Cvar_Get( "vid_ypos", "0", CVAR_ARCHIVE );

		x = vid_xpos->integer;
		y = vid_ypos->integer;

		if ( x == CW_USEDEFAULT ) {
			x = 0;
			usedefault = qtrue;
		}

		rc.left = x;
		rc.top = y;
		rc.right = x + w;
		rc.bottom = y + h;

		hParent = 0;

		if( r_skin->string[0] )
			skin = Skin_Load( r_skin->string );
		
		//account for the border frame
		if( skin )
		{
			s = WS_POPUP;
			es = WS_EX_APPWINDOW;

			Skin_AdjustWindowRect( &rc, skin );
			AdjustWindowRectEx( &rc, s, FALSE, es );
		}
		else
		{
			s = WS_OVERLAPPED | WS_SYSMENU | WS_BORDER | WS_CAPTION;
			es = WS_EX_APPWINDOW;

			AdjustWindowRectEx( &rc, s, FALSE, es );
		}

		x = rc.left;
		y = rc.top;
		w = rc.right - rc.left;
		h = rc.bottom - rc.top;

		//constrain to a monitor
		//this is important as we can't get a
		//pixel format if we're entirely off screen
		monitor = MonitorFromRect( &rc, MONITOR_DEFAULTTONEAREST );

		monitorInfo.cbSize = sizeof( monitorInfo );
		GetMonitorInfo( monitor, &monitorInfo );

		//if we're not actually intersecting the monitor
		//(shoved off of the screen I guess) move back onto it

		if( x > monitorInfo.rcWork.right )
			//left window edge past right screen edge
			x = monitorInfo.rcWork.right - w;
		if( x + w < monitorInfo.rcWork.left )
			//right window edge past left screen edge
			x = monitorInfo.rcWork.left;

		if( y > monitorInfo.rcWork.bottom )
			//top window edge past bottom screen edge
			y = monitorInfo.rcWork.bottom - h;
		if( y + h < monitorInfo.rcWork.top )
			//bottom window edge past top screen edge
			y = monitorInfo.rcWork.top;

		glw_state.cdsFullscreen = qfalse;


		if ( usedefault ) {
			x = monitorInfo.rcMonitor.left + ((monitorInfo.rcMonitor.right-monitorInfo.rcMonitor.left)-w)/2;
			y = monitorInfo.rcMonitor.top + ((monitorInfo.rcMonitor.bottom-monitorInfo.rcMonitor.top)-h)/2;
		}
	}

	winVars->hWnd = NULL;

	if( skin )
	{
		Skin_RegisterClass();
		winVars->hWnd = Skin_CreateWnd( skin, x, y, w, h );
	}
	
	if( !winVars->hWnd )
	{
		GLW_RegisterClass();
		winVars->hWnd = CreateWindowEx( es, WINDOW_CLASS_NAME, WINDOW_CAPTION,
			s, x, y, w, h, hParent, NULL, winVars->hInstance, NULL );
	}

	//the window now owns the skin and will free it

	if( !winVars->hWnd )
		ri.Error( ERR_FATAL, "GLW: could not create window" );

	SetWindowPos( winVars->hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW );

	ShowWindow( winVars->hWnd, SW_SHOWNORMAL );
	SetFocus( winVars->hWnd );

	//get the window to draw once (get rid of graphical clutter)
	UpdateWindow( winVars->hWnd );

	//fire up the GL
	glw_state.hDC = GetDC( winVars->hWnd );
	if( !glw_state.hDC )
		ri.Error( ERR_FATAL, "GLW: could not get window DC" );

	//set up the pixel format
	{
		int pixelFormat;
		PIXELFORMATDESCRIPTOR pfd;

		GLW_CreatePFD( &pfd );
		pixelFormat = GLW_ChoosePFDEx( &pfd );

		if( !pixelFormat )
		{
			pixelFormat = GLW_ChoosePFD( glw_state.hDC, &pfd );
			glConfig.fsaaSamples = 1;
		}

		if( !pixelFormat )
			ri.Error( ERR_FATAL, "GLW: no valid pixel format" );

		pfd.nSize = sizeof( pfd );
		DescribePixelFormat( glw_state.hDC, pixelFormat, sizeof( pfd ), &pfd );
		if( !SetPixelFormat( glw_state.hDC, pixelFormat, &pfd ) )
			ri.Error( ERR_FATAL, "GLW: could not set pixel format" );

		glConfig.colorBits = pfd.cColorBits;
		glConfig.depthBits = pfd.cDepthBits;
		glConfig.stencilBits = pfd.cStencilBits;
		glConfig.stereoEnabled = (pfd.dwFlags & PFD_STEREO) ? qtrue : qfalse;

		ri.Printf( PRINT_ALL, "Using Pixel Format %i\n", pixelFormat );
	}
		
	glw_state.hGLRC = wglCreateContext( glw_state.hDC );
	if( !glw_state.hGLRC || !wglMakeCurrent( glw_state.hDC, glw_state.hGLRC ) )
		ri.Error( ERR_FATAL, "GLW: could not initialize GL" );

	GLW_CheckExtensions();

	//R_PerfInit();

	{
		//get the actual sizes, in case Windows constrained our window
		RECT rc;
		GetClientRect( winVars->hWnd, &rc );
		w = rc.right - rc.left;
		h = rc.bottom - rc.top;

		//fill in some glConfig stuff which *will* be referenced
		//by various subsystem init functions (i.e. Cg, bloom)
		glConfig.vidWidth = w;
		glConfig.vidHeight = h;
		glConfig.windowAspect = aspect;
	}

	glConfig.deviceSupportsGamma = qfalse;
	glConfig.isFullscreen = glw_state.cdsFullscreen ? qtrue : qfalse;

	glConfig.xscale = glConfig.vidWidth / 640.0f;
	glConfig.yscale = glConfig.vidHeight / 480.0f;

	if( glConfig.vidWidth * 480 > glConfig.vidHeight * 640 )
	{
		// wide screen
		glConfig.xscale	= glConfig.yscale;
		glConfig.xbias	= ((float)glConfig.vidWidth - (640.0F * glConfig.xscale)) * 0.5F;
	}
	else
	{
		// no wide screen
		glConfig.xbias	= 0.0f;
	}
}