コード例 #1
0
ファイル: glw_imp.c プロジェクト: q3aql/quake2
/*
** GLimp_SetMode
*/
rserr_t GLimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen )
{
    int width, height;
    const char *win_fs[] = { "W", "FS" };

    Com_Printf ( "Initializing OpenGL display\n");

    Com_Printf ("...setting mode %d:", mode );

    if ( !R_GetModeInfo( &width, &height, mode ) )
    {
        Com_Printf ( " invalid mode\n" );
        return rserr_invalid_mode;
    }

    Com_Printf ( " %d %d %s\n", width, height, win_fs[fullscreen] );

    // destroy the existing window
    if (glw_state.hWnd)
        GLimp_Shutdown ();

    // do a CDS if needed
    if ( fullscreen )
    {
        if (GLimp_SetFSMode(&width, &height))
        {
            *pwidth = width;
            *pheight = height;
            if (!VID_CreateWindow (width, height, true)) {
                Com_Printf("...restoring display settings\n");
                ChangeDisplaySettings( 0, 0 );
                gl_state.fullscreen = false;
                return rserr_invalid_mode;
            }

            EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &fullScreenMode);

            gl_state.fullscreen = true;
            return rserr_ok;
        }
    }

    *pwidth = width;
    *pheight = height;
    Com_Printf ( "...setting windowed mode\n" );

    if (gl_state.fullscreen)
    {
        ChangeDisplaySettings( 0, 0 );
        gl_state.fullscreen = false;
    }

    if (!VID_CreateWindow (width, height, false))
        return rserr_invalid_mode;

    return (fullscreen) ? rserr_invalid_fullscreen : rserr_ok;
}
コード例 #2
0
ファイル: sdl_glimp.c プロジェクト: chitmo/openarena-engine
/*
===============
GLimp_SetMode
===============
*/
static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
{
	const char*   glstring;
	int sdlcolorbits;
	int colorbits, depthbits, stencilbits;
	int tcolorbits, tdepthbits, tstencilbits;
	int samples;
	int i = 0;
	SDL_Surface *vidscreen = NULL;
	Uint32 flags = SDL_OPENGL;

	ri.Printf( PRINT_ALL, "Initializing OpenGL display\n");

	if ( r_allowResize->integer )
		flags |= SDL_RESIZABLE;

	if( videoInfo == NULL )
	{
		static SDL_VideoInfo sVideoInfo;
		static SDL_PixelFormat sPixelFormat;

		videoInfo = SDL_GetVideoInfo( );

		// Take a copy of the videoInfo
		Com_Memcpy( &sPixelFormat, videoInfo->vfmt, sizeof( SDL_PixelFormat ) );
		sPixelFormat.palette = NULL; // Should already be the case
		Com_Memcpy( &sVideoInfo, videoInfo, sizeof( SDL_VideoInfo ) );
		sVideoInfo.vfmt = &sPixelFormat;
		videoInfo = &sVideoInfo;

		if( videoInfo->current_h > 0 )
		{
			// Guess the display aspect ratio through the desktop resolution
			// by assuming (relatively safely) that it is set at or close to
			// the display's native aspect ratio
			displayAspect = (float)videoInfo->current_w / (float)videoInfo->current_h;

			ri.Printf( PRINT_ALL, "Estimated display aspect: %.3f\n", displayAspect );

#ifdef __ANDROID__
			R_SetNativeModeInfo( videoInfo->current_w, videoInfo->current_h );
#endif
		}
		else
		{
			ri.Printf( PRINT_ALL,
					"Cannot estimate display aspect, assuming 1.333\n" );
		}
	}

	ri.Printf (PRINT_ALL, "...setting mode %d:", mode );

	if (mode == -2)
	{
		// use desktop video resolution
		if( videoInfo->current_h > 0 )
		{
			glConfig.vidWidth = videoInfo->current_w;
			glConfig.vidHeight = videoInfo->current_h;
		}
		else
		{
			glConfig.vidWidth = 640;
			glConfig.vidHeight = 480;
			ri.Printf( PRINT_ALL,
					"Cannot determine display resolution, assuming 640x480\n" );
		}

		glConfig.windowAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight;
	}
	else if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) )
	{
		ri.Printf( PRINT_ALL, " invalid mode\n" );
		return RSERR_INVALID_MODE;
	}
	ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight);

	if (fullscreen)
	{
		flags |= SDL_FULLSCREEN;
		glConfig.isFullscreen = qtrue;
	}
	else
	{
		if (noborder)
			flags |= SDL_NOFRAME;

		glConfig.isFullscreen = qfalse;
	}

	colorbits = r_colorbits->value;
	if ((!colorbits) || (colorbits >= 32))
		colorbits = 24;

	if (!r_depthbits->value)
		depthbits = 24;
	else
		depthbits = r_depthbits->value;
	stencilbits = r_stencilbits->value;
	samples = r_ext_multisample->value;

	for (i = 0; i < 16; i++)
	{
		// 0 - default
		// 1 - minus colorbits
		// 2 - minus depthbits
		// 3 - minus stencil
		if ((i % 4) == 0 && i)
		{
			// one pass, reduce
			switch (i / 4)
			{
				case 2 :
					if (colorbits == 24)
						colorbits = 16;
					break;
				case 1 :
					if (depthbits == 24)
						depthbits = 16;
					else if (depthbits == 16)
						depthbits = 8;
				case 3 :
					if (stencilbits == 24)
						stencilbits = 16;
					else if (stencilbits == 16)
						stencilbits = 8;
			}
		}

		tcolorbits = colorbits;
		tdepthbits = depthbits;
		tstencilbits = stencilbits;

		if ((i % 4) == 3)
		{ // reduce colorbits
			if (tcolorbits == 24)
				tcolorbits = 16;
		}

		if ((i % 4) == 2)
		{ // reduce depthbits
			if (tdepthbits == 24)
				tdepthbits = 16;
			else if (tdepthbits == 16)
				tdepthbits = 8;
		}

		if ((i % 4) == 1)
		{ // reduce stencilbits
			if (tstencilbits == 24)
				tstencilbits = 16;
			else if (tstencilbits == 16)
				tstencilbits = 8;
			else
				tstencilbits = 0;
		}

		sdlcolorbits = 4;
		if (tcolorbits == 24)
			sdlcolorbits = 8;

#ifdef __sgi /* Fix for SGIs grabbing too many bits of color */
		if (sdlcolorbits == 4)
			sdlcolorbits = 0; /* Use minimum size for 16-bit color */

		/* Need alpha or else SGIs choose 36+ bit RGB mode */
		SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 1);
#endif

		SDL_GL_SetAttribute( SDL_GL_RED_SIZE, sdlcolorbits );
		SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, sdlcolorbits );
		SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, sdlcolorbits );
		SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, tdepthbits );
		SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, tstencilbits );

		SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, samples ? 1 : 0 );
		SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, samples );

		if(r_stereoEnabled->integer)
		{
			glConfig.stereoEnabled = qtrue;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
		}
		else
		{
			glConfig.stereoEnabled = qfalse;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 0);
		}
		
		SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

#if 0 // See http://bugzilla.icculus.org/show_bug.cgi?id=3526
		// If not allowing software GL, demand accelerated
		if( !r_allowSoftwareGL->integer )
		{
			if( SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 ) < 0 )
			{
				ri.Printf( PRINT_ALL, "Unable to guarantee accelerated "
						"visual with libSDL < 1.2.10\n" );
			}
		}
#endif

		if( SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, r_swapInterval->integer ) < 0 )
			ri.Printf( PRINT_ALL, "r_swapInterval requires libSDL >= 1.2.10\n" );

#ifdef USE_ICON
		{
			SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(
					(void *)CLIENT_WINDOW_ICON.pixel_data,
					CLIENT_WINDOW_ICON.width,
					CLIENT_WINDOW_ICON.height,
					CLIENT_WINDOW_ICON.bytes_per_pixel * 8,
					CLIENT_WINDOW_ICON.bytes_per_pixel * CLIENT_WINDOW_ICON.width,
#ifdef Q3_LITTLE_ENDIAN
					0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
#else
					0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
#endif
					);

			SDL_WM_SetIcon( icon, NULL );
			SDL_FreeSurface( icon );
		}
#endif

		SDL_WM_SetCaption(CLIENT_WINDOW_TITLE, CLIENT_WINDOW_MIN_TITLE);
		SDL_ShowCursor(0);

		if (!(vidscreen = SDL_SetVideoMode(glConfig.vidWidth, glConfig.vidHeight, colorbits, flags)))
		{
			ri.Printf( PRINT_DEVELOPER, "SDL_SetVideoMode failed: %s\n", SDL_GetError( ) );
			continue;
		}

		opengl_context = GLimp_GetCurrentContext();

		ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n",
				sdlcolorbits, sdlcolorbits, sdlcolorbits, tdepthbits, tstencilbits);

		glConfig.colorBits = tcolorbits;
		glConfig.depthBits = tdepthbits;
		glConfig.stencilBits = tstencilbits;
		break;
	}

	GLimp_DetectAvailableModes();

	if (!vidscreen)
	{
		ri.Printf( PRINT_ALL, "Couldn't get a visual\n" );
		return RSERR_INVALID_MODE;
	}

	screen = vidscreen;

	glstring = (char *) qglGetString (GL_RENDERER);
	ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring );

	return RSERR_OK;
}
コード例 #3
0
ファイル: sdl_glimp.c プロジェクト: LBoksha/RTCW-SP-linux
int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
{
	int         sdlcolorbits;
	int         colorbits, depthbits, stencilbits;
	int         tcolorbits, tdepthbits, tstencilbits;
	int         i          = 0;
	Uint32      flags      = SDL_OPENGL;

	ri.Printf(PRINT_ALL, "Initializing OpenGL display\n");

	if (videoInfo == NULL)
	{
		static SDL_VideoInfo   sVideoInfo;
		static SDL_PixelFormat sPixelFormat;

		videoInfo = SDL_GetVideoInfo();

		// Take a copy of the videoInfo
		Com_Memcpy(&sPixelFormat, videoInfo->vfmt, sizeof(SDL_PixelFormat));
		sPixelFormat.palette = NULL; // Should already be the case
		Com_Memcpy(&sVideoInfo, videoInfo, sizeof(SDL_VideoInfo));
		sVideoInfo.vfmt = &sPixelFormat;
		videoInfo       = &sVideoInfo;
	}



	if (mode == -2)
	{
		// use desktop video resolution
		if ( videoInfo->current_w > 0)
		{
			glConfig.vidWidth  = videoInfo->current_w;
			glConfig.vidHeight = videoInfo->current_h;
		}
		else
		{
			glConfig.vidWidth  = 800;
			glConfig.vidHeight = 600;
			ri.Printf(PRINT_ALL,
			          "Cannot determine display resolution, assuming 800x600\n");
		}

		glConfig.windowAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight;
	}
	else if (!R_GetModeInfo(&glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode))
	{
		ri.Printf(PRINT_ALL, " invalid mode\n");
		return RSERR_INVALID_MODE;
	}
	ri.Printf(PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight);

	if (fullscreen)
	{
		flags |= SDL_FULLSCREEN;
		glConfig.isFullscreen = qtrue;
	}
	else
	{
		if (noborder)
			flags |= SDL_NOFRAME;

		glConfig.isFullscreen = qfalse;
	}

	SDL_WM_SetCaption(WINDOW_CLASS_NAME, WINDOW_CLASS_NAME_MIN);
	SDL_ShowCursor(0);

	colorbits = r_colorbits->value;
	if ((!colorbits) || (colorbits >= 32))
		colorbits = 24;

	if (!r_depthbits->value)
		depthbits = 24;
	else
		depthbits = r_depthbits->value;

	stencilbits = r_stencilbits->value;

	for (i = 0; i < 16; i++)
	{
		// 0 - default
		// 1 - minus colorbits
		// 2 - minus depthbits
		// 3 - minus stencil
		if ((i % 4) == 0 && i)
		{
			// one pass, reduce
			switch (i / 4)
			{
			case 2:
				if (colorbits == 24)
					colorbits = 16;
				break;
			case 1:
				if (depthbits == 24)
					depthbits = 16;
				else if (depthbits == 16)
					depthbits = 8;
			case 3:
				if (stencilbits == 24)
					stencilbits = 16;
				else if (stencilbits == 16)
					stencilbits = 8;
			}
		}

		tcolorbits   = colorbits;
		tdepthbits   = depthbits;
		tstencilbits = stencilbits;

		if ((i % 4) == 3) // reduce colorbits
		{
			if (tcolorbits == 24)
				tcolorbits = 16;
		}

		if ((i % 4) == 2) // reduce depthbits
		{
			if (tdepthbits == 24)
				tdepthbits = 16;
			else if (tdepthbits == 16)
				tdepthbits = 8;
		}

		if ((i % 4) == 1) // reduce stencilbits
		{
			if (tstencilbits == 24)
				tstencilbits = 16;
			else if (tstencilbits == 16)
				tstencilbits = 8;
			else
				tstencilbits = 0;
		}

		sdlcolorbits = 4;
		if (tcolorbits == 24)
			sdlcolorbits = 8;

		SDL_GL_SetAttribute(SDL_GL_RED_SIZE, sdlcolorbits);
		SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, sdlcolorbits);
		SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, sdlcolorbits);
		SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, tdepthbits);
		SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, tstencilbits);

		glConfig.stereoEnabled = qfalse;
		SDL_GL_SetAttribute(SDL_GL_STEREO, 0);
		SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

		if (!(SDLvidscreen = SDL_SetVideoMode(glConfig.vidWidth, glConfig.vidHeight, colorbits, flags)))
			continue;

		ri.Printf(PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n",
		          sdlcolorbits, sdlcolorbits, sdlcolorbits, tdepthbits, tstencilbits);

		glConfig.colorBits   = tcolorbits;
		glConfig.depthBits   = tdepthbits;
		glConfig.stencilBits = tstencilbits;
		break;
	}

	if (!SDLvidscreen)
	{
		ri.Printf(PRINT_ALL, "Couldn't get a visual\n");
		return RSERR_INVALID_MODE;
	}
	return RSERR_OK;
}
コード例 #4
0
ファイル: win_glimp.cpp プロジェクト: DaTa-/cnq3x
static qbool GLW_SetMode( qbool cdsFullscreen )
{
	HDC hDC = GetDC( GetDesktopWindow() );
	glw_state.desktopBPP = GetDeviceCaps( hDC, BITSPIXEL );
	glw_state.desktopWidth = GetDeviceCaps( hDC, HORZRES );
	glw_state.desktopHeight = GetDeviceCaps( hDC, VERTRES );
	ReleaseDC( GetDesktopWindow(), hDC );

	glInfo.isFullscreen = cdsFullscreen;
	if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect ) ) {
        
        if (!glInfo.isFullscreen)
        {
            Cvar_SetValue( "vid_xpos", 0 );
            Cvar_SetValue( "vid_ypos", 0 );
        }
        
		glConfig.vidWidth = glw_state.desktopWidth;
		glConfig.vidHeight = glw_state.desktopHeight;
		glConfig.windowAspect = (float)glConfig.vidWidth / glConfig.vidHeight;
		cdsFullscreen = qfalse;
	}
	//ri.Printf( PRINT_DEVELOPER, "...setting mode %dx%d %s\n", glConfig.vidWidth, glConfig.vidHeight, cdsFullscreen ? "FS" : "W" );

	DEVMODE dm;
	memset( &dm, 0, sizeof( dm ) );
	dm.dmSize = sizeof( dm );

	if (cdsFullscreen != glw_state.cdsFullscreen) {
		if (cdsFullscreen) {
			dm.dmPelsWidth  = glConfig.vidWidth;
			dm.dmPelsHeight = glConfig.vidHeight;
			dm.dmFields     = DM_PELSWIDTH | DM_PELSHEIGHT;

			if ( r_displayRefresh->integer ) {
				dm.dmDisplayFrequency = r_displayRefresh->integer;
				dm.dmFields |= DM_DISPLAYFREQUENCY;
			}

			if ( r_colorbits->integer ) {
				dm.dmBitsPerPel = r_colorbits->integer;
				dm.dmFields |= DM_BITSPERPEL;
			}

			glInfo.isFullscreen = qtrue;
			glw_state.cdsFullscreen = qtrue;

			if (!GLW_Fullscreen( dm )) {
				glInfo.isFullscreen = qfalse;
				glw_state.cdsFullscreen = qfalse;
			}
		}
		else
		{
			ChangeDisplaySettings( 0, 0 );
			glw_state.cdsFullscreen = qfalse;
		}
	}

	if (!GLW_CreateWindow( glConfig.vidWidth, glConfig.vidHeight, glConfig.colorBits ))
		return qfalse;

	if (EnumDisplaySettings( NULL, ENUM_CURRENT_SETTINGS, &dm ))
		glInfo.displayFrequency = dm.dmDisplayFrequency;

	GLW_AttemptFSAA();

	return qtrue;
}
コード例 #5
0
ファイル: sdl_glimp.c プロジェクト: redrumrobot/dretchstorm
/*
===============
GLimp_SetMode
===============
*/
static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
{
	const char     *glstring;
	int             sdlcolorbits;
	int             colorbits, depthbits, stencilbits;
	int             tcolorbits, tdepthbits, tstencilbits;
	int             i = 0;
	SDL_Surface    *vidscreen = NULL;
	Uint32          flags = SDL_OPENGL;
	GLenum			glewResult;

	ri.Printf(PRINT_ALL, "Initializing OpenGL display\n");

	if(r_allowResize->integer)
		flags |= SDL_RESIZABLE;

	if(videoInfo == NULL)
	{
		static SDL_VideoInfo sVideoInfo;
		static SDL_PixelFormat sPixelFormat;

		videoInfo = SDL_GetVideoInfo();

		// Take a copy of the videoInfo
		Com_Memcpy(&sPixelFormat, videoInfo->vfmt, sizeof(SDL_PixelFormat));
		sPixelFormat.palette = NULL;	// Should already be the case
		Com_Memcpy(&sVideoInfo, videoInfo, sizeof(SDL_VideoInfo));
		sVideoInfo.vfmt = &sPixelFormat;
		videoInfo = &sVideoInfo;

		if(videoInfo->current_h > 0)
		{
			// Guess the display aspect ratio through the desktop resolution
			// by assuming (relatively safely) that it is set at or close to
			// the display's native aspect ratio
			displayAspect = (float)videoInfo->current_w / (float)videoInfo->current_h;

			ri.Printf(PRINT_ALL, "Estimated display aspect: %.3f\n", displayAspect);
		}
		else
		{
			ri.Printf(PRINT_ALL, "Cannot estimate display aspect, assuming 1.333\n");
		}
	}

	ri.Printf(PRINT_ALL, "...setting mode %d:", mode);

	if(!R_GetModeInfo(&glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode))
	{
		ri.Printf(PRINT_ALL, " invalid mode\n");
		return RSERR_INVALID_MODE;
	}
	ri.Printf(PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight);

	if(fullscreen)
	{
		flags |= SDL_FULLSCREEN;
		glConfig.isFullscreen = qtrue;
	}
	else
	{
		if(noborder)
			flags |= SDL_NOFRAME;

		glConfig.isFullscreen = qfalse;
	}

	colorbits = r_colorbits->value;
	if((!colorbits) || (colorbits >= 32))
		colorbits = 24;

	if(!r_depthbits->value)
		depthbits = 24;
	else
		depthbits = r_depthbits->value;
	stencilbits = r_stencilbits->value;

	for(i = 0; i < 16; i++)
	{
		// 0 - default
		// 1 - minus colorbits
		// 2 - minus depthbits
		// 3 - minus stencil
		if((i % 4) == 0 && i)
		{
			// one pass, reduce
			switch (i / 4)
			{
				case 2:
					if(colorbits == 24)
						colorbits = 16;
					break;
				case 1:
					if(depthbits == 24)
						depthbits = 16;
					else if(depthbits == 16)
						depthbits = 8;
				case 3:
					if(stencilbits == 24)
						stencilbits = 16;
					else if(stencilbits == 16)
						stencilbits = 8;
			}
		}

		tcolorbits = colorbits;
		tdepthbits = depthbits;
		tstencilbits = stencilbits;

		if((i % 4) == 3)
		{						// reduce colorbits
			if(tcolorbits == 24)
				tcolorbits = 16;
		}

		if((i % 4) == 2)
		{						// reduce depthbits
			if(tdepthbits == 24)
				tdepthbits = 16;
			else if(tdepthbits == 16)
				tdepthbits = 8;
		}

		if((i % 4) == 1)
		{						// reduce stencilbits
			if(tstencilbits == 24)
				tstencilbits = 16;
			else if(tstencilbits == 16)
				tstencilbits = 8;
			else
				tstencilbits = 0;
		}

		sdlcolorbits = 4;
		if(tcolorbits == 24)
			sdlcolorbits = 8;

		SDL_GL_SetAttribute(SDL_GL_RED_SIZE, sdlcolorbits);
		SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, sdlcolorbits);
		SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, sdlcolorbits);
		SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, tdepthbits);
		SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, tstencilbits);
		SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

		if(SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, r_swapInterval->integer) < 0)
			ri.Printf(PRINT_ALL, "r_swapInterval requires libSDL >= 1.2.10\n");

