示例#1
0
/*
===============
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;
}
示例#2
0
static void GLimp_InitOpenGL3xContext()
{
	int				retVal;
	const char     *success[] = { "failed", "success" };

	if(!r_glCoreProfile->integer)
		return;

	GLimp_GetCurrentContext();

	// try to initialize an OpenGL 3.0 context
#if defined(WIN32)
	if(WGLEW_ARB_create_context || wglewIsSupported("WGL_ARB_create_context"))
	{
		int				attribs[256];	// should be really enough
		int				numAttribs;

		/*
		int             attribs[] =
		{
			WGL_CONTEXT_MAJOR_VERSION_ARB, r_glMinMajorVersion->integer,
			WGL_CONTEXT_MINOR_VERSION_ARB, r_glMinMinorVersion->integer,
			WGL_CONTEXT_FLAGS_ARB,
			WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,// | WGL_CONTEXT_DEBUG_BIT_ARB,
			WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
			0
		};
		*/

		memset(attribs, 0, sizeof(attribs));
		numAttribs = 0;

		attribs[numAttribs++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
		attribs[numAttribs++] = r_glMinMajorVersion->integer;

		attribs[numAttribs++] = WGL_CONTEXT_MINOR_VERSION_ARB;
		attribs[numAttribs++] = r_glMinMinorVersion->integer;


		if(WGLEW_ARB_create_context_profile)
		{
			attribs[numAttribs++] = WGL_CONTEXT_FLAGS_ARB;

#if 0
			if(GLXEW_ARB_debug_output)
			{
				attribs[numAttribs++] = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB |  WGL_CONTEXT_DEBUG_BIT_ARB;
			}
			else
#endif
			{
				attribs[numAttribs++] = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
			}

			attribs[numAttribs++] = WGL_CONTEXT_PROFILE_MASK_ARB;
			attribs[numAttribs++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
		}

		// set current context to NULL
		retVal = wglMakeCurrent(opengl_context.hDC, NULL) != 0;
		ri.Printf(PRINT_ALL, "...wglMakeCurrent( %p, %p ): %s\n", opengl_context.hDC, NULL, success[retVal]);

		// delete HGLRC
		if(opengl_context.hGLRC)
		{
			retVal = wglDeleteContext(opengl_context.hGLRC) != 0;
			ri.Printf(PRINT_ALL, "...deleting standard GL context: %s\n", success[retVal]);
			opengl_context.hGLRC = NULL;
		}

		ri.Printf(PRINT_ALL, "...initializing OpenGL %i.%i context ", r_glMinMajorVersion->integer, r_glMinMinorVersion->integer);

		opengl_context.hGLRC = wglCreateContextAttribsARB(opengl_context.hDC, 0, attribs);
		
		if(wglMakeCurrent(opengl_context.hDC, opengl_context.hGLRC))
		{
			ri.Printf(PRINT_ALL, " done\n");
			glConfig.driverType = GLDRV_OPENGL3;
		}
		else
		{
			ri.Error(ERR_FATAL, "Could not initialize OpenGL %i.%i context\n"
								"Make sure your graphics card supports OpenGL %i.%i or newer",
								r_glMinMajorVersion->integer, r_glMinMinorVersion->integer,
								r_glMinMajorVersion->integer, r_glMinMinorVersion->integer);
		}
	}
#elif 0 //defined(__linux__)

	// TODO

	/*
// GLX_ARB_create_context
#ifndef GLX_ARB_create_context
#define GLX_CONTEXT_DEBUG_BIT_ARB          0x00000001
#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define GLX_CONTEXT_MAJOR_VERSION_ARB      0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB      0x2092
#define GLX_CONTEXT_FLAGS_ARB              0x2094

extern GLXContext	(APIENTRY * glXCreateContextAttribsARB) (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
*/

	glXCreateContextAttribsARB = SDL_GL_GetProcAddress("glXCreateContextAttribsARB");
	if(glXCreateContextAttribsARB)
	{
		int             attribs[3];

		ri.Printf(PRINT_ALL, "Initializing OpenGL 3.0 context...");

		attribs[0] = WGL_CONTEXT_MAJOR_VERSION_ARB;
		attribs[1] = 3;
		attribs[2] = 0;			//terminate first pair

		opengl_context->hGLRC = glXCreateContextAttribsARB(opengl_context->, attribs);
		if(wglMakeCurrent(opengl_context->hDC, opengl_context->hGLRC))
		{
			ri.Printf(PRINT_ALL, " done\n");
			glConfig.driverType = GLDRV_OPENGL3;
		}
		else
		{
			ri.Printf(PRINT_ALL, " failed\n");
		}
	}
#endif
}
/*
===============
GLimp_SetMode
===============
*/
static int GLimp_SetMode( qboolean failSafe, qboolean fullscreen )
{
	const char*   glstring;
	int sdlcolorbits;
	int colorbits, depthbits, stencilbits;
	int tcolorbits, tdepthbits, tstencilbits;
	int i = 0;
	SDL_Surface *vidscreen = NULL;
	Uint32 flags = SDL_OPENGL;

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

#if !SDL_VERSION_ATLEAST(1, 2, 10)
  // 1.2.10 is needed to get the desktop resolution
  glConfig.displayAspect = 4.0f / 3.0f;
#elif MINSDL_PATCH >= 10
#	error Ifdeffery no longer necessary, please remove
#else
	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;

		// 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->current_w / (float)videoInfo->current_h;

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

	if( !failSafe )
	{
		glConfig.vidWidth = r_width->integer;
		glConfig.vidHeight = r_height->integer;
		glConfig.windowAspect = r_width->value /
			( r_height->value * r_pixelAspect->value );
	}
	else if( glConfig.vidWidth != R_FAILSAFE_WIDTH &&
			glConfig.vidHeight != R_FAILSAFE_HEIGHT )
	{
		ri.Printf( PRINT_ALL, "Setting mode %dx%d failed, falling back on mode %dx%d\n",
			glConfig.vidWidth, glConfig.vidHeight, R_FAILSAFE_WIDTH, R_FAILSAFE_HEIGHT );

		glConfig.vidWidth = R_FAILSAFE_WIDTH;
		glConfig.vidHeight = R_FAILSAFE_HEIGHT;
		glConfig.windowAspect = 1.0f;
	}
	else
		return RSERR_INVALID_MODE;

	ri.Printf (PRINT_ALL, "...setting mode %dx%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 );

		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;
}
示例#4
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;
}
示例#5
0
static int GLimp_SetMode( void )
{
	const char*   glstring;
	//int sdlcolorbits;
	int /*colorbits, depthbits, stencilbits, */stereo;
	//int tcolorbits, tdepthbits, tstencilbits;
	int samples;
	int i = 0;
	SDL_DisplayMode displayMode;
	//SDL_Surface *vidscreen = NULL;
	Uint32 flags = SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE;
	static int desktop_w, desktop_h;  // desktop resolution 
	/*if(window) {
		return RSERR_INVALID_MODE;
	}*/
	ri.Printf( PRINT_DEVELOPER, "Initializing OpenGL display\n");
 
	//if ( r_allowResize->integer )
	//	flags |= SDL_WINDOW_RESIZABLE;

	// 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();
	//if( videoInfo->current_h == 0 )
	if( SDL_GetDesktopDisplayMode( 0, &displayMode ) == 0 )//FIXME: Use SDL_GetWindowDisplayIndex instead of 0?
	{
		if( !desktop_w ) { // first time through, resolve desktop resolution
			desktop_w = displayMode.w;
			desktop_h = displayMode.h;
		}
	}
	else
	{
		ri.Printf( PRINT_ALL, "Cannot get display info, assuming 800x600\n" );
		if( !desktop_w ) { // first time through, resolve desktop resolution
			desktop_w = 800;
			desktop_h = 600;
		}
	}

	glConfig.displayAspect = (float)desktop_w / (float)desktop_h;

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

	//if( !failSafe )
	//{
		if ( r_width->modified || r_height->modified || r_pixelAspect->modified )
		{
			for ( i = 0; i < 12; i++ )
			{
				if ( r_width->integer == vidModes[ i ].width &&
				     r_height->integer == vidModes[ i ].height &&
				     r_pixelAspect->integer == vidModes[ i ].pixelAspect )
				{
					Cvar_SetValue( "r_mode", i );
					break;
				}
			}
			if ( i == 12 )
				Cvar_Set( "r_mode", "-1" );
		}
		else if ( r_mode->modified && r_mode->integer >= 0 )
		{
			Cvar_SetValue( "r_width", vidModes[ r_mode->integer ].width );
			Cvar_SetValue( "r_height", vidModes[ r_mode->integer ].height );
			Cvar_SetValue( "r_pixelAspect", vidModes[ r_mode->integer ].pixelAspect );
		}
		r_width->modified = qfalse;
		r_height->modified = qfalse;
		r_pixelAspect->modified = qfalse;
		r_mode->modified = qfalse;
		glConfig.vidWidth = ( r_width->integer ? r_width->integer : desktop_w );
		glConfig.vidHeight = ( r_height->integer ? r_height->integer : desktop_h );
		if(glConfig.vidWidth > desktop_w) {
			glConfig.vidWidth = desktop_w;
		}
		if(glConfig.vidHeight > desktop_h) {
			glConfig.vidHeight = desktop_h;
		}
		glConfig.windowAspect = glConfig.vidWidth / ( (float)glConfig.vidHeight * r_pixelAspect->value );
	/*}
	else if( glConfig.vidWidth != R_FAILSAFE_WIDTH &&
			glConfig.vidHeight != R_FAILSAFE_HEIGHT )
	{
		ri.Printf( PRINT_ALL, "Setting mode %dx%d failed, falling back on mode %dx%d\n",
			glConfig.vidWidth, glConfig.vidHeight, R_FAILSAFE_WIDTH, R_FAILSAFE_HEIGHT );

		glConfig.vidWidth = R_FAILSAFE_WIDTH;
		glConfig.vidHeight = R_FAILSAFE_HEIGHT;
		glConfig.windowAspect = 1.0f;
	}
	else
		return RSERR_INVALID_MODE;*/

	ri.Printf (PRINT_DEVELOPER, "...setting mode %dx%d\n", glConfig.vidWidth, glConfig.vidHeight);

	if (r_fullscreen->integer) {
		glConfig.vidWidth = desktop_w;
		glConfig.vidHeight = desktop_h;
		flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
	}
	/*colorbits = r_colorbits->value;
	if (!colorbits || colorbits > 32)
		colorbits = 32;

	if (!r_depthbits->value)
		depthbits = 24;
	else
		depthbits = r_depthbits->value;
	stencilbits = r_stencilbits->value;
	samples = r_ext_multisample->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 == 32)
						colorbits = 24;
					else 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 == 32)
				tcolorbits = 24;
			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)
			sdlcolorbits = 8;
		else
			sdlcolorbits = 4;*/

//#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, colorbits );
		SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, colorbits );
		SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, colorbits );
		SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, colorbits );
		SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, depthbits );
		SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, stencilbits );
		*/
		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 );
		SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, samples ? 1 : 0 );
		SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, samples );

		if ( !(window = SDL_CreateWindow( CLIENT_WINDOW_TITLE, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 
											glConfig.vidWidth, glConfig.vidHeight, flags )) )
		//if (!(vidscreen = SDL_SetVideoMode(glConfig.vidWidth, glConfig.vidHeight, colorbits, flags)))
		{
			ri.Printf( PRINT_ALL, "SDL_CreateWindow failed: %s\n", SDL_GetError( ) );
			return RSERR_INVALID_MODE;
		}
		if ( !(context = SDL_GL_CreateContext( window )) ) {
			ri.Printf( PRINT_ALL, "SDL_GL_CreateContext failed: %s\n", SDL_GetError( ) );
			SDL_DestroyWindow( window );
			window = NULL;
			return RSERR_INVALID_MODE;
		}
		//if( SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, r_swapInterval->integer ) < 0 )
		if( SDL_GL_SetSwapInterval( r_swapInterval->integer ) != 0 )
			ri.Printf( PRINT_ALL, "r_swapInterval failed (%s)\n", SDL_GetError( ) );
