SDL_Window * SDLX_CreateWindow( SDLX_video_parameters_t& v, bool make_report ) { SDL_Window * ret = nullptr; int windowPos = SDL_WINDOWPOS_CENTERED; if (Ego::GraphicsSystem::window) return nullptr; if (!v.flags.opengl) { // do our one-and-only video initialization ret = SDLX_CreateWindow(v.flags); if (!ret) { Log::get().message("SDL WARN: Unable to create SDL window: %s\n", SDL_GetError()); } else { SDL_SetWindowSize(ret, v.horizontalResolution, v.verticalResolution); SDL_SetWindowPosition(ret, windowPos, windowPos); } } else { SDLX_sdl_gl_attrib_t::validate(v.gl_att); // synch some parameters between OpenGL and SDL v.colorBufferDepth = v.gl_att.buffer_size; // try a softer video initialization // if it fails, then it tries to get the closest possible valid video mode ret = SDLX_CreateWindow(v.flags); if ( nullptr == ret ) { Log::get().warn("unable to create SDL window: %s\n", SDL_GetError()); } else { SDL_SetWindowSize(ret, v.horizontalResolution, v.verticalResolution); SDL_SetWindowPosition(ret, windowPos, windowPos); SDL_GLContext context = SDLX_CreateContext(ret, v.gl_att); if (!context) { Log::get().warn("unable to create GL context: %s\n", SDL_GetError()); SDL_DestroyWindow(ret); ret = nullptr; } } if (!ret) { // if we're using multisamples, try lowering it until we succeed if ( v.gl_att.multisampling.multisamples > 0 ) { v.gl_att.multisampling.multisamples -= 1; while ( v.gl_att.multisampling.multisamples > 1 && !ret ) { v.gl_att.multisampling.multibuffers = 1; ret = SDLX_CreateWindow(v.flags); if ( nullptr == ret ) { Log::get().warn("unable to create SDL window (%d multisamples): %s\n", v.gl_att.multisampling.multisamples, SDL_GetError()); } else { SDL_SetWindowSize(ret, v.horizontalResolution, v.verticalResolution); SDL_SetWindowPosition(ret, windowPos, windowPos); SDL_GLContext context = SDLX_CreateContext(ret, v.gl_att); if (!context) { Log::get().warn("unable to create GL context (%d multisamples): %s\n", v.gl_att.multisampling.multisamples, SDL_GetError()); SDL_DestroyWindow(ret); ret = nullptr; } } v.gl_att.multisampling.multisamples -= 1; } } } if (nullptr == ret) { // something is interfering with our ability to generate a screen. // assume that it is a complete incompatability with multisampling Log::get().warn("Disabled antialiasing\n"); v.gl_att.multisampling.multibuffers = 0; v.gl_att.multisampling.multisamples = 0; ret = SDLX_CreateWindow(v.flags); if ( nullptr == ret ) { Log::get().warn("unable to create SDL window (no multisamples): %s\n", SDL_GetError()); } else { SDL_SetWindowSize(ret, v.horizontalResolution, v.verticalResolution); SDL_SetWindowPosition(ret, windowPos, windowPos); SDL_GLContext context = SDLX_CreateContext(ret, v.gl_att); if (!context) { Log::get().warn("unable to create GL context (no multisamples): %s\n", SDL_GetError()); SDL_DestroyWindow(ret); ret = nullptr; } } } if (ret) { // grab the actual status of the multi_buffers and multi_samples v.gl_att.multisampling.multibuffers = 0; v.gl_att.multisampling.multisamples = 0; v.gl_att.accelerated_visual = SDL_FALSE; v.gl_att.multisampling.download(); #if !defined(ID_LINUX) SDL_GL_GetAttribute( SDL_GL_ACCELERATED_VISUAL, &( v.gl_att.accelerated_visual ) ); #endif // Swap interval needs a current context SDL_GL_SetSwapInterval(v.gl_att.swap_control); } } // Update the video parameters. Ego::GraphicsSystem::window = ret; if ( NULL != ret ) { SDLX_Get_Screen_Info( sdl_scr, make_report ); SDLX_synch_video_parameters( ret, &v ); } return ret; }
//-------------------------------------------------------------------------------------------- SDL_Surface * SDLX_RequestVideoMode( SDLX_video_parameters_t * v, SDL_bool make_report ) { Uint32 flags; int sdl_nearset_bpp = -1; SDL_Surface * ret = NULL; if ( NULL == v ) return ret; if ( !v->flags.opengl ) { // set the flags = SDLX_upload_sdl_video_flags( v->flags ); // do our one-and-only video initialization ret = NULL; sdl_nearset_bpp = SDL_VideoModeOK( v->width, v->height, v->depth, flags ); if ( 0 != sdl_nearset_bpp ) { ret = SDL_SetVideoMode( v->width, v->height, sdl_nearset_bpp, flags ); if ( NULL == ret ) { fprintf( LOCAL_STDOUT, "SDL WARN: Unable to set SDL video mode: %s\n", SDL_GetError() ); } } } else { int buffer_size = v->gl_att.buffer_size; if ( 0 == buffer_size ) buffer_size = v->depth; if ( 0 == buffer_size ) buffer_size = 32; if ( buffer_size > 32 ) buffer_size = 32; // fix bad colordepth if (( 0 == v->gl_att.color[0] && 0 == v->gl_att.color[1] && 0 == v->gl_att.color[2] ) || ( v->gl_att.color[0] + v->gl_att.color[1] + v->gl_att.color[2] > buffer_size ) ) { if ( buffer_size > 24 ) { v->gl_att.color[0] = v->gl_att.color[1] = v->gl_att.color[2] = buffer_size / 4; } else { // do a kludge in case we have something silly like 16 bit "highcolor" mode v->gl_att.color[0] = v->gl_att.color[2] = buffer_size / 3; v->gl_att.color[1] = buffer_size - v->gl_att.color[0] - v->gl_att.color[2]; } v->gl_att.color[0] = ( v->gl_att.color[0] > 8 ) ? 8 : v->gl_att.color[0]; v->gl_att.color[1] = ( v->gl_att.color[1] > 8 ) ? 8 : v->gl_att.color[1]; v->gl_att.color[2] = ( v->gl_att.color[2] > 8 ) ? 8 : v->gl_att.color[2]; } // fix the alpha value v->gl_att.color[3] = buffer_size - v->gl_att.color[0] - v->gl_att.color[1] - v->gl_att.color[2]; v->gl_att.color[3] = ( v->gl_att.color[3] < 0 ) ? 0 : v->gl_att.color[3]; // get the proper buffer size buffer_size = v->gl_att.color[0] + v->gl_att.color[1] + v->gl_att.color[2] + v->gl_att.color[3]; buffer_size &= ~7; // synch some parameters between OpenGL and SDL v->depth = buffer_size; v->gl_att.buffer_size = buffer_size; v->gl_att.doublebuffer = v->flags.double_buf ? SDL_TRUE : SDL_FALSE; // the GL_ATTRIB_* parameters must be set before opening the video mode SDLX_set_sdl_gl_attrib( v ); // set the flags flags = SDLX_upload_sdl_video_flags( v->flags ); // try a softer video initialization // if it fails, then it tries to get the closest possible valid video mode ret = NULL; sdl_nearset_bpp = SDL_VideoModeOK( v->width, v->height, buffer_size, flags ); if ( 0 != sdl_nearset_bpp ) { ret = SDL_SetVideoMode( v->width, v->height, sdl_nearset_bpp, flags ); if ( NULL == ret ) { fprintf( LOCAL_STDOUT, "SDL WARN: Unable to set SDL video mode: %s\n", SDL_GetError() ); } } #if !defined(__unix__) { int actual_multi_buffers = 0; // ignored in linux // attempt to see if our antialiasing setting is valid SDL_GL_GetAttribute( SDL_GL_MULTISAMPLEBUFFERS, &actual_multi_buffers ); if ( v->gl_att.multi_samples > 0 && 0 == actual_multi_buffers ) { // could not create the multi-buffer with this pixel format // i.e. cross-platform equivalent of the vectors wglChoosePixelFormatARB and // wglGetPixelFormatAttribivARB could not be found // // This is the only feedback we have that the initialization failed // // we will try to reduce the amount of super sampling and try again v->gl_att.multi_samples -= 1; while ( v->gl_att.multi_samples > 1 && 0 == actual_multi_buffers ) { v->gl_att.multi_buffers = 1; SDLX_set_sdl_gl_attrib( v ); sdl_nearset_bpp = SDL_VideoModeOK( v->width, v->height, buffer_size, flags ); if ( 0 != sdl_nearset_bpp ) { ret = SDL_SetVideoMode( v->width, v->height, sdl_nearset_bpp, flags ); if ( NULL == ret ) { fprintf( LOCAL_STDOUT, "SDL WARN: Unable to set SDL video mode: %s\n", SDL_GetError() ); } } actual_multi_buffers = 0; SDL_GL_GetAttribute( SDL_GL_MULTISAMPLEBUFFERS, &actual_multi_buffers ); v->gl_att.multi_samples -= 1; } } } #endif if ( NULL == ret ) { // something is interfering with our ability to generate a screen. // assume that it is a complete incompatability with multisampling SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 0 ); SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, 0 ); sdl_nearset_bpp = SDL_VideoModeOK( v->width, v->height, buffer_size, flags ); if ( 0 != sdl_nearset_bpp ) { ret = SDL_SetVideoMode( v->width, v->height, sdl_nearset_bpp, flags ); if ( NULL == ret ) { fprintf( LOCAL_STDOUT, "SDL WARN: Unable to set SDL video mode: %s\n", SDL_GetError() ); } } } #if !defined(__unix__) // grab the actual status of the multi_buffers and multi_samples v->gl_att.multi_buffers = 0; v->gl_att.multi_samples = 0; v->gl_att.accelerated_visual = SDL_FALSE; SDL_GL_GetAttribute( SDL_GL_MULTISAMPLEBUFFERS, &( v->gl_att.multi_buffers ) ); SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &( v->gl_att.multi_samples ) ); SDL_GL_GetAttribute( SDL_GL_ACCELERATED_VISUAL, &( v->gl_att.accelerated_visual ) ); #endif } // update the video parameters if ( NULL != ret ) { SDLX_Get_Screen_Info( &sdl_scr, make_report ); SDLX_synch_video_parameters( ret, v ); } return ret; }