#ifdef USE_ICON
		{
			SDL_Surface    *icon = SDL_CreateRGBSurfaceFrom((void *)CLIENT_WINDOW_ICON.pixel_data,
															CLIENT_WINDOW_ICON.width,
															CLIENT_WINDOW_ICON.height,
															CLIENT_WINDOW_ICON.bytes_per_pixel * 8,
															CLIENT_WINDOW_ICON.bytes_per_pixel * CLIENT_WINDOW_ICON.width,
#ifdef Q3_LITTLE_ENDIAN
															0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
#else
															0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
#endif
				);

			SDL_WM_SetIcon(icon, NULL);
			SDL_FreeSurface(icon);
		}
#endif

		SDL_WM_SetCaption(CLIENT_WINDOW_TITLE, CLIENT_WINDOW_MIN_TITLE);
		SDL_ShowCursor(0);

		if(!(vidscreen = SDL_SetVideoMode(glConfig.vidWidth, glConfig.vidHeight, colorbits, flags)))
		{
			ri.Printf(PRINT_DEVELOPER, "SDL_SetVideoMode failed: %s\n", SDL_GetError());
			continue;
		}

		ri.Printf(PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n",
				  sdlcolorbits, sdlcolorbits, sdlcolorbits, tdepthbits, tstencilbits);

		glConfig.colorBits = tcolorbits;
		glConfig.depthBits = tdepthbits;
		glConfig.stencilBits = tstencilbits;
		break;
	}

	glewResult = glewInit();
	if(GLEW_OK != glewResult)
	{
		// glewInit failed, something is seriously wrong
		ri.Error(ERR_FATAL, "GLW_StartOpenGL() - could not load OpenGL subsystem: %s", glewGetErrorString(glewResult));
	}
	else
	{
		ri.Printf(PRINT_ALL, "Using GLEW %s\n", glewGetString(GLEW_VERSION));
	}

	GLimp_InitOpenGL3xContext();

	GLimp_DetectAvailableModes();

	if(!vidscreen)
	{
		ri.Printf(PRINT_ALL, "Couldn't get a visual\n");
		return RSERR_INVALID_MODE;
	}

	screen = vidscreen;

	glstring = (char *)glGetString(GL_RENDERER);
	ri.Printf(PRINT_ALL, "GL_RENDERER: %s\n", glstring);

	return RSERR_OK;
}
コード例 #6
0
/*
** GLW_SetMode
*/
static rserr_t GLW_SetMode( const char *drivername, 
						    int mode, 
							int colorbits, 
							qboolean cdsFullscreen )
{
	HDC hDC;
	const char *win_fs[] = { "W", "FS" };
	int		cdsRet;
	DEVMODE dm;
		
	//
	// print out informational messages
	//
	ri.Printf( PRINT_ALL, "...setting mode %d:", mode );
	if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) )
	{
		ri.Printf( PRINT_ALL, " invalid mode\n" );
		return RSERR_INVALID_MODE;
	}
	ri.Printf( PRINT_ALL, " %d %d %s\n", glConfig.vidWidth, glConfig.vidHeight, win_fs[cdsFullscreen] );

	//
	// check our desktop attributes
	//
	hDC = GetDC( GetDesktopWindow() );
	glw_state.desktopBitsPixel = GetDeviceCaps( hDC, BITSPIXEL );
	glw_state.desktopWidth = GetDeviceCaps( hDC, HORZRES );
	glw_state.desktopHeight = GetDeviceCaps( hDC, VERTRES );
	ReleaseDC( GetDesktopWindow(), hDC );

	//
	// verify desktop bit depth
	//
	if ( glConfig.driverType != GLDRV_VOODOO )
	{
		if ( glw_state.desktopBitsPixel < 15 || glw_state.desktopBitsPixel == 24 )
		{
			if ( colorbits == 0 || ( !cdsFullscreen && colorbits >= 15 ) )
			{
				if ( MessageBox( NULL,
							"It is highly unlikely that a correct\n"
							"windowed display can be initialized with\n"
							"the current desktop display depth.  Select\n"
							"'OK' to try anyway.  Press 'Cancel' if you\n"
							"have a 3Dfx Voodoo, Voodoo-2, or Voodoo Rush\n"
							"3D accelerator installed, or if you otherwise\n"
							"wish to quit.",
							"Low Desktop Color Depth",
							MB_OKCANCEL | MB_ICONEXCLAMATION ) != IDOK )
				{
					return RSERR_INVALID_MODE;
				}
			}
		}
	}

	// do a CDS if needed
	if ( cdsFullscreen )
	{
		memset( &dm, 0, sizeof( dm ) );
		
		dm.dmSize = sizeof( dm );
		
		dm.dmPelsWidth  = glConfig.vidWidth;
		dm.dmPelsHeight = glConfig.vidHeight;
		dm.dmFields     = DM_PELSWIDTH | DM_PELSHEIGHT;

		if ( r_displayRefresh->integer != 0 )
		{
			dm.dmDisplayFrequency = r_displayRefresh->integer;
			dm.dmFields |= DM_DISPLAYFREQUENCY;
		}
		
		// try to change color depth if possible
		if ( colorbits != 0 )
		{
			if ( glw_state.allowdisplaydepthchange )
			{
				dm.dmBitsPerPel = colorbits;
				dm.dmFields |= DM_BITSPERPEL;
				ri.Printf( PRINT_ALL, "...using colorsbits of %d\n", colorbits );
			}
			else
			{
				ri.Printf( PRINT_ALL, "WARNING:...changing depth not supported on Win95 < pre-OSR 2.x\n" );
			}
		}
		else
		{
			ri.Printf( PRINT_ALL, "...using desktop display depth of %d\n", glw_state.desktopBitsPixel );
		}

		//
		// if we're already in fullscreen then just create the window
		//
		if ( glw_state.cdsFullscreen )
		{
			ri.Printf( PRINT_ALL, "...already fullscreen, avoiding redundant CDS\n" );

			if ( !GLW_CreateWindow ( drivername, glConfig.vidWidth, glConfig.vidHeight, colorbits, qtrue ) )
			{
				ri.Printf( PRINT_ALL, "...restoring display settings\n" );
				ChangeDisplaySettings( 0, 0 );
				return RSERR_INVALID_MODE;
			}
		}
		//
		// need to call CDS
		//
		else
		{
			ri.Printf( PRINT_ALL, "...calling CDS: " );
			
			// try setting the exact mode requested, because some drivers don't report
			// the low res modes in EnumDisplaySettings, but still work
			if ( ( cdsRet = ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) ) == DISP_CHANGE_SUCCESSFUL )
			{
				ri.Printf( PRINT_ALL, "ok\n" );

				if ( !GLW_CreateWindow ( drivername, glConfig.vidWidth, glConfig.vidHeight, colorbits, qtrue) )
				{
					ri.Printf( PRINT_ALL, "...restoring display settings\n" );
					ChangeDisplaySettings( 0, 0 );
					return RSERR_INVALID_MODE;
				}
				
				glw_state.cdsFullscreen = qtrue;
			}
			else
			{
				//
				// the exact mode failed, so scan EnumDisplaySettings for the next largest mode
				//
				DEVMODE		devmode;
				int			modeNum;

				ri.Printf( PRINT_ALL, "failed, " );
				
				PrintCDSError( cdsRet );
			
				ri.Printf( PRINT_ALL, "...trying next higher resolution:" );
				
				// we could do a better matching job here...
				for ( modeNum = 0 ; ; modeNum++ ) {
					if ( !EnumDisplaySettings( NULL, modeNum, &devmode ) ) {
						modeNum = -1;
						break;
					}
					if ( devmode.dmPelsWidth >= glConfig.vidWidth
						&& devmode.dmPelsHeight >= glConfig.vidHeight
						&& devmode.dmBitsPerPel >= 15 ) {
						break;
					}
				}

				if ( modeNum != -1 && ( cdsRet = ChangeDisplaySettings( &devmode, CDS_FULLSCREEN ) ) == DISP_CHANGE_SUCCESSFUL )
				{
					ri.Printf( PRINT_ALL, " ok\n" );
					if ( !GLW_CreateWindow( drivername, glConfig.vidWidth, glConfig.vidHeight, colorbits, qtrue) )
					{
						ri.Printf( PRINT_ALL, "...restoring display settings\n" );
						ChangeDisplaySettings( 0, 0 );
						return RSERR_INVALID_MODE;
					}
					
					glw_state.cdsFullscreen = qtrue;
				}
				else
				{
					ri.Printf( PRINT_ALL, " failed, " );
					
					PrintCDSError( cdsRet );
					
					ri.Printf( PRINT_ALL, "...restoring display settings\n" );
					ChangeDisplaySettings( 0, 0 );
					
					glw_state.cdsFullscreen = qfalse;
					glConfig.isFullscreen = qfalse;
					if ( !GLW_CreateWindow( drivername, glConfig.vidWidth, glConfig.vidHeight, colorbits, qfalse) )
					{
						return RSERR_INVALID_MODE;
					}
					return RSERR_INVALID_FULLSCREEN;
				}
			}
		}
	}
	else
	{
		if ( glw_state.cdsFullscreen )
		{
			ChangeDisplaySettings( 0, 0 );
		}

		glw_state.cdsFullscreen = qfalse;
		if ( !GLW_CreateWindow( drivername, glConfig.vidWidth, glConfig.vidHeight, colorbits, qfalse ) )
		{
			return RSERR_INVALID_MODE;
		}
	}

	//
	// success, now check display frequency, although this won't be valid on Voodoo(2)
	//
	memset( &dm, 0, sizeof( dm ) );
	dm.dmSize = sizeof( dm );
	if ( EnumDisplaySettings( NULL, ENUM_CURRENT_SETTINGS, &dm ) )
	{
		glConfig.displayFrequency = dm.dmDisplayFrequency;
	}

	// NOTE: this is overridden later on standalone 3Dfx drivers
	glConfig.isFullscreen = cdsFullscreen;

	return RSERR_OK;
}
コード例 #7
0
ファイル: driver_glx.cpp プロジェクト: janisl/jlquake
rserr_t GLimp_SetMode( int mode, int colorbits, bool fullscreen ) {
	if ( !XInitThreads() ) {
		common->Printf( "...XInitThreads() failed, disabling r_smp\n" );
		Cvar_Set( "r_smp", "0" );
	}

	// set up our custom error handler for X failures
	XSetErrorHandler( &qXErrorHandler );

	if ( fullscreen && in_nograb->value ) {
		common->Printf( "Fullscreen not allowed with in_nograb 1\n" );
		Cvar_Set( "r_fullscreen", "0" );
		r_fullscreen->modified = false;
		fullscreen = false;
	}

	common->Printf( "...setting mode %d:", mode );

	if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) ) {
		common->Printf( " invalid mode\n" );
		return RSERR_INVALID_MODE;
	}
	common->Printf( " %d %d\n", glConfig.vidWidth, glConfig.vidHeight );

	// open the display
	if ( !( dpy = XOpenDisplay( NULL ) ) ) {
		fprintf( stderr, "Error couldn't open the X display\n" );
		return RSERR_INVALID_MODE;
	}

	scrnum = DefaultScreen( dpy );
	Window root = RootWindow( dpy, scrnum );

	// Get video mode list
	if ( !XF86VidModeQueryVersion( dpy, &vidmode_MajorVersion, &vidmode_MinorVersion ) ) {
		vidmode_ext = false;
	} else {
		common->Printf( "Using XFree86-VidModeExtension Version %d.%d\n", vidmode_MajorVersion, vidmode_MinorVersion );
		vidmode_ext = true;
	}

	// Check for DGA
	int dga_MajorVersion = 0;
	int dga_MinorVersion = 0;
	if ( in_dgamouse->value ) {
		if ( !XF86DGAQueryVersion( dpy, &dga_MajorVersion, &dga_MinorVersion ) ) {
			// unable to query, probalby not supported
			common->Printf( "Failed to detect XF86DGA Mouse\n" );
			Cvar_Set( "in_dgamouse", "0" );
		} else {
			common->Printf( "XF86DGA Mouse (Version %d.%d) initialized\n", dga_MajorVersion, dga_MinorVersion );
		}
	}

	int actualWidth = glConfig.vidWidth;
	int actualHeight = glConfig.vidHeight;

	if ( vidmode_ext ) {
		int best_fit, best_dist, dist, x, y;

		XF86VidModeGetAllModeLines( dpy, scrnum, &num_vidmodes, &vidmodes );

		// Are we going fullscreen?  If so, let's change video mode
		if ( fullscreen ) {
			best_dist = 9999999;
			best_fit = -1;

			for ( int i = 0; i < num_vidmodes; i++ ) {
				if ( glConfig.vidWidth > vidmodes[ i ]->hdisplay ||
					 glConfig.vidHeight > vidmodes[ i ]->vdisplay ) {
					continue;
				}

				x = glConfig.vidWidth - vidmodes[ i ]->hdisplay;
				y = glConfig.vidHeight - vidmodes[ i ]->vdisplay;
				dist = ( x * x ) + ( y * y );
				if ( dist < best_dist ) {
					best_dist = dist;
					best_fit = i;
				}
			}

			if ( best_fit != -1 ) {
				actualWidth = vidmodes[ best_fit ]->hdisplay;
				actualHeight = vidmodes[ best_fit ]->vdisplay;

				// change to the mode
				XF86VidModeSwitchToMode( dpy, scrnum, vidmodes[ best_fit ] );
				vidmode_active = true;

				// Move the viewport to top left
				XF86VidModeSetViewPort( dpy, scrnum, 0, 0 );

				common->Printf( "XFree86-VidModeExtension Activated at %dx%d\n",
					actualWidth, actualHeight );
			} else {
				fullscreen = 0;
				common->Printf( "XFree86-VidModeExtension: No acceptable modes found\n" );
			}
		} else {
			common->Printf( "XFree86-VidModeExtension:  Ignored on non-fullscreen\n" );
		}
	}

	if ( !colorbits ) {
		colorbits = !r_colorbits->value ? 24 : r_colorbits->value;
	}
	int depthbits = !r_depthbits->value ? 24 : r_depthbits->value;
	int stencilbits = r_stencilbits->value;

	XVisualInfo* visinfo = NULL;
	for ( int i = 0; i < 16; i++ ) {
		// 0 - default
		// 1 - minus colorbits
		// 2 - minus depthbits
		// 3 - minus stencil
		if ( ( i % 4 ) == 0 && i ) {
			// one pass, reduce
			switch ( i / 4 ) {
			case 2:
				if ( colorbits == 24 ) {
					colorbits = 16;
				}
				break;
			case 1:
				if ( depthbits == 24 ) {
					depthbits = 16;
				} else if ( depthbits == 16 ) {
					depthbits = 8;
				}
				break;
			case 3:
				if ( stencilbits == 24 ) {
					stencilbits = 16;
				} else if ( stencilbits == 16 ) {
					stencilbits = 8;
				}
				break;
			}
		}

		int tcolorbits = colorbits;
		int tdepthbits = depthbits;
		int tstencilbits = stencilbits;

		if ( ( i % 4 ) == 3 ) {
			// reduce colorbits
			if ( tcolorbits == 24 ) {
				tcolorbits = 16;
			}
		}

		if ( ( i % 4 ) == 2 ) {
			// reduce depthbits
			if ( tdepthbits == 24 ) {
				tdepthbits = 16;
			} else if ( tdepthbits == 16 ) {
				tdepthbits = 8;
			}
		}

		if ( ( i % 4 ) == 1 ) {
			// reduce stencilbits
			if ( tstencilbits == 24 ) {
				tstencilbits = 16;
			} else if ( tstencilbits == 16 ) {
				tstencilbits = 8;
			} else {
				tstencilbits = 0;
			}
		}

		int attrib[] =
		{
			GLX_RGBA,			// 0
			GLX_RED_SIZE, 4,		// 1, 2
			GLX_GREEN_SIZE, 4,		// 3, 4
			GLX_BLUE_SIZE, 4,		// 5, 6
			GLX_DOUBLEBUFFER,		// 7
			GLX_DEPTH_SIZE, 1,		// 8, 9
			GLX_STENCIL_SIZE, 1,	// 10, 11
			//GLX_SAMPLES_SGIS, 4, /* for better AA */
			None
		};
		// these match in the array
		enum
		{
			ATTR_RED_IDX = 2,
			ATTR_GREEN_IDX = 4,
			ATTR_BLUE_IDX = 6,
			ATTR_DEPTH_IDX = 9,
			ATTR_STENCIL_IDX = 11
		};

		if ( tcolorbits == 24 ) {
			attrib[ ATTR_RED_IDX ] = 8;
			attrib[ ATTR_GREEN_IDX ] = 8;
			attrib[ ATTR_BLUE_IDX ] = 8;
		} else {
			// must be 16 bit
			attrib[ ATTR_RED_IDX ] = 4;
			attrib[ ATTR_GREEN_IDX ] = 4;
			attrib[ ATTR_BLUE_IDX ] = 4;
		}

		attrib[ ATTR_DEPTH_IDX ] = tdepthbits;	// default to 24 depth
		attrib[ ATTR_STENCIL_IDX ] = tstencilbits;

		visinfo = glXChooseVisual( dpy, scrnum, attrib );
		if ( !visinfo ) {
			continue;
		}

		common->Printf( "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n",
			attrib[ ATTR_RED_IDX ], attrib[ ATTR_GREEN_IDX ], attrib[ ATTR_BLUE_IDX ],
			attrib[ ATTR_DEPTH_IDX ], attrib[ ATTR_STENCIL_IDX ] );

		glConfig.colorBits = tcolorbits;
		glConfig.depthBits = tdepthbits;
		glConfig.stencilBits = tstencilbits;
		break;
	}

	if ( !visinfo ) {
		common->Printf( "Couldn't get a visual\n" );
		return RSERR_INVALID_MODE;
	}

	//	Window attributes
	XSetWindowAttributes attr;
	unsigned long mask;
	attr.background_pixel = BlackPixel( dpy, scrnum );
	attr.border_pixel = 0;
	attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone );
	attr.event_mask = X_MASK;
	if ( vidmode_active ) {
		mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore |
			   CWEventMask | CWOverrideRedirect;
		attr.override_redirect = True;
		attr.backing_store = NotUseful;
		attr.save_under = False;
	} else {
		mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
	}

	win = XCreateWindow( dpy, root, 0, 0,
		actualWidth, actualHeight,
		0, visinfo->depth, InputOutput,
		visinfo->visual, mask, &attr );

	XStoreName( dpy, win, R_GetTitleForWindow() );

	/* GH: Don't let the window be resized */
	XSizeHints sizehints;
	sizehints.flags = PMinSize | PMaxSize;
	sizehints.min_width = sizehints.max_width = actualWidth;
	sizehints.min_height = sizehints.max_height = actualHeight;

	XSetWMNormalHints( dpy, win, &sizehints );

	XMapWindow( dpy, win );

	if ( vidmode_active ) {
		XMoveWindow( dpy, win, 0, 0 );
		//XRaiseWindow(dpy, win);
		//XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0);
		//XFlush(dpy);
		// Move the viewport to top left
		//XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
	}

	//	hook to window close
	wm_protocols = XInternAtom( dpy, "WM_PROTOCOLS", False );
	wm_delete_window = XInternAtom( dpy, "WM_DELETE_WINDOW", False );
	XSetWMProtocols( dpy, win, &wm_delete_window, 1 );

	XFlush( dpy );

	XSync( dpy, False );	// bk001130 - from cvs1.17 (mkv)
	ctx = glXCreateContext( dpy, visinfo, NULL, True );
	XSync( dpy, False );	// bk001130 - from cvs1.17 (mkv)

	/* GH: Free the visinfo after we're done with it */
	XFree( visinfo );

	glXMakeCurrent( dpy, win, ctx );

	glConfig.deviceSupportsGamma = false;
	if ( vidmode_ext ) {
		if ( vidmode_MajorVersion < GAMMA_MINMAJOR ||
			 ( vidmode_MajorVersion == GAMMA_MINMAJOR && vidmode_MinorVersion < GAMMA_MINMINOR ) ) {
			common->Printf( "XF86 Gamma extension not supported in this version\n" );
		} else {
			XF86VidModeGetGamma( dpy, scrnum, &vidmode_InitialGamma );
			common->Printf( "XF86 Gamma extension initialized\n" );
			glConfig.deviceSupportsGamma = true;
		}
	}

	//	Check for software GL implementation.
	const char* glstring = ( char* )glGetString( GL_RENDERER );
	if ( !String::ICmp( glstring, "Mesa X11" ) ||
		 !String::ICmp( glstring, "Mesa GLX Indirect" ) ) {
		if ( !r_allowSoftwareGL->integer ) {
			common->Printf( "\n\n***********************************************************\n" );
			common->Printf( " You are using software Mesa (no hardware acceleration)!\n" );
			common->Printf( " If this is intentional, add\n" );
			common->Printf( "       \"+set r_allowSoftwareGL 1\"\n" );
			common->Printf( " to the command line when starting the game.\n" );
			common->Printf( "***********************************************************\n" );
			GLimp_Shutdown();
			return RSERR_INVALID_MODE;
		} else {
			common->Printf( "...using software Mesa (r_allowSoftwareGL==1).\n" );
		}
	}

	GLW_GenDefaultLists();

	return RSERR_OK;
}
コード例 #8
0
ファイル: sdl_glimp.cpp プロジェクト: ensiform/q3pp
/*
===============
GLimp_SetMode
===============
*/
static int GLimp_SetMode(int mode, bool fullscreen, bool noborder)
{
    const char *glstring;
    int perChannelColorBits;
    int colorBits, depthBits, stencilBits;
    int samples;
    int i = 0;
    SDL_Surface *icon = NULL;
    Uint32 flags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL;
    SDL_DisplayMode desktopMode;
    int display = 0;
    int x = SDL_WINDOWPOS_UNDEFINED, y = SDL_WINDOWPOS_UNDEFINED;

    ri->Printf( PRINT_ALL, "Initializing OpenGL display\n");

    if ( r_allowResize->integer )
        flags |= SDL_WINDOW_RESIZABLE;

#ifdef USE_ICON
    icon = SDL_CreateRGBSurfaceFrom(
               (void *)CLIENT_WINDOW_ICON.pixel_data,
               CLIENT_WINDOW_ICON.width,
               CLIENT_WINDOW_ICON.height,
               CLIENT_WINDOW_ICON.bytes_per_pixel * 8,
               CLIENT_WINDOW_ICON.bytes_per_pixel * CLIENT_WINDOW_ICON.width,
#ifdef Q3_LITTLE_ENDIAN
               0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
#else
               0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
#endif
           );
#endif

    // If a window exists, note its display index
    if( SDL_window != NULL )
        display = SDL_GetWindowDisplayIndex( SDL_window );

    if( SDL_GetDesktopDisplayMode( display, &desktopMode ) == 0 )
    {
        displayAspect = (float)desktopMode.w / (float)desktopMode.h;

        ri.Printf( PRINT_ALL, "Display aspect: %.3f\n", displayAspect );
    }
    else
    {
        Com_Memset( &desktopMode, 0, sizeof( SDL_DisplayMode ) );

        ri.Printf( PRINT_ALL,
                   "Cannot determine display aspect, assuming 1.333\n" );
    }

    ri->Printf (PRINT_ALL, "...setting mode %d:", mode );

    if (mode == -2)
    {
        // use desktop video resolution
        if( desktopMode.h > 0 )
        {
            glConfig.vidWidth = desktopMode.w;
            glConfig.vidHeight = desktopMode.h;
        }
        else
        {
            glConfig.vidWidth = 640;
            glConfig.vidHeight = 480;
            ri->Printf( PRINT_ALL,
                        "Cannot determine display resolution, assuming 640x480\n" );
        }

        glConfig.windowAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight;
    }
    else if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) )
    {
        ri->Printf( PRINT_ALL, " invalid mode\n" );
        return RSERR_INVALID_MODE;
    }
    ri->Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight);

    // Center window
    if( r_centerWindow->integer && !fullscreen )
    {
        x = ( desktopMode.w / 2 ) - ( glConfig.vidWidth / 2 );
        y = ( desktopMode.h / 2 ) - ( glConfig.vidHeight / 2 );
    }

    // Destroy existing state if it exists
    if( SDL_glContext != NULL )
    {
        SDL_GL_DeleteContext( SDL_glContext );
        SDL_glContext = NULL;
    }

    if( SDL_window != NULL )
    {
        SDL_GetWindowPosition( SDL_window, &x, &y );
        ri->Printf( PRINT_DEVELOPER, "Existing window at %dx%d before being destroyed\n", x, y );
        SDL_DestroyWindow( SDL_window );
        SDL_window = NULL;
    }

    if( fullscreen )
    {
        flags |= SDL_WINDOW_FULLSCREEN;
        glConfig.isFullscreen = qtrue;
    }
    else
    {
        if( noborder )
            flags |= SDL_WINDOW_BORDERLESS;

        glConfig.isFullscreen = false;
    }

    colorBits = r_colorbits->value;
    if ((!colorBits) || (colorBits >= 32))
        colorBits = 24;

    if (!r_depthbits->value)
        depthBits = 24;
    else
        depthBits = r_depthbits->value;

    stencilBits = r_stencilbits->value;
    samples = r_ext_multisample->value;

    for (i = 0; i < 16; i++)
    {
        int testColorBits, testDepthBits, testStencilBits;

        // 0 - default
        // 1 - minus colorBits
        // 2 - minus depthBits
        // 3 - minus stencil
        if ((i % 4) == 0 && i)
        {
            // one pass, reduce
            switch (i / 4)
            {
            case 2 :
                if (colorBits == 24)
                    colorBits = 16;
                break;
            case 1 :
                if (depthBits == 24)
                    depthBits = 16;
                else if (depthBits == 16)
                    depthBits = 8;
            case 3 :
                if (stencilBits == 24)
                    stencilBits = 16;
                else if (stencilBits == 16)
                    stencilBits = 8;
            }
        }

        testColorBits = colorBits;
        testDepthBits = depthBits;
        testStencilBits = stencilBits;

        if ((i % 4) == 3)
        {   // reduce colorBits
            if (testColorBits == 24)
                testColorBits = 16;
        }

        if ((i % 4) == 2)
        {   // reduce depthBits
            if (testDepthBits == 24)
                testDepthBits = 16;
            else if (testDepthBits == 16)
                testDepthBits = 8;
        }

        if ((i % 4) == 1)
        {   // reduce stencilBits
            if (testStencilBits == 24)
                testStencilBits = 16;
            else if (testStencilBits == 16)
                testStencilBits = 8;
            else
                testStencilBits = 0;
        }

        if (testColorBits == 24)
            perChannelColorBits = 8;
        else
            perChannelColorBits = 4;

#ifdef __sgi /* Fix for SGIs grabbing too many bits of color */
        if (perChannelColorBits == 4)
            perChannelColorBits = 0; /* Use minimum size for 16-bit color */

        /* Need alpha or else SGIs choose 36+ bit RGB mode */
        SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 1);
#endif

        SDL_GL_SetAttribute( SDL_GL_RED_SIZE, perChannelColorBits );
        SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, perChannelColorBits );
        SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, perChannelColorBits );
        SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, testDepthBits );
        SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, testStencilBits );

        SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, samples ? 1 : 0 );
        SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, samples );

        if(r_stereoEnabled->integer)
        {
            glConfig.stereoEnabled = true;
            SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
        }
        else
        {
            glConfig.stereoEnabled = false;
            SDL_GL_SetAttribute(SDL_GL_STEREO, 0);
        }

        SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

#if 0 // if multisampling is enabled on X11, this causes create window to fail.
        // If not allowing software GL, demand accelerated
        if( !r_allowSoftwareGL->integer )
            SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 );
#endif

        if( ( SDL_window = SDL_CreateWindow( CLIENT_WINDOW_TITLE, x, y,
                                             glConfig.vidWidth, glConfig.vidHeight, flags ) ) == 0 )
        {
            ri->Printf( PRINT_DEVELOPER, "SDL_CreateWindow failed: %s\n", SDL_GetError( ) );
            continue;
        }

        if( fullscreen )
        {
            SDL_DisplayMode mode;

            switch( testColorBits )
            {
            case 16:
                mode.format = SDL_PIXELFORMAT_RGB565;
                break;
            case 24:
                mode.format = SDL_PIXELFORMAT_RGB24;
                break;
            default:
                ri.Printf( PRINT_DEVELOPER, "testColorBits is %d, can't fullscreen\n", testColorBits );
                continue;
            }

            mode.w = glConfig.vidWidth;
            mode.h = glConfig.vidHeight;
            mode.refresh_rate = glConfig.displayFrequency = ri->Cvar_VariableIntegerValue( "r_displayRefresh" );
            mode.driverdata = NULL;

            if( SDL_SetWindowDisplayMode( SDL_window, &mode ) < 0 )
            {
                ri.Printf( PRINT_DEVELOPER, "SDL_SetWindowDisplayMode failed: %s\n", SDL_GetError( ) );
                continue;
            }
        }

        SDL_SetWindowIcon( SDL_window, icon );

        if( ( SDL_glContext = SDL_GL_CreateContext( SDL_window ) ) == NULL )
        {
            ri->Printf( PRINT_DEVELOPER, "SDL_GL_CreateContext failed: %s\n", SDL_GetError( ) );
            continue;
        }

        SDL_GL_SetSwapInterval( r_swapInterval->integer );

        glConfig.colorBits = testColorBits;
        glConfig.depthBits = testDepthBits;
        glConfig.stencilBits = testStencilBits;

        ri->Printf( PRINT_ALL, "Using %d color bits, %d depth, %d stencil display.\n",
                    glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits );
        break;
    }

    SDL_FreeSurface( icon );

    if( !SDL_window )
    {
        ri->Printf( PRINT_ALL, "Couldn't get a visual\n" );
        return RSERR_INVALID_MODE;
    }

    GLimp_DetectAvailableModes();

    glstring = (char *) qglGetString (GL_RENDERER);
    ri->Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring );

    return RSERR_OK;
}
コード例 #9
0
ファイル: sdl_glimp.cpp プロジェクト: iMp-Rex/OpenJK
/*
===============
GLimp_SetMode
===============
*/
static rserr_t GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
{
	const char *glstring;
	int perChannelColorBits;
	int colorBits, depthBits, stencilBits;
	int samples;
	int i = 0;
	SDL_Surface *icon = NULL;
	Uint32 flags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL;
	SDL_DisplayMode desktopMode;
	int display = 0;
	int x = 0, y = 0;

	Com_Printf( "Initializing OpenGL display\n");

	if ( r_allowResize->integer )
		flags |= SDL_WINDOW_RESIZABLE;

	/*icon = SDL_CreateRGBSurfaceFrom(
			(void *)CLIENT_WINDOW_ICON.pixel_data,
			CLIENT_WINDOW_ICON.width,
			CLIENT_WINDOW_ICON.height,
			CLIENT_WINDOW_ICON.bytes_per_pixel * 8,
			CLIENT_WINDOW_ICON.bytes_per_pixel * CLIENT_WINDOW_ICON.width,
#ifdef Q3_LITTLE_ENDIAN
			0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
#else
			0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
#endif
			);*/

	// If a window exists, note its display index
	if( screen != NULL )
		display = SDL_GetWindowDisplayIndex( screen );

	if( SDL_GetDesktopDisplayMode( display, &desktopMode ) == 0 )
	{
		displayAspect = (float)desktopMode.w / (float)desktopMode.h;

		Com_Printf( "Display aspect: %.3f\n", displayAspect );
	}
	else
	{
		Com_Memset( &desktopMode, 0, sizeof( SDL_DisplayMode ) );

		Com_Printf( "Cannot determine display aspect, assuming 1.333\n" );
	}

	Com_Printf( "...setting mode %d:", mode );

	if (mode == -2)
	{
		// use desktop video resolution
		if( desktopMode.h > 0 )
		{
			glConfig.vidWidth = desktopMode.w;
			glConfig.vidHeight = desktopMode.h;
		}
		else
		{
			glConfig.vidWidth = 640;
			glConfig.vidHeight = 480;
			Com_Printf( "Cannot determine display resolution, assuming 640x480\n" );
		}

		//glConfig.windowAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight;
	}
	else if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, /*&glConfig.windowAspect,*/ mode ) )
	{
		Com_Printf( " invalid mode\n" );
		return RSERR_INVALID_MODE;
	}
	Com_Printf( " %d %d\n", glConfig.vidWidth, glConfig.vidHeight);

	// Center window
	if( r_centerWindow->integer && !fullscreen )
	{
		x = ( desktopMode.w / 2 ) - ( glConfig.vidWidth / 2 );
		y = ( desktopMode.h / 2 ) - ( glConfig.vidHeight / 2 );
	}

	// Destroy existing state if it exists
	if( opengl_context != NULL )
	{
		SDL_GL_DeleteContext( opengl_context );
		opengl_context = NULL;
	}

	if( screen != NULL )
	{
		SDL_GetWindowPosition( screen, &x, &y );
		ri.Printf( PRINT_DEVELOPER, "Existing window at %dx%d before being destroyed\n", x, y );
		SDL_DestroyWindow( screen );
		screen = NULL;
	}

	if( fullscreen )
	{
		flags |= SDL_WINDOW_FULLSCREEN;
		glConfig.isFullscreen = qtrue;
	}
	else
	{
		if( noborder )
			flags |= SDL_WINDOW_BORDERLESS;

		glConfig.isFullscreen = qfalse;
	}

	colorBits = r_colorbits->value;
	if ((!colorBits) || (colorBits >= 32))
		colorBits = 24;

	if (!r_depthbits->value)
		depthBits = 24;
	else
		depthBits = r_depthbits->value;

	stencilBits = r_stencilbits->value;
	//samples = r_ext_multisample->value;

	for (i = 0; i < 16; i++)
	{
		int testColorBits, testDepthBits, testStencilBits;

		// 0 - default
		// 1 - minus colorBits
		// 2 - minus depthBits
		// 3 - minus stencil
		if ((i % 4) == 0 && i)
		{
			// one pass, reduce
			switch (i / 4)
			{
				case 2 :
					if (colorBits == 24)
						colorBits = 16;
					break;
				case 1 :
					if (depthBits == 24)
						depthBits = 16;
					else if (depthBits == 16)
						depthBits = 8;
				case 3 :
					if (stencilBits == 24)
						stencilBits = 16;
					else if (stencilBits == 16)
						stencilBits = 8;
			}
		}

		testColorBits = colorBits;
		testDepthBits = depthBits;
		testStencilBits = stencilBits;

		if ((i % 4) == 3)
		{ // reduce colorBits
			if (testColorBits == 24)
				testColorBits = 16;
		}

		if ((i % 4) == 2)
		{ // reduce depthBits
			if (testDepthBits == 24)
				testDepthBits = 16;
			else if (testDepthBits == 16)
				testDepthBits = 8;
		}

		if ((i % 4) == 1)
		{ // reduce stencilBits
			if (testStencilBits == 24)
				testStencilBits = 16;
			else if (testStencilBits == 16)
				testStencilBits = 8;
			else
				testStencilBits = 0;
		}

		if (testColorBits == 24)
			perChannelColorBits = 8;
		else
			perChannelColorBits = 4;

#ifdef __sgi /* Fix for SGIs grabbing too many bits of color */
		if (perChannelColorBits == 4)
			perChannelColorBits = 0; /* Use minimum size for 16-bit color */

		/* Need alpha or else SGIs choose 36+ bit RGB mode */
		SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 1);
#endif

		SDL_GL_SetAttribute( SDL_GL_RED_SIZE, perChannelColorBits );
		SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, perChannelColorBits );
		SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, perChannelColorBits );
		SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, testDepthBits );
		SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, testStencilBits );

		/*SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, samples ? 1 : 0 );
		SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, samples );*/

		if(r_stereo->integer)
		{
			glConfig.stereoEnabled = qtrue;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
		}
		else
		{
			glConfig.stereoEnabled = qfalse;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 0);
		}

		SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

		// If not allowing software GL, demand accelerated
		if( !r_allowSoftwareGL->integer )
			SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 );

		if( ( screen = SDL_CreateWindow( CLIENT_WINDOW_TITLE, x, y,
				glConfig.vidWidth, glConfig.vidHeight, flags ) ) == 0 )
		{
			ri.Printf( PRINT_DEVELOPER, "SDL_CreateWindow failed: %s\n", SDL_GetError( ) );
			continue;
		}

		if( fullscreen )
		{
			SDL_DisplayMode mode;

			switch( testColorBits )
			{
				case 16: mode.format = SDL_PIXELFORMAT_RGB565; break;
				case 24: mode.format = SDL_PIXELFORMAT_RGB24;  break;
				default: ri.Printf( PRINT_DEVELOPER, "testColorBits is %d, can't fullscreen\n", testColorBits ); continue;
			}

			mode.w = glConfig.vidWidth;
			mode.h = glConfig.vidHeight;
			mode.refresh_rate = glConfig.displayFrequency = ri.Cvar_VariableIntegerValue( "r_displayRefresh" );
			mode.driverdata = NULL;

			if( SDL_SetWindowDisplayMode( screen, &mode ) < 0 )
			{
				ri.Printf( PRINT_DEVELOPER, "SDL_SetWindowDisplayMode failed: %s\n", SDL_GetError( ) );
				continue;
			}
		}

		SDL_SetWindowTitle( screen, CLIENT_WINDOW_TITLE );
		SDL_SetWindowIcon( screen, icon );

        if( ( opengl_context = (QGLContext)SDL_GL_CreateContext( screen ) ) == NULL )
		{
			Com_Printf( "SDL_GL_CreateContext failed: %s\n", SDL_GetError( ) );
			continue;
		}

		if( SDL_GL_MakeCurrent( screen, opengl_context ) < 0 )
		{
			Com_Printf( "SDL_GL_MakeCurrent failed: %s\n", SDL_GetError( ) );
			continue;
		}

		SDL_GL_SetSwapInterval( r_swapInterval->integer );

		glConfig.colorBits = testColorBits;
		glConfig.depthBits = testDepthBits;
		glConfig.stencilBits = testStencilBits;

		Com_Printf( "Using %d color bits, %d depth, %d stencil display.\n",
				glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits );
		break;
	}

	/*SDL_FreeSurface( icon );*/

	GLimp_DetectAvailableModes();

	glstring = (char *) qglGetString (GL_RENDERER);
	Com_Printf( "GL_RENDERER: %s\n", glstring );

	return RSERR_OK;
