mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-06-02 01:31:45 +00:00
Moved OpenGL initialization to GL backend
This commit is contained in:
parent
3d9f9b75db
commit
bca006b8fc
4 changed files with 452 additions and 615 deletions
|
@ -247,7 +247,6 @@ On exit, the idImage will have a valid OpenGL texture number that can be bound
|
||||||
*/
|
*/
|
||||||
void idImage::ActuallyLoadImage( bool fromBackEnd )
|
void idImage::ActuallyLoadImage( bool fromBackEnd )
|
||||||
{
|
{
|
||||||
|
|
||||||
// if we don't have a rendering context yet, just return
|
// if we don't have a rendering context yet, just return
|
||||||
if( !R_IsInitialized() )
|
if( !R_IsInitialized() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -116,8 +116,447 @@ bool GL_CheckErrors_( const char* filename, int line )
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool r_initialized = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============================
|
||||||
|
R_IsInitialized
|
||||||
|
=============================
|
||||||
|
*/
|
||||||
|
bool R_IsInitialized()
|
||||||
|
{
|
||||||
|
return r_initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
DebugCallback
|
||||||
|
|
||||||
|
For ARB_debug_output
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
// RB: added const to userParam
|
||||||
|
static void CALLBACK DebugCallback( unsigned int source, unsigned int type,
|
||||||
|
unsigned int id, unsigned int severity, int length, const char* message, const void* userParam )
|
||||||
|
{
|
||||||
|
// it probably isn't safe to do an idLib::Printf at this point
|
||||||
|
|
||||||
|
// RB: printf should be thread safe on Linux
|
||||||
|
#if defined(_WIN32)
|
||||||
|
OutputDebugString( message );
|
||||||
|
OutputDebugString( "\n" );
|
||||||
|
#else
|
||||||
|
printf( "%s\n", message );
|
||||||
|
#endif
|
||||||
|
// RB end
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
R_CheckPortableExtensions
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
// RB: replaced QGL with GLEW
|
||||||
|
static void R_CheckPortableExtensions()
|
||||||
|
{
|
||||||
|
glConfig.glVersion = atof( glConfig.version_string );
|
||||||
|
const char* badVideoCard = idLocalization::GetString( "#str_06780" );
|
||||||
|
if( glConfig.glVersion < 2.0f )
|
||||||
|
{
|
||||||
|
idLib::FatalError( "%s", badVideoCard );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( idStr::Icmpn( glConfig.renderer_string, "ATI ", 4 ) == 0 || idStr::Icmpn( glConfig.renderer_string, "AMD ", 4 ) == 0 )
|
||||||
|
{
|
||||||
|
glConfig.vendor = VENDOR_AMD;
|
||||||
|
}
|
||||||
|
else if( idStr::Icmpn( glConfig.renderer_string, "NVIDIA", 6 ) == 0 )
|
||||||
|
{
|
||||||
|
glConfig.vendor = VENDOR_NVIDIA;
|
||||||
|
}
|
||||||
|
else if( idStr::Icmpn( glConfig.renderer_string, "Intel", 5 ) == 0 )
|
||||||
|
{
|
||||||
|
glConfig.vendor = VENDOR_INTEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RB: Mesa support
|
||||||
|
if( idStr::Icmpn( glConfig.renderer_string, "Mesa", 4 ) == 0 || idStr::Icmpn( glConfig.renderer_string, "X.org", 5 ) == 0 || idStr::Icmpn( glConfig.renderer_string, "Gallium", 7 ) == 0 ||
|
||||||
|
strcmp( glConfig.vendor_string, "X.Org" ) == 0 ||
|
||||||
|
idStr::Icmpn( glConfig.renderer_string, "llvmpipe", 8 ) == 0 )
|
||||||
|
{
|
||||||
|
if( glConfig.driverType == GLDRV_OPENGL32_CORE_PROFILE )
|
||||||
|
{
|
||||||
|
glConfig.driverType = GLDRV_OPENGL_MESA_CORE_PROFILE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glConfig.driverType = GLDRV_OPENGL_MESA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// RB end
|
||||||
|
|
||||||
|
// GL_ARB_multitexture
|
||||||
|
if( glConfig.driverType != GLDRV_OPENGL3X )
|
||||||
|
{
|
||||||
|
glConfig.multitextureAvailable = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glConfig.multitextureAvailable = GLEW_ARB_multitexture != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GL_EXT_direct_state_access
|
||||||
|
glConfig.directStateAccess = GLEW_EXT_direct_state_access != 0;
|
||||||
|
|
||||||
|
|
||||||
|
// GL_ARB_texture_compression + GL_S3_s3tc
|
||||||
|
// DRI drivers may have GL_ARB_texture_compression but no GL_EXT_texture_compression_s3tc
|
||||||
|
if( glConfig.driverType == GLDRV_OPENGL_MESA_CORE_PROFILE )
|
||||||
|
{
|
||||||
|
glConfig.textureCompressionAvailable = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glConfig.textureCompressionAvailable = GLEW_ARB_texture_compression != 0 && GLEW_EXT_texture_compression_s3tc != 0;
|
||||||
|
}
|
||||||
|
// GL_EXT_texture_filter_anisotropic
|
||||||
|
glConfig.anisotropicFilterAvailable = GLEW_EXT_texture_filter_anisotropic != 0;
|
||||||
|
if( glConfig.anisotropicFilterAvailable )
|
||||||
|
{
|
||||||
|
glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig.maxTextureAnisotropy );
|
||||||
|
common->Printf( " maxTextureAnisotropy: %f\n", glConfig.maxTextureAnisotropy );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glConfig.maxTextureAnisotropy = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GL_EXT_texture_lod_bias
|
||||||
|
// The actual extension is broken as specificed, storing the state in the texture unit instead
|
||||||
|
// of the texture object. The behavior in GL 1.4 is the behavior we use.
|
||||||
|
glConfig.textureLODBiasAvailable = ( glConfig.glVersion >= 1.4 || GLEW_EXT_texture_lod_bias != 0 );
|
||||||
|
if( glConfig.textureLODBiasAvailable )
|
||||||
|
{
|
||||||
|
common->Printf( "...using %s\n", "GL_EXT_texture_lod_bias" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
common->Printf( "X..%s not found\n", "GL_EXT_texture_lod_bias" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// GL_ARB_seamless_cube_map
|
||||||
|
glConfig.seamlessCubeMapAvailable = GLEW_ARB_seamless_cube_map != 0;
|
||||||
|
r_useSeamlessCubeMap.SetModified(); // the CheckCvars() next frame will enable / disable it
|
||||||
|
|
||||||
|
// GL_ARB_framebuffer_sRGB
|
||||||
|
glConfig.sRGBFramebufferAvailable = GLEW_ARB_framebuffer_sRGB != 0;
|
||||||
|
r_useSRGB.SetModified(); // the CheckCvars() next frame will enable / disable it
|
||||||
|
|
||||||
|
// GL_ARB_vertex_buffer_object
|
||||||
|
if( glConfig.driverType == GLDRV_OPENGL_MESA_CORE_PROFILE )
|
||||||
|
{
|
||||||
|
glConfig.vertexBufferObjectAvailable = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glConfig.vertexBufferObjectAvailable = GLEW_ARB_vertex_buffer_object != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GL_ARB_map_buffer_range, map a section of a buffer object's data store
|
||||||
|
//if( glConfig.driverType == GLDRV_OPENGL_MESA_CORE_PROFILE )
|
||||||
|
//{
|
||||||
|
// glConfig.mapBufferRangeAvailable = true;
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
{
|
||||||
|
glConfig.mapBufferRangeAvailable = GLEW_ARB_map_buffer_range != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GL_ARB_vertex_array_object
|
||||||
|
//if( glConfig.driverType == GLDRV_OPENGL_MESA_CORE_PROFILE )
|
||||||
|
//{
|
||||||
|
// glConfig.vertexArrayObjectAvailable = true;
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
{
|
||||||
|
glConfig.vertexArrayObjectAvailable = GLEW_ARB_vertex_array_object != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GL_ARB_draw_elements_base_vertex
|
||||||
|
glConfig.drawElementsBaseVertexAvailable = GLEW_ARB_draw_elements_base_vertex != 0;
|
||||||
|
|
||||||
|
// GL_ARB_vertex_program / GL_ARB_fragment_program
|
||||||
|
glConfig.fragmentProgramAvailable = GLEW_ARB_fragment_program != 0;
|
||||||
|
//if( glConfig.fragmentProgramAvailable )
|
||||||
|
{
|
||||||
|
glGetIntegerv( GL_MAX_TEXTURE_COORDS, ( GLint* )&glConfig.maxTextureCoords );
|
||||||
|
glGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS, ( GLint* )&glConfig.maxTextureImageUnits );
|
||||||
|
}
|
||||||
|
|
||||||
|
// GLSL, core in OpenGL > 2.0
|
||||||
|
glConfig.glslAvailable = ( glConfig.glVersion >= 2.0f );
|
||||||
|
|
||||||
|
// GL_ARB_uniform_buffer_object
|
||||||
|
glConfig.uniformBufferAvailable = GLEW_ARB_uniform_buffer_object != 0;
|
||||||
|
if( glConfig.uniformBufferAvailable )
|
||||||
|
{
|
||||||
|
glGetIntegerv( GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, ( GLint* )&glConfig.uniformBufferOffsetAlignment );
|
||||||
|
if( glConfig.uniformBufferOffsetAlignment < 256 )
|
||||||
|
{
|
||||||
|
glConfig.uniformBufferOffsetAlignment = 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// RB: make GPU skinning optional for weak OpenGL drivers
|
||||||
|
glConfig.gpuSkinningAvailable = glConfig.uniformBufferAvailable && ( glConfig.driverType == GLDRV_OPENGL3X || glConfig.driverType == GLDRV_OPENGL32_CORE_PROFILE || glConfig.driverType == GLDRV_OPENGL32_COMPATIBILITY_PROFILE );
|
||||||
|
|
||||||
|
// ATI_separate_stencil / OpenGL 2.0 separate stencil
|
||||||
|
glConfig.twoSidedStencilAvailable = ( glConfig.glVersion >= 2.0f ) || GLEW_ATI_separate_stencil != 0;
|
||||||
|
|
||||||
|
// GL_EXT_depth_bounds_test
|
||||||
|
glConfig.depthBoundsTestAvailable = GLEW_EXT_depth_bounds_test != 0;
|
||||||
|
|
||||||
|
// GL_ARB_sync
|
||||||
|
glConfig.syncAvailable = GLEW_ARB_sync &&
|
||||||
|
// as of 5/24/2012 (driver version 15.26.12.64.2761) sync objects
|
||||||
|
// do not appear to work for the Intel HD 4000 graphics
|
||||||
|
( glConfig.vendor != VENDOR_INTEL || r_skipIntelWorkarounds.GetBool() );
|
||||||
|
|
||||||
|
// GL_ARB_occlusion_query
|
||||||
|
glConfig.occlusionQueryAvailable = GLEW_ARB_occlusion_query != 0;
|
||||||
|
|
||||||
|
// GL_ARB_timer_query
|
||||||
|
glConfig.timerQueryAvailable = ( GLEW_ARB_timer_query != 0 || GLEW_EXT_timer_query != 0 ) && ( glConfig.vendor != VENDOR_INTEL || r_skipIntelWorkarounds.GetBool() ) && glConfig.driverType != GLDRV_OPENGL_MESA;
|
||||||
|
|
||||||
|
// GREMEDY_string_marker
|
||||||
|
glConfig.gremedyStringMarkerAvailable = GLEW_GREMEDY_string_marker != 0;
|
||||||
|
if( glConfig.gremedyStringMarkerAvailable )
|
||||||
|
{
|
||||||
|
common->Printf( "...using %s\n", "GL_GREMEDY_string_marker" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
common->Printf( "X..%s not found\n", "GL_GREMEDY_string_marker" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// GL_ARB_framebuffer_object
|
||||||
|
glConfig.framebufferObjectAvailable = GLEW_ARB_framebuffer_object != 0;
|
||||||
|
if( glConfig.framebufferObjectAvailable )
|
||||||
|
{
|
||||||
|
glGetIntegerv( GL_MAX_RENDERBUFFER_SIZE, &glConfig.maxRenderbufferSize );
|
||||||
|
glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS, &glConfig.maxColorAttachments );
|
||||||
|
|
||||||
|
common->Printf( "...using %s\n", "GL_ARB_framebuffer_object" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
common->Printf( "X..%s not found\n", "GL_ARB_framebuffer_object" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// GL_EXT_framebuffer_blit
|
||||||
|
glConfig.framebufferBlitAvailable = GLEW_EXT_framebuffer_blit != 0;
|
||||||
|
if( glConfig.framebufferBlitAvailable )
|
||||||
|
{
|
||||||
|
common->Printf( "...using %s\n", "GL_EXT_framebuffer_blit" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
common->Printf( "X..%s not found\n", "GL_EXT_framebuffer_blit" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// GL_ARB_debug_output
|
||||||
|
glConfig.debugOutputAvailable = GLEW_ARB_debug_output != 0;
|
||||||
|
if( glConfig.debugOutputAvailable )
|
||||||
|
{
|
||||||
|
if( r_debugContext.GetInteger() >= 1 )
|
||||||
|
{
|
||||||
|
glDebugMessageCallbackARB( ( GLDEBUGPROCARB ) DebugCallback, NULL );
|
||||||
|
}
|
||||||
|
if( r_debugContext.GetInteger() >= 2 )
|
||||||
|
{
|
||||||
|
// force everything to happen in the main thread instead of in a separate driver thread
|
||||||
|
glEnable( GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB );
|
||||||
|
}
|
||||||
|
if( r_debugContext.GetInteger() >= 3 )
|
||||||
|
{
|
||||||
|
// enable all the low priority messages
|
||||||
|
glDebugMessageControlARB( GL_DONT_CARE,
|
||||||
|
GL_DONT_CARE,
|
||||||
|
GL_DEBUG_SEVERITY_LOW_ARB,
|
||||||
|
0, NULL, true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GL_ARB_multitexture
|
||||||
|
if( !glConfig.multitextureAvailable )
|
||||||
|
{
|
||||||
|
idLib::Error( "GL_ARB_multitexture not available" );
|
||||||
|
}
|
||||||
|
// GL_ARB_texture_compression + GL_EXT_texture_compression_s3tc
|
||||||
|
if( !glConfig.textureCompressionAvailable )
|
||||||
|
{
|
||||||
|
idLib::Error( "GL_ARB_texture_compression or GL_EXT_texture_compression_s3tc not available" );
|
||||||
|
}
|
||||||
|
// GL_ARB_vertex_buffer_object
|
||||||
|
if( !glConfig.vertexBufferObjectAvailable )
|
||||||
|
{
|
||||||
|
idLib::Error( "GL_ARB_vertex_buffer_object not available" );
|
||||||
|
}
|
||||||
|
// GL_ARB_map_buffer_range
|
||||||
|
if( !glConfig.mapBufferRangeAvailable )
|
||||||
|
{
|
||||||
|
idLib::Error( "GL_ARB_map_buffer_range not available" );
|
||||||
|
}
|
||||||
|
// GL_ARB_vertex_array_object
|
||||||
|
if( !glConfig.vertexArrayObjectAvailable )
|
||||||
|
{
|
||||||
|
idLib::Error( "GL_ARB_vertex_array_object not available" );
|
||||||
|
}
|
||||||
|
// GL_ARB_draw_elements_base_vertex
|
||||||
|
if( !glConfig.drawElementsBaseVertexAvailable )
|
||||||
|
{
|
||||||
|
idLib::Error( "GL_ARB_draw_elements_base_vertex not available" );
|
||||||
|
}
|
||||||
|
// GL_ARB_vertex_program / GL_ARB_fragment_program
|
||||||
|
//if( !glConfig.fragmentProgramAvailable )
|
||||||
|
//{
|
||||||
|
// idLib::Warning( "GL_ARB_fragment_program not available" );
|
||||||
|
//}
|
||||||
|
// GLSL
|
||||||
|
if( !glConfig.glslAvailable )
|
||||||
|
{
|
||||||
|
idLib::Error( "GLSL not available" );
|
||||||
|
}
|
||||||
|
// GL_ARB_uniform_buffer_object
|
||||||
|
if( !glConfig.uniformBufferAvailable )
|
||||||
|
{
|
||||||
|
idLib::Error( "GL_ARB_uniform_buffer_object not available" );
|
||||||
|
}
|
||||||
|
// GL_EXT_stencil_two_side
|
||||||
|
if( !glConfig.twoSidedStencilAvailable )
|
||||||
|
{
|
||||||
|
idLib::Error( "GL_ATI_separate_stencil not available" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate one global Vertex Array Object (VAO)
|
||||||
|
glGenVertexArrays( 1, &glConfig.global_vao );
|
||||||
|
glBindVertexArray( glConfig.global_vao );
|
||||||
|
}
|
||||||
// RB end
|
// RB end
|
||||||
|
|
||||||
|
idStr extensions_string;
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
R_InitOpenGL
|
||||||
|
|
||||||
|
This function is responsible for initializing a valid OpenGL subsystem
|
||||||
|
for rendering. This is done by calling the system specific GLimp_Init,
|
||||||
|
which gives us a working OGL subsystem, then setting all necessary openGL
|
||||||
|
state, including images, vertex programs, and display lists.
|
||||||
|
|
||||||
|
Changes to the vertex cache size or smp state require a vid_restart.
|
||||||
|
|
||||||
|
If R_IsInitialized() is false, no rendering can take place, but
|
||||||
|
all renderSystem functions will still operate properly, notably the material
|
||||||
|
and model information functions.
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
void idRenderBackend::Init()
|
||||||
|
{
|
||||||
|
common->Printf( "----- R_InitOpenGL -----\n" );
|
||||||
|
|
||||||
|
if( R_IsInitialized() )
|
||||||
|
{
|
||||||
|
common->FatalError( "R_InitOpenGL called while active" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// DG: make sure SDL has setup video so getting supported modes in R_SetNewMode() works
|
||||||
|
GLimp_PreInit();
|
||||||
|
// DG end
|
||||||
|
|
||||||
|
R_SetNewMode( true );
|
||||||
|
|
||||||
|
// input and sound systems need to be tied to the new window
|
||||||
|
Sys_InitInput();
|
||||||
|
|
||||||
|
// get our config strings
|
||||||
|
glConfig.vendor_string = ( const char* )glGetString( GL_VENDOR );
|
||||||
|
glConfig.renderer_string = ( const char* )glGetString( GL_RENDERER );
|
||||||
|
glConfig.version_string = ( const char* )glGetString( GL_VERSION );
|
||||||
|
glConfig.shading_language_string = ( const char* )glGetString( GL_SHADING_LANGUAGE_VERSION );
|
||||||
|
glConfig.extensions_string = ( const char* )glGetString( GL_EXTENSIONS );
|
||||||
|
|
||||||
|
if( glConfig.extensions_string == NULL )
|
||||||
|
{
|
||||||
|
// As of OpenGL 3.2, glGetStringi is required to obtain the available extensions
|
||||||
|
//glGetStringi = ( PFNGLGETSTRINGIPROC )GLimp_ExtensionPointer( "glGetStringi" );
|
||||||
|
|
||||||
|
// Build the extensions string
|
||||||
|
GLint numExtensions;
|
||||||
|
glGetIntegerv( GL_NUM_EXTENSIONS, &numExtensions );
|
||||||
|
extensions_string.Clear();
|
||||||
|
for( int i = 0; i < numExtensions; i++ )
|
||||||
|
{
|
||||||
|
extensions_string.Append( ( const char* )glGetStringi( GL_EXTENSIONS, i ) );
|
||||||
|
// the now deprecated glGetString method usaed to create a single string with each extension separated by a space
|
||||||
|
if( i < numExtensions - 1 )
|
||||||
|
{
|
||||||
|
extensions_string.Append( ' ' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glConfig.extensions_string = extensions_string.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float glVersion = atof( glConfig.version_string );
|
||||||
|
float glslVersion = atof( glConfig.shading_language_string );
|
||||||
|
idLib::Printf( "OpenGL Version : %3.1f\n", glVersion );
|
||||||
|
idLib::Printf( "OpenGL Vendor : %s\n", glConfig.vendor_string );
|
||||||
|
idLib::Printf( "OpenGL Renderer : %s\n", glConfig.renderer_string );
|
||||||
|
idLib::Printf( "OpenGL GLSL : %3.1f\n", glslVersion );
|
||||||
|
idLib::Printf( "OpenGL Extensions: %s\n", glConfig.extensions_string );
|
||||||
|
|
||||||
|
// OpenGL driver constants
|
||||||
|
GLint temp;
|
||||||
|
glGetIntegerv( GL_MAX_TEXTURE_SIZE, &temp );
|
||||||
|
glConfig.maxTextureSize = temp;
|
||||||
|
|
||||||
|
// stubbed or broken drivers may have reported 0...
|
||||||
|
if( glConfig.maxTextureSize <= 0 )
|
||||||
|
{
|
||||||
|
glConfig.maxTextureSize = 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
r_initialized = true;
|
||||||
|
|
||||||
|
// recheck all the extensions (FIXME: this might be dangerous)
|
||||||
|
R_CheckPortableExtensions();
|
||||||
|
|
||||||
|
renderProgManager.Init();
|
||||||
|
|
||||||
|
r_initialized = true;
|
||||||
|
|
||||||
|
// allocate the vertex array range or vertex objects
|
||||||
|
vertexCache.Init( glConfig.uniformBufferOffsetAlignment );
|
||||||
|
|
||||||
|
// allocate the frame data, which may be more if smp is enabled
|
||||||
|
R_InitFrameData();
|
||||||
|
|
||||||
|
// Reset our gamma
|
||||||
|
R_SetColorMappings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void idRenderBackend::Shutdown()
|
||||||
|
{
|
||||||
|
GLimp_Shutdown();
|
||||||
|
r_initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============
|
=============
|
||||||
idRenderBackend::DrawElementsWithCounters
|
idRenderBackend::DrawElementsWithCounters
|
||||||
|
@ -986,7 +1425,6 @@ void idRenderBackend::CheckCVars()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern idCVar r_useSeamlessCubeMap;
|
|
||||||
if( r_useSeamlessCubeMap.IsModified() )
|
if( r_useSeamlessCubeMap.IsModified() )
|
||||||
{
|
{
|
||||||
r_useSeamlessCubeMap.ClearModified();
|
r_useSeamlessCubeMap.ClearModified();
|
||||||
|
@ -1003,7 +1441,6 @@ void idRenderBackend::CheckCVars()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern idCVar r_useSRGB;
|
|
||||||
if( r_useSRGB.IsModified() )
|
if( r_useSRGB.IsModified() )
|
||||||
{
|
{
|
||||||
r_useSRGB.ClearModified();
|
r_useSRGB.ClearModified();
|
||||||
|
@ -1412,7 +1849,8 @@ idRenderBackend::idRenderBackend
|
||||||
*/
|
*/
|
||||||
idRenderBackend::idRenderBackend()
|
idRenderBackend::idRenderBackend()
|
||||||
{
|
{
|
||||||
Init();
|
memset( glcontext.tmu, 0, sizeof( glcontext.tmu ) );
|
||||||
|
memset( glcontext.stencilOperations, 0, sizeof( glcontext.stencilOperations ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1425,17 +1863,6 @@ idRenderBackend::~idRenderBackend()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
=============
|
|
||||||
idRenderBackend::Init
|
|
||||||
=============
|
|
||||||
*/
|
|
||||||
void idRenderBackend::Init()
|
|
||||||
{
|
|
||||||
memset( glcontext.tmu, 0, sizeof( glcontext.tmu ) );
|
|
||||||
memset( glcontext.stencilOperations, 0, sizeof( glcontext.stencilOperations ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
====================
|
====================
|
||||||
R_MakeStereoRenderImage
|
R_MakeStereoRenderImage
|
||||||
|
|
|
@ -858,6 +858,11 @@ extern glconfig_t glConfig; // outside of TR since it shouldn't be cleared du
|
||||||
//
|
//
|
||||||
// cvars
|
// cvars
|
||||||
//
|
//
|
||||||
|
extern idCVar r_windowX;
|
||||||
|
extern idCVar r_windowY;
|
||||||
|
extern idCVar r_windowWidth;
|
||||||
|
extern idCVar r_windowHeight;
|
||||||
|
|
||||||
extern idCVar r_debugContext; // enable various levels of context debug
|
extern idCVar r_debugContext; // enable various levels of context debug
|
||||||
extern idCVar r_glDriver; // "opengl32", etc
|
extern idCVar r_glDriver; // "opengl32", etc
|
||||||
extern idCVar r_skipIntelWorkarounds; // skip work arounds for Intel driver bugs
|
extern idCVar r_skipIntelWorkarounds; // skip work arounds for Intel driver bugs
|
||||||
|
@ -909,6 +914,7 @@ extern idCVar r_useShadowMapping; // use shadow mapping instead of stencil sha
|
||||||
extern idCVar r_useHalfLambertLighting; // use Half-Lambert lighting instead of classic Lambert
|
extern idCVar r_useHalfLambertLighting; // use Half-Lambert lighting instead of classic Lambert
|
||||||
extern idCVar r_useHDR;
|
extern idCVar r_useHDR;
|
||||||
extern idCVar r_useSRGB;
|
extern idCVar r_useSRGB;
|
||||||
|
extern idCVar r_useSeamlessCubeMap;
|
||||||
// RB end
|
// RB end
|
||||||
|
|
||||||
extern idCVar r_skipStaticInteractions; // skip interactions created at level load
|
extern idCVar r_skipStaticInteractions; // skip interactions created at level load
|
||||||
|
@ -1001,6 +1007,7 @@ extern idCVar r_materialOverride; // override all materials
|
||||||
|
|
||||||
extern idCVar r_debugRenderToTexture;
|
extern idCVar r_debugRenderToTexture;
|
||||||
|
|
||||||
|
extern idCVar stereoRender_enable;
|
||||||
extern idCVar stereoRender_deGhost; // subtract from opposite eye to reduce ghosting
|
extern idCVar stereoRender_deGhost; // subtract from opposite eye to reduce ghosting
|
||||||
|
|
||||||
extern idCVar r_useGPUSkinning;
|
extern idCVar r_useGPUSkinning;
|
||||||
|
@ -1059,8 +1066,7 @@ INITIALIZATION
|
||||||
====================================================================
|
====================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void R_Init();
|
void R_SetNewMode( const bool fullInit );
|
||||||
void R_InitOpenGL();
|
|
||||||
|
|
||||||
void R_SetColorMappings();
|
void R_SetColorMappings();
|
||||||
|
|
||||||
|
|
|
@ -286,386 +286,10 @@ const char* envDirection[6] = { "_px", "_nx", "_py", "_ny", "_pz", "_nz" };
|
||||||
const char* skyDirection[6] = { "_forward", "_back", "_left", "_right", "_up", "_down" };
|
const char* skyDirection[6] = { "_forward", "_back", "_left", "_right", "_up", "_down" };
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
========================
|
|
||||||
glBindMultiTextureEXT
|
|
||||||
|
|
||||||
As of 2011/09/16 the Intel drivers for "Sandy Bridge" and "Ivy Bridge" integrated graphics do not support this extension.
|
|
||||||
========================
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
void APIENTRY glBindMultiTextureEXT( GLenum texunit, GLenum target, GLuint texture )
|
|
||||||
{
|
|
||||||
glActiveTextureARB( texunit );
|
|
||||||
glBindTexture( target, texture );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
=================
|
|
||||||
R_CheckExtension
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
// RB begin
|
|
||||||
static bool R_CheckExtension( const char* name )
|
|
||||||
// RB end
|
|
||||||
{
|
|
||||||
if( !strstr( glConfig.extensions_string, name ) )
|
|
||||||
{
|
|
||||||
common->Printf( "X..%s not found\n", name );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
common->Printf( "...using %s\n", name );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
========================
|
|
||||||
DebugCallback
|
|
||||||
|
|
||||||
For ARB_debug_output
|
|
||||||
========================
|
|
||||||
*/
|
|
||||||
// RB: added const to userParam
|
|
||||||
static void CALLBACK DebugCallback( unsigned int source, unsigned int type,
|
|
||||||
unsigned int id, unsigned int severity, int length, const char* message, const void* userParam )
|
|
||||||
{
|
|
||||||
// it probably isn't safe to do an idLib::Printf at this point
|
|
||||||
|
|
||||||
// RB: printf should be thread safe on Linux
|
|
||||||
#if defined(_WIN32)
|
|
||||||
OutputDebugString( message );
|
|
||||||
OutputDebugString( "\n" );
|
|
||||||
#else
|
|
||||||
printf( "%s\n", message );
|
|
||||||
#endif
|
|
||||||
// RB end
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
=================
|
|
||||||
R_CheckExtension
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
bool R_CheckExtension( char* name )
|
|
||||||
{
|
|
||||||
if( !strstr( glConfig.extensions_string, name ) )
|
|
||||||
{
|
|
||||||
common->Printf( "X..%s not found\n", name );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
common->Printf( "...using %s\n", name );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
==================
|
|
||||||
R_CheckPortableExtensions
|
|
||||||
==================
|
|
||||||
*/
|
|
||||||
// RB: replaced QGL with GLEW
|
|
||||||
static void R_CheckPortableExtensions()
|
|
||||||
{
|
|
||||||
glConfig.glVersion = atof( glConfig.version_string );
|
|
||||||
const char* badVideoCard = idLocalization::GetString( "#str_06780" );
|
|
||||||
if( glConfig.glVersion < 2.0f )
|
|
||||||
{
|
|
||||||
idLib::FatalError( "%s", badVideoCard );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( idStr::Icmpn( glConfig.renderer_string, "ATI ", 4 ) == 0 || idStr::Icmpn( glConfig.renderer_string, "AMD ", 4 ) == 0 )
|
|
||||||
{
|
|
||||||
glConfig.vendor = VENDOR_AMD;
|
|
||||||
}
|
|
||||||
else if( idStr::Icmpn( glConfig.renderer_string, "NVIDIA", 6 ) == 0 )
|
|
||||||
{
|
|
||||||
glConfig.vendor = VENDOR_NVIDIA;
|
|
||||||
}
|
|
||||||
else if( idStr::Icmpn( glConfig.renderer_string, "Intel", 5 ) == 0 )
|
|
||||||
{
|
|
||||||
glConfig.vendor = VENDOR_INTEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// RB: Mesa support
|
|
||||||
if( idStr::Icmpn( glConfig.renderer_string, "Mesa", 4 ) == 0 || idStr::Icmpn( glConfig.renderer_string, "X.org", 5 ) == 0 || idStr::Icmpn( glConfig.renderer_string, "Gallium", 7 ) == 0 ||
|
|
||||||
strcmp( glConfig.vendor_string, "X.Org" ) == 0 ||
|
|
||||||
idStr::Icmpn( glConfig.renderer_string, "llvmpipe", 8 ) == 0 )
|
|
||||||
{
|
|
||||||
if( glConfig.driverType == GLDRV_OPENGL32_CORE_PROFILE )
|
|
||||||
{
|
|
||||||
glConfig.driverType = GLDRV_OPENGL_MESA_CORE_PROFILE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glConfig.driverType = GLDRV_OPENGL_MESA;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// RB end
|
|
||||||
|
|
||||||
// GL_ARB_multitexture
|
|
||||||
if( glConfig.driverType != GLDRV_OPENGL3X )
|
|
||||||
{
|
|
||||||
glConfig.multitextureAvailable = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glConfig.multitextureAvailable = GLEW_ARB_multitexture != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GL_EXT_direct_state_access
|
|
||||||
glConfig.directStateAccess = GLEW_EXT_direct_state_access != 0;
|
|
||||||
|
|
||||||
|
|
||||||
// GL_ARB_texture_compression + GL_S3_s3tc
|
|
||||||
// DRI drivers may have GL_ARB_texture_compression but no GL_EXT_texture_compression_s3tc
|
|
||||||
if( glConfig.driverType == GLDRV_OPENGL_MESA_CORE_PROFILE )
|
|
||||||
{
|
|
||||||
glConfig.textureCompressionAvailable = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glConfig.textureCompressionAvailable = GLEW_ARB_texture_compression != 0 && GLEW_EXT_texture_compression_s3tc != 0;
|
|
||||||
}
|
|
||||||
// GL_EXT_texture_filter_anisotropic
|
|
||||||
glConfig.anisotropicFilterAvailable = GLEW_EXT_texture_filter_anisotropic != 0;
|
|
||||||
if( glConfig.anisotropicFilterAvailable )
|
|
||||||
{
|
|
||||||
glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig.maxTextureAnisotropy );
|
|
||||||
common->Printf( " maxTextureAnisotropy: %f\n", glConfig.maxTextureAnisotropy );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glConfig.maxTextureAnisotropy = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GL_EXT_texture_lod_bias
|
|
||||||
// The actual extension is broken as specificed, storing the state in the texture unit instead
|
|
||||||
// of the texture object. The behavior in GL 1.4 is the behavior we use.
|
|
||||||
glConfig.textureLODBiasAvailable = ( glConfig.glVersion >= 1.4 || GLEW_EXT_texture_lod_bias != 0 );
|
|
||||||
if( glConfig.textureLODBiasAvailable )
|
|
||||||
{
|
|
||||||
common->Printf( "...using %s\n", "GL_EXT_texture_lod_bias" );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
common->Printf( "X..%s not found\n", "GL_EXT_texture_lod_bias" );
|
|
||||||
}
|
|
||||||
|
|
||||||
// GL_ARB_seamless_cube_map
|
|
||||||
glConfig.seamlessCubeMapAvailable = GLEW_ARB_seamless_cube_map != 0;
|
|
||||||
r_useSeamlessCubeMap.SetModified(); // the CheckCvars() next frame will enable / disable it
|
|
||||||
|
|
||||||
// GL_ARB_framebuffer_sRGB
|
|
||||||
glConfig.sRGBFramebufferAvailable = GLEW_ARB_framebuffer_sRGB != 0;
|
|
||||||
r_useSRGB.SetModified(); // the CheckCvars() next frame will enable / disable it
|
|
||||||
|
|
||||||
// GL_ARB_vertex_buffer_object
|
|
||||||
if( glConfig.driverType == GLDRV_OPENGL_MESA_CORE_PROFILE )
|
|
||||||
{
|
|
||||||
glConfig.vertexBufferObjectAvailable = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glConfig.vertexBufferObjectAvailable = GLEW_ARB_vertex_buffer_object != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GL_ARB_map_buffer_range, map a section of a buffer object's data store
|
|
||||||
//if( glConfig.driverType == GLDRV_OPENGL_MESA_CORE_PROFILE )
|
|
||||||
//{
|
|
||||||
// glConfig.mapBufferRangeAvailable = true;
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
{
|
|
||||||
glConfig.mapBufferRangeAvailable = GLEW_ARB_map_buffer_range != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GL_ARB_vertex_array_object
|
|
||||||
//if( glConfig.driverType == GLDRV_OPENGL_MESA_CORE_PROFILE )
|
|
||||||
//{
|
|
||||||
// glConfig.vertexArrayObjectAvailable = true;
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
{
|
|
||||||
glConfig.vertexArrayObjectAvailable = GLEW_ARB_vertex_array_object != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GL_ARB_draw_elements_base_vertex
|
|
||||||
glConfig.drawElementsBaseVertexAvailable = GLEW_ARB_draw_elements_base_vertex != 0;
|
|
||||||
|
|
||||||
// GL_ARB_vertex_program / GL_ARB_fragment_program
|
|
||||||
glConfig.fragmentProgramAvailable = GLEW_ARB_fragment_program != 0;
|
|
||||||
//if( glConfig.fragmentProgramAvailable )
|
|
||||||
{
|
|
||||||
glGetIntegerv( GL_MAX_TEXTURE_COORDS, ( GLint* )&glConfig.maxTextureCoords );
|
|
||||||
glGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS, ( GLint* )&glConfig.maxTextureImageUnits );
|
|
||||||
}
|
|
||||||
|
|
||||||
// GLSL, core in OpenGL > 2.0
|
|
||||||
glConfig.glslAvailable = ( glConfig.glVersion >= 2.0f );
|
|
||||||
|
|
||||||
// GL_ARB_uniform_buffer_object
|
|
||||||
glConfig.uniformBufferAvailable = GLEW_ARB_uniform_buffer_object != 0;
|
|
||||||
if( glConfig.uniformBufferAvailable )
|
|
||||||
{
|
|
||||||
glGetIntegerv( GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, ( GLint* )&glConfig.uniformBufferOffsetAlignment );
|
|
||||||
if( glConfig.uniformBufferOffsetAlignment < 256 )
|
|
||||||
{
|
|
||||||
glConfig.uniformBufferOffsetAlignment = 256;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// RB: make GPU skinning optional for weak OpenGL drivers
|
|
||||||
glConfig.gpuSkinningAvailable = glConfig.uniformBufferAvailable && ( glConfig.driverType == GLDRV_OPENGL3X || glConfig.driverType == GLDRV_OPENGL32_CORE_PROFILE || glConfig.driverType == GLDRV_OPENGL32_COMPATIBILITY_PROFILE );
|
|
||||||
|
|
||||||
// ATI_separate_stencil / OpenGL 2.0 separate stencil
|
|
||||||
glConfig.twoSidedStencilAvailable = ( glConfig.glVersion >= 2.0f ) || GLEW_ATI_separate_stencil != 0;
|
|
||||||
|
|
||||||
// GL_EXT_depth_bounds_test
|
|
||||||
glConfig.depthBoundsTestAvailable = GLEW_EXT_depth_bounds_test != 0;
|
|
||||||
|
|
||||||
// GL_ARB_sync
|
|
||||||
glConfig.syncAvailable = GLEW_ARB_sync &&
|
|
||||||
// as of 5/24/2012 (driver version 15.26.12.64.2761) sync objects
|
|
||||||
// do not appear to work for the Intel HD 4000 graphics
|
|
||||||
( glConfig.vendor != VENDOR_INTEL || r_skipIntelWorkarounds.GetBool() );
|
|
||||||
|
|
||||||
// GL_ARB_occlusion_query
|
|
||||||
glConfig.occlusionQueryAvailable = GLEW_ARB_occlusion_query != 0;
|
|
||||||
|
|
||||||
// GL_ARB_timer_query
|
|
||||||
glConfig.timerQueryAvailable = ( GLEW_ARB_timer_query != 0 || GLEW_EXT_timer_query != 0 ) && ( glConfig.vendor != VENDOR_INTEL || r_skipIntelWorkarounds.GetBool() ) && glConfig.driverType != GLDRV_OPENGL_MESA;
|
|
||||||
|
|
||||||
// GREMEDY_string_marker
|
|
||||||
glConfig.gremedyStringMarkerAvailable = GLEW_GREMEDY_string_marker != 0;
|
|
||||||
if( glConfig.gremedyStringMarkerAvailable )
|
|
||||||
{
|
|
||||||
common->Printf( "...using %s\n", "GL_GREMEDY_string_marker" );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
common->Printf( "X..%s not found\n", "GL_GREMEDY_string_marker" );
|
|
||||||
}
|
|
||||||
|
|
||||||
// GL_ARB_framebuffer_object
|
|
||||||
glConfig.framebufferObjectAvailable = GLEW_ARB_framebuffer_object != 0;
|
|
||||||
if( glConfig.framebufferObjectAvailable )
|
|
||||||
{
|
|
||||||
glGetIntegerv( GL_MAX_RENDERBUFFER_SIZE, &glConfig.maxRenderbufferSize );
|
|
||||||
glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS, &glConfig.maxColorAttachments );
|
|
||||||
|
|
||||||
common->Printf( "...using %s\n", "GL_ARB_framebuffer_object" );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
common->Printf( "X..%s not found\n", "GL_ARB_framebuffer_object" );
|
|
||||||
}
|
|
||||||
|
|
||||||
// GL_EXT_framebuffer_blit
|
|
||||||
glConfig.framebufferBlitAvailable = GLEW_EXT_framebuffer_blit != 0;
|
|
||||||
if( glConfig.framebufferBlitAvailable )
|
|
||||||
{
|
|
||||||
common->Printf( "...using %s\n", "GL_EXT_framebuffer_blit" );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
common->Printf( "X..%s not found\n", "GL_EXT_framebuffer_blit" );
|
|
||||||
}
|
|
||||||
|
|
||||||
// GL_ARB_debug_output
|
|
||||||
glConfig.debugOutputAvailable = GLEW_ARB_debug_output != 0;
|
|
||||||
if( glConfig.debugOutputAvailable )
|
|
||||||
{
|
|
||||||
if( r_debugContext.GetInteger() >= 1 )
|
|
||||||
{
|
|
||||||
glDebugMessageCallbackARB( ( GLDEBUGPROCARB ) DebugCallback, NULL );
|
|
||||||
}
|
|
||||||
if( r_debugContext.GetInteger() >= 2 )
|
|
||||||
{
|
|
||||||
// force everything to happen in the main thread instead of in a separate driver thread
|
|
||||||
glEnable( GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB );
|
|
||||||
}
|
|
||||||
if( r_debugContext.GetInteger() >= 3 )
|
|
||||||
{
|
|
||||||
// enable all the low priority messages
|
|
||||||
glDebugMessageControlARB( GL_DONT_CARE,
|
|
||||||
GL_DONT_CARE,
|
|
||||||
GL_DEBUG_SEVERITY_LOW_ARB,
|
|
||||||
0, NULL, true );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GL_ARB_multitexture
|
|
||||||
if( !glConfig.multitextureAvailable )
|
|
||||||
{
|
|
||||||
idLib::Error( "GL_ARB_multitexture not available" );
|
|
||||||
}
|
|
||||||
// GL_ARB_texture_compression + GL_EXT_texture_compression_s3tc
|
|
||||||
if( !glConfig.textureCompressionAvailable )
|
|
||||||
{
|
|
||||||
idLib::Error( "GL_ARB_texture_compression or GL_EXT_texture_compression_s3tc not available" );
|
|
||||||
}
|
|
||||||
// GL_ARB_vertex_buffer_object
|
|
||||||
if( !glConfig.vertexBufferObjectAvailable )
|
|
||||||
{
|
|
||||||
idLib::Error( "GL_ARB_vertex_buffer_object not available" );
|
|
||||||
}
|
|
||||||
// GL_ARB_map_buffer_range
|
|
||||||
if( !glConfig.mapBufferRangeAvailable )
|
|
||||||
{
|
|
||||||
idLib::Error( "GL_ARB_map_buffer_range not available" );
|
|
||||||
}
|
|
||||||
// GL_ARB_vertex_array_object
|
|
||||||
if( !glConfig.vertexArrayObjectAvailable )
|
|
||||||
{
|
|
||||||
idLib::Error( "GL_ARB_vertex_array_object not available" );
|
|
||||||
}
|
|
||||||
// GL_ARB_draw_elements_base_vertex
|
|
||||||
if( !glConfig.drawElementsBaseVertexAvailable )
|
|
||||||
{
|
|
||||||
idLib::Error( "GL_ARB_draw_elements_base_vertex not available" );
|
|
||||||
}
|
|
||||||
// GL_ARB_vertex_program / GL_ARB_fragment_program
|
|
||||||
//if( !glConfig.fragmentProgramAvailable )
|
|
||||||
//{
|
|
||||||
// idLib::Warning( "GL_ARB_fragment_program not available" );
|
|
||||||
//}
|
|
||||||
// GLSL
|
|
||||||
if( !glConfig.glslAvailable )
|
|
||||||
{
|
|
||||||
idLib::Error( "GLSL not available" );
|
|
||||||
}
|
|
||||||
// GL_ARB_uniform_buffer_object
|
|
||||||
if( !glConfig.uniformBufferAvailable )
|
|
||||||
{
|
|
||||||
idLib::Error( "GL_ARB_uniform_buffer_object not available" );
|
|
||||||
}
|
|
||||||
// GL_EXT_stencil_two_side
|
|
||||||
if( !glConfig.twoSidedStencilAvailable )
|
|
||||||
{
|
|
||||||
idLib::Error( "GL_ATI_separate_stencil not available" );
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate one global Vertex Array Object (VAO)
|
|
||||||
glGenVertexArrays( 1, &glConfig.global_vao );
|
|
||||||
glBindVertexArray( glConfig.global_vao );
|
|
||||||
}
|
|
||||||
// RB end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static bool r_initialized = false;
|
|
||||||
|
|
||||||
/*
|
|
||||||
=============================
|
|
||||||
R_IsInitialized
|
|
||||||
=============================
|
|
||||||
*/
|
|
||||||
bool R_IsInitialized()
|
|
||||||
{
|
|
||||||
return r_initialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============================
|
=============================
|
||||||
|
@ -818,139 +442,6 @@ safeMode:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
idStr extensions_string;
|
|
||||||
|
|
||||||
/*
|
|
||||||
==================
|
|
||||||
R_InitOpenGL
|
|
||||||
|
|
||||||
This function is responsible for initializing a valid OpenGL subsystem
|
|
||||||
for rendering. This is done by calling the system specific GLimp_Init,
|
|
||||||
which gives us a working OGL subsystem, then setting all necessary openGL
|
|
||||||
state, including images, vertex programs, and display lists.
|
|
||||||
|
|
||||||
Changes to the vertex cache size or smp state require a vid_restart.
|
|
||||||
|
|
||||||
If R_IsInitialized() is false, no rendering can take place, but
|
|
||||||
all renderSystem functions will still operate properly, notably the material
|
|
||||||
and model information functions.
|
|
||||||
==================
|
|
||||||
*/
|
|
||||||
void R_InitOpenGL()
|
|
||||||
{
|
|
||||||
common->Printf( "----- R_InitOpenGL -----\n" );
|
|
||||||
|
|
||||||
if( R_IsInitialized() )
|
|
||||||
{
|
|
||||||
common->FatalError( "R_InitOpenGL called while active" );
|
|
||||||
}
|
|
||||||
|
|
||||||
// DG: make sure SDL has setup video so getting supported modes in R_SetNewMode() works
|
|
||||||
GLimp_PreInit();
|
|
||||||
// DG end
|
|
||||||
|
|
||||||
R_SetNewMode( true );
|
|
||||||
|
|
||||||
// input and sound systems need to be tied to the new window
|
|
||||||
Sys_InitInput();
|
|
||||||
|
|
||||||
// get our config strings
|
|
||||||
glConfig.vendor_string = ( const char* )glGetString( GL_VENDOR );
|
|
||||||
glConfig.renderer_string = ( const char* )glGetString( GL_RENDERER );
|
|
||||||
glConfig.version_string = ( const char* )glGetString( GL_VERSION );
|
|
||||||
glConfig.shading_language_string = ( const char* )glGetString( GL_SHADING_LANGUAGE_VERSION );
|
|
||||||
glConfig.extensions_string = ( const char* )glGetString( GL_EXTENSIONS );
|
|
||||||
|
|
||||||
if( glConfig.extensions_string == NULL )
|
|
||||||
{
|
|
||||||
// As of OpenGL 3.2, glGetStringi is required to obtain the available extensions
|
|
||||||
//glGetStringi = ( PFNGLGETSTRINGIPROC )GLimp_ExtensionPointer( "glGetStringi" );
|
|
||||||
|
|
||||||
// Build the extensions string
|
|
||||||
GLint numExtensions;
|
|
||||||
glGetIntegerv( GL_NUM_EXTENSIONS, &numExtensions );
|
|
||||||
extensions_string.Clear();
|
|
||||||
for( int i = 0; i < numExtensions; i++ )
|
|
||||||
{
|
|
||||||
extensions_string.Append( ( const char* )glGetStringi( GL_EXTENSIONS, i ) );
|
|
||||||
// the now deprecated glGetString method usaed to create a single string with each extension separated by a space
|
|
||||||
if( i < numExtensions - 1 )
|
|
||||||
{
|
|
||||||
extensions_string.Append( ' ' );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
glConfig.extensions_string = extensions_string.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
float glVersion = atof( glConfig.version_string );
|
|
||||||
float glslVersion = atof( glConfig.shading_language_string );
|
|
||||||
idLib::Printf( "OpenGL Version : %3.1f\n", glVersion );
|
|
||||||
idLib::Printf( "OpenGL Vendor : %s\n", glConfig.vendor_string );
|
|
||||||
idLib::Printf( "OpenGL Renderer : %s\n", glConfig.renderer_string );
|
|
||||||
idLib::Printf( "OpenGL GLSL : %3.1f\n", glslVersion );
|
|
||||||
idLib::Printf( "OpenGL Extensions: %s\n", glConfig.extensions_string );
|
|
||||||
|
|
||||||
// OpenGL driver constants
|
|
||||||
GLint temp;
|
|
||||||
glGetIntegerv( GL_MAX_TEXTURE_SIZE, &temp );
|
|
||||||
glConfig.maxTextureSize = temp;
|
|
||||||
|
|
||||||
// stubbed or broken drivers may have reported 0...
|
|
||||||
if( glConfig.maxTextureSize <= 0 )
|
|
||||||
{
|
|
||||||
glConfig.maxTextureSize = 256;
|
|
||||||
}
|
|
||||||
|
|
||||||
r_initialized = true;
|
|
||||||
|
|
||||||
// recheck all the extensions (FIXME: this might be dangerous)
|
|
||||||
R_CheckPortableExtensions();
|
|
||||||
|
|
||||||
renderProgManager.Init();
|
|
||||||
|
|
||||||
r_initialized = true;
|
|
||||||
|
|
||||||
// allocate the vertex array range or vertex objects
|
|
||||||
vertexCache.Init( glConfig.uniformBufferOffsetAlignment );
|
|
||||||
|
|
||||||
// allocate the frame data, which may be more if smp is enabled
|
|
||||||
R_InitFrameData();
|
|
||||||
|
|
||||||
// Reset our gamma
|
|
||||||
R_SetColorMappings();
|
|
||||||
|
|
||||||
// RB begin
|
|
||||||
#if defined(_WIN32)
|
|
||||||
static bool glCheck = false;
|
|
||||||
if( !glCheck && win32.osversion.dwMajorVersion == 6 )
|
|
||||||
{
|
|
||||||
glCheck = true;
|
|
||||||
if( !idStr::Icmp( glConfig.vendor_string, "Microsoft" ) && idStr::FindText( glConfig.renderer_string, "OpenGL-D3D" ) != -1 )
|
|
||||||
{
|
|
||||||
if( cvarSystem->GetCVarBool( "r_fullscreen" ) )
|
|
||||||
{
|
|
||||||
cmdSystem->BufferCommandText( CMD_EXEC_NOW, "vid_restart partial windowed\n" );
|
|
||||||
Sys_GrabMouseCursor( false );
|
|
||||||
}
|
|
||||||
int ret = MessageBox( NULL, "Please install OpenGL drivers from your graphics hardware vendor to run " GAME_NAME ".\nYour OpenGL functionality is limited.",
|
|
||||||
"Insufficient OpenGL capabilities", MB_OKCANCEL | MB_ICONWARNING | MB_TASKMODAL );
|
|
||||||
if( ret == IDCANCEL )
|
|
||||||
{
|
|
||||||
cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "quit\n" );
|
|
||||||
cmdSystem->ExecuteCommandBuffer();
|
|
||||||
}
|
|
||||||
if( cvarSystem->GetCVarBool( "r_fullscreen" ) )
|
|
||||||
{
|
|
||||||
cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "vid_restart\n" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// RB end
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=====================
|
=====================
|
||||||
|
@ -2371,89 +1862,6 @@ void R_VidRestart_f( const idCmdArgs& args )
|
||||||
|
|
||||||
// set the mode without re-initializing the context
|
// set the mode without re-initializing the context
|
||||||
R_SetNewMode( false );
|
R_SetNewMode( false );
|
||||||
|
|
||||||
#if 0
|
|
||||||
bool full = true;
|
|
||||||
bool forceWindow = false;
|
|
||||||
for( int i = 1 ; i < args.Argc() ; i++ )
|
|
||||||
{
|
|
||||||
if( idStr::Icmp( args.Argv( i ), "partial" ) == 0 )
|
|
||||||
{
|
|
||||||
full = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if( idStr::Icmp( args.Argv( i ), "windowed" ) == 0 )
|
|
||||||
{
|
|
||||||
forceWindow = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// this could take a while, so give them the cursor back ASAP
|
|
||||||
Sys_GrabMouseCursor( false );
|
|
||||||
|
|
||||||
// dump ambient caches
|
|
||||||
renderModelManager->FreeModelVertexCaches();
|
|
||||||
|
|
||||||
// free any current world interaction surfaces and vertex caches
|
|
||||||
R_FreeDerivedData();
|
|
||||||
|
|
||||||
// make sure the defered frees are actually freed
|
|
||||||
R_ToggleSmpFrame();
|
|
||||||
R_ToggleSmpFrame();
|
|
||||||
|
|
||||||
// free the vertex caches so they will be regenerated again
|
|
||||||
vertexCache.PurgeAll();
|
|
||||||
|
|
||||||
// sound and input are tied to the window we are about to destroy
|
|
||||||
|
|
||||||
if( full )
|
|
||||||
{
|
|
||||||
// free all of our texture numbers
|
|
||||||
Sys_ShutdownInput();
|
|
||||||
globalImages->PurgeAllImages();
|
|
||||||
// free the context and close the window
|
|
||||||
GLimp_Shutdown();
|
|
||||||
r_initialized = false;
|
|
||||||
|
|
||||||
// create the new context and vertex cache
|
|
||||||
bool latch = cvarSystem->GetCVarBool( "r_fullscreen" );
|
|
||||||
if( forceWindow )
|
|
||||||
{
|
|
||||||
cvarSystem->SetCVarBool( "r_fullscreen", false );
|
|
||||||
}
|
|
||||||
R_InitOpenGL();
|
|
||||||
cvarSystem->SetCVarBool( "r_fullscreen", latch );
|
|
||||||
|
|
||||||
// regenerate all images
|
|
||||||
globalImages->ReloadImages( true );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glimpParms_t parms;
|
|
||||||
parms.width = glConfig.nativeScreenWidth;
|
|
||||||
parms.height = glConfig.nativeScreenHeight;
|
|
||||||
parms.fullScreen = ( forceWindow ) ? false : r_fullscreen.GetInteger();
|
|
||||||
parms.displayHz = r_displayRefresh.GetInteger();
|
|
||||||
parms.multiSamples = r_multiSamples.GetInteger();
|
|
||||||
parms.stereo = false;
|
|
||||||
GLimp_SetScreenParms( parms );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// make sure the regeneration doesn't use anything no longer valid
|
|
||||||
tr.viewCount++;
|
|
||||||
tr.viewDef = NULL;
|
|
||||||
|
|
||||||
// check for problems
|
|
||||||
int err = glGetError();
|
|
||||||
if( err != GL_NO_ERROR )
|
|
||||||
{
|
|
||||||
common->Printf( "glGetError() = 0x%x\n", err );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2826,7 +2234,6 @@ idRenderSystemLocal::Init
|
||||||
*/
|
*/
|
||||||
void idRenderSystemLocal::Init()
|
void idRenderSystemLocal::Init()
|
||||||
{
|
{
|
||||||
|
|
||||||
common->Printf( "------- Initializing renderSystem --------\n" );
|
common->Printf( "------- Initializing renderSystem --------\n" );
|
||||||
|
|
||||||
// clear all our internal state
|
// clear all our internal state
|
||||||
|
@ -2839,8 +2246,6 @@ void idRenderSystemLocal::Init()
|
||||||
ambientLightVector[2] = 0.8925f;
|
ambientLightVector[2] = 0.8925f;
|
||||||
ambientLightVector[3] = 1.0f;
|
ambientLightVector[3] = 1.0f;
|
||||||
|
|
||||||
backend.Init();
|
|
||||||
|
|
||||||
R_InitCommands();
|
R_InitCommands();
|
||||||
|
|
||||||
guiModel = new( TAG_RENDER ) idGuiModel;
|
guiModel = new( TAG_RENDER ) idGuiModel;
|
||||||
|
@ -3070,7 +2475,7 @@ void idRenderSystemLocal::InitOpenGL()
|
||||||
// if OpenGL isn't started, start it now
|
// if OpenGL isn't started, start it now
|
||||||
if( !R_IsInitialized() )
|
if( !R_IsInitialized() )
|
||||||
{
|
{
|
||||||
R_InitOpenGL();
|
backend.Init();
|
||||||
|
|
||||||
// Reloading images here causes the rendertargets to get deleted. Figure out how to handle this properly on 360
|
// Reloading images here causes the rendertargets to get deleted. Figure out how to handle this properly on 360
|
||||||
globalImages->ReloadImages( true );
|
globalImages->ReloadImages( true );
|
||||||
|
@ -3092,8 +2497,8 @@ void idRenderSystemLocal::ShutdownOpenGL()
|
||||||
{
|
{
|
||||||
// free the context and close the window
|
// free the context and close the window
|
||||||
R_ShutdownFrameData();
|
R_ShutdownFrameData();
|
||||||
GLimp_Shutdown();
|
|
||||||
r_initialized = false;
|
backend.Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue