#include "COpenGLExtensionHandler.h" #include "irrString.h" #include "SMaterial.h" // for MATERIAL_MAX_TEXTURES #include "fast_atof.h" #include "IrrCompileConfig.h" #ifdef _IRR_COMPILE_WITH_OPENGL_ namespace irr { namespace video { COpenGLExtensionHandler::COpenGLExtensionHandler() : StencilBuffer(false), MultiTextureExtension(false), MultiSamplingExtension(false), AnisotropyExtension(false), TextureCompressionExtension(false), MaxTextureUnits(1), MaxLights(1), MaxIndices(65535), MaxAnisotropy(1.0f), MaxUserClipPlanes(0), Version(0), ShaderLanguageVersion(0) #ifdef _IRR_OPENGL_USE_EXTPOINTER_ ,pGlActiveTextureARB(0), pGlClientActiveTextureARB(0), pGlGenProgramsARB(0), pGlBindProgramARB(0), pGlProgramStringARB(0), pGlDeleteProgramsARB(0), pGlProgramLocalParameter4fvARB(0), pGlCreateShaderObjectARB(0), pGlShaderSourceARB(0), pGlCompileShaderARB(0), pGlCreateProgramObjectARB(0), pGlAttachObjectARB(0), pGlLinkProgramARB(0), pGlUseProgramObjectARB(0), pGlDeleteObjectARB(0), pGlGetObjectParameterivARB(0), pGlGetUniformLocationARB(0), pGlUniform1ivARB(0), pGlUniform1fvARB(0), pGlUniform2fvARB(0), pGlUniform3fvARB(0), pGlUniform4fvARB(0), pGlUniformMatrix2fvARB(0), pGlUniformMatrix3fvARB(0), pGlUniformMatrix4fvARB(0), pGlGetActiveUniformARB(0), pGlPointParameterfARB(0), pGlPointParameterfvARB(0), pGlStencilFuncSeparate(0), pGlStencilOpSeparate(0), pGlStencilFuncSeparateATI(0), pGlStencilOpSeparateATI(0), pGlCompressedTexImage2D(0), #ifdef _IRR_USE_WINDOWS_DEVICE_ wglSwapIntervalEXT(0), #elif defined(GLX_SGI_swap_control) glxSwapIntervalSGI(0), #endif pGlBindFramebufferEXT(0), pGlDeleteFramebuffersEXT(0), pGlGenFramebuffersEXT(0), pGlCheckFramebufferStatusEXT(0), pGlFramebufferTexture2DEXT(0), pGlBindRenderbufferEXT(0), pGlDeleteRenderbuffersEXT(0), pGlGenRenderbuffersEXT(0), pGlRenderbufferStorageEXT(0), pGlFramebufferRenderbufferEXT(0), pGlGenBuffersARB(0), pGlBindBufferARB(0), pGlBufferDataARB(0), pGlDeleteBuffersARB(0), pGlBufferSubDataARB(0), pGlGetBufferSubDataARB(0), pGlMapBufferARB(0), pGlUnmapBufferARB(0), pGlIsBufferARB(0), pGlGetBufferParameterivARB(0), pGlGetBufferPointervARB(0) #endif // _IRR_OPENGL_USE_EXTPOINTER_ { for (u32 i=0; i(glGetString(GL_VERSION))); Version = core::floor32(ogl_ver)*100+core::ceil32(core::fract(ogl_ver)*10.0f); if ( Version >= 102) os::Printer::log("OpenGL driver version is 1.2 or better.", ELL_INFORMATION); else os::Printer::log("OpenGL driver version is not 1.2 or better.", ELL_WARNING); { const char* t = reinterpret_cast(glGetString(GL_EXTENSIONS)); const size_t len = strlen(t); c8 *str = new c8[len+1]; c8* p = str; for (size_t i=0; i(t[i]); if (str[i] == ' ') { str[i] = 0; for (u32 j=0; j(x)) #else // Accessing the correct function is quite complex // All libraries should support the ARB version, however // since GLX 1.4 the non-ARB version is the official one // So we have to check the runtime environment and // choose the proper symbol // In case you still have problems please enable the // next line by uncommenting it // #define _IRR_GETPROCADDRESS_WORKAROUND_ #ifndef _IRR_GETPROCADDRESS_WORKAROUND_ __GLXextFuncPtr (*IRR_OGL_LOAD_EXTENSION)(const GLubyte*)=0; #ifdef GLX_VERSION_1_4 int major,minor; glXQueryVersion(glXGetCurrentDisplay(), &major, &minor); if ((major>1) || (minor>3)) IRR_OGL_LOAD_EXTENSION=glXGetProcAddress; else #endif IRR_OGL_LOAD_EXTENSION=glXGetProcAddressARB; #else #define IRR_OGL_LOAD_EXTENSION glXGetProcAddressARB #endif #endif pGlActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glActiveTextureARB")); pGlClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glClientActiveTextureARB")); // get fragment and vertex program function pointers pGlGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glGenProgramsARB")); pGlBindProgramARB = (PFNGLBINDPROGRAMARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glBindProgramARB")); pGlProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glProgramStringARB")); pGlDeleteProgramsARB = (PFNGLDELETEPROGRAMSNVPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glDeleteProgramsARB")); pGlProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glProgramLocalParameter4fvARB")); pGlCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glCreateShaderObjectARB")); pGlShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glShaderSourceARB")); pGlCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glCompileShaderARB")); pGlCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glCreateProgramObjectARB")); pGlAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glAttachObjectARB")); pGlLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glLinkProgramARB")); pGlUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUseProgramObjectARB")); pGlDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glDeleteObjectARB")); pGlGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glGetInfoLogARB")); pGlGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glGetObjectParameterivARB")); pGlGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glGetUniformLocationARB")); pGlUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUniform4fvARB")); pGlUniform1ivARB = (PFNGLUNIFORM1IVARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUniform1ivARB")); pGlUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUniform1fvARB")); pGlUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUniform2fvARB")); pGlUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUniform3fvARB")); pGlUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUniform4fvARB")); pGlUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUniformMatrix2fvARB")); pGlUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUniformMatrix3fvARB")); pGlUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUniformMatrix4fvARB")); pGlGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glGetActiveUniformARB")); // get point parameter extension pGlPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glPointParameterfARB")); pGlPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glPointParameterfvARB")); // get stencil extension pGlStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glStencilFuncSeparate")); pGlStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glStencilOpSeparate")); pGlStencilFuncSeparateATI = (PFNGLSTENCILFUNCSEPARATEATIPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glStencilFuncSeparateATI")); pGlStencilOpSeparateATI = (PFNGLSTENCILOPSEPARATEATIPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glStencilOpSeparateATI")); // compressed textures pGlCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glCompressedTexImage2D")); #if defined(GLX_SGI_swap_control) && !defined(_IRR_USE_SDL_DEVICE_) // get vsync extension glxSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glXSwapIntervalSGI")); #endif // FrameBufferObjects pGlBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glBindFramebufferEXT")); pGlDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glDeleteFramebuffersEXT")); pGlGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glGenFramebuffersEXT")); pGlCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glCheckFramebufferStatusEXT")); pGlFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glFramebufferTexture2DEXT")); pGlBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glBindRenderbufferEXT")); pGlDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glDeleteRenderbuffersEXT")); pGlGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glGenRenderbuffersEXT")); pGlRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glRenderbufferStorageEXT")); pGlFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glFramebufferRenderbufferEXT")); pGlGenBuffersARB = (PFNGLGENBUFFERSARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glGenBuffersARB")); pGlBindBufferARB = (PFNGLBINDBUFFERARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glBindBufferARB")); pGlBufferDataARB = (PFNGLBUFFERDATAARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glBufferDataARB")); pGlDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glDeleteBuffersARB")); pGlBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glBufferSubDataARB")); pGlGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glGetBufferSubDataARB")); pGlMapBufferARB = (PFNGLMAPBUFFERARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glMapBufferARB")); pGlUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUnmapBufferARB")); pGlIsBufferARB = (PFNGLISBUFFERARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glIsBufferARB")); pGlGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glGetBufferParameterivARB")); pGlGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glGetBufferPointervARB")); #endif // _IRR_OPENGL_USE_EXTPOINTER_ #endif // _IRR_WINDOWS_API_ // set some properties #if defined(GL_ARB_multitexture) || defined(GL_VERSION_1_3) if (Version>102 || FeatureAvailable[IRR_ARB_multitexture]) { GLint num; glGetIntegerv(GL_MAX_TEXTURE_UNITS, &num); MaxTextureUnits=num; } #endif glGetIntegerv(GL_MAX_LIGHTS, &MaxLights); #ifdef GL_EXT_texture_filter_anisotropic if (FeatureAvailable[IRR_EXT_texture_filter_anisotropic]) glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &MaxAnisotropy); #endif #ifdef GL_VERSION_1_2 if (Version>101) glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &MaxIndices); #endif glGetIntegerv(GL_MAX_CLIP_PLANES, reinterpret_cast(&MaxUserClipPlanes)); #if defined(GL_ARB_shading_language_100) || defined (GL_VERSION_2_0) if (FeatureAvailable[IRR_ARB_shading_language_100] || Version>=200) { glGetError(); // clean error buffer #ifdef GL_SHADING_LANGUAGE_VERSION const GLubyte* shaderVersion = glGetString(GL_SHADING_LANGUAGE_VERSION); #else const GLubyte* shaderVersion = glGetString(GL_SHADING_LANGUAGE_VERSION_ARB); #endif if (glGetError() == GL_INVALID_ENUM) ShaderLanguageVersion = 100; else { const f32 sl_ver = core::fast_atof(reinterpret_cast(shaderVersion)); ShaderLanguageVersion = core::floor32(sl_ver)*100+core::ceil32(core::fract(sl_ver)*10.0f); } } #endif #ifdef _IRR_OPENGL_USE_EXTPOINTER_ if (!pGlActiveTextureARB || !pGlClientActiveTextureARB) { MultiTextureExtension = false; os::Printer::log("Failed to load OpenGL's multitexture extension, proceeding without.", ELL_WARNING); } else #endif if (MaxTextureUnits < 2) { MultiTextureExtension = false; os::Printer::log("Warning: OpenGL device only has one texture unit. Disabling multitexturing.", ELL_WARNING); } MaxTextureUnits = core::min_(MaxTextureUnits,MATERIAL_MAX_TEXTURES); } bool COpenGLExtensionHandler::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const { switch (feature) { case EVDF_RENDER_TO_TARGET: return true; case EVDF_MULTITEXTURE: return MultiTextureExtension; case EVDF_BILINEAR_FILTER: return true; case EVDF_MIP_MAP: return true; case EVDF_MIP_MAP_AUTO_UPDATE: return FeatureAvailable[IRR_SGIS_generate_mipmap]; case EVDF_STENCIL_BUFFER: return StencilBuffer; case EVDF_ARB_VERTEX_PROGRAM_1: return FeatureAvailable[IRR_ARB_vertex_program]; case EVDF_ARB_FRAGMENT_PROGRAM_1: return FeatureAvailable[IRR_ARB_fragment_program]; case EVDF_ARB_GLSL: return FeatureAvailable[IRR_ARB_shading_language_100]; case EVDF_TEXTURE_NPOT: return FeatureAvailable[IRR_ARB_texture_non_power_of_two]; case EVDF_FRAMEBUFFER_OBJECT: return FeatureAvailable[IRR_EXT_framebuffer_object]; case EVDF_VERTEX_BUFFER_OBJECT: return FeatureAvailable[IRR_ARB_vertex_buffer_object]; default: return false; }; } } } #endif