#if 0
	const char*   glstring;
	int sdlcolorbits;
	int colorbits, depthbits, stencilbits;
	int tcolorbits, tdepthbits, tstencilbits;
	int samples;
	int i = 0;
	Uint32 flags = SDL_WINDOW_OPENGL;

	Com_Printf( "Initializing OpenGL display\n");

	if ( r_allowResize->integer )
		flags |= SDL_WINDOW_RESIZABLE;

	if( videoInfo == NULL )
	{
		static SDL_DisplayMode sVideoInfo;
		static SDL_PixelFormat sPixelFormat;

		if (SDL_GetCurrentDisplayMode( 0, &sVideoInfo ) < 0)
		  Com_Error(ERR_FATAL, "SDL_GetCurrentDisplayMode failed : %s\n", SDL_GetError());

		// Take a copy of the videoInfo
		sPixelFormat.format = sVideoInfo.format;
		sPixelFormat.palette = NULL; // Should already be the case
		//Com_Memcpy( &sVideoInfo, videoInfo, sizeof( SDL_DisplayMode ) );
		sVideoInfo.format = sPixelFormat.format;
		videoInfo = &sVideoInfo;

		if( videoInfo->h > 0 )
		{
			glConfig.displayWidth = videoInfo->w;
			glConfig.displayHeight = videoInfo->h;

			// Guess the display aspect ratio through the desktop resolution
			// by assuming (relatively safely) that it is set at or close to
			// the display's native aspect ratio
			glConfig.displayAspect = (float)videoInfo->w / (float)videoInfo->h;

			Com_Printf( "Estimated display aspect: %.3f\n", glConfig.displayAspect );
		}
		else
		{
			glConfig.displayWidth = 480;
			glConfig.displayHeight = 640;
			glConfig.displayAspect = 1.333f;

			Com_Printf(
					"Cannot estimate display resolution/aspect, assuming 640x480/1.333\n" );
		}
	}

	Com_Printf( "...setting mode %d:", mode );

	if (mode == -2)
	{
		// use desktop video resolution
		if( videoInfo->h > 0 )
		{
			glConfig.vidWidth = videoInfo->w;
			glConfig.vidHeight = videoInfo->h;
		}
		else
		{
			glConfig.vidWidth = 640;
			glConfig.vidHeight = 480;
			Com_Printf(
					"Cannot determine display resolution, assuming 640x480\n" );
		}

		glConfig.displayAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight;
	}
	else if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, /*&glConfig.displayAspect,*/ mode ) )
	{
		Com_Printf( " invalid mode\n" );
		return RSERR_INVALID_MODE;
	}
	Com_Printf( " %d %d\n", glConfig.vidWidth, glConfig.vidHeight);

	if (fullscreen)
	{
		flags |= SDL_WINDOW_FULLSCREEN;
		glConfig.isFullscreen = qtrue;
	}
	else
	{
		if (noborder)
			flags |= SDL_WINDOW_BORDERLESS;

		glConfig.isFullscreen = qfalse;
	}

	colorbits = r_colorbits->value;
	if ((!colorbits) || (colorbits >= 32))
		colorbits = 24;

	if (!r_depthbits->value)
		depthbits = 24;
	else
		depthbits = r_depthbits->value;
	stencilbits = r_stencilbits->value;
	//samples = r_ext_multisample->value;

	for (i = 0; i < 16; i++)
	{
		// 0 - default
		// 1 - minus colorbits
		// 2 - minus depthbits
		// 3 - minus stencil
		if ((i % 4) == 0 && i)
		{
			// one pass, reduce
			switch (i / 4)
			{
				case 2 :
					if (colorbits == 24)
						colorbits = 16;
					break;
				case 1 :
					if (depthbits == 24)
						depthbits = 16;
					else if (depthbits == 16)
						depthbits = 8;
				case 3 :
					if (stencilbits == 24)
						stencilbits = 16;
					else if (stencilbits == 16)
						stencilbits = 8;
			}
		}

		tcolorbits = colorbits;
		tdepthbits = depthbits;
		tstencilbits = stencilbits;

		if ((i % 4) == 3)
		{ // reduce colorbits
			if (tcolorbits == 24)
				tcolorbits = 16;
		}

		if ((i % 4) == 2)
		{ // reduce depthbits
			if (tdepthbits == 24)
				tdepthbits = 16;
			else if (tdepthbits == 16)
				tdepthbits = 8;
		}

		if ((i % 4) == 1)
		{ // reduce stencilbits
			if (tstencilbits == 24)
				tstencilbits = 16;
			else if (tstencilbits == 16)
				tstencilbits = 8;
			else
				tstencilbits = 0;
		}

		sdlcolorbits = 4;
		if (tcolorbits == 24)
			sdlcolorbits = 8;

#ifdef __sgi /* Fix for SGIs grabbing too many bits of color */
		if (sdlcolorbits == 4)
			sdlcolorbits = 0; /* Use minimum size for 16-bit color */

		/* Need alpha or else SGIs choose 36+ bit RGB mode */
		SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 1);
#endif

		SDL_GL_SetAttribute( SDL_GL_RED_SIZE, sdlcolorbits );
		SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, sdlcolorbits );
		SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, sdlcolorbits );
		SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, tdepthbits );
		SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, tstencilbits );

		SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, samples ? 1 : 0 );
		SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, samples );

		/*if(r_stereoEnabled->integer)
		{
			glConfig.stereoEnabled = qtrue;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
		}
		else
		{*/
			glConfig.stereoEnabled = qfalse;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 0);
		//}

		SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

#if 0 // See http://bugzilla.icculus.org/show_bug.cgi?id=3526
		// If not allowing software GL, demand accelerated
		if( !r_allowSoftwareGL->integer )
		{
			if( SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 ) < 0 )
			{
				Com_Printf( "Unable to guarantee accelerated "
						"visual with libSDL < 1.2.10\n" );
			}
		}
#endif

		if( SDL_GL_SetSwapInterval(r_swapInterval->integer ) < 0 )
			Com_Printf( "SDL_GL_SetSwapInterval not supported\n" );

#ifdef USE_ICON
		{
			SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(
					(void *)CLIENT_WINDOW_ICON.pixel_data,
					CLIENT_WINDOW_ICON.width,
					CLIENT_WINDOW_ICON.height,
					CLIENT_WINDOW_ICON.bytes_per_pixel * 8,
					CLIENT_WINDOW_ICON.bytes_per_pixel * CLIENT_WINDOW_ICON.width,
#ifdef Q3_LITTLE_ENDIAN
					0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
#else
					0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
#endif
					);

			SDL_WM_SetIcon( icon, NULL );
			SDL_FreeSurface( icon );
		}
#endif

		SDL_ShowCursor(0);

		if (!(window = SDL_CreateWindow(CLIENT_WINDOW_TITLE, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, glConfig.vidWidth, glConfig.vidHeight, flags)))
		{
			Com_Printf( "SDL_CreateWindow failed: %s\n", SDL_GetError( ) );
			continue;
		}

		opengl_context = SDL_GL_CreateContext(window);

		Com_Printf( "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n",
				sdlcolorbits, sdlcolorbits, sdlcolorbits, tdepthbits, tstencilbits);

		glConfig.colorBits = tcolorbits;
		glConfig.depthBits = tdepthbits;
		glConfig.stencilBits = tstencilbits;
		break;
	}

	GLimp_DetectAvailableModes();

	if (!window)
	{
		Com_Printf( "Couldn't get a visual\n" );
		return RSERR_INVALID_MODE;
	}

	screen = window;

	// FIXME: Defines needed here
	glstring = (char *) qglGetString (GL_RENDERER);
	Com_Printf( "GL_RENDERER: %s\n", glstring );

	return RSERR_OK;
#endif
}
コード例 #10
0
ファイル: driver_wgl.cpp プロジェクト: janisl/jlquake
rserr_t GLimp_SetMode( int mode, int colorbits, bool fullscreen ) {
	const char* win_fs[] = { "W", "FS" };

	//
	// print out informational messages
	//
	common->Printf( "...setting mode %d:", mode );
	if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) ) {
		common->Printf( " invalid mode\n" );
		return RSERR_INVALID_MODE;
	}
	common->Printf( " %d %d %s\n", glConfig.vidWidth, glConfig.vidHeight, win_fs[ fullscreen ] );

	//
	// check our desktop attributes
	//
	HDC hDC = GetDC( GetDesktopWindow() );
	desktopBitsPixel = GetDeviceCaps( hDC, BITSPIXEL );
	desktopWidth = GetDeviceCaps( hDC, HORZRES );
	desktopHeight = GetDeviceCaps( hDC, VERTRES );
	ReleaseDC( GetDesktopWindow(), hDC );

	//
	// verify desktop bit depth
	//
	if ( desktopBitsPixel < 15 || desktopBitsPixel == 24 ) {
		if ( colorbits == 0 || ( !cdsFullscreen && colorbits >= 15 ) ) {
			if ( MessageBox( NULL,
					 "It is highly unlikely that a correct\n"
					 "windowed display can be initialized with\n"
					 "the current desktop display depth.  Select\n"
					 "'OK' to try anyway.  Press 'Cancel' if you otherwise\n"
					 "wish to quit.",
					 "Low Desktop Color Depth",
					 MB_OKCANCEL | MB_ICONEXCLAMATION ) != IDOK ) {
				return RSERR_INVALID_MODE;
			}
		}
	}

	DEVMODE dm;

	// do a CDS if needed
	if ( fullscreen ) {
		Com_Memset( &dm, 0, sizeof ( dm ) );

		dm.dmSize = sizeof ( dm );

		dm.dmPelsWidth = glConfig.vidWidth;
		dm.dmPelsHeight = glConfig.vidHeight;
		dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;

		if ( r_displayRefresh->integer != 0 ) {
			dm.dmDisplayFrequency = r_displayRefresh->integer;
			dm.dmFields |= DM_DISPLAYFREQUENCY;
		}

		// try to change color depth if possible
		if ( colorbits != 0 ) {
			dm.dmBitsPerPel = colorbits;
			dm.dmFields |= DM_BITSPERPEL;
			common->Printf( "...using colorsbits of %d\n", colorbits );
		} else {
			common->Printf( "...using desktop display depth of %d\n", desktopBitsPixel );
		}

		//
		//	If we're already in fullscreen then just create the window.
		//
		if ( cdsFullscreen ) {
			common->Printf( "...already fullscreen, avoiding redundant CDS\n" );

			if ( !GLW_CreateWindow( glConfig.vidWidth, glConfig.vidHeight, colorbits, true ) ) {
				common->Printf( "...restoring display settings\n" );
				ChangeDisplaySettings( 0, 0 );
				cdsFullscreen = false;
				return RSERR_INVALID_MODE;
			}
		}
		//
		// need to call CDS
		//
		else {
			common->Printf( "...calling CDS: " );

			// try setting the exact mode requested, because some drivers don't report
			// the low res modes in EnumDisplaySettings, but still work
			int cdsRet = ChangeDisplaySettings( &dm, CDS_FULLSCREEN );
			if ( cdsRet == DISP_CHANGE_SUCCESSFUL ) {
				common->Printf( "ok\n" );

				if ( !GLW_CreateWindow( glConfig.vidWidth, glConfig.vidHeight, colorbits, true ) ) {
					common->Printf( "...restoring display settings\n" );
					ChangeDisplaySettings( 0, 0 );
					return RSERR_INVALID_MODE;
				}

				cdsFullscreen = true;
			} else {
				common->Printf( "failed, " );

				PrintCDSError( cdsRet );

				//
				// the exact mode failed, so scan EnumDisplaySettings for the next largest mode
				//
				common->Printf( "...trying next higher resolution:" );

				// we could do a better matching job here...
				DEVMODE devmode;
				int modeNum;
				for ( modeNum = 0;; modeNum++ ) {
					if ( !EnumDisplaySettings( NULL, modeNum, &devmode ) ) {
						modeNum = -1;
						break;
					}
					if ( devmode.dmPelsWidth >= glConfig.vidWidth &&
						 devmode.dmPelsHeight >= glConfig.vidHeight &&
						 devmode.dmBitsPerPel >= 15 ) {
						break;
					}
				}

				if ( modeNum != -1 ) {
					cdsRet = ChangeDisplaySettings( &devmode, CDS_FULLSCREEN );
				}
				if ( modeNum != -1 && cdsRet == DISP_CHANGE_SUCCESSFUL ) {
					common->Printf( " ok\n" );
					if ( !GLW_CreateWindow( glConfig.vidWidth, glConfig.vidHeight, colorbits, true ) ) {
						common->Printf( "...restoring display settings\n" );
						ChangeDisplaySettings( 0, 0 );
						return RSERR_INVALID_MODE;
					}

					cdsFullscreen = true;
				} else {
					common->Printf( " failed, " );

					PrintCDSError( cdsRet );

					common->Printf( "...restoring display settings\n" );
					ChangeDisplaySettings( 0, 0 );

					cdsFullscreen = false;
					glConfig.isFullscreen = false;
					if ( !GLW_CreateWindow( glConfig.vidWidth, glConfig.vidHeight, colorbits, false ) ) {
						return RSERR_INVALID_MODE;
					}
					return RSERR_INVALID_FULLSCREEN;
				}
			}
		}
	} else {
		if ( cdsFullscreen ) {
			ChangeDisplaySettings( 0, 0 );
		}

		cdsFullscreen = false;
		if ( !GLW_CreateWindow( glConfig.vidWidth, glConfig.vidHeight, colorbits, false ) ) {
			return RSERR_INVALID_MODE;
		}
	}

	//
	// success, now check display frequency
	//
	Com_Memset( &dm, 0, sizeof ( dm ) );
	dm.dmSize = sizeof ( dm );
	if ( EnumDisplaySettings( NULL, ENUM_CURRENT_SETTINGS, &dm ) ) {
		glConfig.displayFrequency = dm.dmDisplayFrequency;
	}

	glConfig.isFullscreen = fullscreen;

	return RSERR_OK;
}
コード例 #11
0
ファイル: linux_glimp.c プロジェクト: 3ddy/Jedi-Academy
/*
** GLW_SetMode
*/
int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen )
{
	int attrib[] = {
		GLX_RGBA,					// 0
		GLX_RED_SIZE, 4,			// 1, 2
		GLX_GREEN_SIZE, 4,			// 3, 4
		GLX_BLUE_SIZE, 4,			// 5, 6
		GLX_DOUBLEBUFFER,			// 7
		GLX_DEPTH_SIZE, 1,			// 8, 9
		GLX_STENCIL_SIZE, 1,		// 10, 11
		None
	};
// these match in the array
#define ATTR_RED_IDX 2
#define ATTR_GREEN_IDX 4
#define ATTR_BLUE_IDX 6
#define ATTR_DEPTH_IDX 9
#define ATTR_STENCIL_IDX 11
	Window root;
	XVisualInfo *visinfo;
	XSetWindowAttributes attr;
	unsigned long mask;
	int colorbits, depthbits, stencilbits;
	int tcolorbits, tdepthbits, tstencilbits;
	int MajorVersion, MinorVersion;
	int actualWidth, actualHeight;
	int i;

	r_fakeFullscreen = ri.Cvar_Get( "r_fakeFullscreen", "0", CVAR_ARCHIVE);

	ri.Printf( PRINT_ALL, "Initializing OpenGL display\n");

	ri.Printf (PRINT_ALL, "...setting mode %d:", mode );

	if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) )
	{
		ri.Printf( PRINT_ALL, " invalid mode\n" );
		return RSERR_INVALID_MODE;
	}
	ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight);

	if (!(dpy = XOpenDisplay(NULL))) {
		fprintf(stderr, "Error couldn't open the X display\n");
		return RSERR_INVALID_MODE;
	}

	scrnum = DefaultScreen(dpy);
	root = RootWindow(dpy, scrnum);

	actualWidth = glConfig.vidWidth;
	actualHeight = glConfig.vidHeight;

	// Get video mode list
	MajorVersion = MinorVersion = 0;
	if (!XF86VidModeQueryVersion(dpy, &MajorVersion, &MinorVersion)) { 
		vidmode_ext = qfalse;
	} else {
		ri.Printf(PRINT_ALL, "Using XFree86-VidModeExtension Version %d.%d\n",
			MajorVersion, MinorVersion);
		vidmode_ext = qtrue;
	}

	if (vidmode_ext) {
		int best_fit, best_dist, dist, x, y;
		
		XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes);

		// Are we going fullscreen?  If so, let's change video mode
		if (fullscreen && !r_fakeFullscreen->integer) {
			best_dist = 9999999;
			best_fit = -1;

			for (i = 0; i < num_vidmodes; i++) {
				if (glConfig.vidWidth > vidmodes[i]->hdisplay ||
					glConfig.vidHeight > vidmodes[i]->vdisplay)
					continue;

				x = glConfig.vidWidth - vidmodes[i]->hdisplay;
				y = glConfig.vidHeight - vidmodes[i]->vdisplay;
				dist = (x * x) + (y * y);
				if (dist < best_dist) {
					best_dist = dist;
					best_fit = i;
				}
			}

			if (best_fit != -1) {
				actualWidth = vidmodes[best_fit]->hdisplay;
				actualHeight = vidmodes[best_fit]->vdisplay;

				// change to the mode
				XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]);
				vidmode_active = qtrue;

				// Move the viewport to top left
				XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
			} else
				fullscreen = 0;
		}
	}


	if (!r_colorbits->value)
		colorbits = 24;
	else
		colorbits = r_colorbits->value;

	if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) )
		colorbits = 16;

	if (!r_depthbits->value)
		depthbits = 24;
	else
		depthbits = r_depthbits->value;
	stencilbits = r_stencilbits->value;

	for (i = 0; i < 16; i++) {
		// 0 - default
		// 1 - minus colorbits
		// 2 - minus depthbits
		// 3 - minus stencil
		if ((i % 4) == 0 && i) {
			// one pass, reduce
			switch (i / 4) {
			case 2 :
				if (colorbits == 24)
					colorbits = 16;
				break;
			case 1 :
				if (depthbits == 24)
					depthbits = 16;
				else if (depthbits == 16)
					depthbits = 8;
			case 3 :
				if (stencilbits == 24)
					stencilbits = 16;
				else if (stencilbits == 16)
					stencilbits = 8;
			}
		}

		tcolorbits = colorbits;
		tdepthbits = depthbits;
		tstencilbits = stencilbits;

		if ((i % 4) == 3) { // reduce colorbits
			if (tcolorbits == 24)
				tcolorbits = 16;
		}	

		if ((i % 4) == 2) { // reduce depthbits
			if (tdepthbits == 24)
				tdepthbits = 16;
			else if (tdepthbits == 16)
				tdepthbits = 8;
		}

		if ((i % 4) == 1) { // reduce stencilbits
			if (tstencilbits == 24)
				tstencilbits = 16;
			else if (tstencilbits == 16)
				tstencilbits = 8;
			else
				tstencilbits = 0;
		}

		if (tcolorbits == 24) {
			attrib[ATTR_RED_IDX] = 8;
			attrib[ATTR_GREEN_IDX] = 8;
			attrib[ATTR_BLUE_IDX] = 8;
		} else  {
			// must be 16 bit
			attrib[ATTR_RED_IDX] = 4;
			attrib[ATTR_GREEN_IDX] = 4;
			attrib[ATTR_BLUE_IDX] = 4;
		}

		attrib[ATTR_DEPTH_IDX] = tdepthbits; // default to 24 depth
		attrib[ATTR_STENCIL_IDX] = tstencilbits;

#if 0
		ri.Printf( PRINT_DEVELOPER, "Attempting %d/%d/%d Color bits, %d depth, %d stencil display...", 
			attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX], attrib[ATTR_BLUE_IDX],
			attrib[ATTR_DEPTH_IDX], attrib[ATTR_STENCIL_IDX]);
