|  | /****************************************************************************** | 
|  |  | 
|  | @File         OGLES2/PVRTgles2Ext.cpp | 
|  |  | 
|  | @Title        OGLES2/PVRTgles2Ext | 
|  |  | 
|  | @Version | 
|  |  | 
|  | @Copyright    Copyright (c) Imagination Technologies Limited. | 
|  |  | 
|  | @Platform     Independent | 
|  |  | 
|  | @Description  OpenGL ES 2.0 extensions | 
|  |  | 
|  | ******************************************************************************/ | 
|  | #include <string.h> | 
|  |  | 
|  | #include "PVRTContext.h" | 
|  | #include "PVRTgles2Ext.h" | 
|  |  | 
|  | /**************************************************************************** | 
|  | ** Local code | 
|  | ****************************************************************************/ | 
|  |  | 
|  | /**************************************************************************** | 
|  | ** Class: CPVRTgles2Ext | 
|  | ****************************************************************************/ | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @Function			LoadExtensions | 
|  | @Description		Initialises IMG extensions | 
|  | *****************************************************************************/ | 
|  | void CPVRTgles2Ext::LoadExtensions() | 
|  | { | 
|  | glMultiDrawElementsEXT = 0; | 
|  | glMultiDrawArraysEXT = 0; | 
|  | glMapBufferOES = 0; | 
|  | glUnmapBufferOES = 0; | 
|  | glGetBufferPointervOES = 0; | 
|  | glDiscardFramebufferEXT = 0; | 
|  | glBindVertexArrayOES = 0; | 
|  | glDeleteVertexArraysOES = 0; | 
|  | glGenVertexArraysOES = 0; | 
|  | glIsVertexArrayOES = 0; | 
|  | glRenderbufferStorageMultisampleIMG = 0; | 
|  | glFramebufferTexture2DMultisampleIMG = 0; | 
|  | glGenQueriesEXT = 0; | 
|  | glDeleteQueriesEXT = 0; | 
|  | glIsQueryEXT = 0; | 
|  | glBeginQueryEXT = 0; | 
|  | glEndQueryEXT = 0; | 
|  | glGetQueryivEXT = 0; | 
|  | glGetQueryObjectuivEXT = 0; | 
|  | glRenderbufferStorageMultisampleANGLE = 0; | 
|  | glBlitFramebufferNV = 0; | 
|  | glTexImage3DOES = 0; | 
|  | glTexSubImage3DOES = 0; | 
|  | glCopyTexSubImage3DOES = 0; | 
|  | glCompressedTexImage3DOES = 0; | 
|  | glCompressedTexSubImage3DOES = 0; | 
|  | glFramebufferTexture3DOES = 0; | 
|  | glDrawBuffersEXT = 0; | 
|  |  | 
|  | // Supported extensions provide new entry points for OpenGL ES 2.0. | 
|  |  | 
|  | const GLubyte *pszGLExtensions; | 
|  |  | 
|  | /* Retrieve GL extension string */ | 
|  | pszGLExtensions = glGetString(GL_EXTENSIONS); | 
|  |  | 
|  | #if !defined(TARGET_OS_IPHONE) | 
|  | /* GL_EXT_multi_draw_arrays */ | 
|  | if (strstr((char *)pszGLExtensions, "GL_EXT_multi_draw_arrays")) | 
|  | { | 
|  | glMultiDrawElementsEXT = (PFNGLMULTIDRAWELEMENTS) PVRGetProcAddress(glMultiDrawElementsEXT); | 
|  | glMultiDrawArraysEXT = (PFNGLMULTIDRAWARRAYS) PVRGetProcAddress(glMultiDrawArraysEXT); | 
|  | } | 
|  |  | 
|  | /* GL_EXT_multi_draw_arrays */ | 
|  | if (strstr((char *)pszGLExtensions, "GL_OES_mapbuffer")) | 
|  | { | 
|  | glMapBufferOES = (PFNGLMAPBUFFEROES) PVRGetProcAddress(glMapBufferOES); | 
|  | glUnmapBufferOES = (PFNGLUNMAPBUFFEROES) PVRGetProcAddress(glUnmapBufferOES); | 
|  | glGetBufferPointervOES = (PFNGLGETBUFFERPOINTERVOES) PVRGetProcAddress(glGetBufferPointervOES); | 
|  | } | 
|  |  | 
|  | /* GL_OES_vertex_array_object */ | 
|  | if (strstr((char *)pszGLExtensions, "GL_OES_vertex_array_object")) | 
|  | { | 
|  | glBindVertexArrayOES = (PFNGLBINDVERTEXARRAYOES) PVRGetProcAddress(glBindVertexArrayOES); | 
|  | glDeleteVertexArraysOES = (PFNGLDELETEVERTEXARRAYSOES) PVRGetProcAddress(glDeleteVertexArraysOES); | 
|  | glGenVertexArraysOES = (PFNGLGENVERTEXARRAYSOES) PVRGetProcAddress(glGenVertexArraysOES); | 
|  | glIsVertexArrayOES = (PFNGLISVERTEXARRAYOES) PVRGetProcAddress(glIsVertexArrayOES); | 
|  | } | 
|  |  | 
|  | /* GL_IMG_multisampled_render_to_texture */ | 
|  | if (strstr((char *)pszGLExtensions, "GL_IMG_multisampled_render_to_texture")) | 
|  | { | 
|  | glRenderbufferStorageMultisampleIMG = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMG) PVRGetProcAddress(glRenderbufferStorageMultisampleIMG); | 
|  | glFramebufferTexture2DMultisampleIMG = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMG) PVRGetProcAddress(glFramebufferTexture2DMultisampleIMG); | 
|  | } | 
|  |  | 
|  | /* GL_ANGLE_framebuffer_multisample */ | 
|  | if (strstr((char *)pszGLExtensions, "GL_ANGLE_framebuffer_multisample")) | 
|  | { | 
|  | glRenderbufferStorageMultisampleANGLE = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC)PVRGetProcAddress(glRenderbufferStorageMultisampleANGLE); | 
|  | } | 
|  |  | 
|  | /* GL_NV_framebuffer_blit */ | 
|  | if (strstr((char *)pszGLExtensions, "GL_NV_framebuffer_blit")) | 
|  | { | 
|  | glBlitFramebufferNV = (PFNGLBLITFRAMEBUFFERNVPROC) PVRGetProcAddress(glBlitFramebufferNV); | 
|  | } | 
|  |  | 
|  | /* GL_OES_texture_3D */ | 
|  | if(strstr((char *)pszGLExtensions, "GL_OES_texture_3D")) | 
|  | { | 
|  | glTexImage3DOES = (PFNGLTEXIMAGE3DOES) PVRGetProcAddress(glTexImage3DOES); | 
|  | glTexSubImage3DOES = (PFNGLTEXSUBIMAGE3DOES) PVRGetProcAddress(glTexSubImage3DOES); | 
|  | glCopyTexSubImage3DOES = (PFNGLCOPYTEXSUBIMAGE3DOES) PVRGetProcAddress(glCopyTexSubImage3DOES); | 
|  | glCompressedTexImage3DOES = (PFNGLCOMPRESSEDTEXIMAGE3DOES) PVRGetProcAddress(glCompressedTexImage3DOES); | 
|  | glCompressedTexSubImage3DOES = (PFNGLCOMPRESSEDTEXSUBIMAGE3DOES) PVRGetProcAddress(glCompressedTexSubImage3DOES); | 
|  | glFramebufferTexture3DOES = (PFNGLFRAMEBUFFERTEXTURE3DOES) PVRGetProcAddress(glFramebufferTexture3DOES); | 
|  | } | 
|  |  | 
|  | /* GL_EXT_draw_buffers */ | 
|  | if (strstr((char *)pszGLExtensions, "GL_EXT_draw_buffers")) | 
|  | { | 
|  | glDrawBuffersEXT = (PFNGLDRAWBUFFERSEXT) PVRGetProcAddress(glDrawBuffersEXT); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | #if defined(GL_EXT_discard_framebuffer) | 
|  | /* GL_EXT_discard_framebuffer */ | 
|  | if (strstr((char *)pszGLExtensions, "GL_EXT_discard_framebuffer")) | 
|  | { | 
|  | glDiscardFramebufferEXT = (PFNGLDISCARDFRAMEBUFFEREXT) PVRGetProcAddress(glDiscardFramebufferEXT); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | /* GL_EXT_occlusion_query_boolean */ | 
|  | if (strstr((char *)pszGLExtensions, "GL_EXT_occlusion_query_boolean")) | 
|  | { | 
|  | glGenQueriesEXT = (PFNGLGENQUERIESEXT) PVRGetProcAddress(glGenQueriesEXT); | 
|  | glDeleteQueriesEXT = (PFNGLDELETEQUERIESEXT) PVRGetProcAddress(glDeleteQueriesEXT); | 
|  | glIsQueryEXT = (PFNGLISQUERYEXT) PVRGetProcAddress(glIsQueryEXT); | 
|  | glBeginQueryEXT = (PFNGLBEGINQUERYEXT) PVRGetProcAddress(glBeginQueryEXT); | 
|  | glEndQueryEXT = (PFNGLENDQUERYEXT) PVRGetProcAddress(glEndQueryEXT); | 
|  | glGetQueryivEXT = (PFNGLGETQUERYIVEXT) PVRGetProcAddress(glGetQueryivEXT); | 
|  | glGetQueryObjectuivEXT = (PFNGLGETQUERYOBJECTUIVEXT) PVRGetProcAddress(glGetQueryObjectuivEXT); | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @Function			IsGLExtensionSupported | 
|  | @Input				extension extension to query for | 
|  | @Returns			True if the extension is supported | 
|  | @Description		Queries for support of an extension | 
|  | *************************************************************************/ | 
|  | bool CPVRTgles2Ext::IsGLExtensionSupported(const char * const extension) | 
|  | { | 
|  | // The recommended technique for querying OpenGL extensions; | 
|  | // from http://opengl.org/resources/features/OGLextensions/ | 
|  | 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; | 
|  |  | 
|  | extensions = glGetString(GL_EXTENSIONS); | 
|  |  | 
|  | /* 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 true; | 
|  | start = terminator; | 
|  | } | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /***************************************************************************** | 
|  | End of file (PVRTglesExt.cpp) | 
|  | *****************************************************************************/ | 
|  |  |