/*============================================================================= GLSystem.cpp : HW depended OpenGL functions and extensions handling. Copyright (c) 2001 Crytek Studios. All Rights Reserved. Revision history: * Created by Honitch Andrey =============================================================================*/ #undef THIS_FILE static char THIS_FILE[] = __FILE__; #include "RenderPCH.h" #include "GL_Renderer.h" #include "cg\cgGL.h" #include "GLCGVProgram.h" #include "GLCGPShader.h" #ifdef USE_3DC #include "../Common/3Dc/CompressorLib.h" void (*DeleteDataATI)(void *pData); COMPRESSOR_ERROR (*CompressTextureATI)(DWORD width, DWORD height, UNCOMPRESSED_FORMAT sourceFormat, COMPRESSED_FORMAT destinationFormat, void *inputData, void **dataOut, DWORD *outDataSize); #endif /////////////////////////////////////////////////////////////////// // Gamma Functions /////////////////////////////////////////////////////////////////// void CGLRenderer::CheckGammaSupport(void) { m_Features &= ~RFT_HWGAMMA; if (CV_r_nohwgamma) return; m_Features |= RFT_HWGAMMA; } void CGLRenderer::SetDeviceGamma(ushort *r, ushort *g, ushort *b) { ushort gamma[3][256]; int i; if (!(GetFeatures() & RFT_HWGAMMA)) return; if (CV_r_nohwgamma) return; if (!m_CurrContext->m_hDC) return; for (i=0; i<256; i++) { gamma[0][i] = r[i]; gamma[1][i] = g[i]; gamma[2][i] = b[i]; } if (SUPPORTS_WGL_3DFX_gamma_control) wglSetDeviceGammaRamp3DFX(m_CurrContext->m_hDC, gamma); else SetDeviceGammaRamp(m_CurrContext->m_hDC, gamma); } void CGLRenderer::RestoreDeviceGamma(void) { if (!(GetFeatures() & RFT_HWGAMMA)) return; if (CV_r_nohwgamma) return; HDC dc; struct { ushort red[256]; ushort green[256]; ushort blue[256]; } Ramp; for(int i=0; i<256; i++) { Ramp.red[i] = Ramp.green[i] = Ramp.blue[i] = i << 8; } dc = GetDC(GetDesktopWindow()); if (SUPPORTS_WGL_3DFX_gamma_control) wglSetDeviceGammaRamp3DFX(dc, &Ramp); else SetDeviceGammaRamp(dc, &Ramp); ReleaseDC(GetDesktopWindow(), dc); } void CGLRenderer::SetGamma(float fGamma, float fBrightness, float fContrast) { int i; fGamma = CLAMP(fGamma, 0.5f, 3.0f); if (m_fLastGamma == fGamma && m_fLastBrightness == fBrightness && m_fLastContrast == fContrast) return; //int n; for ( i=0; i<256; i++ ) { m_GammaTable[i] = CLAMP((int)((fContrast+0.5f)*cry_powf((float)i/255.f,1.0f/fGamma)*65535.f + (fBrightness-0.5f)*32768.f - fContrast*32768.f + 16384.f), 0, 65535); /*if ( fGamma == 1.0f ) n = i; else { float f = (float)i; n = (int)(pow(f/255.0, 1.0/fGamma) * 255.0 + 0.5); } if ( n < 0 ) n = 0; if ( n > 255 ) n = 255; m_GammaTable[i] = n | (n<<8); */ } m_fLastGamma = fGamma; m_fLastBrightness = fBrightness; m_fLastContrast = fContrast; SetDeviceGamma(m_GammaTable, m_GammaTable, m_GammaTable); } bool CGLRenderer::SetGammaDelta(const float fGamma) { m_fDeltaGamma = fGamma; SetGamma(CV_r_gamma + fGamma, CV_r_brightness, CV_r_contrast); return true; } //================================================================================ // Library funcs void CGLRenderer::FreeLibrary() { if (m_hLibHandle) { ::FreeLibrary((HINSTANCE)m_hLibHandle); m_hLibHandle = NULL; } if (m_hLibHandleGDI) { ::FreeLibrary((HINSTANCE)m_hLibHandleGDI); m_hLibHandleGDI = NULL; } // Free OpenGL function. #define GL_EXT(name) SUPPORTS##name=0; #define GL_PROC(ext,ret,func,parms) func = NULL; #include "GLFuncs.h" #undef GL_EXT #undef GL_PROC } bool CGLRenderer::LoadLibrary() { strcpy(m_LibName, "OpenGL32.dll"); m_hLibHandle = ::LoadLibrary(m_LibName); if (!m_hLibHandle) { iLog->Log("Warning: Couldn't load library <%s>\n", m_LibName); return false; } m_hLibHandleGDI = ::LoadLibrary("GDI32.dll"); assert(m_hLibHandleGDI); return true; } typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (); static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB; static PFNWGLGETEXTENSIONSSTRINGEXTPROC wglGetExtensionsStringEXT; #define GET_GL_PROC(functype,funcname) \ static functype funcname = (functype)pwglGetProcAddress(#funcname);\ assert(funcname);\ bool CGLRenderer::FindExt( const char* Name ) { char *str = (char*)glGetString(GL_EXTENSIONS); if (strstr(str, Name)) return true; GET_GL_PROC(PFNWGLGETEXTENSIONSSTRINGARBPROC,wglGetExtensionsStringARB); if(wglGetExtensionsStringARB) { const char * wglExt = wglGetExtensionsStringARB(m_RContexts[0]->m_hDC); if (wglExt) return (strstr(wglExt, Name) != NULL); } return false; } void CGLRenderer::FindProc( void*& ProcAddress, char* Name, char* SupportName, byte& Supports, bool AllowExt ) { if (Name[0] == 'p') Name = &Name[1]; if( !ProcAddress ) ProcAddress = GetProcAddress( (HINSTANCE)m_hLibHandle, Name ); if( !ProcAddress ) ProcAddress = GetProcAddress( (HINSTANCE)m_hLibHandleGDI, Name ); if( !ProcAddress && Supports && AllowExt ) ProcAddress = pwglGetProcAddress( Name ); if( !ProcAddress ) { if( Supports ) iLog->Log("Warning: Missing function '%s' for '%s' support\n", Name, SupportName ); Supports = 0; } } void CGLRenderer::FindProcs( bool AllowExt ) { #define GL_EXT(name) if( AllowExt ) SUPPORTS##name = FindExt( TEXT(#name)+1 ); #define GL_PROC(ext,ret,func,parms) FindProc( *(void**)&func, #func, #ext, SUPPORTS##ext, AllowExt ); #include "GLFuncs.h" #undef GL_EXT #undef GL_PROC } bool CGLRenderer::CheckOGLExtensions(void) { CTexMan::m_bRGBA = true; iLog->Log("\n...Check OpenGL extensions\n"); FindProcs( true ); ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_ARB_texture_compression) iLog->Log(" ...GL_ARB_texture_compression not found\n"); else if (CV_gl_arb_texture_compression && CV_r_supportcompressedtextures) { m_Features |= RFT_COMPRESSTEXTURE; iLog->Log(" ...using GL_ARB_texture_compression\n"); } else { SUPPORTS_GL_ARB_texture_compression = 0; iLog->Log(" ...ignoring GL_ARB_texture_compression\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_WGL_EXT_swap_control) iLog->Log(" ...WGL_EXT_swap_control not found\n"); else if (CV_gl_ext_swapcontrol) iLog->Log(" ...using WGL_EXT_swap_control\n"); else { SUPPORTS_WGL_EXT_swap_control = 0; wglSwapIntervalEXT = NULL; iLog->Log(" ...ignoring WGL_EXT_swap_control\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_WGL_ARB_render_texture) iLog->Log(" ...WGL_ARB_render_texture not found\n"); else if (CV_gl_arb_render_texture) iLog->Log(" ...using WGL_ARB_render_texture\n"); else { SUPPORTS_WGL_ARB_render_texture = 0; iLog->Log(" ...ignoring WGL_ARB_render_texture\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_WGL_3DFX_gamma_control) iLog->Log(" ...WGL_3DFX_gamma_control not found\n"); else if (CV_gl_3dfx_gamma_control) iLog->Log(" ...using WGL_3DFX_gamma_control\n"); else { SUPPORTS_WGL_3DFX_gamma_control = 0; wglGetDeviceGammaRamp3DFX = NULL; wglSetDeviceGammaRamp3DFX = NULL; iLog->Log(" ...ignoring WGL_3DFX_gamma_control\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_ARB_multisample) iLog->Log(" ...GL_ARB_multisample not found\n"); else if (CV_gl_arb_multisample) iLog->Log(" ...using GL_ARB_multisample\n"); else { SUPPORTS_GL_ARB_multisample = 0; iLog->Log(" ...ignoring GL_ARB_multisample\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_WGL_ARB_pbuffer) iLog->Log(" ...WGL_ARB_pbuffer not found\n"); else if (CV_gl_arb_pbuffer) iLog->Log(" ...using WGL_ARB_pbuffer\n"); else { SUPPORTS_WGL_ARB_pbuffer = 0; iLog->Log(" ...ignoring WGL_ARB_pbuffer\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_WGL_ARB_pixel_format) iLog->Log(" ...WGL_ARB_pixel_format not found\n"); else if (CV_gl_arb_pixel_format) iLog->Log(" ...using WGL_ARB_pixel_format\n"); else { SUPPORTS_WGL_ARB_pixel_format = 0; iLog->Log(" ...ignoring WGL_ARB_pixel_format\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_WGL_ARB_buffer_region) iLog->Log(" ...WGL_ARB_buffer_region not found\n"); else if (CV_gl_arb_buffer_region) iLog->Log(" ...using WGL_ARB_buffer_region\n"); else { SUPPORTS_WGL_ARB_buffer_region = 0; iLog->Log(" ...ignoring WGL_ARB_buffer_region\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_ARB_texture_env_combine) iLog->Log(" ...GL_ARB_texture_env_combine not found\n"); else if (CV_gl_arb_texture_env_combine) iLog->Log(" ...using GL_ARB_texture_env_combine\n"); else { SUPPORTS_GL_ARB_texture_env_combine = 0; iLog->Log(" ...ignoring GL_ARB_texture_env_combine\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_SGIX_depth_texture) { iLog->Log(" ...GL_SGIX_depth_texture not found\n"); } else if (CV_gl_sgix_depth_texture) { #ifdef WIN64 //m_Features |= RFT_DEPTHMAPS; #else m_Features |= RFT_DEPTHMAPS; #endif iLog->Log(" ...using GL_SGIX_depth_texture\n"); } else { SUPPORTS_GL_SGIX_depth_texture = 0; iLog->Log(" ...ignoring GL_SGIX_depth_texture\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_SGIX_shadow) iLog->Log(" ...GL_SGIX_shadow not found\n"); else if (CV_gl_sgix_shadow) iLog->Log(" ...using GL_SGIX_shadow\n"); else { SUPPORTS_GL_SGIX_shadow = 0; iLog->Log(" ...ignoring GL_SGIX_shadow\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_SGIS_generate_mipmap) iLog->Log(" ...GL_SGIS_generate_mipmap not found\n"); else if (CV_gl_sgis_generate_mipmap) iLog->Log(" ...using GL_SGIS_generate_mipmap\n"); else { SUPPORTS_GL_SGIS_generate_mipmap = 0; iLog->Log(" ...ignoring GL_SGIS_generate_mipmap\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_SGIS_texture_lod) iLog->Log(" ...GL_SGIS_texture_lod not found\n"); else if (CV_gl_sgis_texture_lod) iLog->Log(" ...using GL_SGIS_texture_lod\n"); else { SUPPORTS_GL_SGIS_texture_lod = 0; iLog->Log(" ...ignoring GL_SGIS_texture_lod\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_ARB_multitexture) iLog->Log(" ...GL_ARB_multitexture not found\n"); else if (CV_gl_arb_multitexture) { iLog->Log(" ...using GL_ARB_multitexture\n"); m_Features |= RFT_MULTITEXTURE; } else { SUPPORTS_GL_ARB_multitexture = 0; iLog->Log(" ...ignoring GL_ARB_multitexture\n"); } if (!(GetFeatures() & RFT_MULTITEXTURE)) { glActiveTextureARB = NULL; glClientActiveTextureARB = NULL; glMultiTexCoord2fARB = NULL; glMultiTexCoord2fvARB = NULL; m_MaxActiveTexturesARBFixed = 0; } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_NV_texgen_reflection) iLog->Log(" ...GL_NV_texgen_reflection not found\n"); else if (CV_gl_nv_texgen_reflection) { iLog->Log(" ...using GL_NV_texgen_reflection\n"); m_Features |= RFT_TEXGEN_REFLECTION; } else { SUPPORTS_GL_NV_texgen_reflection = 0; iLog->Log(" ...ignoring GL_NV_texgen_reflection\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_HP_occlusion_test) iLog->Log(" ...GL_HP_occlusion_test not found\n"); else if (CV_gl_hp_occlusion_test) { iLog->Log(" ...using GL_HP_occlusion_test\n"); m_Features |= RFT_OCCLUSIONTEST; } else { SUPPORTS_GL_HP_occlusion_test = 0; iLog->Log(" ...ignoring GL_HP_occlusion_test\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_NV_occlusion_query) iLog->Log(" ...GL_NV_occlusion_query not found\n"); else if (CV_gl_hp_occlusion_test) { iLog->Log(" ...using GL_NV_occlusion_query\n"); m_Features |= RFT_OCCLUSIONTEST; } else { SUPPORTS_GL_NV_occlusion_query = 0; iLog->Log(" ...ignoring GL_NV_occlusion_query\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_NV_multisample_filter_hint) iLog->Log(" ...GL_NV_multisample_filter_hint not found\n"); else if (CV_gl_nv_multisample_filter_hint) iLog->Log(" ...using GL_NV_multisample_filter_hint\n"); else { SUPPORTS_GL_NV_multisample_filter_hint = 0; iLog->Log(" ...ignoring GL_NV_multisample_filter_hint\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_NV_fog_distance) iLog->Log(" ...GL_NV_fog_distance not found\n"); else if (CV_gl_nv_fog_distance) { iLog->Log(" ...using GL_NV_fog_distance\n"); } else { SUPPORTS_GL_NV_fog_distance = 0; iLog->Log(" ...ignoring GL_NV_fog_distance\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_NV_texgen_emboss) iLog->Log(" ...GL_NV_texgen_emboss not found\n"); else if (CV_gl_nv_texgen_emboss) { iLog->Log(" ...using GL_NV_texgen_emboss\n"); m_Features |= RFT_TEXGEN_EMBOSS; } else { SUPPORTS_GL_NV_texgen_emboss = 0; iLog->Log(" ...ignoring GL_NV_texgen_emboss\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_EXT_separate_specular_color) iLog->Log(" ...GL_EXT_separate_specular_color not found\n"); else if (CV_gl_ext_separate_specular_color) { iLog->Log(" ...using GL_EXT_separate_specular_color\n"); glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SEPARATE_SPECULAR_COLOR_EXT); } else { SUPPORTS_GL_EXT_separate_specular_color = 0; iLog->Log(" ...ignoring GL_EXT_separate_specular_color\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_EXT_texture_env_combine) iLog->Log(" ...GL_EXT_texture_env_combine not found\n"); else if (CV_gl_ext_texture_env_combine) iLog->Log(" ...using GL_EXT_texture_env_combine\n"); else { SUPPORTS_GL_EXT_texture_env_combine = 0; iLog->Log(" ...ignoring GL_EXT_texture_env_combine\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_EXT_multi_draw_arrays) iLog->Log(" ...GL_EXT_multi_draw_arrays not found\n"); else if (CV_gl_ext_multi_draw_arrays) { iLog->Log(" ...using GL_EXT_multi_draw_arrays\n"); } else { SUPPORTS_GL_EXT_multi_draw_arrays = 0; iLog->Log(" ...ignoring GL_EXT_multi_draw_arrays\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_NV_texture_env_combine4) iLog->Log(" ...GL_NV_texture_env_combine4 not found\n"); else if (CV_gl_nv_texture_env_combine4) { iLog->Log(" ...using GL_NV_texture_env_combine4\n"); if (GetFeatures() & RFT_MULTITEXTURE) m_Features |= RFT_DETAILTEXTURE; } else { SUPPORTS_GL_NV_texture_env_combine4 = 0; iLog->Log(" ...ignoring GL_NV_texture_env_combine4\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_NV_point_sprite) iLog->Log(" ...GL_NV_point_sprite not found\n"); else if (CV_gl_nv_point_sprite) { iLog->Log(" ...using GL_NV_point_sprite\n"); } else { SUPPORTS_GL_NV_point_sprite = 0; iLog->Log(" ...ignoring GL_NV_point_sprite\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_NV_vertex_array_range) iLog->Log(" ...GL_NV_vertex_array_range not found\n"); else if (CV_gl_nv_vertex_array_range) iLog->Log(" ...using GL_NV_vertex_array_range\n"); else { SUPPORTS_GL_NV_vertex_array_range = 0; iLog->Log(" ...ignoring GL_NV_vertex_array_range\n"); wglAllocateMemoryNV = NULL; glVertexArrayRangeNV = NULL; wglFreeMemoryNV = NULL; } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_NV_fence) iLog->Log(" ...GL_NV_fence not found\n"); else if (CV_gl_nv_fence) iLog->Log(" ...using GL_NV_fence\n"); else { SUPPORTS_GL_NV_fence = 0; iLog->Log(" ...ignoring GL_NV_fence\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_EXT_compiled_vertex_array) iLog->Log(" ...GL_EXT_compiled_vertex_array not found.\n"); else if ( CV_gl_ext_compiled_vertex_array) iLog->Log(" ...using GL_EXT_compiled_vertex_array.\n"); else { SUPPORTS_GL_EXT_compiled_vertex_array = 0; glLockArraysEXT = NULL; glUnlockArraysEXT = NULL; iLog->Log(" ...ignoring GL_EXT_compiled_vertex_array.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_EXT_texture_env_add) iLog->Log(" ...GL_EXT_texture_env_add not found.\n"); else if ( CV_gl_ext_texture_env_add) iLog->Log(" ...using GL_EXT_texture_env_add.\n"); else { SUPPORTS_GL_EXT_texture_env_add = 0; iLog->Log(" ...ignoring GL_EXT_texture_env_add.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_EXT_texture_filter_anisotropic) iLog->Log(" ...GL_EXT_texture_filter_anisotropic not found.\n"); else if ( CV_gl_ext_texture_filter_anisotropic) { iLog->Log(" ...using GL_EXT_texture_filter_anisotropic.\n"); glGetIntegerv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &m_MaxAnisotropicLevel ); m_Features |= RFT_ALLOWANISOTROPIC; if (!CV_r_texture_anisotropic_level) CV_r_texture_anisotropic_level = 1; } else { SUPPORTS_GL_EXT_texture_filter_anisotropic = 0; iLog->Log(" ...ignoring GL_EXT_texture_filter_anisotropic.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_EXT_bgra) iLog->Log(" ...GL_EXT_bgra not found.\n"); else if ( CV_gl_ext_bgra) iLog->Log(" ...using GL_EXT_bgra.\n"); else { SUPPORTS_GL_EXT_bgra = 0; iLog->Log(" ...ignoring GL_EXT_bgra.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_EXT_depth_bounds_test) iLog->Log(" ...GL_EXT_depth_bounds_test not found.\n"); else if (CV_gl_ext_depth_bounds_test) iLog->Log(" ...using GL_EXT_depth_bounds_test.\n"); else { SUPPORTS_GL_EXT_depth_bounds_test = 0; iLog->Log(" ...ignoring GL_EXT_depth_bounds_test.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_EXT_secondary_color) iLog->Log(" ...GL_EXT_secondary_color not found.\n"); else if (CV_gl_ext_secondary_color) { iLog->Log(" ...using GL_EXT_secondary_color.\n"); m_Features |= RFT_ALLOWSECONDCOLOR; } else { SUPPORTS_GL_EXT_secondary_color = 0; iLog->Log(" ...ignoring GL_EXT_secondary_color.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_EXT_paletted_texture) iLog->Log(" ...GL_EXT_paletted_texture not found.\n"); else if (CV_gl_ext_paletted_texture && CV_r_supportpalettedtextures) { iLog->Log(" ...using GL_EXT_paletted_texture.\n"); m_Features |= RFT_PALTEXTURE; } else { SUPPORTS_GL_EXT_paletted_texture = 0; iLog->Log(" ...ignoring GL_EXT_paletted_texture.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_EXT_stencil_two_side) iLog->Log(" ...GL_EXT_stencil_two_side not found.\n"); else if (CV_gl_ext_stencil_two_side) iLog->Log(" ...using GL_EXT_stencil_two_side.\n"); else { SUPPORTS_GL_EXT_stencil_two_side = 0; iLog->Log(" ...ignoring GL_EXT_stencil_two_side.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_EXT_stencil_wrap) iLog->Log(" ...GL_EXT_stencil_wrap not found.\n"); else if (CV_gl_ext_stencil_wrap) iLog->Log(" ...using GL_EXT_stencil_wrap.\n"); else { SUPPORTS_GL_EXT_stencil_wrap = 0; iLog->Log(" ...ignoring GL_EXT_stencil_wrap.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_NV_register_combiners) iLog->Log(" ...GL_NV_register_combiners not found.\n"); else if (CV_gl_nv_register_combiners) { iLog->Log(" ...using GL_NV_register_combiners.\n"); m_Features &= ~RFT_HW_MASK; m_Features |= RFT_HW_GF2; m_Features |= RFT_FOGVP; } else { SUPPORTS_GL_NV_register_combiners = 0; iLog->Log(" ...ignoring GL_NV_register_combiners.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_NV_register_combiners2) iLog->Log(" ...GL_NV_register_combiners2 not found.\n"); else if (CV_gl_nv_register_combiners2) { iLog->Log(" ...using GL_NV_register_combiners2.\n"); m_Features |= RFT_HW_RC; m_Features |= RFT_FOGVP; glEnable(GL_PER_STAGE_CONSTANTS_NV); } else { SUPPORTS_GL_NV_register_combiners2 = 0; iLog->Log(" ...ignoring GL_NV_register_combiners2.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_NV_vertex_program) iLog->Log(" ...GL_NV_vertex_program not found.\n"); else if (CV_gl_nv_vertex_program) { iLog->Log(" ...using GL_NV_vertex_program.\n"); m_Features |= RFT_HW_VS; m_Features |= RFT_FOGVP; } else { SUPPORTS_GL_NV_vertex_program = 0; iLog->Log(" ...ignoring GL_NV_vertex_program3.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_ARB_vertex_program) iLog->Log(" ...GL_ARB_vertex_program not found.\n"); else if (CV_gl_arb_vertex_program) { iLog->Log(" ...using GL_ARB_vertex_program.\n"); m_Features |= RFT_HW_VS; m_Features |= RFT_FOGVP; } else { SUPPORTS_GL_ARB_vertex_program = 0; iLog->Log(" ...ignoring GL_ARB_vertex_program.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_NV_texture_shader) iLog->Log(" ...GL_NV_texture_shader not found.\n"); else if (CV_gl_nv_texture_shader) { iLog->Log(" ...using GL_NV_texture_shader.\n"); m_Features |= RFT_HW_TS; m_Features &= ~RFT_HW_MASK; m_Features |= RFT_HW_GF3; m_Features |= RFT_FOGVP; } else { SUPPORTS_GL_NV_texture_shader = 0; iLog->Log(" ...ignoring GL_NV_texture_shader.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_NV_texture_shader2) iLog->Log(" ...GL_NV_texture_shader2 not found.\n"); else if (CV_gl_nv_texture_shader2) { iLog->Log(" ...using GL_NV_texture_shader2.\n"); m_Features |= RFT_HW_TS; m_Features |= RFT_FOGVP; } else { SUPPORTS_GL_NV_texture_shader2 = 0; iLog->Log(" ...ignoring GL_NV_texture_shader2.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_NV_texture_shader3) iLog->Log(" ...GL_NV_texture_shader3 not found.\n"); else if (CV_gl_nv_texture_shader3) { iLog->Log(" ...using GL_NV_texture_shader3.\n"); m_Features |= RFT_HW_TS | RFT_HW_ENVBUMPPROJECTED; } else { SUPPORTS_GL_NV_texture_shader3 = 0; iLog->Log(" ...ignoring GL_NV_texture_shader3.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_NV_texture_rectangle) iLog->Log(" ...GL_NV_texture_rectangle not found.\n"); else if (CV_gl_nv_texture_rectangle) { iLog->Log(" ...using GL_NV_texture_rectangle.\n"); m_Features |= RFT_ALLOWRECTTEX; } else { SUPPORTS_GL_NV_texture_rectangle = 0; iLog->Log(" ...ignoring GL_NV_texture_rectangle.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_EXT_texture_rectangle) iLog->Log(" ...GL_EXT_texture_rectangle not found.\n"); else if (CV_gl_ext_texture_rectangle && !SUPPORTS_GL_NV_texture_rectangle) { iLog->Log(" ...using GL_EXT_texture_rectangle.\n"); m_Features |= RFT_ALLOWRECTTEX; } else { SUPPORTS_GL_EXT_texture_rectangle = 0; iLog->Log(" ...ignoring GL_EXT_texture_rectangle.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_EXT_texture_cube_map) iLog->Log(" ...GL_EXT_texture_cube_map not found.\n"); else if (CV_gl_ext_texture_cube_map) { iLog->Log(" ...using GL_EXT_texture_cube_map.\n"); } else { SUPPORTS_GL_EXT_texture_cube_map = 0; iLog->Log(" ...ignoring GL_EXT_texture_cube_map.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_ATI_separate_stencil) iLog->Log(" ...GL_ATI_separate_stencil not found.\n"); else if (CV_gl_ati_separate_stencil) { iLog->Log(" ...using GL_ATI_separate_stencil.\n"); } else { SUPPORTS_GL_ATI_separate_stencil = 0; iLog->Log(" ...ignoring GL_ATI_separate_stencil.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_ATI_fragment_shader) iLog->Log(" ...GL_ATI_fragment_shader not found.\n"); else if (CV_gl_ati_fragment_shader) { iLog->Log(" ...using GL_ATI_fragment_shader.\n"); m_Features &= ~RFT_HW_MASK; m_Features |= RFT_HW_RADEON; } else { SUPPORTS_GL_ATI_fragment_shader = 0; iLog->Log(" ...ignoring GL_ATI_fragment_shader.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_ARB_vertex_buffer_object) iLog->Log(" ...GL_ARB_vertex_buffer_object not found.\n"); else if (CV_gl_arb_vertex_buffer_object || !SUPPORTS_GL_NV_fence) { SUPPORTS_GL_ATI_fragment_shader = 0; SUPPORTS_GL_NV_fence = 0; SUPPORTS_GL_NV_vertex_array_range = 0; iLog->Log(" ...using GL_ARB_vertex_buffer_object.\n"); } else { SUPPORTS_GL_ARB_vertex_buffer_object = 0; iLog->Log(" ...ignoring GL_ARB_vertex_buffer_object.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_NV_fragment_program) iLog->Log(" ...GL_NV_fragment_program not found.\n"); else if (CV_gl_nv_fragment_program) { iLog->Log(" ...using GL_NV_fragment_program.\n"); SUPPORTS_GL_ATI_fragment_shader = 0; SUPPORTS_GL_ARB_fragment_program = 0; m_Features |= RFT_HW_TS | RFT_HW_PS20; m_Features &= ~RFT_HW_MASK; m_Features |= RFT_HW_GFFX; m_Features |= RFT_HW_ENVBUMPPROJECTED; //m_MaxActiveTexturesARB = Max(m_MaxActiveTexturesARB, 6); } else { SUPPORTS_GL_NV_fragment_program = 0; iLog->Log(" ...ignoring GL_NV_fragment_program.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_ARB_fragment_program) iLog->Log(" ...GL_ARB_fragment_program not found.\n"); else if (CV_gl_arb_fragment_program && !SUPPORTS_GL_NV_fragment_program) { iLog->Log(" ...using GL_ARB_fragment_program.\n"); SUPPORTS_GL_ATI_fragment_shader = 0; m_Features |= RFT_HW_TS | RFT_HW_PS20; if (((m_Features & RFT_HW_MASK) != RFT_HW_RADEON)) { m_Features &= ~RFT_HW_MASK; m_Features |= RFT_HW_GFFX; } m_Features |= RFT_HW_ENVBUMPPROJECTED; m_Features |= RFT_FOGVP; //m_MaxActiveTexturesARB = Max(m_MaxActiveTexturesARB, 6); } else { SUPPORTS_GL_ARB_fragment_program = 0; iLog->Log(" ...ignoring GL_ARB_fragment_program.\n"); } if (!SUPPORTS_GL_NV_vertex_program3) iLog->Log(" ...GL_NV_vertex_program3 not found.\n"); else if (CV_gl_nv_vertex_program3) { iLog->Log(" ...using GL_NV_vertex_program3.\n"); m_Features |= RFT_HW_VS; m_Features |= RFT_FOGVP; m_Features &= ~RFT_HW_MASK; m_Features |= RFT_HW_NV4X; if (SUPPORTS_GL_ARB_vertex_program) SUPPORTS_GL_NV_vertex_program = 0; } else { SUPPORTS_GL_NV_vertex_program3 = 0; iLog->Log(" ...ignoring GL_NV_vertex_program3.\n"); } ///////////////////////////////////////////////////////////////////////////////////// if (!SUPPORTS_GL_ARB_texture_env_combine) iLog->Log(" ...GL_ARB_texture_env_combine not found.\n"); else if (CV_gl_arb_fragment_program) { iLog->Log(" ...using GL_ARB_texture_env_combine.\n"); } else { SUPPORTS_GL_ARB_texture_env_combine = 0; iLog->Log(" ...ignoring GL_ARB_texture_env_combine.\n"); } m_Features |= RFT_BUMP; if (SUPPORTS_GL_ARB_fragment_program || (m_Features & RFT_DEPTHMAPS)) m_Features |= RFT_SHADOWMAP_SELFSHADOW; if (CV_r_shadowtype == 1) m_Features &= ~(RFT_SHADOWMAP_SELFSHADOW | RFT_DEPTHMAPS); iLog->Log("\n"); if (SUPPORTS_GL_ARB_fragment_program) { glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &m_MaxActiveTexturesARB_VP); glGetIntegerv(GL_MAX_TEXTURES_UNITS_ARB, &m_MaxActiveTexturesARBFixed); } else { glGetIntegerv(GL_MAX_TEXTURES_UNITS_ARB, &m_MaxActiveTexturesARBFixed); m_MaxActiveTexturesARB_VP = m_MaxActiveTexturesARBFixed; } m_MaxActiveTexturesARB_VP = min(m_MaxActiveTexturesARB_VP, MAX_TMU); m_MaxActiveTexturesARBFixed = min(m_MaxActiveTexturesARBFixed, MAX_TMU); return true; } void CGLRenderer::MakeCurrent() { int i; if (pwglGetCurrentContext() == m_RContexts[0]->m_hRC) return; if (pwglMakeCurrent(m_RContexts[0]->m_hDC, m_RContexts[0]->m_hRC) != TRUE) { if (iLog) iLog->LogToFile( "Warning: MakeCurrent of OpenGL context failed!" ); } for (i=0; i<96; i++) { CCGVProgram_GL::m_CurParams[i][0] = -999999; CCGVProgram_GL::m_CurParams[i][1] = -999999; CCGVProgram_GL::m_CurParams[i][2] = -999999; CCGVProgram_GL::m_CurParams[i][3] = -999999; } CVProgram::m_LastVP = 0; CPShader::m_CurRC = NULL; } void CGLRenderer::ShareResources( IRenderer *renderer ) { // Ignore share with myself! if (renderer == this) return; // Assume that renderer is of same type. CGLRenderer *glRend = (CGLRenderer*)renderer; if (pwglShareLists( m_CurrContext->m_hRC, glRend->m_CurrContext->m_hRC ) == FALSE) { if (iLog) iLog->Log("Warning: Sharing of OpenGL resources failed!" ); } } ////////////////////////////////////////////////////////////////////// bool CGLRenderer::SetupPixelFormat(unsigned char colorbits,unsigned char zbits,unsigned char sbits,SRendContext *rc) { #ifdef WIN32 iLog->LogToFile("SetupPixelFormat ..."); PIXELFORMATDESCRIPTOR pfd; int pixelFormat; memset(&pfd, 0, sizeof(pfd)); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER; pfd.dwLayerMask = PFD_MAIN_PLANE; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = colorbits; pfd.cAlphaBits = CV_gl_alpha_bits; pfd.cDepthBits = zbits; pfd.cAccumBits = 0; pfd.cStencilBits = sbits; BOOL status = FALSE; if (m_RContexts.Num() && rc != m_RContexts[0]) pixelFormat = m_RContexts[0]->m_PixFormat; else pixelFormat = ChoosePixelFormat(m_CurrContext->m_hDC, &pfd); m_CurrContext->m_PixFormat = pixelFormat; if (!pixelFormat) { iLog->LogToFile("Cannot ChoosePixelFormat \n"); return (false); } iLog->LogToFile("Selected cColorBits = %d, cDepthBits = %d, Stencilbits=%d\n", pfd.cColorBits, pfd.cDepthBits,pfd.cStencilBits); iLog->LogToFile("GL PIXEL FORMAT:\n"); memset(&pfd, 0, sizeof(pfd)); if (DescribePixelFormat(m_CurrContext->m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd)) { if (pfd.dwFlags & PFD_DRAW_TO_WINDOW) iLog->LogToFile("PFD_DRAW_TO_WINDOW\n"); if (pfd.dwFlags & PFD_DRAW_TO_BITMAP) iLog->LogToFile("PFD_DRAW_TO_BITMAP\n"); if (pfd.dwFlags & PFD_SUPPORT_GDI) iLog->LogToFile("PFD_SUPPORT_GDI\n"); if (pfd.dwFlags & PFD_SUPPORT_OPENGL) iLog->LogToFile("PFD_SUPPORT_OPENGL\n"); if (pfd.dwFlags & PFD_GENERIC_ACCELERATED) iLog->LogToFile("PFD_GENERIC_ACCELERATED\n"); if (pfd.dwFlags & PFD_NEED_PALETTE) iLog->LogToFile("PFD_NEED_PALETTE\n"); if (pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE) iLog->LogToFile("PFD_NEED_SYSTEM_PALETTE\n"); if (pfd.dwFlags & PFD_DOUBLEBUFFER) iLog->LogToFile("PFD_DOUBLEBUFFER\n"); if (pfd.dwFlags & PFD_STEREO) iLog->LogToFile("PFD_STEREO\n"); if (pfd.dwFlags & PFD_SWAP_LAYER_BUFFERS) iLog->LogToFile("PFD_SWAP_LAYER_BUFFERS\n"); iLog->LogToFile("Pixel format %d:\n",pixelFormat); iLog->LogToFile("Pixel Type: %d\n",pfd.iPixelType); iLog->LogToFile("Bits: Color=%d R=%d G=%d B=%d A=%d\n", pfd.cColorBits, pfd.cRedBits, pfd.cGreenBits, pfd.cBlueBits, pfd.cAlphaBits); iLog->LogToFile("Bits: Accum=%d Depth=%d Stencil=%d\n", pfd.cAccumBits, pfd.cDepthBits, pfd.cStencilBits); iLog->LogToFile("Using cColorBits = %d, cDepthBits = %d, Stencilbits=%d\n", pfd.cColorBits, pfd.cDepthBits,pfd.cStencilBits); if (pfd.dwFlags & PFD_GENERIC_FORMAT) { iLog->LogToFile("PFD_GENERIC_FORMAT\n"); return (false); } m_abpp = pfd.cAlphaBits; m_sbpp = pfd.cStencilBits; m_cbpp = pfd.cColorBits; m_zbpp = pfd.cDepthBits; } else { iLog->LogToFile("Warning: Cannot DescribePixelFormat \n"); return (false); } // set the format to closest match SetPixelFormat(m_CurrContext->m_hDC, pixelFormat, &pfd); return (true); #else return (false); #endif } //! Return all supported by video card video AA formats int CGLRenderer::EnumAAFormats(TArray& Formats, bool bReset) { return 0; } int CGLRenderer::EnumDisplayFormats(TArray& Formats, bool bReset) { SDispFormat frm; Formats.Free(); if (bReset) return 0; int i, j; for (i=0; idmPelsWidth < 640 || m->dmPelsHeight < 480 || m->dmBitsPerPel < 15) continue; for (j=0; jm_Width == m->dmPelsWidth && f->m_Height == m->dmPelsHeight && f->m_BPP == m->dmBitsPerPel) break; } if (j == Formats.Num()) { frm.m_Width = m->dmPelsWidth; frm.m_Height = m->dmPelsHeight; frm.m_BPP = m->dmBitsPerPel; if (frm.m_BPP == 24) frm.m_BPP = 32; Formats.AddElem(frm); } } return Formats.Num(); } HWND CGLRenderer::SetMode(int x,int y,int width,int height,unsigned int cbpp, int zbpp, int sbits, bool fullscreen,HINSTANCE hinst, HWND Glhwnd) { ///////////////////////////////////Get Desktop Settings HWND temp = GetDesktopWindow(); RECT trect; GetWindowRect(temp, &trect); m_deskwidth =trect.right-trect.left; m_deskheight=trect.bottom-trect.top; HDC hDC = GetDC (NULL); m_deskbpp = GetDeviceCaps( hDC, BITSPIXEL ); // m_deskfreq= GetDeviceCaps( hDC, VREFRESH ); ReleaseDC (NULL,hDC); iLog->Log("Desktop settings: %d x %d x %d",m_deskwidth,m_deskheight,m_deskbpp/*,m_deskfreq*/); iLog->Log("Available video modes:\n"); ///////////////////////////////////Find available video modes int nummode; for (nummode=0;;nummode++) { DEVMODE Tmp; ZeroMemory(&Tmp,sizeof(Tmp)); Tmp.dmSize = sizeof(Tmp); if (!EnumDisplaySettings(NULL,nummode,&Tmp)) break; } //nummode if (nummode>0) { if (m_vidmodes) delete [] m_vidmodes; m_vidmodes = new DEVMODE [m_numvidmodes=nummode]; } for (nummode=0;;nummode++) { DEVMODE Tmp; ZeroMemory(&Tmp,sizeof(Tmp)); Tmp.dmSize = sizeof(Tmp); if (!EnumDisplaySettings(NULL,nummode,&Tmp)) break; m_vidmodes[nummode]=Tmp; } //nummode if (m_numvidmodes==0) { iLog->Log("Warning: Cannot find at least one video mode available\n"); return (NULL); } ///////////////////////////////////Find the best video mode if (width < 640) width = 640; if (height < 480) height = 480; if (cbpp < 16) cbpp = 16; int best_mode=0; for (int mode = 0; mode < m_numvidmodes; mode++) { if (((int)(m_vidmodes[mode].dmPelsWidth) >= (int)(m_vidmodes[best_mode].dmPelsWidth)) && ((int)(m_vidmodes[mode].dmPelsWidth) <= width) && ((int)(m_vidmodes[mode].dmPelsHeight) >= (int)(m_vidmodes[best_mode].dmPelsHeight)) && ((int)(m_vidmodes[mode].dmPelsHeight) <= height) && ((int)(m_vidmodes[mode].dmBitsPerPel) >= (int)(m_vidmodes[best_mode].dmBitsPerPel)) && ((int)(m_vidmodes[mode].dmBitsPerPel) <= cbpp)) best_mode = mode; } ///////////////////////////////////Create window if (width==m_deskwidth && height==m_deskheight) fullscreen=true; char szWinTitle[80]; sprintf(szWinTitle,"- Far Cry - %s (%s)",__DATE__, __TIME__); if (fullscreen) { if (!ChangeDisplay(m_vidmodes[best_mode].dmPelsWidth,m_vidmodes[best_mode].dmPelsHeight,m_vidmodes[best_mode].dmBitsPerPel)) return (false); Glhwnd = CreateWindowEx(WS_EX_APPWINDOW, "CryENGINE", szWinTitle, WS_POPUP | WS_CLIPSIBLINGS, 0, 0, width, height, NULL, NULL, hinst, NULL); m_width=m_vidmodes[best_mode].dmPelsWidth; m_height=m_vidmodes[best_mode].dmPelsHeight; SetCursor(NULL); ShowCursor(FALSE); } else { if(!Glhwnd) { WNDCLASS wc; if (!GetClassInfo(hinst, "CryENGINE", &wc)) { wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = DefWindowProc; wc.cbClsExtra = 4; wc.cbWndExtra = 4; wc.hInstance = hinst; wc.hIcon = NULL; wc.hCursor = NULL; wc.hbrBackground = (HBRUSH)(BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = "CryENGINE"; RegisterClass(&wc); } Glhwnd = CreateWindowEx(WS_EX_APPWINDOW, "CryENGINE", szWinTitle, WS_BORDER | WS_DLGFRAME | WS_CLIPSIBLINGS | WS_SYSMENU, (GetSystemMetrics(SM_CXFULLSCREEN)-width)/2, (GetSystemMetrics(SM_CYFULLSCREEN)-height)/2, GetSystemMetrics(SM_CXDLGFRAME)*2 + width, GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXDLGFRAME)*2 + height, NULL, NULL, hinst, NULL); } DWORD err=GetLastError(); m_width = width; m_height = height; } m_VX = m_VY = 0; m_VWidth = m_width; m_VHeight = m_height; if (!Glhwnd) { iLog->Log("Error: CreateWindowEx\n"); return (false); } m_FullScreen = fullscreen; if (!m_FullScreen) SetWindowPos(Glhwnd, HWND_NOTOPMOST, (GetSystemMetrics(SM_CXFULLSCREEN)-width)/2, (GetSystemMetrics(SM_CYFULLSCREEN)-height)/2, GetSystemMetrics(SM_CXDLGFRAME)*2 + width, GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXDLGFRAME)*2 + height, SWP_SHOWWINDOW); //SAFE_DELETE_ARRAY(m_vidmodes); return Glhwnd; } ////////////////////////////////////////////////////////////////////// typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); typedef PROC (WINAPI * PFNWGLGETPROCADDRESSPROC) (LPCSTR str); // Determine if an OpenGL WGL extension is supported. // // NOTE: This routine uses wglGetProcAddress so this routine REQUIRES // that the calling thread is bound to a hardware-accelerated OpenGL // rendering context. int CGLRenderer::_wglExtensionSupported(const char *extension) { // Lazy initialization - We don't know if we've initialized this yet, so do it here. wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) pwglGetProcAddress("wglGetExtensionsStringEXT"); wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) pwglGetProcAddress("wglGetExtensionsStringARB"); if (wglGetExtensionsStringARB || wglGetExtensionsStringEXT) { static const GLubyte *extensions = NULL; const GLubyte *start; GLubyte *where, *terminator; // Extension names should not have spaces. where = (GLubyte *) strchr(extension, ' '); if (where || *extension == '\0') return 0; if (!extensions) { HDC hdc = GetDC(0); if (wglGetExtensionsStringARB) extensions = (const GLubyte *) wglGetExtensionsStringARB(hdc); else extensions = (const GLubyte *) wglGetExtensionsStringEXT(); ::ReleaseDC(0,hdc); } // It takes a bit of care to be fool-proof about parsing the // OpenGL extensions string. Don't be fooled by sub-strings, // etc. start = extensions; for (;;) { where = (GLubyte *) strstr((const char *) start, extension); if (!where) break; terminator = where + strlen(extension); if (where == start || *(where - 1) == ' ') { if (*terminator == ' ' || *terminator == '\0') return 1; } start = terminator; } } return 0; } //====================================================================== int nTexSize=0; int nFrameTexSize=0; static int curBind=-1; int BindSizes[TX_LASTBIND]; int BindFrame[TX_LASTBIND]; int TargetTex[TX_LASTBIND]; static int bAutoMips = 0; static _inline void sUpdateTexSize(int target, int width, int height, int depth, int internalFormat, int nLevel) { if (target > GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT) return; int size; if (!nLevel && bAutoMips) { int wdt = width; int hgt = height; int dpt = depth; size = 0; while (wdt || hgt || dpt) { if (!wdt) wdt = 1; if (!hgt) hgt = 1; if (!dpt) dpt = 1; size += CGLTexMan::TexSize(wdt, hgt, dpt, internalFormat); wdt >>= 1; hgt >>= 1; dpt >>= 1; } } else size = CGLTexMan::TexSize(width, height, depth, internalFormat); assert (curBind >= 0 && curBind < TX_LASTBIND); if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT) size *= 6; if (!nLevel) { nTexSize -= BindSizes[curBind]; BindSizes[curBind] = size; } else if (nLevel < 0) { int wdt = width; int hgt = height; int dpt = depth; int mips = 1-nLevel; size = 0; for (int i=0; i>= 1; hgt >>= 1; dpt >>= 1; } BindSizes[curBind] = size; } else BindSizes[curBind] += size; nTexSize += size; } static int nPrevBindARB[2] = {-1,-1}; void (__stdcall *nnglBindBufferARB) (GLenum target, GLuint param); void __stdcall nglBindBufferARB (GLenum target, GLuint param) { if (nPrevBindARB[target-GL_ARRAY_BUFFER_ARB] != param) { nPrevBindARB[target-GL_ARRAY_BUFFER_ARB] = param; nnglBindBufferARB(target, param); } } void (__stdcall *nnglGenBuffersARB) (GLsizei n, GLuint *buffers); void __stdcall nglGenBuffersARB (GLsizei n, GLuint *buffers) { nnglGenBuffersARB(n, buffers); nPrevBindARB[0] = -1; nPrevBindARB[1] = -1; } void (__stdcall *nnglDeleteBuffersARB) (GLsizei n, const GLuint *buffers); void __stdcall nglDeleteBuffersARB (GLsizei n, const GLuint *buffers) { nnglDeleteBuffersARB(n, buffers); nPrevBindARB[0] = -1; nPrevBindARB[1] = -1; } void (__stdcall *nnglTexParameteri) (GLenum target, GLenum pname, GLint param); void __stdcall nglTexParameteri (GLenum target, GLenum pname, GLint param) { if (pname == GL_GENERATE_MIPMAP_SGIS) bAutoMips = param; nnglTexParameteri(target, pname, param); } void (__stdcall *nnglTexImage2D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); void __stdcall nglTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { sUpdateTexSize(target, width, height, 1, internalformat, level); nnglTexImage2D (target, level, internalformat, width, height, border, format, type, pixels); } void (__stdcall *nnglBindTexture) (GLenum Parm0, GLuint Parm1); void __stdcall nglBindTexture (GLenum Parm0, GLuint Parm1) { /*float fSize = 0; for (int i=0; i=0 && Parm1 GetFrameID()) { BindFrame[Parm1] = gcpOGL->GetFrameID(); nFrameTexSize += BindSizes[Parm1]; } if (!Parm1) bAutoMips = 0; } void (__stdcall *nnglCompressedTexImage2DARB) (GLenum Parm0, GLint Parm1, GLenum Parm2, GLsizei Parm3, GLsizei Parm4, GLint Parm5, GLsizei Parm6, const GLvoid *Parm7); void __stdcall nglCompressedTexImage2DARB (GLenum Parm0, GLint Parm1, GLenum Parm2, GLsizei Parm3, GLsizei Parm4, GLint Parm5, GLsizei Parm6, const GLvoid *Parm7) { sUpdateTexSize(Parm0, Parm3, Parm4, 1, Parm2, Parm1); nnglCompressedTexImage2DARB (Parm0, Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7); } void (__stdcall *nnglCopyTexImage2D) (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); void __stdcall nglCopyTexImage2D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { sUpdateTexSize(target, width, height, 1, internalFormat, level); nnglCopyTexImage2D (target, level, internalFormat, x, y, width, height, border); } void (__stdcall *nnglDeleteTextures) (GLsizei n, const GLuint *textures); void __stdcall nglDeleteTextures (GLsizei n, const GLuint *textures) { for (int i=0; im_Prev; pLB->Unload(); pLB = Next; } ShutDownVAR(); FreeResources(FRR_TEXTURES | FRR_REINITHW); ShutDown(true); } if (!Glhdc) Glhwnd = SetMode(x, y, width, height, cbpp, zbpp, sbits, fullscreen, (HINSTANCE)hinst, (HWND)Glhwnd); else { m_width = width; m_height = height; m_FullScreen = fullscreen; m_VX = m_VY = 0; m_VWidth = m_width; m_VHeight = m_height; } if ( !LoadLibrary() ) { iLog->Log("Error: Could not open OpenGL library\n"); exr: FreeLibrary(); ShutDown(); return NULL; } if (!m_RContexts.Num()) { SRendContext *rc = new SRendContext; m_RContexts.AddElem(rc); } SRendContext *rc = m_RContexts[0]; if (Glhdc) { rc->m_hDC = (HDC)Glhdc; } else { rc->m_hDC = GetDC((HWND)Glhwnd); } rc->m_Glhwnd = (HWND)Glhwnd; m_CurrContext = rc; // Find functions. SUPPORTS_GL = 1; FindProcs( false ); if( !SUPPORTS_GL ) { iLog->Log("Error: Library <%s> isn't OpenGL library\n", m_LibName); goto exr; } CreateRContext(rc, Glhdc, hGLrc, cbpp, zbpp, sbits, true); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_MaxTextureSize); if (CV_gl_maxtexsize) { if (CV_gl_maxtexsize < 128) CV_gl_maxtexsize = 128; else if (CV_gl_maxtexsize > 2048) CV_gl_maxtexsize = 2048; m_MaxTextureSize = min(CV_gl_maxtexsize, m_MaxTextureSize); } iLog->Log("****** OpenGL Driver Stats ******\n"); iLog->Log("Driver: %s\n", m_LibName); m_VendorName = glGetString(GL_VENDOR); iLog->Log("GL_VENDOR: %s\n", m_VendorName); m_RendererName = glGetString(GL_RENDERER); iLog->Log("GL_RENDERER: %s\n", m_RendererName); m_VersionName = glGetString(GL_VERSION); iLog->Log("GL_VERSION: %s\n", m_VersionName); m_ExtensionsName = glGetString(GL_EXTENSIONS); iLog->LogToFile("GL_EXTENSIONS:\n"); char ext[8192]; char *token; strcpy(ext, (char *)m_ExtensionsName); token = strtok(ext, " "); while (token) { iLog->LogToFile(" %s\n", token); token = strtok(NULL, " "); } iLog->LogToFile("\n"); GET_GL_PROC(PFNWGLGETEXTENSIONSSTRINGARBPROC,wglGetExtensionsStringARB); if(wglGetExtensionsStringARB) { const char * wglExt = wglGetExtensionsStringARB(m_CurrContext->m_hDC); if (wglExt) { iLog->LogToFile("WGL_EXTENSIONS:\n"); strcpy(ext, (char *)wglExt); token = strtok(ext, " "); while (token) { iLog->LogToFile(" %s\n", token); token = strtok(NULL, " "); } iLog->LogToFile("\n"); } } CheckOGLExtensions(); CheckGammaSupport(); ChangeLog(); if (m_Features & RFT_HW_PS20) { if (CV_r_shadowtype == 0) m_Features |= RFT_SHADOWMAP_SELFSHADOW; } ICVar *var; int nGPU = m_Features & RFT_HW_MASK; var = iConsole->GetCVar("r_NoPS30"); if (var) var->Set(1); m_NoPS30 = 1; var = iConsole->GetCVar("r_HDRRenderingForce"); if (var) var->Set(0); var = iConsole->GetCVar("r_HDRRendering"); if (var) var->Set(0); // Disable per-pixel lighting if pixel-shaders aren't supported if (!(m_Features & (RFT_HW_PS20 | RFT_HW_TS | RFT_HW_RC))) { if (CV_r_Quality_BumpMapping) { var = iConsole->GetCVar("r_Quality_BumpMapping"); if (var) var->Set(0); } if (CV_r_checkSunVis >= 2) { var = iConsole->GetCVar("r_checkSunVis"); if (var) var->Set(1); } } // Allow pixel shaders 2.0 lighting on Radeon only cards with PS.2.0 support if (CV_r_Quality_BumpMapping == 3) { if (!(m_Features & RFT_HW_PS20) || (nGPU == RFT_HW_GFFX && !CV_gl_nv30_ps20)) { var = iConsole->GetCVar("r_Quality_BumpMapping"); if (var) var->Set(2); } } // Shaders remapping for non-PS20 hardware if (!(m_Features & RFT_HW_PS20) || (nGPU == RFT_HW_GFFX && !CV_gl_nv30_ps20)) { var = iConsole->GetCVar("r_NoPS20"); if (var) var->Set(1); } // Disable trees per-pixel lighting from medium and low spec settings if (CV_r_Quality_BumpMapping < 2) { var = iConsole->GetCVar("r_Vegetation_PerpixelLight"); if (var) var->Set(0); } // Allow offset bump-mapping and parametric shaders system for very high spec settings only if (CV_r_Quality_BumpMapping < 3) { var = iConsole->GetCVar("r_UseHWShaders"); if (var && var->GetIVal() == 2) var->Set(1); if (CV_r_offsetbump) { var = iConsole->GetCVar("r_OffsetBump"); if (var) var->Set(0); } } iLog->Log(" ****** OGL CryRenderer Stats ******\n"); iLog->Log(" Mode: %d x %d (%s)\n", m_width, m_height, fullscreen ? "FullScreen" : "Windowed"); iLog->Log(" Gamma: %s\n", (m_Features & RFT_HWGAMMA) ? "Hardware" : "Software"); if (CV_r_fsaa && SUPPORTS_GL_ARB_multisample && (m_Features & RFT_SUPPORTFSAA)) iLog->Log(" Full scene AA: Enabled (%d samples)\n", CV_r_fsaa_samples); else iLog->Log(" Full scene AA: Disabled\n"); iLog->Log(" Stencil type: %s\n", (SUPPORTS_GL_ATI_separate_stencil || SUPPORTS_GL_EXT_stencil_two_side) ? "Two sided" : "Single sided"); iLog->Log(" Max Texture size: %d\n", m_MaxTextureSize); iLog->Log(" Max Active Textures ARB: %d\n", m_MaxActiveTexturesARBFixed); iLog->Log(" Max Active Textures ARB (For ARB_fragment_program): %d\n", m_MaxActiveTexturesARB_VP); iLog->Log(" Projective EMBM: %s\n", (m_Features & RFT_HW_ENVBUMPPROJECTED) ? "enabled" : "disabled"); iLog->Log(" Multitexture: %s\n", (m_Features & RFT_MULTITEXTURE) ? "enabled" : "disabled"); iLog->Log(" Compressed textures: %s\n", (m_Features & RFT_COMPRESSTEXTURE) ? "enabled" : "disabled"); iLog->Log(" Vertex buffers usage: %s\n", SUPPORTS_GL_ARB_vertex_buffer_object ? "VBO" : SUPPORTS_GL_NV_vertex_array_range ? "VAR" : "System memory"); iLog->Log(" Anisotropic texture filtering: %s (Maximum level: %d)\n", (m_Features & RFT_ALLOWANISOTROPIC) ? "enabled" : "disabled", m_MaxAnisotropicLevel); if (m_Features & RFT_BUMP) iLog->Log(" Bump mapping: enabled (%s)\n", (m_Features & RFT_BUMP) ? "DOT3" : "EMBM"); else iLog->Log(" Bump mapping: disabled\n"); iLog->Log(" Detail microtextures: %s\n", (m_Features & RFT_DETAILTEXTURE) ? "enabled" : "disabled"); iLog->Log(" Paletted textures: %s\n", (m_Features & RFT_PALTEXTURE) ? "enabled" : "disabled"); if (nGPU == RFT_HW_NV4X) iLog->Log(" Use Hardware Shaders for NV4x GPUs\n"); else if (nGPU == RFT_HW_GFFX) iLog->Log(" Use Hardware Shaders for NV3x GPUs\n"); else if (nGPU == RFT_HW_GF2) iLog->Log(" Use Hardware Shaders for NV1x GPU\n"); else if (nGPU == RFT_HW_GF3) iLog->Log(" Use Hardware Shaders for NV2x GPU\n"); else if (nGPU == RFT_HW_RADEON) iLog->Log(" Use Hardware Shaders for ATI R300 GPU\n"); else iLog->Log(" Hardware Shaders are not supported\n"); char *str; if (nGPU == RFT_HW_GF2) str = "Not using pixel shaders"; else if (CV_r_nops20) str = "Replace PS.2.0 to PS.1.1"; else if (CV_r_Quality_BumpMapping == 3) { if (m_Features & RFT_HW_PS30) str = "PS.3.0, PS.2.0 and PS.1.1"; else str = "PS.2.0 and PS.1.1"; } else str ="PS1.1 only"; iLog->Log(" Pixel shaders usage: %s\n", str); if (nGPU == RFT_HW_GF2) str = "Not using vertex shaders"; else if (CV_r_nops20) str = "Replace VS.2.0 to VS.1.1"; else if (CV_r_Quality_BumpMapping == 3) { if (m_Features & RFT_HW_PS30) str = "VS.3.0, VS.2.0 and VS.1.1"; else str = "VS.2.0 and VS.1.1"; } else str ="VS1.1 only"; iLog->Log(" Vertex shaders usage: %s\n", str); iLog->Log(" Shadow maps type: %s\n", (m_Features & RFT_DEPTHMAPS) ? "Depth maps" : (m_Features & RFT_SHADOWMAP_SELFSHADOW) ? "Mixed Depth/2D maps" : "2D shadow maps"); m_numtmus = m_MaxActiveTexturesARB_VP; glLoadIdentity(); glRotatef(60, 0, 1, 0); Matrix44 m; glGetFloatv(GL_MODELVIEW_MATRIX, m.GetData()); int parms[4]; glGetIntegerv(GL_MAX_CLIP_PLANES, &m_MaxClipPlanes); iLog->Log(" OGL Max Clip Planes=%d", m_MaxClipPlanes); glGetIntegerv(GL_MAX_LIGHTS, &m_MaxLightSources); iLog->Log(" OGL Max Lights=%d", m_MaxLightSources); glGetIntegerv(GL_MAX_TEXTURE_SIZE,parms); iLog->Log(" OGL Max Texture size=%dx%d",parms[0],parms[0]); glGetIntegerv(GL_MAX_VIEWPORT_DIMS,parms); iLog->Log(" OGL Max Viewport dims=%dx%d",parms[0],parms[1]); int nDepth; glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH, &nDepth); iLog->Log(" OGL Max ModelView Matrix stack depth=%d", nDepth); glGetIntegerv(GL_MAX_PROJECTION_STACK_DEPTH, &nDepth); iLog->Log(" OGL Max Projection Matrix stack depth=%d", nDepth); if (nGPU == RFT_HW_GFFX || nGPU == RFT_HW_GF3) m_MaxClipPlanes = 0; CheckError("CGLRenderer::Init"); { static bool bSet = false; if (!bSet) { bSet = true; nnglTexImage2D = glTexImage2D; glTexImage2D = nglTexImage2D; nnglBindTexture = glBindTexture; glBindTexture = nglBindTexture; nnglCompressedTexImage2DARB = glCompressedTexImage2DARB; glCompressedTexImage2DARB = nglCompressedTexImage2DARB; nnglCopyTexImage2D = glCopyTexImage2D; glCopyTexImage2D = nglCopyTexImage2D; nnglDeleteTextures = glDeleteTextures; glDeleteTextures = nglDeleteTextures; nnglTexParameteri = glTexParameteri; glTexParameteri = nglTexParameteri; nnglBindBufferARB = glBindBufferARB; glBindBufferARB = nglBindBufferARB; nnglGenBuffersARB = glGenBuffersARB; glGenBuffersARB = nglGenBuffersARB; nnglDeleteBuffersARB = glDeleteBuffersARB; glDeleteBuffersARB = nglDeleteBuffersARB; } } GLSetDefaultState(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SetPolygonMode(R_SOLID_MODE); ::ShowWindow(m_CurrContext->m_Glhwnd,1); ::UpdateWindow(m_CurrContext->m_Glhwnd); ::SetForegroundWindow(m_CurrContext->m_Glhwnd); ::SetFocus(m_CurrContext->m_Glhwnd); SetGamma(CV_r_gamma+m_fDeltaGamma, CV_r_brightness, CV_r_contrast); m_width = width; m_height = height; InitVAR(); if (glVertexArrayRangeNV && IsVarPresent()) m_RP.m_NumFences = MAX_DYNVBS; if (bReInit) { iLog->Log("Reload textures\n"); RefreshResources(0); } iLog->Log("Init Shaders\n"); gRenDev->m_cEF.mfInit(); EF_PipelineInit(); return (m_CurrContext->m_Glhwnd); } bool CGLRenderer::CreateRContext(SRendContext *rc, WIN_HDC Glhdc, WIN_HGLRC hGLrc, int cbpp, int zbpp, int sbits, bool bAllowFSAA) { BOOL statusFSAA = false; int pixelFormat; m_CurrContext = rc; int nFSAA = bAllowFSAA ? CV_r_fsaa : 0; m_Features &= ~RFT_SUPPORTFSAA; if (bAllowFSAA && m_RContexts.Num() && rc == m_RContexts[0]) { WNDCLASS wc; wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = ::DefWindowProc; wc.cbClsExtra = 4; wc.cbWndExtra = 4; wc.hInstance = m_hInst; wc.hIcon = 0; wc.hCursor = NULL; wc.hbrBackground = (HBRUSH)(BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = "FAKE_WINDOW"; RegisterClass(&wc); HWND hWnd = ::CreateWindow( "FAKE_WINDOW", // window class name "Fake", // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x pos CW_USEDEFAULT, // initial y pos CW_USEDEFAULT, // initial x size CW_USEDEFAULT, // initial x size NULL, // parent window handle NULL, // window menu handle m_hInst, // program instance handle NULL ); // creation params if (hWnd) { PIXELFORMATDESCRIPTOR pfd; memset(&pfd, 0, sizeof(pfd)); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER; pfd.dwLayerMask = PFD_MAIN_PLANE; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = cbpp; pfd.cAlphaBits = CV_gl_alpha_bits; pfd.cDepthBits = zbpp; pfd.cAccumBits = 0; pfd.cStencilBits = sbits; BOOL status = FALSE; HDC hDC = GetDC(hWnd); pixelFormat = ChoosePixelFormat(m_CurrContext->m_hDC, &pfd); if (SetPixelFormat(hDC, pixelFormat, &pfd) != FALSE) { // Create a rendering context HGLRC hGLRC = pwglCreateContext(hDC); // Make the rendering context current pwglMakeCurrent(hDC, hGLRC); // Search for best matching pixel format pwglGetProcAddress = (PFNWGLGETPROCADDRESSPROC)GetProcAddress( (HINSTANCE)m_hLibHandle, "wglGetProcAddress" ); if (_wglExtensionSupported("WGL_ARB_multisample")) { wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)pwglGetProcAddress("wglGetPixelFormatAttribivARB"); wglGetPixelFormatAttribfvARB = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)pwglGetProcAddress("wglGetPixelFormatAttribfvARB"); wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)pwglGetProcAddress("wglChoosePixelFormatARB"); if (wglChoosePixelFormatARB) m_Features |= RFT_SUPPORTFSAA; } // make no rendering context current wglMakeCurrent(NULL, NULL); // Destroy the rendering context... wglDeleteContext(hGLRC); } ReleaseDC(hWnd, hDC); DestroyWindow(hWnd); UnregisterClass("FAKE_WINDOW", m_hInst); } } if (nFSAA && (m_Features & RFT_SUPPORTFSAA)) { // Search for best matching pixel format iLog->Log("Tryng to set FSAA pixel format..."); int iAttributes[30]; float fAttributes[] = {0, 0}; uint numFormats; // Choose a Pixel Format Descriptor (PFD) with multisampling support. iAttributes[0] = WGL_DOUBLE_BUFFER_ARB; iAttributes[1] = TRUE; iAttributes[2] = WGL_COLOR_BITS_ARB; iAttributes[3] = cbpp; iAttributes[4] = WGL_DEPTH_BITS_ARB; iAttributes[5] = zbpp; iAttributes[6] = WGL_ALPHA_BITS_ARB; iAttributes[7] = CV_gl_alpha_bits; iAttributes[8] = WGL_STENCIL_BITS_ARB; iAttributes[9] = sbits; iAttributes[10] = WGL_SAMPLE_BUFFERS_ARB; iAttributes[11] = TRUE; iAttributes[12] = WGL_SAMPLES_ARB; iAttributes[13] = CV_r_fsaa_samples; iAttributes[14] = 0; iAttributes[15] = 0; // First attempt... statusFSAA = wglChoosePixelFormatARB(m_CurrContext->m_hDC, iAttributes, fAttributes, 1, &pixelFormat, &numFormats); // Failure happens not only when the function fails, but also when no matching pixel format has been found if (statusFSAA == FALSE || numFormats == 0) { iAttributes[6] = 0; iAttributes[7] = 0; statusFSAA = wglChoosePixelFormatARB(m_CurrContext->m_hDC, iAttributes, fAttributes, 1, &pixelFormat, &numFormats); } if (statusFSAA) { rc->m_bFSAAWasSet = true; iLog->Log("Ok"); } else iLog->Log("False"); } if (m_RContexts.Num() && rc != m_RContexts[0]) statusFSAA = m_RContexts[0]->m_bFSAAWasSet; if (!statusFSAA) CV_r_fsaa = 0; if (statusFSAA) { PIXELFORMATDESCRIPTOR pfd; memset(&pfd, 0, sizeof(pfd)); DescribePixelFormat(m_CurrContext->m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); SetPixelFormat(m_CurrContext->m_hDC, pixelFormat, &pfd); rc->m_PixFormat = pixelFormat; m_CurrContext->m_hRC = pwglCreateContext(m_CurrContext->m_hDC); m_CurrContext->m_bFSAAWasSet = true; pwglMakeCurrent(m_CurrContext->m_hDC, m_CurrContext->m_hRC); glEnable(GL_MULTISAMPLE_ARB); } else { m_CurrContext->m_bFSAAWasSet = false; if (!Glhdc && !SetupPixelFormat(cbpp,zbpp,sbits,rc)) { iLog->Log("Warning: SetupPixelFormat failed\n"); //try to change alpha bits if (CV_gl_alpha_bits>0) { iLog->Log("Trying to change alpha bits"); CV_gl_alpha_bits = 0; //and call pixel format again if (!SetupPixelFormat(cbpp,zbpp,sbits,rc)) return (false); } } if (!hGLrc) rc->m_hRC = pwglCreateContext(rc->m_hDC); else { rc->m_hRC = (HGLRC)hGLrc; m_bEditor = true; } } if (!rc->m_hRC) { iLog->Log("Warning: wglCreateContext failed\n"); return (false); } pwglMakeCurrent(rc->m_hDC, rc->m_hRC); if (m_RContexts[0] != rc) { pwglShareLists(m_RContexts[0]->m_hRC, rc->m_hRC); CV_r_vsync = 1; } return true; } bool CGLRenderer::SetCurrentContext(WIN_HWND hWnd) { int i; for (i=0; im_Glhwnd == hWnd) break; } if (i == m_RContexts.Num()) return false; if (m_CurrContext == m_RContexts[i]) return true; m_CurrContext = m_RContexts[i]; if (pwglGetCurrentContext() != m_RContexts[i]->m_hRC) { pwglMakeCurrent(m_RContexts[i]->m_hDC, m_RContexts[i]->m_hRC); for (i=0; i<96; i++) { CCGVProgram_GL::m_CurParams[i][0] = -999999; CCGVProgram_GL::m_CurParams[i][1] = -999999; CCGVProgram_GL::m_CurParams[i][2] = -999999; CCGVProgram_GL::m_CurParams[i][3] = -999999; } CVProgram::m_LastVP = NULL; CPShader::m_CurRC = NULL; } return true; } bool CGLRenderer::CreateContext(WIN_HWND hWnd, bool bAllowFSAA) { int i; for (i=0; im_Glhwnd == hWnd) break; } if (i != m_RContexts.Num()) return false; SRendContext *rc = new SRendContext; m_RContexts.AddElem(rc); rc->m_Glhwnd = (HWND)hWnd; rc->m_hDC = GetDC((HWND)hWnd); rc->m_hRC = NULL; int cbpp = m_cbpp; int zbpp = m_zbpp; int sbpp = m_sbpp; bool bRes = CreateRContext(rc, NULL, NULL, cbpp, zbpp, sbpp, bAllowFSAA); if (bRes) { for (i=0; i<96; i++) { CCGVProgram_GL::m_CurParams[i][0] = -999999; CCGVProgram_GL::m_CurParams[i][1] = -999999; CCGVProgram_GL::m_CurParams[i][2] = -999999; CCGVProgram_GL::m_CurParams[i][3] = -999999; } CVProgram::m_LastVP = NULL; CPShader::m_CurRC = NULL; } return bRes; } bool CGLRenderer::DeleteContext(WIN_HWND hWnd) { int i; for (i=0; im_Glhwnd == hWnd) break; } if (i == m_RContexts.Num()) return false; SRendContext *rc = m_RContexts[i]; pwglMakeCurrent(NULL, NULL); if (rc->m_hRC) { pwglDeleteContext(rc->m_hRC); rc->m_hRC = NULL; } if (rc->m_hDC) { ReleaseDC(rc->m_Glhwnd, rc->m_hDC); rc->m_hDC = NULL; } delete rc; m_RContexts.Remove(i, 1); return true; } #else //PS2 bool CGLRenderer::Init(int x,int y,int width,int height,unsigned int cbpp, int zbpp, int sbits, bool fullscreen) { return false; } #endif //endif void CGLRenderer::RefreshResources(int nFlags) { if (nFlags & FRO_TEXTURES) m_TexMan->ReloadAll(nFlags); if (nFlags & (FRO_SHADERS | FRO_SHADERTEXTURES)) gRenDev->m_cEF.mfReloadAllShaders(nFlags); } extern float gFOpenTime; extern int nRejectFOpen; extern int nAcceptFOpen; void CGLRenderer::ShutDown(bool bReInit) { int i; // CRendElement::mfLogAllREs(); if (CV_r_printmemoryleaks) { FILE *fp = fxopen("LeafBufferLeaks.txt", "w"); if (fp) { CLeafBuffer *pLB = CLeafBuffer::m_RootGlobal.m_NextGlobal; while (pLB != &CLeafBuffer::m_RootGlobal) { CLeafBuffer *Next = pLB->m_NextGlobal; float fSize = pLB->Size(0)/1024.0f/1024.0f; fprintf(fp, "*** LB %s: %0.3fMb\n", pLB->m_sSource, fSize); iLog->Log("WARNING: LB Leak %s: %0.3fMb", pLB->m_sSource, fSize); DeleteLeafBuffer(pLB); pLB = Next; } CRendElement *pRE = CRendElement::m_RootGlobal.m_NextGlobal; while (pRE != &CRendElement::m_RootGlobal) { CRendElement *Next = pRE->m_NextGlobal; float fSize = pRE->Size()/1024.0f/1024.0f; fprintf(fp, "*** LB %s: %0.3fMb\n", pRE->mfTypeString(), fSize); iLog->Log("WARNING: RE Leak %s: %0.3fMb", pRE->mfTypeString(), fSize); SAFE_RELEASE(pRE); pRE = Next; } fclose(fp); } } FreeResources(FRR_ALL); EF_PipelineShutdown(); GenerateVBLog("VBLeaks.txt"); ShutDownVAR(); CName::mfExitSubsystem(); if (m_CGContext) { #ifndef WIN64 // TODO: AMD64 port: find 64-bit CG cgDestroyContext(m_CGContext); #endif m_CGContext = NULL; } iLog->LogToFile("Tex. FOpen time: %f sec\n", gFOpenTime); iLog->LogToFile("Tex. Accept FOpen: %d\n", nAcceptFOpen); iLog->LogToFile("Tex. Reject FOpen: %d\n", nRejectFOpen); iLog->LogToFile("GlRenderer Shutdown\n"); RestoreDeviceGamma(); glFinish(); HWND hWnd = m_RContexts[0]->m_Glhwnd; for (i=0; im_Glhwnd); } if (hWnd && !bReInit) { DestroyWindow(hWnd); } //ChangeDisplay(m_deskwidth,m_deskheight,m_deskbpp); ChangeDisplay(0,0,0); FreeLibrary(); if (m_vidmodes) { delete [] m_vidmodes; m_vidmodes=NULL; } } //======================================================================= ILog *iLog; IConsole *iConsole; ITimer *iTimer; ISystem *iSystem; //CVars *cVars; int *pTest_int; //CryCharManager *pCharMan; IPhysicalWorld *pIPhysicalWorld; ISystem *GetISystem() { return iSystem; } extern "C" DLL_EXPORT IRenderer* PackageRenderConstructor(int argc, char* argv[], SCryRenderInterface *sp); DLL_EXPORT IRenderer* PackageRenderConstructor(int argc, char* argv[], SCryRenderInterface *sp) { gbRgb = false; iConsole = sp->ipConsole; iLog = sp->ipLog; iTimer = sp->ipTimer; iSystem = sp->ipSystem; // cVars = sp->ipVars; pTest_int = sp->ipTest_int; pIPhysicalWorld = sp->pIPhysicalWorld; // pCharMan = sp->ipCharMan; #ifdef DEBUGALLOC #undef new #endif IRenderer *rd = (IRenderer *) (new CGLRenderer()); #ifdef DEBUGALLOC #define new DEBUG_CLIENTBLOCK #endif g_SecondsPerCycle = iSystem->GetSecondsPerCycle(); g_CpuFlags = iSystem->GetCPUFlags(); srand( GetTickCount() ); return rd; } void *gGet_D3DDevice() { return NULL; } void *gGet_glReadPixels() { return glReadPixels; }