#endif

		visinfo = qglXChooseVisual(dpy, scrnum, attrib);
		if (!visinfo) {
#if 0
			ri.Printf( PRINT_DEVELOPER, "failed\n");
#endif
			continue;
		}

#if 0
		ri.Printf( PRINT_DEVELOPER, "Successful\n");
#endif

		ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n", 
			attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX], attrib[ATTR_BLUE_IDX],
			attrib[ATTR_DEPTH_IDX], attrib[ATTR_STENCIL_IDX]);

		glConfig.colorBits = tcolorbits;
		glConfig.depthBits = tdepthbits;
		glConfig.stencilBits = tstencilbits;
		break;
	}

	if (!visinfo) {
		ri.Printf( PRINT_ALL, "Couldn't get a visual\n" );
		return RSERR_INVALID_MODE;
	}

	/* window attributes */
	attr.background_pixel = BlackPixel(dpy, scrnum);
	attr.border_pixel = 0;
	attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
	attr.event_mask = X_MASK;
	if (vidmode_active) {
		mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore | 
			CWEventMask | CWOverrideRedirect;
		attr.override_redirect = True;
		attr.backing_store = NotUseful;
		attr.save_under = False;
	} else
		mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;

	win = XCreateWindow(dpy, root, 0, 0, 
			actualWidth, actualHeight, 
			0, visinfo->depth, InputOutput,
			visinfo->visual, mask, &attr);
	XMapWindow(dpy, win);

	if (vidmode_active)
		XMoveWindow(dpy, win, 0, 0);

	// Check for DGA
	if (in_dgamouse->value) {
		if (!XF86DGAQueryVersion(dpy, &MajorVersion, &MinorVersion)) { 
			// unable to query, probalby not supported
			ri.Printf( PRINT_ALL, "Failed to detect XF86DGA Mouse\n" );
			ri.Cvar_Set( "in_dgamouse", "0" );
		} else
			ri.Printf( PRINT_ALL, "XF86DGA Mouse (Version %d.%d) initialized\n",
				MajorVersion, MinorVersion);
	}

	XFlush(dpy);

	ctx = qglXCreateContext(dpy, visinfo, NULL, True);

	qglXMakeCurrent(dpy, win, ctx);

	return RSERR_OK;
}
コード例 #12
0
/*
===============
GLimp_SetMode
===============
*/
static int GLimp_SetMode( int mode, bool fullscreen, bool noborder )
{
	const char  *glstring;
	int         perChannelColorBits;
	int         alphaBits, depthBits, stencilBits;
	int         samples;
	int         i = 0;
	SDL_Surface *icon = nullptr;
	SDL_DisplayMode desktopMode;
	Uint32      flags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL;
	int         x, y;
	GLenum      glewResult;

	ri.Printf( PRINT_ALL, "Initializing OpenGL display\n" );

	if ( r_allowResize->integer )
	{
		flags |= SDL_WINDOW_RESIZABLE;
	}

	if ( r_centerWindow->integer )
	{
		// center window on specified display
		x = SDL_WINDOWPOS_CENTERED_DISPLAY( r_displayIndex->integer );
		y = SDL_WINDOWPOS_CENTERED_DISPLAY( r_displayIndex->integer );
	}
	else
	{
		x = SDL_WINDOWPOS_UNDEFINED_DISPLAY( r_displayIndex->integer );
		y = SDL_WINDOWPOS_UNDEFINED_DISPLAY( r_displayIndex->integer );
	}

	icon = SDL_CreateRGBSurfaceFrom( ( void * ) CLIENT_WINDOW_ICON.pixel_data,
			        CLIENT_WINDOW_ICON.width,
			        CLIENT_WINDOW_ICON.height,
			        CLIENT_WINDOW_ICON.bytes_per_pixel * 8,
			        CLIENT_WINDOW_ICON.bytes_per_pixel * CLIENT_WINDOW_ICON.width,
#ifdef Q3_LITTLE_ENDIAN
			        0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
#else
			        0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
#endif
					);

	if ( SDL_GetDesktopDisplayMode( r_displayIndex->integer, &desktopMode ) == 0 )
	{
		displayAspect = ( float ) desktopMode.w / ( float ) desktopMode.h;

		ri.Printf( PRINT_ALL, "Display aspect: %.3f\n", displayAspect );
	}
	else
	{
		Com_Memset( &desktopMode, 0, sizeof( SDL_DisplayMode ) );

		ri.Printf( PRINT_ALL, "Cannot determine display aspect (%s), assuming 1.333\n", SDL_GetError() );
	}

	ri.Printf( PRINT_ALL, "...setting mode %d:", mode );

	if ( mode == -2 )
	{
		// use desktop video resolution
		if ( desktopMode.h > 0 )
		{
			glConfig.vidWidth = desktopMode.w;
			glConfig.vidHeight = desktopMode.h;
		}
		else
		{
			glConfig.vidWidth = 640;
			glConfig.vidHeight = 480;
			ri.Printf( PRINT_ALL, "Cannot determine display resolution, assuming 640x480\n" );
		}

		glConfig.windowAspect = ( float ) glConfig.vidWidth / ( float ) glConfig.vidHeight;
	}
	else if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) )
	{
		ri.Printf( PRINT_ALL, " invalid mode\n" );
		return RSERR_INVALID_MODE;
	}

	ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight );
	Cvar_Set( "r_customwidth", va("%d", glConfig.vidWidth ) );
	Cvar_Set( "r_customheight", va("%d", glConfig.vidHeight ) );

	do
	{
		if ( glContext != nullptr )
		{
			SDL_GL_DeleteContext( glContext );
			glContext = nullptr;
		}

		if ( window != nullptr )
		{
			SDL_GetWindowPosition( window, &x, &y );
			ri.Printf( PRINT_DEVELOPER, "Existing window at %dx%d before being destroyed\n", x, y );
			SDL_DestroyWindow( window );
			window = nullptr;
		}
		// we come back here if we couldn't get a visual and there's
		// something we can switch off

		if ( fullscreen )
		{
			flags |= SDL_WINDOW_FULLSCREEN;
			glConfig.isFullscreen = true;
		}
		else
		{
			if ( noborder )
			{
				flags |= SDL_WINDOW_BORDERLESS;
			}

			glConfig.isFullscreen = false;
		}

		colorBits = r_colorbits->integer;

		if ( ( !colorBits ) || ( colorBits >= 32 ) )
		{
			colorBits = 24;
		}

		alphaBits = r_alphabits->integer;

		if ( alphaBits < 0 )
		{
			alphaBits = 0;
		}

		depthBits = r_depthbits->integer;

		if ( !depthBits )
		{
			depthBits = 24;
		}

		stencilBits = r_stencilbits->integer;
		samples = r_ext_multisample->integer;

		for ( i = 0; i < 16; i++ )
		{
			int testColorBits, testDepthBits, testStencilBits;

			// 0 - default
			// 1 - minus colorbits
			// 2 - minus depthbits
			// 3 - minus stencil
			if ( ( i % 4 ) == 0 && i )
			{
				// one pass, reduce
				switch ( i / 4 )
				{
					case 2:
						if ( colorBits == 24 )
						{
							colorBits = 16;
						}

						break;

					case 1:
						if ( depthBits == 24 )
						{
							depthBits = 16;
						}
						else if ( depthBits == 16 )
						{
							depthBits = 8;
						}

					case 3:
						if ( stencilBits == 24 )
						{
							stencilBits = 16;
						}
						else if ( stencilBits == 16 )
						{
							stencilBits = 8;
						}
				}
			}

			testColorBits = colorBits;
			testDepthBits = depthBits;
			testStencilBits = stencilBits;

			if ( ( i % 4 ) == 3 )
			{
				// reduce colorbits
				if ( testColorBits == 24 )
				{
					testColorBits = 16;
				}
			}

			if ( ( i % 4 ) == 2 )
			{
				// reduce depthbits
				if ( testDepthBits == 24 )
				{
					testDepthBits = 16;
				}
				else if ( testDepthBits == 16 )
				{
					testDepthBits = 8;
				}
			}

			if ( ( i % 4 ) == 1 )
			{
				// reduce stencilbits
				if ( testStencilBits == 24 )
				{
					testStencilBits = 16;
				}
				else if ( testStencilBits == 16 )
				{
					testStencilBits = 8;
				}
				else
				{
					testStencilBits = 0;
				}
			}

			if ( testColorBits == 24 )
			{
				perChannelColorBits = 8;
			}
			else
			{
				perChannelColorBits = 4;
			}

			SDL_GL_SetAttribute( SDL_GL_RED_SIZE, perChannelColorBits );
			SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, perChannelColorBits );
			SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, perChannelColorBits );
			SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, alphaBits );
			SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, testDepthBits );
			SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, testStencilBits );
			SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, samples ? 1 : 0 );
			SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, samples );
			SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

			if ( !r_glAllowSoftware->integer )
			{
				SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 );
			}

			if ( r_glCoreProfile->integer || r_glDebugProfile->integer )
			{
				int major = r_glMajorVersion->integer;
				int minor = r_glMinorVersion->integer;

				SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, major );
				SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, minor );

				if ( r_glCoreProfile->integer )
				{
					SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
				}
				else
				{
					SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY );
				}

				if ( r_glDebugProfile->integer )
				{
					SDL_GL_SetAttribute( SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG );
				}
			}
			window = SDL_CreateWindow( CLIENT_WINDOW_TITLE, x, y, glConfig.vidWidth, glConfig.vidHeight, flags );

			if ( !window )
			{
				ri.Printf( PRINT_DEVELOPER, "SDL_CreateWindow failed: %s\n", SDL_GetError() );
				continue;
			}

			SDL_SetWindowIcon( window, icon );

			glContext = SDL_GL_CreateContext( window );

			if ( !glContext )
			{
				ri.Printf( PRINT_DEVELOPER, "SDL_GL_CreateContext failed: %s\n", SDL_GetError() );
				continue;
			}
			SDL_GL_SetSwapInterval( r_swapInterval->integer );

			glConfig.colorBits = testColorBits;
			glConfig.depthBits = testDepthBits;
			glConfig.stencilBits = testStencilBits;

			ri.Printf( PRINT_ALL, "Using %d Color bits, %d depth, %d stencil display.\n",
				glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits );

			break;
		}

		if ( samples && ( !glContext || !window ) )
		{
			r_ext_multisample->integer = 0;
		}

	} while ( ( !glContext || !window ) && samples );

	SDL_FreeSurface( icon );

	glewResult = glewInit();

	if ( glewResult != GLEW_OK )
	{
		// glewInit failed, something is seriously wrong
		ri.Error( ERR_FATAL, "GLW_StartOpenGL() - could not load OpenGL subsystem: %s", glewGetErrorString( glewResult ) );
	}
	else
	{
		ri.Printf( PRINT_ALL, "Using GLEW %s\n", glewGetString( GLEW_VERSION ) );
	}

	int GLmajor, GLminor;
	sscanf( ( const char * ) glGetString( GL_VERSION ), "%d.%d", &GLmajor, &GLminor );
	if ( GLmajor < 2 || ( GLmajor == 2 && GLminor < 1 ) )
	{
		// missing shader support, switch to 1.x renderer
		return RSERR_OLD_GL;
	}

	if ( GLmajor < 3 || ( GLmajor == 3 && GLminor < 2 ) )
	{
		// shaders are supported, but not all GL3.x features
		ri.Printf( PRINT_ALL, "Using enhanced (GL3) Renderer in GL 2.x mode...\n" );
	}
	else
	{
		ri.Printf( PRINT_ALL, "Using enhanced (GL3) Renderer in GL 3.x mode...\n" );
		glConfig.driverType = GLDRV_OPENGL3;
	}
	GLimp_DetectAvailableModes();

	glstring = ( char * ) glGetString( GL_RENDERER );
	ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring );

	return RSERR_OK;
}
コード例 #13
0
ファイル: linux_glimp.c プロジェクト: Justasic/RTCW-MP
/*
** GLW_SetMode
*/
int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen ) {
	int attrib[] = {
		GLX_RGBA,     // 0
		GLX_RED_SIZE, 4,  // 1, 2
		GLX_GREEN_SIZE, 4,  // 3, 4
		GLX_BLUE_SIZE, 4, // 5, 6
		GLX_DOUBLEBUFFER, // 7
		GLX_DEPTH_SIZE, 1,  // 8, 9
		GLX_STENCIL_SIZE, 1, // 10, 11
		None
	};
	// these match in the array
#define ATTR_RED_IDX 2
#define ATTR_GREEN_IDX 4
#define ATTR_BLUE_IDX 6
#define ATTR_DEPTH_IDX 9
#define ATTR_STENCIL_IDX 11
	Window root;
	XVisualInfo *visinfo;
	XSetWindowAttributes attr;
	XSizeHints sizehints;
	unsigned long mask;
	int colorbits, depthbits, stencilbits;
	int tcolorbits, tdepthbits, tstencilbits;
	int dga_MajorVersion, dga_MinorVersion;
	int actualWidth, actualHeight;
	int i;
	const char*   glstring; // bk001130 - from cvs1.17 (mkv)

	ri.Printf( PRINT_ALL, "Initializing OpenGL display\n" );

	ri.Printf( PRINT_ALL, "...setting mode %d:", mode );

	if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) ) {
		ri.Printf( PRINT_ALL, " invalid mode\n" );
		return RSERR_INVALID_MODE;
	}
	ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight );

	if ( !( dpy = XOpenDisplay( NULL ) ) ) {
		fprintf( stderr, "Error couldn't open the X display\n" );
		return RSERR_INVALID_MODE;
	}

	scrnum = DefaultScreen( dpy );
	root = RootWindow( dpy, scrnum );

	actualWidth = glConfig.vidWidth;
	actualHeight = glConfig.vidHeight;

	// Get video mode list
	if ( !XF86VidModeQueryVersion( dpy, &vidmode_MajorVersion, &vidmode_MinorVersion ) ) {
		vidmode_ext = qfalse;
	} else
	{
		ri.Printf( PRINT_ALL, "Using XFree86-VidModeExtension Version %d.%d\n",
				   vidmode_MajorVersion, vidmode_MinorVersion );
		vidmode_ext = qtrue;
	}

	// Check for DGA
	dga_MajorVersion = 0, dga_MinorVersion = 0;
	if ( in_dgamouse->value ) {
		if ( !XF86DGAQueryVersion( dpy, &dga_MajorVersion, &dga_MinorVersion ) ) {
			// unable to query, probalby not supported
			ri.Printf( PRINT_ALL, "Failed to detect XF86DGA Mouse\n" );
			ri.Cvar_Set( "in_dgamouse", "0" );
		} else
		{
			ri.Printf( PRINT_ALL, "XF86DGA Mouse (Version %d.%d) initialized\n",
					   dga_MajorVersion, dga_MinorVersion );
		}
	}

	if ( vidmode_ext ) {
		int best_fit, best_dist, dist, x, y;

		XF86VidModeGetAllModeLines( dpy, scrnum, &num_vidmodes, &vidmodes );

		// Are we going fullscreen?  If so, let's change video mode
		if ( fullscreen ) {
			best_dist = 9999999;
			best_fit = -1;

			for ( i = 0; i < num_vidmodes; i++ )
			{
				if ( glConfig.vidWidth > vidmodes[i]->hdisplay ||
					 glConfig.vidHeight > vidmodes[i]->vdisplay ) {
					continue;
				}

				x = glConfig.vidWidth - vidmodes[i]->hdisplay;
				y = glConfig.vidHeight - vidmodes[i]->vdisplay;
				dist = ( x * x ) + ( y * y );
				if ( dist < best_dist ) {
					best_dist = dist;
					best_fit = i;
				}
			}

			if ( best_fit != -1 ) {
				actualWidth = vidmodes[best_fit]->hdisplay;
				actualHeight = vidmodes[best_fit]->vdisplay;

				// change to the mode
				XF86VidModeSwitchToMode( dpy, scrnum, vidmodes[best_fit] );
				vidmode_active = qtrue;

				// Move the viewport to top left
				XF86VidModeSetViewPort( dpy, scrnum, 0, 0 );

				ri.Printf( PRINT_ALL, "XFree86-VidModeExtension Activated at %dx%d\n",
						   actualWidth, actualHeight );

			} else
			{
				fullscreen = 0;
				ri.Printf( PRINT_ALL, "XFree86-VidModeExtension: No acceptable modes found\n" );
			}
		} else
		{
			ri.Printf( PRINT_ALL, "XFree86-VidModeExtension:  Ignored on non-fullscreen/Voodoo\n" );
		}
	}


	if ( !r_colorbits->value ) {
		colorbits = 24;
	} else {
		colorbits = r_colorbits->value;
	}

	if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) ) {
		colorbits = 16;
	}

	if ( !r_depthbits->value ) {
		depthbits = 24;
	} else {
		depthbits = r_depthbits->value;
	}
	stencilbits = r_stencilbits->value;

	for ( i = 0; i < 16; i++ )
	{
		// 0 - default
		// 1 - minus colorbits
		// 2 - minus depthbits
		// 3 - minus stencil
		if ( ( i % 4 ) == 0 && i ) {
			// one pass, reduce
			switch ( i / 4 )
			{
			case 2:
				if ( colorbits == 24 ) {
					colorbits = 16;
				}
				break;
			case 1:
				if ( depthbits == 24 ) {
					depthbits = 16;
				} else if ( depthbits == 16 ) {
					depthbits = 8;
				}
			case 3:
				if ( stencilbits == 24 ) {
					stencilbits = 16;
				} else if ( stencilbits == 16 ) {
					stencilbits = 8;
				}
			}
		}

		tcolorbits = colorbits;
		tdepthbits = depthbits;
		tstencilbits = stencilbits;

		if ( ( i % 4 ) == 3 ) { // reduce colorbits
			if ( tcolorbits == 24 ) {
				tcolorbits = 16;
			}
		}

		if ( ( i % 4 ) == 2 ) { // reduce depthbits
			if ( tdepthbits == 24 ) {
				tdepthbits = 16;
			} else if ( tdepthbits == 16 ) {
				tdepthbits = 8;
			}
		}

		if ( ( i % 4 ) == 1 ) { // reduce stencilbits
			if ( tstencilbits == 24 ) {
				tstencilbits = 16;
			} else if ( tstencilbits == 16 ) {
				tstencilbits = 8;
			} else {
				tstencilbits = 0;
			}
		}

		if ( tcolorbits == 24 ) {
			attrib[ATTR_RED_IDX] = 8;
			attrib[ATTR_GREEN_IDX] = 8;
			attrib[ATTR_BLUE_IDX] = 8;
		} else
		{
			// must be 16 bit
			attrib[ATTR_RED_IDX] = 4;
			attrib[ATTR_GREEN_IDX] = 4;
			attrib[ATTR_BLUE_IDX] = 4;
		}

		attrib[ATTR_DEPTH_IDX] = tdepthbits; // default to 24 depth
		attrib[ATTR_STENCIL_IDX] = tstencilbits;

		visinfo = qglXChooseVisual( dpy, scrnum, attrib );
		if ( !visinfo ) {
			continue;
		}

		ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n",
				   attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX], attrib[ATTR_BLUE_IDX],
				   attrib[ATTR_DEPTH_IDX], attrib[ATTR_STENCIL_IDX] );

		glConfig.colorBits = tcolorbits;
		glConfig.depthBits = tdepthbits;
		glConfig.stencilBits = tstencilbits;
		break;
	}

	if ( !visinfo ) {
		ri.Printf( PRINT_ALL, "Couldn't get a visual\n" );
		return RSERR_INVALID_MODE;
	}

	/* window attributes */
	attr.background_pixel = BlackPixel( dpy, scrnum );
	attr.border_pixel = 0;
	attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone );
	attr.event_mask = X_MASK;
	if ( vidmode_active ) {
		mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore |
			   CWEventMask | CWOverrideRedirect;
		attr.override_redirect = True;
		attr.backing_store = NotUseful;
		attr.save_under = False;
	} else {
		mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
	}

	win = XCreateWindow( dpy, root, 0, 0,
						 actualWidth, actualHeight,
						 0, visinfo->depth, InputOutput,
						 visinfo->visual, mask, &attr );

	XStoreName( dpy, win, WINDOW_CLASS_NAME );

	/* GH: Don't let the window be resized */
	sizehints.flags = PMinSize | PMaxSize;
	sizehints.min_width = sizehints.max_width = actualWidth;
	sizehints.min_height = sizehints.max_height = actualHeight;

	XSetWMNormalHints( dpy, win, &sizehints );

	XMapWindow( dpy, win );

	if ( vidmode_active ) {
		XMoveWindow( dpy, win, 0, 0 );
	}

	XFlush( dpy );
	XSync( dpy,False ); // bk001130 - from cvs1.17 (mkv)
	ctx = qglXCreateContext( dpy, visinfo, NULL, True );
	XSync( dpy,False ); // bk001130 - from cvs1.17 (mkv)

	/* GH: Free the visinfo after we're done with it */
	XFree( visinfo );

	qglXMakeCurrent( dpy, win, ctx );

	// bk001130 - from cvs1.17 (mkv)
	glstring = qglGetString( GL_RENDERER );
	ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring );

	// bk010122 - new software token (Indirect)
	if ( !Q_stricmp( glstring, "Mesa X11" )
		 || !Q_stricmp( glstring, "Mesa GLX Indirect" ) ) {
		if ( !r_allowSoftwareGL->integer ) {
			ri.Printf( PRINT_ALL, "\n\n***********************************************************\n" );
			ri.Printf( PRINT_ALL, " You are using software Mesa (no hardware acceleration)!   \n" );
			ri.Printf( PRINT_ALL, " Driver DLL used: %s\n", drivername );
			ri.Printf( PRINT_ALL, " If this is intentional, add\n" );
			ri.Printf( PRINT_ALL, "       \"+set r_allowSoftwareGL 1\"\n" );
			ri.Printf( PRINT_ALL, " to the command line when starting the game.\n" );
			ri.Printf( PRINT_ALL, "***********************************************************\n" );
			GLimp_Shutdown();
			return RSERR_INVALID_MODE;
		} else
		{
			ri.Printf( PRINT_ALL, "...using software Mesa (r_allowSoftwareGL==1).\n" );
		}
	}

	return RSERR_OK;
}
コード例 #14
0
ファイル: sdl_glimp.c プロジェクト: gitter-badger/etlegacy
static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
{
	int             perChannelColorBits;
	int             colorBits, depthBits, stencilBits;
	int             samples;
	int             i     = 0;
	SDL_Surface     *icon = NULL;
	SDL_DisplayMode desktopMode;
	int             display = 0;
	int             x       = SDL_WINDOWPOS_UNDEFINED, y = SDL_WINDOWPOS_UNDEFINED;

	Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_INPUT_GRABBED;

#ifndef FEATURE_RENDERER_GLES
	GLenum glewResult;
#endif

	Ren_Print("Initializing OpenGL display\n");

	if (r_allowResize->integer && !fullscreen)
	{
		flags |= SDL_WINDOW_RESIZABLE;
	}

	icon = SDL_CreateRGBSurfaceFrom(
	    (void *)CLIENT_WINDOW_ICON.pixel_data,
	    CLIENT_WINDOW_ICON.width,
	    CLIENT_WINDOW_ICON.height,
	    CLIENT_WINDOW_ICON.bytes_per_pixel * 8,
	    CLIENT_WINDOW_ICON.bytes_per_pixel * CLIENT_WINDOW_ICON.width,
#ifdef Q3_LITTLE_ENDIAN
	    0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
#else
	    0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
#endif
	    );

	// If a window exists, note its display index
	if (main_window != NULL)
	{
		display = SDL_GetWindowDisplayIndex(main_window);
	}

	if (SDL_GetDesktopDisplayMode(display, &desktopMode) == 0)
	{
		displayAspect = (float)desktopMode.w / (float)desktopMode.h;

		Ren_Print("Estimated display aspect: %.3f\n", displayAspect);
	}
	else
	{
		Com_Memset(&desktopMode, 0, sizeof(SDL_DisplayMode));

		Ren_Print("Cannot estimate display aspect, assuming 1.333\n");
	}

	Ren_Print("...setting mode %d: ", mode);

	if (mode == -2)
	{
		// use desktop video resolution
		if (desktopMode.h > 0)
		{
			glConfig.vidWidth  = desktopMode.w;
			glConfig.vidHeight = desktopMode.h;
		}
		else
		{
			glConfig.vidWidth  = 640;
			glConfig.vidHeight = 480;
			Ren_Print("Cannot determine display resolution, assuming 640x480\n");
		}

		glConfig.windowAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight;
	}
	else if (!R_GetModeInfo(&glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode))
	{
		Ren_Print("invalid mode\n");
		return RSERR_INVALID_MODE;
	}
	Ren_Print("%dx%d\n", glConfig.vidWidth, glConfig.vidHeight);

	// Center window
	if (r_centerWindow->integer && !fullscreen)
	{
		x = (desktopMode.w / 2) - (glConfig.vidWidth / 2);
		y = (desktopMode.h / 2) - (glConfig.vidHeight / 2);
	}

	// Destroy existing state if it exists
	if (SDL_glContext != NULL)
	{
		SDL_GL_DeleteContext(SDL_glContext);
		SDL_glContext = NULL;
	}

	if (main_window != NULL)
	{
		SDL_GetWindowPosition(main_window, &x, &y);
		Ren_Developer("Existing window at %dx%d before being destroyed\n", x, y);
		SDL_DestroyWindow(main_window);
		main_window = NULL;
	}

	if (fullscreen)
	{
		if (r_mode->integer == -2)
		{
			flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
		}
		else
		{
			flags |= SDL_WINDOW_FULLSCREEN;
		}

		glConfig.isFullscreen = qtrue;
	}
	else
	{
		if (noborder)
		{
			flags |= SDL_WINDOW_BORDERLESS;
		}

		glConfig.isFullscreen = qfalse;
	}

	colorBits = r_colorbits->value;
	if ((!colorBits) || (colorBits >= 32))
	{
		colorBits = 24;
	}

	if (!r_depthbits->value)
	{
		depthBits = 24;
	}
	else
	{
		depthBits = r_depthbits->value;
	}
	stencilBits = r_stencilbits->value;
	samples     = r_ext_multisample->value;

	for (i = 0; i < 16; i++)
	{
		int testColorBits, testDepthBits, testStencilBits;

		// 0 - default
		// 1 - minus colorBits
		// 2 - minus depthBits
		// 3 - minus stencil
		if ((i % 4) == 0 && i)
		{
			// one pass, reduce
			switch (i / 4)
			{
			case 2:
				if (colorBits == 24)
				{
					colorBits = 16;
				}
				break;
			case 1:
				if (depthBits == 32)
				{
					depthBits = 24;
				}
				else if (depthBits == 24)
				{
					depthBits = 16;
				}
				else if (depthBits == 16)
				{
					depthBits = 8;
				}
			case 3: // fall through
				if (stencilBits == 24)
				{
					stencilBits = 16;
				}
				else if (stencilBits == 16)
				{
					stencilBits = 8;
				}
			}
		}

		testColorBits   = colorBits;
		testDepthBits   = depthBits;
		testStencilBits = stencilBits;

		if ((i % 4) == 3) // reduce colorbits
		{
			if (testColorBits == 24)
			{
				testColorBits = 16;
			}
		}

		if ((i % 4) == 2) // reduce depthbits
		{
			if (testDepthBits == 24)
			{
				testDepthBits = 16;
			}
			else if (testDepthBits == 16)
			{
				testDepthBits = 8;
			}
		}

		if ((i % 4) == 1) // reduce stencilbits
		{
			if (testStencilBits == 24)
			{
				testStencilBits = 16;
			}
			else if (testStencilBits == 16)
			{
				testStencilBits = 8;
			}
			else
			{
				testStencilBits = 0;
			}
		}

		if (testColorBits == 24)
		{
			perChannelColorBits = 8;
		}
		else
		{
			perChannelColorBits = 4;
		}

#ifdef __sgi // Fix for SGIs grabbing too many bits of color
		if (perChannelColorBits == 4)
		{
			perChannelColorBits = 0; /* Use minimum size for 16-bit color */

		}
		// Need alpha or else SGIs choose 36+ bit RGB mode
		SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 1);
#endif

		SDL_GL_SetAttribute(SDL_GL_RED_SIZE, perChannelColorBits);
		SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, perChannelColorBits);
		SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, perChannelColorBits);
		SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, testDepthBits);
		SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, testStencilBits);

		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, samples ? 1 : 0);
		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, samples);

		// SDL2 uses opengl by default, if we want opengl es we need to set this attribute
		//SDL_GL_SetAttribute(SDL_GL_CONTEXT_EGL, 1);

		if (r_stereoEnabled->integer)
		{
			glConfig.stereoEnabled = qtrue;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
		}
		else
		{
			glConfig.stereoEnabled = qfalse;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 0);
		}

		SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

		// If not allowing software GL, demand accelerated
		if (!r_allowSoftwareGL->integer)
		{
			SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
		}

		main_window = SDL_CreateWindow(CLIENT_WINDOW_TITLE, x, y, glConfig.vidWidth, glConfig.vidHeight, flags | SDL_WINDOW_SHOWN);

		if (!main_window)
		{
			Ren_Developer("SDL_CreateWindow failed: %s\n", SDL_GetError());
			continue;
		}

		//This is disabled since at least now we have no use for this
		/*
		if (!Glimp_Create2DRenderer(main_window))
		{
		    continue;
		}
		*/

		if (fullscreen)
		{
			SDL_DisplayMode mode;

			switch (testColorBits)
			{
			case 16: mode.format = SDL_PIXELFORMAT_RGB565; break;
			case 24: mode.format = SDL_PIXELFORMAT_RGB24;  break;
			default: Ren_Developer("testColorBits is %d, can't fullscreen\n", testColorBits); continue;
			}

			mode.w            = glConfig.vidWidth;
			mode.h            = glConfig.vidHeight;
			mode.refresh_rate = glConfig.displayFrequency = ri.Cvar_VariableIntegerValue("r_displayRefresh");
			mode.driverdata   = NULL;

			if (SDL_SetWindowDisplayMode(main_window, &mode) < 0)
			{
				Ren_Developer("SDL_SetWindowDisplayMode failed: %s\n", SDL_GetError());
				continue;
			}
		}

		SDL_SetWindowIcon(main_window, icon);

