/* static */ bool wxGLCanvasBase::IsExtensionSupported(const char *extension) { static const char *s_extensionsList = (char *)wxUIntPtr(-1); if ( s_extensionsList == (char *)wxUIntPtr(-1) ) { typedef const char * (WINAPI *wglGetExtensionsStringARB_t)(HDC hdc); wxDEFINE_WGL_FUNC(wglGetExtensionsStringARB); if ( wglGetExtensionsStringARB ) { s_extensionsList = wglGetExtensionsStringARB(wglGetCurrentDC()); } else { typedef const char * (WINAPI * wglGetExtensionsStringEXT_t)(); wxDEFINE_WGL_FUNC(wglGetExtensionsStringEXT); if ( wglGetExtensionsStringEXT ) { s_extensionsList = wglGetExtensionsStringEXT(); } else { s_extensionsList = NULL; } } } return s_extensionsList && IsExtensionInList(s_extensionsList, extension); }
static int has_ext(const char *ext) { const char *terminator; const char *loc; const char *extensions; if(wglGetExtensionsStringEXT == NULL && wglGetExtensionsStringARB == NULL) return 0; if(wglGetExtensionsStringARB == NULL || GLADWGLhdc == INVALID_HANDLE_VALUE) extensions = wglGetExtensionsStringEXT(); else extensions = wglGetExtensionsStringARB(GLADWGLhdc); if(extensions == NULL || ext == NULL) return 0; while(1) { loc = strstr(extensions, ext); if(loc == NULL) break; terminator = loc + strlen(ext); if((loc == extensions || *(loc - 1) == ' ') && (*terminator == ' ' || *terminator == '\0')) { return 1; } extensions = terminator; } return 0; }
void wgl_features() { #ifdef GLLOADER_WGL std::string exts_str; LOAD_FUNC1(wglGetExtensionsStringARB); if (wglGetExtensionsStringARB != NULL) { exts_str = wglGetExtensionsStringARB(::wglGetCurrentDC()); } else { LOAD_FUNC1(wglGetExtensionsStringEXT); if (wglGetExtensionsStringEXT != NULL) { exts_str = wglGetExtensionsStringEXT(); } } std::vector<std::string> wgl_exts = split(exts_str); wgl_exts.erase(std::remove(wgl_exts.begin(), wgl_exts.end(), ""), wgl_exts.end()); features_.insert(features_.end(), wgl_exts.begin(), wgl_exts.end()); #endif // GLLOADER_WGL }
WINGDIAPI const char *wglGetExtensionsStringARB() { return wglGetExtensionsStringEXT(); }
void CheckGLExtensions() { // Make sure to only do this once. It's okay to call CheckGLExtensions from wherever. static bool done = false; if (done) return; done = true; memset(&gl_extensions, 0, sizeof(gl_extensions)); const char *renderer = (const char *)glGetString(GL_RENDERER); const char *versionStr = (const char *)glGetString(GL_VERSION); // Check vendor string to try and guess GPU const char *cvendor = (char *)glGetString(GL_VENDOR); // TODO: move this stuff to gpu_features.cpp if (cvendor) { const std::string vendor(cvendor); if (vendor == "NVIDIA Corporation" || vendor == "Nouveau" || vendor == "nouveau") { gl_extensions.gpuVendor = GPU_VENDOR_NVIDIA; } else if (vendor == "Advanced Micro Devices, Inc." || vendor == "ATI Technologies Inc.") { gl_extensions.gpuVendor = GPU_VENDOR_AMD; } else if (vendor == "Intel" || vendor == "Intel Inc." || vendor == "Intel Corporation" || vendor == "Tungsten Graphics, Inc") { // We'll assume this last one means Intel gl_extensions.gpuVendor = GPU_VENDOR_INTEL; } else if (vendor == "ARM") { gl_extensions.gpuVendor = GPU_VENDOR_ARM; } else if (vendor == "Imagination Technologies") { gl_extensions.gpuVendor = GPU_VENDOR_POWERVR; } else if (vendor == "Qualcomm") { gl_extensions.gpuVendor = GPU_VENDOR_ADRENO; } else if (vendor == "Broadcom") { gl_extensions.gpuVendor = GPU_VENDOR_BROADCOM; // Just for reference: Galaxy Y has renderer == "VideoCore IV HW" } else { gl_extensions.gpuVendor = GPU_VENDOR_UNKNOWN; } } else { gl_extensions.gpuVendor = GPU_VENDOR_UNKNOWN; } ILOG("GPU Vendor : %s", cvendor); #ifndef USING_GLES2 char buffer[64] = {0}; if (versionStr) { ILOG("GL version str: %s", versionStr); strncpy(buffer, versionStr, 63); } const char *lastNumStart = buffer; int numVer = 0; int len = (int)strlen(buffer); for (int i = 0; i < len && numVer < 3; i++) { if (buffer[i] == '.') { buffer[i] = 0; gl_extensions.ver[numVer++] = strtol(lastNumStart, NULL, 10); i++; lastNumStart = buffer + i; } } if (numVer < 3) gl_extensions.ver[numVer++] = strtol(lastNumStart, NULL, 10); #else gl_extensions.ver[0] = 2; #endif #if defined(USING_GLES2) // MAY_HAVE_GLES3 defined on all platforms that support it #if defined(MAY_HAVE_GLES3) // Try to load GLES 3.0 only if "3.0" found in version // This simple heuristic avoids issues on older devices where you can only call eglGetProcAddress a limited // number of times. if (strstr(versionStr, "3.0") && GL_TRUE == gl3stubInit()) { gl_extensions.ver[0] = 3; gl_extensions.GLES3 = true; ILOG("Full OpenGL ES 3.0 support detected!\n"); // Though, let's ban Mali from the GLES 3 path for now, see #4078 if (strstr(renderer, "Mali") != 0) { gl_extensions.GLES3 = false; } } #endif #else // If the GL version >= 4.3, we know it's a true superset of OpenGL ES 3.0 and can thus enable // modern paths. // Most of it could be enabled on lower GPUs as well, but let's start this way. if ((gl_extensions.ver[0] == 4 && gl_extensions.ver[1] >= 3) || gl_extensions.ver[0] > 4) { gl_extensions.GLES3 = true; } #endif const char *extString = (const char *)glGetString(GL_EXTENSIONS); if (extString) { g_all_gl_extensions = extString; } else { g_all_gl_extensions = ""; } #ifdef WIN32 const char *wglString = 0; if (wglGetExtensionsStringEXT) wglString = wglGetExtensionsStringEXT(); if (wglString) { gl_extensions.EXT_swap_control_tear = strstr(wglString, "WGL_EXT_swap_control_tear") != 0; g_all_egl_extensions = wglString; } else { g_all_egl_extensions = ""; } #elif !defined(USING_GLES2) // const char *glXString = glXQueryExtensionString(); // gl_extensions.EXT_swap_control_tear = strstr(glXString, "GLX_EXT_swap_control_tear") != 0; #endif #ifdef USING_GLES2 gl_extensions.OES_packed_depth_stencil = strstr(extString, "GL_OES_packed_depth_stencil") != 0; gl_extensions.OES_depth24 = strstr(extString, "GL_OES_depth24") != 0; gl_extensions.OES_depth_texture = strstr(extString, "GL_OES_depth_texture") != 0; gl_extensions.OES_mapbuffer = strstr(extString, "GL_OES_mapbuffer") != 0; gl_extensions.EXT_blend_minmax = strstr(extString, "GL_EXT_blend_minmax") != 0; gl_extensions.EXT_shader_framebuffer_fetch = (strstr(extString, "GL_EXT_shader_framebuffer_fetch") != 0) || (strstr(extString, "GL_NV_shader_framebuffer_fetch") != 0); gl_extensions.NV_draw_texture = strstr(extString, "GL_NV_draw_texture") != 0; gl_extensions.NV_copy_image = strstr(extString, "GL_NV_copy_image") != 0; #if defined(ANDROID) || defined(BLACKBERRY) // On Android, incredibly, this is not consistently non-zero! It does seem to have the same value though. // https://twitter.com/ID_AA_Carmack/status/387383037794603008 void *invalidAddress = (void *)eglGetProcAddress("InvalidGlCall1"); void *invalidAddress2 = (void *)eglGetProcAddress("AnotherInvalidGlCall2"); ILOG("Addresses returned for invalid extensions: %p %p", invalidAddress, invalidAddress2); if (gl_extensions.NV_draw_texture) { glDrawTextureNV = (PFNGLDRAWTEXTURENVPROC)eglGetProcAddress("glDrawTextureNV"); } if (gl_extensions.NV_copy_image) { glCopyImageSubDataNV = (PFNGLCOPYIMAGESUBDATANVPROC)eglGetProcAddress("glCopyImageSubDataNV"); } gl_extensions.OES_vertex_array_object = strstr(extString, "GL_OES_vertex_array_object") != 0; if (gl_extensions.OES_vertex_array_object) { glGenVertexArraysOES = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress ( "glGenVertexArraysOES" ); glBindVertexArrayOES = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress ( "glBindVertexArrayOES" ); glDeleteVertexArraysOES = (PFNGLDELETEVERTEXARRAYSOESPROC)eglGetProcAddress ( "glDeleteVertexArraysOES" ); glIsVertexArrayOES = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress ( "glIsVertexArrayOES" ); } gl_extensions.EXT_discard_framebuffer = strstr(extString, "GL_EXT_discard_framebuffer") != 0; if (gl_extensions.EXT_discard_framebuffer) { glDiscardFramebufferEXT = (PFNGLDISCARDFRAMEBUFFEREXTPROC)eglGetProcAddress("glDiscardFramebufferEXT"); } #else gl_extensions.OES_vertex_array_object = false; gl_extensions.EXT_discard_framebuffer = false; #endif #else // Desktops support minmax gl_extensions.EXT_blend_minmax = true; #endif #if defined(ANDROID) || defined(BLACKBERRY) if (gl_extensions.OES_mapbuffer) { glMapBuffer = (PFNGLMAPBUFFERPROC)eglGetProcAddress( "glMapBufferOES" ); } gl_extensions.QCOM_alpha_test = strstr(extString, "GL_QCOM_alpha_test") != 0; // Load extensions that are not auto-loaded by Android. if (gl_extensions.QCOM_alpha_test) { glAlphaFuncQCOM = (PFNGLALPHAFUNCQCOMPROC)eglGetProcAddress("glAlphaFuncQCOM"); } // Look for EGL extensions EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); const char *eglString = eglQueryString(display, EGL_EXTENSIONS); if (eglString) { g_all_egl_extensions = eglString; gl_extensions.EGL_NV_system_time = strstr(eglString, "EGL_NV_system_time") != 0; gl_extensions.EGL_NV_coverage_sample = strstr(eglString, "EGL_NV_coverage_sample") != 0; if (gl_extensions.EGL_NV_system_time) { eglGetSystemTimeNV = (PFNEGLGETSYSTEMTIMENVPROC) eglGetProcAddress("eglGetSystemTimeNV"); eglGetSystemTimeFrequencyNV = (PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) eglGetProcAddress("eglGetSystemTimeFrequencyNV"); } } else { g_all_egl_extensions = ""; } #endif #ifdef USING_GLES2 gl_extensions.FBO_ARB = true; gl_extensions.FBO_EXT = false; #else gl_extensions.FBO_ARB = false; gl_extensions.FBO_EXT = false; gl_extensions.PBO_ARB = true; if (extString) { gl_extensions.FBO_ARB = strstr(extString, "GL_ARB_framebuffer_object") != 0; gl_extensions.FBO_EXT = strstr(extString, "GL_EXT_framebuffer_object") != 0; gl_extensions.PBO_ARB = strstr(extString, "GL_ARB_pixel_buffer_object") != 0; gl_extensions.ATIClampBug = ((strncmp (renderer, "ATI RADEON X", 12) != 0) || (strncmp (renderer, "ATI MOBILITY RADEON X",21) != 0)); } #endif ProcessGPUFeatures(); }
void CheckGLExtensions() { #if !PPSSPP_PLATFORM(UWP) // Make sure to only do this once. It's okay to call CheckGLExtensions from wherever. if (extensionsDone) return; extensionsDone = true; memset(&gl_extensions, 0, sizeof(gl_extensions)); gl_extensions.IsCoreContext = useCoreContext; #ifdef USING_GLES2 gl_extensions.IsGLES = true; #endif const char *renderer = (const char *)glGetString(GL_RENDERER); const char *versionStr = (const char *)glGetString(GL_VERSION); const char *glslVersionStr = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION); // Check vendor string to try and guess GPU const char *cvendor = (char *)glGetString(GL_VENDOR); // TODO: move this stuff to gpu_features.cpp if (cvendor) { const std::string vendor = StripSpaces(std::string(cvendor)); if (vendor == "NVIDIA Corporation" || vendor == "Nouveau" || vendor == "nouveau") { gl_extensions.gpuVendor = GPU_VENDOR_NVIDIA; } else if (vendor == "Advanced Micro Devices, Inc." || vendor == "ATI Technologies Inc.") { gl_extensions.gpuVendor = GPU_VENDOR_AMD; } else if (vendor == "Intel" || vendor == "Intel Inc." || vendor == "Intel Corporation" || vendor == "Tungsten Graphics, Inc") { // We'll assume this last one means Intel gl_extensions.gpuVendor = GPU_VENDOR_INTEL; } else if (vendor == "ARM") { gl_extensions.gpuVendor = GPU_VENDOR_ARM; } else if (vendor == "Imagination Technologies") { gl_extensions.gpuVendor = GPU_VENDOR_POWERVR; } else if (vendor == "Qualcomm") { gl_extensions.gpuVendor = GPU_VENDOR_ADRENO; } else if (vendor == "Broadcom") { gl_extensions.gpuVendor = GPU_VENDOR_BROADCOM; // Just for reference: Galaxy Y has renderer == "VideoCore IV HW" } else { gl_extensions.gpuVendor = GPU_VENDOR_UNKNOWN; } } else { gl_extensions.gpuVendor = GPU_VENDOR_UNKNOWN; } ILOG("GPU Vendor : %s ; renderer: %s version str: %s ; GLSL version str: %s", cvendor, renderer ? renderer : "N/A", versionStr ? versionStr : "N/A", glslVersionStr ? glslVersionStr : "N/A"); if (renderer) { strncpy(gl_extensions.model, renderer, sizeof(gl_extensions.model)); gl_extensions.model[sizeof(gl_extensions.model) - 1] = 0; } if (!gl_extensions.IsGLES) { // For desktop GL, grab the version and attempt to parse. char buffer[64] = { 0 }; if (versionStr) { strncpy(buffer, versionStr, 63); } const char *lastNumStart = buffer; int numVer = 0; int len = (int)strlen(buffer); for (int i = 0; i < len && numVer < 3; i++) { if (buffer[i] == '.') { buffer[i] = 0; gl_extensions.ver[numVer++] = strtol(lastNumStart, NULL, 10); i++; lastNumStart = buffer + i; } } if (numVer < 3) gl_extensions.ver[numVer++] = strtol(lastNumStart, NULL, 10); // If the GL version >= 4.3, we know it's a true superset of OpenGL ES 3.0 and can thus enable // all the same modern paths. // Most of it could be enabled on lower GPUs as well, but let's start this way. if (gl_extensions.VersionGEThan(4, 3, 0)) { gl_extensions.GLES3 = true; } } else { // Start by assuming we're at 2.0. gl_extensions.ver[0] = 2; #ifdef USING_GLES2 #ifdef GL_MAJOR_VERSION // Before grabbing the values, reset the error. glGetError(); glGetIntegerv(GL_MAJOR_VERSION, &gl_extensions.ver[0]); glGetIntegerv(GL_MINOR_VERSION, &gl_extensions.ver[1]); // We check error here to detect if these properties were supported. if (glGetError() != GL_NO_ERROR) { // They weren't, reset to GLES 2.0. gl_extensions.ver[0] = 2; gl_extensions.ver[1] = 0; } #endif // If the above didn't give us a version, or gave us a crazy version, fallback. if (gl_extensions.ver[0] < 3 || gl_extensions.ver[0] > 5) { // Try to load GLES 3.0 only if "3.0" found in version // This simple heuristic avoids issues on older devices where you can only call eglGetProcAddress a limited // number of times. Make sure to check for 3.0 in the shader version too to avoid false positives, see #5584. bool gl_3_0_in_string = strstr(versionStr, "3.0") && strstr(glslVersionStr, "3.0"); bool gl_3_1_in_string = strstr(versionStr, "3.1") && strstr(glslVersionStr, "3.1"); // intentionally left out .1 if ((gl_3_0_in_string || gl_3_1_in_string) && gl3stubInit()) { gl_extensions.ver[0] = 3; if (gl_3_1_in_string) { gl_extensions.ver[1] = 1; } gl_extensions.GLES3 = true; // Though, let's ban Mali from the GLES 3 path for now, see #4078 if (strstr(renderer, "Mali") != 0) { gl_extensions.GLES3 = false; } } else { // Just to be safe. gl_extensions.ver[0] = 2; gl_extensions.ver[1] = 0; } } else { // Otherwise, let's trust GL_MAJOR_VERSION. Note that Mali is intentionally not banned here. if (gl_extensions.ver[0] >= 3) { gl_extensions.GLES3 = gl3stubInit(); } } #endif if (gl_extensions.GLES3) { if (gl_extensions.ver[1] >= 1) { ILOG("OpenGL ES 3.1 support detected!\n"); } else { ILOG("OpenGL ES 3.0 support detected!\n"); } } } const char *extString = nullptr; if (gl_extensions.ver[0] >= 3) { // Let's use the new way for OpenGL 3.x+, required in the core profile. GLint numExtensions = 0; glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions); g_all_gl_extensions = ""; for (GLint i = 0; i < numExtensions; ++i) { g_all_gl_extensions += (const char *)glGetStringi(GL_EXTENSIONS, i); g_all_gl_extensions += " "; } extString = g_all_gl_extensions.c_str(); } else { extString = (const char *)glGetString(GL_EXTENSIONS); if (extString) { g_all_gl_extensions = extString; } else { g_all_gl_extensions = ""; extString = ""; } } #ifdef WIN32 const char *wglString = 0; if (wglGetExtensionsStringEXT) wglString = wglGetExtensionsStringEXT(); if (wglString) { gl_extensions.EXT_swap_control_tear = strstr(wglString, "WGL_EXT_swap_control_tear") != 0; g_all_egl_extensions = wglString; } else { g_all_egl_extensions = ""; } #elif !defined(USING_GLES2) // const char *glXString = glXQueryExtensionString(); // gl_extensions.EXT_swap_control_tear = strstr(glXString, "GLX_EXT_swap_control_tear") != 0; #endif // Check the desktop extension instead of the OES one. They are very similar. // Also explicitly check those ATI devices that claims to support npot gl_extensions.OES_texture_npot = strstr(extString, "GL_ARB_texture_non_power_of_two") != 0 && !(((strncmp(renderer, "ATI RADEON X", 12) == 0) || (strncmp(renderer, "ATI MOBILITY RADEON X", 21) == 0))); gl_extensions.ARB_blend_func_extended = strstr(extString, "GL_ARB_blend_func_extended") != 0; gl_extensions.EXT_blend_func_extended = strstr(extString, "GL_EXT_blend_func_extended") != 0; gl_extensions.ARB_conservative_depth = strstr(extString, "GL_ARB_conservative_depth") != 0; gl_extensions.ARB_shader_image_load_store = (strstr(extString, "GL_ARB_shader_image_load_store") != 0) || (strstr(extString, "GL_EXT_shader_image_load_store") != 0); gl_extensions.EXT_bgra = strstr(extString, "GL_EXT_bgra") != 0; gl_extensions.EXT_gpu_shader4 = strstr(extString, "GL_EXT_gpu_shader4") != 0; gl_extensions.NV_framebuffer_blit = strstr(extString, "GL_NV_framebuffer_blit") != 0; gl_extensions.NV_copy_image = strstr(extString, "GL_NV_copy_image") != 0; gl_extensions.OES_copy_image = strstr(extString, "GL_OES_copy_image") != 0; gl_extensions.EXT_copy_image = strstr(extString, "GL_EXT_copy_image") != 0; gl_extensions.ARB_copy_image = strstr(extString, "GL_ARB_copy_image") != 0; gl_extensions.ARB_vertex_array_object = strstr(extString, "GL_ARB_vertex_array_object") != 0; gl_extensions.ARB_texture_float = strstr(extString, "GL_ARB_texture_float") != 0; if (gl_extensions.IsGLES) { gl_extensions.OES_texture_npot = strstr(extString, "GL_OES_texture_npot") != 0; gl_extensions.OES_packed_depth_stencil = (strstr(extString, "GL_OES_packed_depth_stencil") != 0) || gl_extensions.GLES3; gl_extensions.OES_depth24 = strstr(extString, "GL_OES_depth24") != 0; gl_extensions.OES_depth_texture = strstr(extString, "GL_OES_depth_texture") != 0; gl_extensions.OES_mapbuffer = strstr(extString, "GL_OES_mapbuffer") != 0; gl_extensions.EXT_blend_minmax = strstr(extString, "GL_EXT_blend_minmax") != 0; gl_extensions.EXT_unpack_subimage = strstr(extString, "GL_EXT_unpack_subimage") != 0; gl_extensions.EXT_shader_framebuffer_fetch = strstr(extString, "GL_EXT_shader_framebuffer_fetch") != 0; gl_extensions.NV_shader_framebuffer_fetch = strstr(extString, "GL_NV_shader_framebuffer_fetch") != 0; gl_extensions.ARM_shader_framebuffer_fetch = strstr(extString, "GL_ARM_shader_framebuffer_fetch") != 0; gl_extensions.OES_texture_float = strstr(extString, "GL_OES_texture_float") != 0; gl_extensions.OES_texture_half_float = strstr(extString, "GL_OES_texture_half_float") != 0; #if defined(__ANDROID__) // On Android, incredibly, this is not consistently non-zero! It does seem to have the same value though. // https://twitter.com/ID_AA_Carmack/status/387383037794603008 #ifdef _DEBUG void *invalidAddress = (void *)eglGetProcAddress("InvalidGlCall1"); void *invalidAddress2 = (void *)eglGetProcAddress("AnotherInvalidGlCall2"); DLOG("Addresses returned for invalid extensions: %p %p", invalidAddress, invalidAddress2); #endif // These are all the same. Let's alias. if (!gl_extensions.OES_copy_image) { if (gl_extensions.NV_copy_image) { glCopyImageSubDataOES = (decltype(glCopyImageSubDataOES))eglGetProcAddress("glCopyImageSubDataNV"); } else if (gl_extensions.EXT_copy_image) { glCopyImageSubDataOES = (decltype(glCopyImageSubDataOES))eglGetProcAddress("glCopyImageSubDataEXT"); } } if (gl_extensions.NV_framebuffer_blit) { glBlitFramebufferNV = (PFNGLBLITFRAMEBUFFERNVPROC)eglGetProcAddress("glBlitFramebufferNV"); } gl_extensions.OES_vertex_array_object = strstr(extString, "GL_OES_vertex_array_object") != 0; if (gl_extensions.OES_vertex_array_object) { glGenVertexArraysOES = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress("glGenVertexArraysOES"); glBindVertexArrayOES = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress("glBindVertexArrayOES"); glDeleteVertexArraysOES = (PFNGLDELETEVERTEXARRAYSOESPROC)eglGetProcAddress("glDeleteVertexArraysOES"); glIsVertexArrayOES = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress("glIsVertexArrayOES"); } // Hm, this should be available on iOS too. gl_extensions.EXT_discard_framebuffer = strstr(extString, "GL_EXT_discard_framebuffer") != 0; if (gl_extensions.EXT_discard_framebuffer) { glDiscardFramebufferEXT = (PFNGLDISCARDFRAMEBUFFEREXTPROC)eglGetProcAddress("glDiscardFramebufferEXT"); } #else gl_extensions.OES_vertex_array_object = false; gl_extensions.EXT_discard_framebuffer = false; #endif } else { // Desktops support minmax and subimage unpack (GL_UNPACK_ROW_LENGTH etc) gl_extensions.EXT_blend_minmax = true; gl_extensions.EXT_unpack_subimage = true; } // GLES 3 subsumes many ES2 extensions. if (gl_extensions.GLES3) { gl_extensions.EXT_unpack_subimage = true; } #if defined(__ANDROID__) if (gl_extensions.OES_mapbuffer) { glMapBuffer = (PFNGLMAPBUFFERPROC)eglGetProcAddress("glMapBufferOES"); } // Look for EGL extensions EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); const char *eglString = eglQueryString(display, EGL_EXTENSIONS); if (eglString) { g_all_egl_extensions = eglString; gl_extensions.EGL_NV_system_time = strstr(eglString, "EGL_NV_system_time") != 0; gl_extensions.EGL_NV_coverage_sample = strstr(eglString, "EGL_NV_coverage_sample") != 0; if (gl_extensions.EGL_NV_system_time) { eglGetSystemTimeNV = (PFNEGLGETSYSTEMTIMENVPROC)eglGetProcAddress("eglGetSystemTimeNV"); eglGetSystemTimeFrequencyNV = (PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC)eglGetProcAddress("eglGetSystemTimeFrequencyNV"); } } else { g_all_egl_extensions = ""; } #endif // This is probably a waste of time, implementations lie. if (gl_extensions.IsGLES || strstr(extString, "GL_ARB_ES2_compatibility")) { const GLint precisions[6] = { GL_LOW_FLOAT, GL_MEDIUM_FLOAT, GL_HIGH_FLOAT, GL_LOW_INT, GL_MEDIUM_INT, GL_HIGH_INT }; GLint shaderTypes[2] = { GL_VERTEX_SHADER, GL_FRAGMENT_SHADER }; for (int st = 0; st < 2; st++) { for (int p = 0; p < 6; p++) { glGetShaderPrecisionFormat(shaderTypes[st], precisions[p], gl_extensions.range[st][p], &gl_extensions.precision[st][p]); } } } gl_extensions.ARB_framebuffer_object = strstr(extString, "GL_ARB_framebuffer_object") != 0; gl_extensions.EXT_framebuffer_object = strstr(extString, "GL_EXT_framebuffer_object") != 0; gl_extensions.ARB_pixel_buffer_object = strstr(extString, "GL_ARB_pixel_buffer_object") != 0; gl_extensions.NV_pixel_buffer_object = strstr(extString, "GL_NV_pixel_buffer_object") != 0; if (!gl_extensions.IsGLES && gl_extensions.IsCoreContext) { // These are required, and don't need to be specified by the driver (they aren't on Apple.) gl_extensions.ARB_vertex_array_object = true; gl_extensions.ARB_framebuffer_object = true; } #ifdef __APPLE__ if (!gl_extensions.IsGLES && !gl_extensions.IsCoreContext) { // Apple doesn't allow OpenGL 3.x+ in compatibility contexts. gl_extensions.ForceGL2 = true; } #endif ProcessGPUFeatures(); int error = glGetError(); if (error) ELOG("GL error in init: %i", error); #endif }
int main (int argc, char** argv) { GLenum err; GLContext ctx; /* ---------------------------------------------------------------------- */ /* parse arguments */ if (GL_TRUE == ParseArgs(argc-1, argv+1)) { #if defined(_WIN32) fprintf(stderr, "Usage: visualinfo [-a] [-s] [-h] [-pf <id>]\n"); fprintf(stderr, " -a: show all visuals\n"); fprintf(stderr, " -s: display to stdout instead of visualinfo.txt\n"); fprintf(stderr, " -pf <id>: use given pixelformat\n"); fprintf(stderr, " -h: this screen\n"); #else fprintf(stderr, "Usage: visualinfo [-h] [-display <display>] [-visual <id>]\n"); fprintf(stderr, " -h: this screen\n"); fprintf(stderr, " -display <display>: use given display\n"); fprintf(stderr, " -visual <id>: use given visual\n"); #endif return 1; } /* ---------------------------------------------------------------------- */ /* create OpenGL rendering context */ InitContext(&ctx); if (GL_TRUE == CreateContext(&ctx)) { fprintf(stderr, "Error: CreateContext failed\n"); DestroyContext(&ctx); return 1; } /* ---------------------------------------------------------------------- */ /* initialize GLEW */ glewExperimental = GL_TRUE; #ifdef GLEW_MX err = glewContextInit(glewGetContext()); # ifdef _WIN32 err = err || wglewContextInit(wglewGetContext()); # elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) err = err || glxewContextInit(glxewGetContext()); # endif #else err = glewInit(); #endif if (GLEW_OK != err) { fprintf(stderr, "Error [main]: glewInit failed: %s\n", glewGetErrorString(err)); DestroyContext(&ctx); return 1; } /* ---------------------------------------------------------------------- */ /* open file */ #if defined(_WIN32) if (!displaystdout) file = fopen("visualinfo.txt", "w"); if (file == NULL) file = stdout; #else file = stdout; #endif /* ---------------------------------------------------------------------- */ /* output header information */ /* OpenGL extensions */ fprintf(file, "OpenGL vendor string: %s\n", glGetString(GL_VENDOR)); fprintf(file, "OpenGL renderer string: %s\n", glGetString(GL_RENDERER)); fprintf(file, "OpenGL version string: %s\n", glGetString(GL_VERSION)); fprintf(file, "OpenGL extensions (GL_): \n"); PrintExtensions((char*)glGetString(GL_EXTENSIONS)); /* GLU extensions */ fprintf(file, "GLU version string: %s\n", gluGetString(GLU_VERSION)); fprintf(file, "GLU extensions (GLU_): \n"); PrintExtensions((char*)gluGetString(GLU_EXTENSIONS)); /* ---------------------------------------------------------------------- */ /* extensions string */ #if defined(_WIN32) /* WGL extensions */ if (WGLEW_ARB_extensions_string || WGLEW_EXT_extensions_string) { fprintf(file, "WGL extensions (WGL_): \n"); PrintExtensions(wglGetExtensionsStringARB ? (char*)wglGetExtensionsStringARB(ctx.dc) : (char*)wglGetExtensionsStringEXT()); } #elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) #else /* GLX extensions */ fprintf(file, "GLX extensions (GLX_): \n"); PrintExtensions(glXQueryExtensionsString(glXGetCurrentDisplay(), DefaultScreen(glXGetCurrentDisplay()))); #endif /* ---------------------------------------------------------------------- */ /* enumerate all the formats */ VisualInfo(&ctx); /* ---------------------------------------------------------------------- */ /* release resources */ DestroyContext(&ctx); if (file != stdout) fclose(file); return 0; }
bool VDOpenGLBinding::Attach(HDC hdc, int minColorBits, int minAlphaBits, int minDepthBits, int minStencilBits, bool doubleBuffer) { PIXELFORMATDESCRIPTOR pfd= {}; pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; if (doubleBuffer) pfd.dwFlags |= PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = minColorBits; pfd.cAlphaBits = minAlphaBits; pfd.cDepthBits = minDepthBits; pfd.cStencilBits = minStencilBits; pfd.iLayerType = PFD_MAIN_PLANE; int pf = ChoosePixelFormat(hdc, &pfd); if (!pf) { Detach(); return false; } if (!SetPixelFormat(hdc, pf, &pfd)) { Detach(); return false; } mhglrc = wglCreateContext(hdc); if (!mhglrc) return false; if (!Begin(hdc)) { Detach(); return false; } for(int i=0; i<sizeof(kGLFunctions)/sizeof(kGLFunctions[0]); ++i) { void *p = (void *)GetProcAddress(mhmodOGL, kGLFunctions[i]); if (!p) { Detach(); return false; } ((void **)static_cast<VDAPITableOpenGL *>(this))[i] = p; } for(int i=0; i<sizeof(kGLExtFunctions)/sizeof(kGLExtFunctions[0]); ++i) { void *p = (void *)wglGetProcAddress(kGLExtFunctions[i]); ((void **)static_cast<VDAPITableOpenGLEXT *>(this))[i] = p; } const char *ext = (const char *)glGetString(GL_EXTENSIONS); ARB_fragment_program = false; ARB_multitexture = false; ARB_pixel_buffer_object = false; ARB_vertex_program = false; ATI_fragment_shader = false; EXT_blend_minmax = false; EXT_blend_subtract = false; EXT_framebuffer_object = false; EXT_pixel_buffer_object = false; EXT_texture_env_combine = false; EXT_texture_edge_clamp = false; NV_occlusion_query = false; NV_register_combiners = false; NV_register_combiners2 = false; if (ext) { for(;;) { while(*ext == ' ') ++ext; if (!*ext) break; const char *start = ext; while(*ext && *ext != ' ') ++ext; int len = ext - start; switch(len) { case 19: if (!memcmp(start, "GL_ARB_multitexture", 19)) ARB_multitexture = true; else if (!memcmp(start, "GL_EXT_blend_minmax", 19)) EXT_blend_minmax = true; break; case 20: if (!memcmp(start, "GL_EXT_blend_subtract", 20)) EXT_blend_subtract = true; break; case 21: if (!memcmp(start, "GL_NV_occlusion_query", 21)) NV_occlusion_query = true; else if (!memcmp(start, "GL_ARB_vertex_program", 21)) ARB_vertex_program = true; break; case 22: if (!memcmp(start, "GL_ATI_fragment_shader", 22)) ATI_fragment_shader = true; else if (!memcmp(start, "GL_EXT_secondary_color", 22)) EXT_secondary_color = true; break; case 23: if (!memcmp(start, "GL_ARB_fragment_program", 23)) ARB_fragment_program = true; break; case 24: if (!memcmp(start, "GL_NV_register_combiners", 24)) NV_register_combiners = true; break; case 25: if (!memcmp(start, "GL_NV_register_combiners2", 25)) NV_register_combiners2 = true; else if (!memcmp(start, "GL_EXT_framebuffer_object", 25)) EXT_framebuffer_object = true; else if (!memcmp(start, "GL_EXT_texture_edge_clamp", 25)) EXT_texture_edge_clamp = true; break; case 26: if (!memcmp(start, "GL_EXT_pixel_buffer_object", 26)) EXT_pixel_buffer_object = true; else if (!memcmp(start, "GL_ARB_pixel_buffer_object", 26)) EXT_pixel_buffer_object = ARB_pixel_buffer_object = true; else if (!memcmp(start, "GL_EXT_texture_env_combine", 26)) EXT_texture_env_combine = true; else if (!memcmp(start, "GL_ARB_texture_env_combine", 26)) EXT_texture_env_combine = true; break; } } } ext = NULL; if (wglGetExtensionsStringARB) ext = wglGetExtensionsStringARB(hdc); else if (wglGetExtensionsStringEXT) ext = wglGetExtensionsStringEXT(); EXT_swap_control = false; ARB_make_current_read = false; if (ext) { for(;;) { while(*ext == ' ') ++ext; if (!*ext) break; const char *start = ext; while(*ext && *ext != ' ') ++ext; int len = ext - start; switch(len) { case 20: if (!memcmp(start, "WGL_EXT_swap_control", 20)) EXT_swap_control = true; break; case 25: if (!memcmp(start, "WGL_ARB_make_current_read", 25)) ARB_make_current_read = true; break; } } } End(); return true; }