#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_SetWindowIcon( window, icon );
			SDL_FreeSurface( icon );
		}
#endif

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

		//ri.Printf( PRINT_DEVELOPER, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n",
		//		sdlcolorbits, sdlcolorbits, sdlcolorbits, tdepthbits, tstencilbits);
		SDL_GL_GetAttribute( SDL_GL_RED_SIZE, &glConfig.colorBits );
		SDL_GL_GetAttribute( SDL_GL_DEPTH_SIZE, &glConfig.depthBits );
		SDL_GL_GetAttribute( SDL_GL_STENCIL_SIZE, &glConfig.stencilBits );
		SDL_GL_GetAttribute( SDL_GL_STEREO, &stereo );
		if(stereo) {
			glConfig.stereoEnabled = qtrue;
		}
		else {
			glConfig.stereoEnabled = qfalse;
		}
		if(SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP) {
			glConfig.isFullscreen = qtrue;
		}
		else {
			if(r_fullscreen->integer) {
				Cvar_Set( "r_fullscreen", "0" );
			}
			glConfig.isFullscreen = qfalse;
		}
		/*glConfig.colorBits = tcolorbits;
		glConfig.depthBits = tdepthbits;
		glConfig.stencilBits = tstencilbits;
		break;
	}
	*/
	GLimp_DetectAvailableModes();

	if (!window || !context)
	{
		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;
}