#if defined(FEATURE_RENDERER2)
		glewExperimental = GL_TRUE;

		SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
#endif

		if ((SDL_glContext = SDL_GL_CreateContext(main_window)) == NULL)
		{
			Ren_Developer("SDL_GL_CreateContext failed: %s\n", SDL_GetError());
			continue;
		}

		SDL_GL_MakeCurrent(main_window, SDL_glContext);
		SDL_GL_SetSwapInterval(r_swapInterval->integer);

		glConfig.colorBits   = testColorBits;
		glConfig.depthBits   = testDepthBits;
		glConfig.stencilBits = testStencilBits;

		ri.Printf(PRINT_ALL, "Using %d color bits, %d depth, %d stencil display.\n",
		          glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits);
		break;
	}

	GLimp_DetectAvailableModes();

#if !defined(FEATURE_RENDERER_GLES)
	glewResult = glewInit();

	if (GLEW_OK != glewResult)
	{
		// glewInit failed, something is seriously wrong
		Ren_Fatal("GLW_StartOpenGL() - could not load OpenGL subsystem: %s", glewGetErrorString(glewResult));
	}
	else
	{
		Ren_Print("Using GLEW %s\n", glewGetString(GLEW_VERSION));
	}
#endif

	if (!GLimp_InitOpenGLContext())
	{
		return RSERR_OLD_GL;
	}

	if (!main_window) //|| !main_renderer)
	{
		Ren_Print("Couldn't get a visual\n");
		return RSERR_INVALID_MODE;
	}

	SDL_FreeSurface(icon);

	return RSERR_OK;
}
コード例 #15
0
ファイル: sdl_vid.c プロジェクト: SHOVELL/Unvanquished
/*
===============
GLimp_SetMode
===============
*/
static int GLimp_SetMode( int mode, int fullscreen, int noborder )
{
	int                 sdlcolorbits;
	int                 colorbits, depthbits, stencilbits;
	int                 tcolorbits, tdepthbits, tstencilbits;
	int                 i = 0;
	SDL_Surface         *vidscreen = NULL;
	Uint32              flags = 0;
	const SDL_VideoInfo *videoInfo;

	ri.Printf( PRINT_ALL, "Initializing Direct3D display\n" );

	if ( r_allowResize->integer )
	{
		flags |= SDL_RESIZABLE;
	}

	if ( displayAspect == 0.0f )
	{
#if !SDL_VERSION_ATLEAST(1, 2, 10)
		// 1.2.10 is needed to get the desktop resolution
		displayAspect = 4.0f / 3.0f;
#else
		// Guess the display aspect ratio through the desktop resolution
		// by assuming (relatively safely) that it is set at or close to
		// the display's native aspect ratio
		videoInfo = SDL_GetVideoInfo();
		displayAspect = ( float ) videoInfo->current_w / ( float ) videoInfo->current_h;
#endif

		ri.Printf( PRINT_ALL, "Estimated display aspect: %.3f\n", displayAspect );
	}

	ri.Printf( PRINT_ALL, "...setting mode %d:", mode );

	if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) )
	{
		ri.Printf( PRINT_ALL, " invalid mode\n" );
		return RSERR_INVALID_MODE;
	}

	ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight );

	if ( fullscreen )
	{
		flags |= SDL_FULLSCREEN;
		glConfig.isFullscreen = qtrue;
	}
	else
	{
		glConfig.isFullscreen = qfalse;
	}

	if ( !r_colorbits->value )
	{
		colorbits = 24;
	}
	else
	{
		colorbits = r_colorbits->value;
	}

	if ( !r_depthbits->value )
	{
		depthbits = 24;
	}
	else
	{
		depthbits = r_depthbits->value;
	}

	stencilbits = r_stencilbits->value;

	for ( i = 0; i < 16; i++ )
	{
		// 0 - default
		// 1 - minus colorbits
		// 2 - minus depthbits
		// 3 - minus stencil
		if ( ( i % 4 ) == 0 && i )
		{
			// one pass, reduce
			switch ( i / 4 )
			{
				case 2:
					if ( colorbits == 24 )
					{
						colorbits = 16;
					}

					break;

				case 1:
					if ( depthbits == 24 )
					{
						depthbits = 16;
					}
					else if ( depthbits == 16 )
					{
						depthbits = 8;
					}

				case 3:
					if ( stencilbits == 24 )
					{
						stencilbits = 16;
					}
					else if ( stencilbits == 16 )
					{
						stencilbits = 8;
					}
			}
		}

		tcolorbits = colorbits;
		tdepthbits = depthbits;
		tstencilbits = stencilbits;

		if ( ( i % 4 ) == 3 )
		{
			// reduce colorbits
			if ( tcolorbits == 24 )
			{
				tcolorbits = 16;
			}
		}

		if ( ( i % 4 ) == 2 )
		{
			// reduce depthbits
			if ( tdepthbits == 24 )
			{
				tdepthbits = 16;
			}
			else if ( tdepthbits == 16 )
			{
				tdepthbits = 8;
			}
		}

		if ( ( i % 4 ) == 1 )
		{
			// reduce stencilbits
			if ( tstencilbits == 24 )
			{
				tstencilbits = 16;
			}
			else if ( tstencilbits == 16 )
			{
				tstencilbits = 8;
			}
			else
			{
				tstencilbits = 0;
			}
		}

		sdlcolorbits = 4;

		if ( tcolorbits == 24 )
		{
			sdlcolorbits = 8;
		}

		SDL_GL_SetAttribute( SDL_GL_RED_SIZE, sdlcolorbits );
		SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, sdlcolorbits );
		SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, sdlcolorbits );
		SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, tdepthbits );
		SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, tstencilbits );
		SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

		if ( SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, r_swapInterval->integer ) < 0 )
		{
			ri.Printf( PRINT_ALL, "r_swapInterval requires libSDL >= 1.2.10\n" );
		}

#ifdef USE_ICON
		{
			SDL_Surface *icon = SDL_CreateRGBSurfaceFrom( ( void * ) CLIENT_WINDOW_ICON.pixel_data,
			                    CLIENT_WINDOW_ICON.width,
			                    CLIENT_WINDOW_ICON.height,
			                    CLIENT_WINDOW_ICON.bytes_per_pixel * 8,
			                    CLIENT_WINDOW_ICON.bytes_per_pixel * CLIENT_WINDOW_ICON.width,
#ifdef Q3_LITTLE_ENDIAN
			                    0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
#else
			                    0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
#endif
			                                            );

			SDL_WM_SetIcon( icon, NULL );
			SDL_FreeSurface( icon );
		}
#endif

		SDL_WM_SetCaption( CLIENT_WINDOW_TITLE, CLIENT_WINDOW_MIN_TITLE );
		SDL_ShowCursor( 0 );

		if ( !( vidscreen = SDL_SetVideoMode( glConfig.vidWidth, glConfig.vidHeight, colorbits, flags ) ) )
		{
			ri.Printf( PRINT_DEVELOPER, "SDL_SetVideoMode failed: %s\n", SDL_GetError() );
			continue;
		}

		//GLimp_GetCurrentContext();

		ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n",
		           sdlcolorbits, sdlcolorbits, sdlcolorbits, tdepthbits, tstencilbits );

		glConfig.colorBits = tcolorbits;
		glConfig.depthBits = tdepthbits;
		glConfig.stencilBits = tstencilbits;
		break;
	}

	GLimp_DetectAvailableModes();

	if ( !vidscreen )
	{
		ri.Printf( PRINT_ALL, "Couldn't get a visual\n" );
		return RSERR_INVALID_MODE;
	}

	screen = vidscreen;

	//glstring = (char *)qglGetString(GL_RENDERER);
	//ri.Printf(PRINT_ALL, "GL_RENDERER: %s\n", glstring);

	return RSERR_OK;
}
コード例 #16
0
/*
** GLW_SetMode
*/
static int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen )
{
  const char*   glstring; // bk001130 - from cvs1.17 (mkv)
  int sdlcolorbits;
  int colorbits, depthbits, stencilbits;
  int tcolorbits, tdepthbits, tstencilbits;
  int i = 0;
  SDL_Surface *vidscreen = NULL;

  ri.Printf( PRINT_ALL, "Initializing OpenGL display\n");

  ri.Printf (PRINT_ALL, "...setting mode %d:", mode );

  if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) )
  {
    ri.Printf( PRINT_ALL, " invalid mode\n" );
    return RSERR_INVALID_MODE;
  }
  ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight);

  Uint32 flags = SDL_OPENGL;
  if (fullscreen)
  {
    flags |= SDL_FULLSCREEN;
    glConfig.isFullscreen = qtrue;
  }
  else
    glConfig.isFullscreen = qfalse;

  if (!r_colorbits->value)
    colorbits = 24;
  else
    colorbits = r_colorbits->value;

  if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) )
    colorbits = 16;

  if (!r_depthbits->value)
    depthbits = 24;
  else
    depthbits = r_depthbits->value;
  stencilbits = r_stencilbits->value;

  for (i = 0; i < 16; i++)
  {
    // 0 - default
    // 1 - minus colorbits
    // 2 - minus depthbits
    // 3 - minus stencil
    if ((i % 4) == 0 && i)
    {
      // one pass, reduce
      switch (i / 4)
      {
      case 2 :
        if (colorbits == 24)
          colorbits = 16;
        break;
      case 1 :
        if (depthbits == 24)
          depthbits = 16;
        else if (depthbits == 16)
          depthbits = 8;
      case 3 :
        if (stencilbits == 24)
          stencilbits = 16;
        else if (stencilbits == 16)
          stencilbits = 8;
      }
    }

    tcolorbits = colorbits;
    tdepthbits = depthbits;
    tstencilbits = stencilbits;

    if ((i % 4) == 3)
    { // reduce colorbits
      if (tcolorbits == 24)
        tcolorbits = 16;
    }

    if ((i % 4) == 2)
    { // reduce depthbits
      if (tdepthbits == 24)
        tdepthbits = 16;
      else if (tdepthbits == 16)
        tdepthbits = 8;
    }

    if ((i % 4) == 1)
    { // reduce stencilbits
      if (tstencilbits == 24)
        tstencilbits = 16;
      else if (tstencilbits == 16)
        tstencilbits = 8;
      else
        tstencilbits = 0;
    }

    sdlcolorbits = 4;
    if (tcolorbits == 24)
        sdlcolorbits = 8;

    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, sdlcolorbits );
    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, sdlcolorbits );
    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, sdlcolorbits );
    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, tdepthbits );
    SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, tstencilbits );
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

#if SDL_VERSION_ATLEAST( 1, 2, 10 )
    if( SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, r_swapInterval->integer ) )
        ri.Printf( PRINT_ALL, "r_swapInterval requires libSDL >= 1.2.10\n" );
#else
    #warning libSDL >= 1.2.10  required for r_swapInterval support
#endif // SDL_GL_SWAP_CONTROL

    SDL_WM_SetCaption(CLIENT_WINDOW_TITLE, CLIENT_WINDOW_ICON);
    SDL_ShowCursor(0);
    SDL_EnableUNICODE(1);
    SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
    sdlrepeatenabled = qtrue;

    if (!(vidscreen = SDL_SetVideoMode(glConfig.vidWidth, glConfig.vidHeight, colorbits, flags)))
    {
        fprintf(stderr, "SDL_SetVideoMode failed: %s\n", SDL_GetError());
        continue;
    }

    opengl_context = GLimp_GetCurrentContext();

    ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n",
               sdlcolorbits, sdlcolorbits, sdlcolorbits,
               tdepthbits, tstencilbits);

    glConfig.colorBits = tcolorbits;
    glConfig.depthBits = tdepthbits;
    glConfig.stencilBits = tstencilbits;
    break;
  }

  if (!vidscreen)
  {
    ri.Printf( PRINT_ALL, "Couldn't get a visual\n" );
    return RSERR_INVALID_MODE;
  }

  screen = vidscreen;

  // bk001130 - from cvs1.17 (mkv)
  glstring = (char *) qglGetString (GL_RENDERER);
  ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring );

  // bk010122 - new software token (Indirect)
  if ( !Q_stricmp( glstring, "Mesa X11")
       || !Q_stricmp( glstring, "Mesa GLX Indirect") )
  {
    if ( !r_allowSoftwareGL->integer )
    {
      ri.Printf( PRINT_ALL, "\n\n***********************************************************\n" );
      ri.Printf( PRINT_ALL, " You are using software Mesa (no hardware acceleration)!   \n" );
      ri.Printf( PRINT_ALL, " Driver DLL used: %s\n", drivername ); 
      ri.Printf( PRINT_ALL, " If this is intentional, add\n" );
      ri.Printf( PRINT_ALL, "       \"+set r_allowSoftwareGL 1\"\n" );
      ri.Printf( PRINT_ALL, " to the command line when starting the game.\n" );
      ri.Printf( PRINT_ALL, "***********************************************************\n");
      GLimp_Shutdown( );
      return RSERR_INVALID_MODE;
    } else
    {
      ri.Printf( PRINT_ALL, "...using software Mesa (r_allowSoftwareGL==1).\n" );
    }
  }

  return RSERR_OK;
}
コード例 #17
0
/*
** GLW_SetMode
*/
int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen ) {
#ifdef HAVE_GLES
	glConfig.vidWidth = 800;
	glConfig.vidHeight = 480;
//	glConfig.windowAspect = 800.0 / 480.0;

	long event_mask=X_MASK;
	dpy = XOpenDisplay(0);
	if(!dpy)
	{
		ri.Printf( PRINT_ALL, "couldn't open display\n");
		return qfalse;
	}
	
	scrnum = DefaultScreen(dpy);
	ri.Printf( PRINT_ALL, "using default screen %d\n", scrnum);
	ri.Printf( PRINT_ALL, "setting up EGL window\n");
 
	XSetWindowAttributes attr = { 0 };
	attr.event_mask = event_mask;
//	attr.colormap = colormap;
	attr.override_redirect = qtrue;
	win = XCreateWindow(dpy, RootWindow(dpy, scrnum),
		0, 0, glConfig.vidWidth, glConfig.vidHeight, 0, 
		CopyFromParent, InputOutput,
		CopyFromParent, CWEventMask, &attr);

	if(!win) {
		return qfalse;
	}

	Atom wmState = XInternAtom(dpy, "_NET_WM_STATE", False);
	Atom wmFullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
	XChangeProperty(dpy, win, wmState, XA_ATOM, 32, PropModeReplace, (unsigned char *)&wmFullscreen, 1);

	XMapRaised(dpy, win);

	g_EGLWindow = (NativeWindowType)win;
	#ifdef PANDORA
	g_EGLDisplay  =  eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY);
	#else
	g_EGLDisplay  =  eglGetDisplay((EGLNativeDisplayType)dpy);
	#endif

	if(g_EGLDisplay == EGL_NO_DISPLAY) {
		ri.Printf( PRINT_ALL, "error getting EGL display\n");
		return qfalse;
	}

	if(!eglInitialize(g_EGLDisplay, NULL, NULL)) {
		ri.Printf( PRINT_ALL, "error initializing EGL");
		return 0;
	}

	const EGLint attribs[] = {
		EGL_RED_SIZE, 5,
		EGL_GREEN_SIZE, 6,
		EGL_BLUE_SIZE, 5,
		EGL_ALPHA_SIZE, 0,
		EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
		EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT,
		EGL_DEPTH_SIZE, 16,
		EGL_NONE, 0,
	};

	EGLint configs = 0;
	eglChooseConfig(g_EGLDisplay, attribs, &g_EGLConfig, 1, &configs);
	if(!configs) {
		static const EGLint eglAttrWinLowColor[] = {
			EGL_NONE
		};
		ri.Printf( PRINT_ALL, "falling back to lowest color config\n");
		eglChooseConfig(g_EGLDisplay, eglAttrWinLowColor, &g_EGLConfig, 1, &configs);
		if(!configs) {
			ri.Printf( PRINT_ALL, "no valid EGL configs found\n");
			return qfalse;
		}
	}
	
	#ifdef PANDORA
	g_EGLWindowSurface = eglCreateWindowSurface(g_EGLDisplay, g_EGLConfig,
		NULL, NULL);
	#else
	g_EGLWindowSurface = eglCreateWindowSurface(g_EGLDisplay, g_EGLConfig,
		g_EGLWindow, NULL);
	#endif
	if(g_EGLWindowSurface == EGL_NO_SURFACE) {
		ri.Printf( PRINT_ALL, "error creating window surface: 0x%X\n", (int)eglGetError());
		return qfalse;
	}

	EGLint ctxAttr[] = {
		EGL_CONTEXT_CLIENT_VERSION, 1,
		EGL_NONE
	};
	g_EGLContext = eglCreateContext(g_EGLDisplay, g_EGLConfig, EGL_NO_CONTEXT, ctxAttr);
	if(g_EGLContext == EGL_NO_CONTEXT) {
		ri.Printf( PRINT_ALL, "error creating context: 0x%X\n", (int)eglGetError());
		return qfalse;
	}
	
	eglMakeCurrent(g_EGLDisplay, g_EGLWindowSurface, g_EGLWindowSurface, g_EGLContext);
	{
	  EGLint width, height, color, depth, stencil;
	  eglQuerySurface(g_EGLDisplay, g_EGLWindowSurface, EGL_WIDTH, &width);
	  eglQuerySurface(g_EGLDisplay, g_EGLWindowSurface, EGL_HEIGHT, &height);
	  ri.Printf(PRINT_ALL, "Window size: %dx%d\n", width, height);
	  eglGetConfigAttrib(g_EGLDisplay, g_EGLConfig, EGL_BUFFER_SIZE, &color);
	  eglGetConfigAttrib(g_EGLDisplay, g_EGLConfig, EGL_DEPTH_SIZE, &depth);
	  eglGetConfigAttrib(g_EGLDisplay, g_EGLConfig, EGL_STENCIL_SIZE, &stencil);
/*	  glConfig.vidWidth = width;
	  glConfig.vidHeight = height;*/
	  glConfig.colorBits = color;
	  glConfig.depthBits = depth;
	  glConfig.stencilBits = stencil;
	}

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

#else
	int attrib[] = {
		GLX_RGBA,     // 0
		GLX_RED_SIZE, 4,  // 1, 2
		GLX_GREEN_SIZE, 4,  // 3, 4
		GLX_BLUE_SIZE, 4, // 5, 6
		GLX_DOUBLEBUFFER, // 7
		GLX_DEPTH_SIZE, 1,  // 8, 9
		GLX_STENCIL_SIZE, 1, // 10, 11
		None
	};
	// these match in the array
#define ATTR_RED_IDX 2
#define ATTR_GREEN_IDX 4
#define ATTR_BLUE_IDX 6
#define ATTR_DEPTH_IDX 9
#define ATTR_STENCIL_IDX 11
	Window root;
	XVisualInfo *visinfo;
	XSetWindowAttributes attr;
	unsigned long mask;
	int colorbits, depthbits, stencilbits;
	int tcolorbits, tdepthbits, tstencilbits;
	int dga_MajorVersion, dga_MinorVersion;
	int actualWidth, actualHeight;
	int i;
	const char*   glstring; // bk001130 - from cvs1.17 (mkv)

	ri.Printf( PRINT_ALL, "Initializing OpenGL display\n" );

	ri.Printf( PRINT_ALL, "...setting mode %d:", mode );

	if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) ) {
		ri.Printf( PRINT_ALL, " invalid mode\n" );
		return RSERR_INVALID_MODE;
	}
	ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight );

	if ( !( dpy = XOpenDisplay( NULL ) ) ) {
		fprintf( stderr, "Error couldn't open the X display\n" );
		return RSERR_INVALID_MODE;
	}

	scrnum = DefaultScreen( dpy );
	root = RootWindow( dpy, scrnum );

	actualWidth = glConfig.vidWidth;
	actualHeight = glConfig.vidHeight;

	// Get video mode list
	if ( !XF86VidModeQueryVersion( dpy, &vidmode_MajorVersion, &vidmode_MinorVersion ) ) {
		vidmode_ext = qfalse;
	} else
	{
		ri.Printf( PRINT_ALL, "Using XFree86-VidModeExtension Version %d.%d\n",
				   vidmode_MajorVersion, vidmode_MinorVersion );
		vidmode_ext = qtrue;
	}

	// Check for DGA
	dga_MajorVersion = 0, dga_MinorVersion = 0;
	if ( in_dgamouse->value ) {
		if ( !XF86DGAQueryVersion( dpy, &dga_MajorVersion, &dga_MinorVersion ) ) {
			// unable to query, probalby not supported
			ri.Printf( PRINT_ALL, "Failed to detect XF86DGA Mouse\n" );
			ri.Cvar_Set( "in_dgamouse", "0" );
		} else
		{
			ri.Printf( PRINT_ALL, "XF86DGA Mouse (Version %d.%d) initialized\n",
					   dga_MajorVersion, dga_MinorVersion );
		}
	}

	if ( vidmode_ext ) {
		int best_fit, best_dist, dist, x, y;

		XF86VidModeGetAllModeLines( dpy, scrnum, &num_vidmodes, &vidmodes );

		// Are we going fullscreen?  If so, let's change video mode
		if ( fullscreen ) {
			best_dist = 9999999;
			best_fit = -1;

			for ( i = 0; i < num_vidmodes; i++ )
			{
				if ( glConfig.vidWidth > vidmodes[i]->hdisplay ||
					 glConfig.vidHeight > vidmodes[i]->vdisplay ) {
					continue;
				}

				x = glConfig.vidWidth - vidmodes[i]->hdisplay;
				y = glConfig.vidHeight - vidmodes[i]->vdisplay;
				dist = ( x * x ) + ( y * y );
				if ( dist < best_dist ) {
					best_dist = dist;
					best_fit = i;
				}
			}

			if ( best_fit != -1 ) {
				actualWidth = vidmodes[best_fit]->hdisplay;
				actualHeight = vidmodes[best_fit]->vdisplay;

				// change to the mode
				XF86VidModeSwitchToMode( dpy, scrnum, vidmodes[best_fit] );
				vidmode_active = qtrue;

				// Move the viewport to top left
				XF86VidModeSetViewPort( dpy, scrnum, 0, 0 );

				ri.Printf( PRINT_ALL, "XFree86-VidModeExtension Activated at %dx%d\n",
						   actualWidth, actualHeight );

			} else
			{
				fullscreen = 0;
				ri.Printf( PRINT_ALL, "XFree86-VidModeExtension: No acceptable modes found\n" );
			}
		} else
		{
			ri.Printf( PRINT_ALL, "XFree86-VidModeExtension:  Ignored on non-fullscreen/Voodoo\n" );
		}
	}


	if ( !r_colorbits->value ) {
		colorbits = 24;
	} else {
		colorbits = r_colorbits->value;
	}

	if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) ) {
		colorbits = 16;
	}

	if ( !r_depthbits->value ) {
		depthbits = 24;
	} else {
		depthbits = r_depthbits->value;
	}
	stencilbits = r_stencilbits->value;

	for ( i = 0; i < 16; i++ )
	{
		// 0 - default
		// 1 - minus colorbits
		// 2 - minus depthbits
		// 3 - minus stencil
		if ( ( i % 4 ) == 0 && i ) {
			// one pass, reduce
			switch ( i / 4 )
			{
			case 2:
				if ( colorbits == 24 ) {
					colorbits = 16;
				}
				break;
			case 1:
				if ( depthbits == 24 ) {
					depthbits = 16;
				} else if ( depthbits == 16 ) {
					depthbits = 8;
				}
			case 3:
				if ( stencilbits == 24 ) {
					stencilbits = 16;
				} else if ( stencilbits == 16 ) {
					stencilbits = 8;
				}
			}
		}

		tcolorbits = colorbits;
		tdepthbits = depthbits;
		tstencilbits = stencilbits;

		if ( ( i % 4 ) == 3 ) { // reduce colorbits
			if ( tcolorbits == 24 ) {
				tcolorbits = 16;
			}
		}

		if ( ( i % 4 ) == 2 ) { // reduce depthbits
			if ( tdepthbits == 24 ) {
				tdepthbits = 16;
			} else if ( tdepthbits == 16 ) {
				tdepthbits = 8;
			}
		}

		if ( ( i % 4 ) == 1 ) { // reduce stencilbits
			if ( tstencilbits == 24 ) {
				tstencilbits = 16;
			} else if ( tstencilbits == 16 ) {
				tstencilbits = 8;
			} else {
				tstencilbits = 0;
			}
		}

		if ( tcolorbits == 24 ) {
			attrib[ATTR_RED_IDX] = 8;
			attrib[ATTR_GREEN_IDX] = 8;
			attrib[ATTR_BLUE_IDX] = 8;
		} else
		{
			// must be 16 bit
			attrib[ATTR_RED_IDX] = 4;
			attrib[ATTR_GREEN_IDX] = 4;
			attrib[ATTR_BLUE_IDX] = 4;
		}

		attrib[ATTR_DEPTH_IDX] = tdepthbits; // default to 24 depth
		attrib[ATTR_STENCIL_IDX] = tstencilbits;

		visinfo = qglXChooseVisual( dpy, scrnum, attrib );
		if ( !visinfo ) {
			continue;
		}

		ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n",
				   attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX], attrib[ATTR_BLUE_IDX],
				   attrib[ATTR_DEPTH_IDX], attrib[ATTR_STENCIL_IDX] );

		glConfig.colorBits = tcolorbits;
		glConfig.depthBits = tdepthbits;
		glConfig.stencilBits = tstencilbits;
		break;
	}

	if ( !visinfo ) {
		ri.Printf( PRINT_ALL, "Couldn't get a visual\n" );
		return RSERR_INVALID_MODE;
	}

	/* window attributes */
	attr.background_pixel = BlackPixel( dpy, scrnum );
	attr.border_pixel = 0;
	attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone );
	attr.event_mask = X_MASK;
	if ( vidmode_active ) {
		mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore |
			   CWEventMask | CWOverrideRedirect;
		attr.override_redirect = True;
		attr.backing_store = NotUseful;
		attr.save_under = False;
	} else {
		mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
	}

	win = XCreateWindow( dpy, root, 0, 0,
						 actualWidth, actualHeight,
						 0, visinfo->depth, InputOutput,
						 visinfo->visual, mask, &attr );

	XStoreName( dpy, win, WINDOW_CLASS_NAME );

	XMapWindow( dpy, win );

	if ( vidmode_active ) {
		XMoveWindow( dpy, win, 0, 0 );
	}

	XFlush( dpy );
	XSync( dpy,False ); // bk001130 - from cvs1.17 (mkv)
	ctx = qglXCreateContext( dpy, visinfo, NULL, True );
	XSync( dpy,False ); // bk001130 - from cvs1.17 (mkv)

	qglXMakeCurrent( dpy, win, ctx );

	// bk001130 - from cvs1.17 (mkv)
	glstring = qglGetString( GL_RENDERER );
	ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring );

	// bk010122 - new software token (Indirect)
	if ( !Q_stricmp( glstring, "Mesa X11" )
		 || !Q_stricmp( glstring, "Mesa GLX Indirect" ) ) {
		if ( !r_allowSoftwareGL->integer ) {
			ri.Printf( PRINT_ALL, "\n\n***********************************************************\n" );
			ri.Printf( PRINT_ALL, " You are using software Mesa (no hardware acceleration)!   \n" );
			ri.Printf( PRINT_ALL, " Driver DLL used: %s\n", drivername );
			ri.Printf( PRINT_ALL, " If this is intentional, add\n" );
			ri.Printf( PRINT_ALL, "       \"+set r_allowSoftwareGL 1\"\n" );
			ri.Printf( PRINT_ALL, " to the command line when starting the game.\n" );
			ri.Printf( PRINT_ALL, "***********************************************************\n" );
			GLimp_Shutdown();
			return RSERR_INVALID_MODE;
		} else
		{
			ri.Printf( PRINT_ALL, "...using software Mesa (r_allowSoftwareGL==1).\n" );
		}
	}
#endif	//HAVE_GLES
	return RSERR_OK;
}
コード例 #18
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;
	}
}
コード例 #19
0
/*
===============
GLimp_SetMode
===============
*/
static rserr_t GLimp_SetMode(glconfig_t *glConfig, const windowDesc_t *windowDesc, const char *windowTitle, int mode, qboolean fullscreen, qboolean noborder)
{
	int perChannelColorBits;
	int colorBits, depthBits, stencilBits;
	int samples;
	int i = 0;
	SDL_Surface *icon = NULL;
	Uint32 flags = SDL_WINDOW_SHOWN;
	SDL_DisplayMode desktopMode;
	int display = 0;
	int x = SDL_WINDOWPOS_UNDEFINED, y = SDL_WINDOWPOS_UNDEFINED;

	if ( windowDesc->api == GRAPHICS_API_OPENGL )
	{
		flags |= SDL_WINDOW_OPENGL;
	}

	Com_Printf( "Initializing display\n");

	icon = SDL_CreateRGBSurfaceFrom(
		(void *)CLIENT_WINDOW_ICON.pixel_data,
		CLIENT_WINDOW_ICON.width,
		CLIENT_WINDOW_ICON.height,
		CLIENT_WINDOW_ICON.bytes_per_pixel * 8,
		CLIENT_WINDOW_ICON.bytes_per_pixel * CLIENT_WINDOW_ICON.width,
#ifdef Q3_LITTLE_ENDIAN
		0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
#else
		0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
#endif
		);

	// If a window exists, note its display index
	if( screen != NULL )
		display = SDL_GetWindowDisplayIndex( screen );

	if( SDL_GetDesktopDisplayMode( display, &desktopMode ) == 0 )
	{
		displayAspect = (float)desktopMode.w / (float)desktopMode.h;

		Com_Printf( "Display aspect: %.3f\n", displayAspect );
	}
	else
	{
		Com_Memset( &desktopMode, 0, sizeof( SDL_DisplayMode ) );

		Com_Printf( "Cannot determine display aspect, assuming 1.333\n" );
	}

	Com_Printf( "...setting mode %d:", mode );

	if (mode == -2)
	{
		// use desktop video resolution
		if( desktopMode.h > 0 )
		{
			glConfig->vidWidth = desktopMode.w;
			glConfig->vidHeight = desktopMode.h;
		}
		else
		{
			glConfig->vidWidth = 640;
			glConfig->vidHeight = 480;
			Com_Printf( "Cannot determine display resolution, assuming 640x480\n" );
		}

		//glConfig.windowAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight;
	}
	else if ( !R_GetModeInfo( &glConfig->vidWidth, &glConfig->vidHeight, /*&glConfig.windowAspect,*/ mode ) )
	{
		Com_Printf( " invalid mode\n" );
		SDL_FreeSurface( icon );
		return RSERR_INVALID_MODE;
	}
	Com_Printf( " %d %d\n", glConfig->vidWidth, glConfig->vidHeight);

	// Center window
	if( r_centerWindow->integer && !fullscreen )
	{
		x = ( desktopMode.w / 2 ) - ( glConfig->vidWidth / 2 );
		y = ( desktopMode.h / 2 ) - ( glConfig->vidHeight / 2 );
	}

	// Destroy existing state if it exists
	if( opengl_context != NULL )
	{
		SDL_GL_DeleteContext( opengl_context );
		opengl_context = NULL;
	}

	if( screen != NULL )
	{
		SDL_GetWindowPosition( screen, &x, &y );
		Com_DPrintf( "Existing window at %dx%d before being destroyed\n", x, y );
		SDL_DestroyWindow( screen );
		screen = NULL;
	}

	if( fullscreen )
	{
		flags |= SDL_WINDOW_FULLSCREEN;
		glConfig->isFullscreen = qtrue;
	}
	else
	{
		if( noborder )
			flags |= SDL_WINDOW_BORDERLESS;

		glConfig->isFullscreen = qfalse;
	}

	colorBits = r_colorbits->integer;
	if ((!colorBits) || (colorBits >= 32))
		colorBits = 24;

	if (!r_depthbits->integer)
		depthBits = 24;
	else
		depthBits = r_depthbits->integer;

	stencilBits = r_stencilbits->integer;
	samples = r_ext_multisample->integer;

	if ( windowDesc->api == GRAPHICS_API_OPENGL )
	{
		for (i = 0; i < 16; i++)
		{
			int testColorBits, testDepthBits, testStencilBits;

			// 0 - default
			// 1 - minus colorBits
			// 2 - minus depthBits
			// 3 - minus stencil
			if ((i % 4) == 0 && i)
			{
				// one pass, reduce
				switch (i / 4)
				{
					case 2 :
						if (colorBits == 24)
							colorBits = 16;
						break;
					case 1 :
						if (depthBits == 24)
							depthBits = 16;
						else if (depthBits == 16)
							depthBits = 8;
					case 3 :
						if (stencilBits == 24)
							stencilBits = 16;
						else if (stencilBits == 16)
							stencilBits = 8;
				}
			}

			testColorBits = colorBits;
			testDepthBits = depthBits;
			testStencilBits = stencilBits;

			if ((i % 4) == 3)
			{ // reduce colorBits
				if (testColorBits == 24)
					testColorBits = 16;
			}

			if ((i % 4) == 2)
			{ // reduce depthBits
				if (testDepthBits == 24)
					testDepthBits = 16;
				else if (testDepthBits == 16)
					testDepthBits = 8;
			}

			if ((i % 4) == 1)
			{ // reduce stencilBits
				if (testStencilBits == 24)
					testStencilBits = 16;
				else if (testStencilBits == 16)
					testStencilBits = 8;
				else
					testStencilBits = 0;
			}

			if (testColorBits == 24)
				perChannelColorBits = 8;
			else
				perChannelColorBits = 4;

			SDL_GL_SetAttribute( SDL_GL_RED_SIZE, perChannelColorBits );
			SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, perChannelColorBits );
			SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, perChannelColorBits );
			SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, testDepthBits );
			SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, testStencilBits );

			SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, samples ? 1 : 0 );
			SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, samples );

			if ( windowDesc->gl.majorVersion )
			{
				int compactVersion = windowDesc->gl.majorVersion * 100 + windowDesc->gl.minorVersion * 10;

				SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, windowDesc->gl.majorVersion );
				SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, windowDesc->gl.minorVersion );

				if ( windowDesc->gl.profile == GLPROFILE_ES || compactVersion >= 320 )
				{
					int profile;
					switch ( windowDesc->gl.profile )
					{
					default:
					case GLPROFILE_COMPATIBILITY:
						profile = SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
						break;

					case GLPROFILE_CORE:
						profile = SDL_GL_CONTEXT_PROFILE_CORE;
						break;

					case GLPROFILE_ES:
						profile = SDL_GL_CONTEXT_PROFILE_ES;
						break;
					}

					SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, profile );
				}
			}

			if ( windowDesc->gl.contextFlags & GLCONTEXT_DEBUG )
			{
				SDL_GL_SetAttribute( SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG );
			}

			if(r_stereo->integer)
			{
				glConfig->stereoEnabled = qtrue;
				SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
			}
			else
			{
				glConfig->stereoEnabled = qfalse;
				SDL_GL_SetAttribute(SDL_GL_STEREO, 0);
			}

			SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
			SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 );

			if( ( screen = SDL_CreateWindow( windowTitle, x, y,
					glConfig->vidWidth, glConfig->vidHeight, flags ) ) == NULL )
			{
				Com_DPrintf( "SDL_CreateWindow failed: %s\n", SDL_GetError( ) );
				continue;
			}

#ifndef MACOS_X
			SDL_SetWindowIcon( screen, icon );
#endif

			if( fullscreen )
			{
				SDL_DisplayMode mode;

				switch( testColorBits )
				{
					case 16: mode.format = SDL_PIXELFORMAT_RGB565; break;
					case 24: mode.format = SDL_PIXELFORMAT_RGB24;  break;
					default: Com_DPrintf( "testColorBits is %d, can't fullscreen\n", testColorBits ); continue;
				}

				mode.w = glConfig->vidWidth;
				mode.h = glConfig->vidHeight;
				mode.refresh_rate = glConfig->displayFrequency = r_displayRefresh->integer;
				mode.driverdata = NULL;

				if( SDL_SetWindowDisplayMode( screen, &mode ) < 0 )
				{
					Com_DPrintf( "SDL_SetWindowDisplayMode failed: %s\n", SDL_GetError( ) );
					continue;
				}
			}

			if( ( opengl_context = SDL_GL_CreateContext( screen ) ) == NULL )
			{
				Com_Printf( "SDL_GL_CreateContext failed: %s\n", SDL_GetError( ) );
				continue;
			}

			SDL_GL_SetSwapInterval( r_swapInterval->integer );

			glConfig->colorBits = testColorBits;
			glConfig->depthBits = testDepthBits;
			glConfig->stencilBits = testStencilBits;

			Com_Printf( "Using %d color bits, %d depth, %d stencil display.\n",
					glConfig->colorBits, glConfig->depthBits, glConfig->stencilBits );
			break;
		}
	}
	else
	{
		// Just create a regular window
		if( ( screen = SDL_CreateWindow( windowTitle, x, y,
				glConfig->vidWidth, glConfig->vidHeight, flags ) ) == NULL )
		{
			Com_DPrintf( "SDL_CreateWindow failed: %s\n", SDL_GetError( ) );
		}
		else
		{
#ifndef MACOS_X
			SDL_SetWindowIcon( screen, icon );
#endif
			if( fullscreen )
			{
				if( SDL_SetWindowDisplayMode( screen, NULL ) < 0 )
				{
					Com_DPrintf( "SDL_SetWindowDisplayMode failed: %s\n", SDL_GetError( ) );
				}
			}
		}
	}

	SDL_FreeSurface( icon );

	if (!GLimp_DetectAvailableModes())
	{
		return RSERR_UNKNOWN;
	}

	return RSERR_OK;
}
コード例 #20
0
ファイル: win_glimp.cpp プロジェクト: Hasimir/jedi-outcast-1
/*
** GLW_SetMode
*/
static rserr_t GLW_SetMode( int mode, 
							int colorbits, 
							qboolean cdsFullscreen )
{
	HDC hDC;
	const char *win_fs[] = { "W", "FS" };
	int		cdsRet;
	DEVMODE dm;
		
	//
	// print out informational messages
	//
	ri.Printf( PRINT_ALL, "...setting mode %d:", mode );
	if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) )
	{
		ri.Printf( PRINT_ALL, " invalid mode\n" );
		return RSERR_INVALID_MODE;
	}
	ri.Printf( PRINT_ALL, " %d %d %s\n", glConfig.vidWidth, glConfig.vidHeight, win_fs[cdsFullscreen] );

	//
	// check our desktop attributes
	//
	hDC = GetDC( GetDesktopWindow() );
	glw_state.desktopBitsPixel = GetDeviceCaps( hDC, BITSPIXEL );
	glw_state.desktopWidth = GetDeviceCaps( hDC, HORZRES );
	glw_state.desktopHeight = GetDeviceCaps( hDC, VERTRES );
	ReleaseDC( GetDesktopWindow(), hDC );

	//
	// verify desktop bit depth
	//
	if ( glw_state.desktopBitsPixel < 15 || glw_state.desktopBitsPixel == 24 )
	{
		if ( colorbits == 0 || ( !cdsFullscreen && colorbits >= 15 ) )
		{
			// since I can't be bothered trying to mess around with asian codepages and MBCS stuff for a windows
			//	error box that'll only appear if something's seriously f****d then I'm going to fallback to
			//	english text when these would otherwise be used...
			//
			char sErrorHead[1024];	// ott

			extern qboolean Language_IsAsian(void);
			Q_strncpyz(sErrorHead, Language_IsAsian() ? "Low Desktop Color Depth" : SP_GetStringTextString("CON_TEXT_LOW_DESKTOP_COLOUR_DEPTH"), sizeof(sErrorHead) );

			const char *psErrorBody = Language_IsAsian() ?
												"It is highly unlikely that a correct windowed\n"
												"display can be initialized with the current\n"
												"desktop display depth.  Select 'OK' to try\n"
												"anyway.  Select 'Cancel' to try a fullscreen\n"
												"mode instead."
												:
												SP_GetStringTextString("CON_TEXT_TRY_ANYWAY");

			if ( MessageBox( NULL, 							
						psErrorBody,
						sErrorHead,
						MB_OKCANCEL | MB_ICONEXCLAMATION ) != IDOK )
			{
				return RSERR_INVALID_MODE;
			}
		}
	}

	// do a CDS if needed
	if ( cdsFullscreen )
	{
		memset( &dm, 0, sizeof( dm ) );
		
		dm.dmSize = sizeof( dm );
		
		dm.dmPelsWidth  = glConfig.vidWidth;
		dm.dmPelsHeight = glConfig.vidHeight;
		dm.dmFields     = DM_PELSWIDTH | DM_PELSHEIGHT;

		if ( r_displayRefresh->integer != 0 )
		{
			dm.dmDisplayFrequency = r_displayRefresh->integer;
			dm.dmFields |= DM_DISPLAYFREQUENCY;
		}
		
		// try to change color depth if possible
		if ( colorbits != 0 )
		{
			if ( glw_state.allowdisplaydepthchange )
			{
				dm.dmBitsPerPel = colorbits;
				dm.dmFields |= DM_BITSPERPEL;
				ri.Printf( PRINT_ALL, "...using colorsbits of %d\n", colorbits );
			}
			else
			{
				ri.Printf( PRINT_ALL, "WARNING:...changing depth not supported on Win95 < pre-OSR 2.x\n" );
			}
		}
		else
		{
			ri.Printf( PRINT_ALL, "...using desktop display depth of %d\n", glw_state.desktopBitsPixel );
		}

		//
		// if we're already in fullscreen then just create the window
		//
		if ( glw_state.cdsFullscreen )
		{
			ri.Printf( PRINT_ALL, "...already fullscreen, avoiding redundant CDS\n" );

			if ( !GLW_CreateWindow ( glConfig.vidWidth, glConfig.vidHeight, colorbits, qtrue ) )
			{
				ri.Printf( PRINT_ALL, "...restoring display settings\n" );
				ChangeDisplaySettings( 0, 0 );
				return RSERR_INVALID_MODE;
			}
		}
		//
		// need to call CDS
		//
		else
		{
			ri.Printf( PRINT_ALL, "...calling CDS: " );
			
			// try setting the exact mode requested, because some drivers don't report
			// the low res modes in EnumDisplaySettings, but still work
			if ( ( cdsRet = ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) ) == DISP_CHANGE_SUCCESSFUL )
			{
				ri.Printf( PRINT_ALL, "ok\n" );

				if ( !GLW_CreateWindow ( glConfig.vidWidth, glConfig.vidHeight, colorbits, qtrue) )
				{
					ri.Printf( PRINT_ALL, "...restoring display settings\n" );
					ChangeDisplaySettings( 0, 0 );
					return RSERR_INVALID_MODE;
				}
				
				glw_state.cdsFullscreen = qtrue;
			}
			else
			{
				//
				// the exact mode failed, so scan EnumDisplaySettings for the next largest mode
				//
				DEVMODE		devmode;
				int			modeNum;

				ri.Printf( PRINT_ALL, "failed, " );
				
				PrintCDSError( cdsRet );
			
				ri.Printf( PRINT_ALL, "...trying next higher resolution:" );
				
				// we could do a better matching job here...
				for ( modeNum = 0 ; ; modeNum++ ) {
					if ( !EnumDisplaySettings( NULL, modeNum, &devmode ) ) {
						modeNum = -1;
						break;
					}
					if ( devmode.dmPelsWidth >= glConfig.vidWidth
						&& devmode.dmPelsHeight >= glConfig.vidHeight
						&& devmode.dmBitsPerPel >= 15 ) {
						break;
					}
				}

				if ( modeNum != -1 && ( cdsRet = ChangeDisplaySettings( &devmode, CDS_FULLSCREEN ) ) == DISP_CHANGE_SUCCESSFUL )
				{
					ri.Printf( PRINT_ALL, " ok\n" );
					if ( !GLW_CreateWindow( glConfig.vidWidth, glConfig.vidHeight, colorbits, qtrue) )
					{
						ri.Printf( PRINT_ALL, "...restoring display settings\n" );
						ChangeDisplaySettings( 0, 0 );
						return RSERR_INVALID_MODE;
					}
					
					glw_state.cdsFullscreen = qtrue;
				}
				else
				{
					ri.Printf( PRINT_ALL, " failed, " );
					
					PrintCDSError( cdsRet );
					
					ri.Printf( PRINT_ALL, "...restoring display settings\n" );
					ChangeDisplaySettings( 0, 0 );
					
/*				jfm:  i took out the following code to allow fallback to mode 3, with this code it goes half windowed and just doesn't work.
					glw_state.cdsFullscreen = qfalse;
					glConfig.isFullscreen = qfalse;
					if ( !GLW_CreateWindow( glConfig.vidWidth, glConfig.vidHeight, colorbits, qfalse) )
					{
						return RSERR_INVALID_MODE;
					}
*/
					return RSERR_INVALID_FULLSCREEN;
				}
			}
		}
	}
	else
	{
		if ( glw_state.cdsFullscreen )
		{
			ChangeDisplaySettings( 0, 0 );
		}

		glw_state.cdsFullscreen = qfalse;
		if ( !GLW_CreateWindow( glConfig.vidWidth, glConfig.vidHeight, colorbits, qfalse ) )
		{
			return RSERR_INVALID_MODE;
		}
	}

	//
	// success, now check display frequency, although this won't be valid on Voodoo(2)
	//
	memset( &dm, 0, sizeof( dm ) );
	dm.dmSize = sizeof( dm );
	if ( EnumDisplaySettings( NULL, ENUM_CURRENT_SETTINGS, &dm ) )
	{
		glConfig.displayFrequency = dm.dmDisplayFrequency;
	}

	// NOTE: this is overridden later on standalone 3Dfx drivers
	glConfig.isFullscreen = cdsFullscreen;

	return RSERR_OK;
}