Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,4 @@ Release*
*VC.db
*.vcxproj
*.vcxproj.filters
*.depend
91 changes: 65 additions & 26 deletions src/SOIL.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,59 @@ int query_DXT_capability( void );
#define SOIL_RGBA_S3TC_DXT5 0x83F3
typedef void (APIENTRY * P_SOIL_GLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid * data);
P_SOIL_GLCOMPRESSEDTEXIMAGE2DPROC soilGlCompressedTexImage2D = NULL;
typedef const GLubyte* (APIENTRY * P_SOIL_GLGETSTRINGIPROC) (GLenum name, GLuint index);

/**
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=727175

"Most SOIL functions crash if OpenGL context is 3.2+ core profile. SOIL calls
glGetString with a value that is no longer valid, and then sends the returned
null pointer to strstr.

This patch checks the OpenGL version at runtime, and uses a glGetString function
that is appropriate and available. It doesn't crash if, for whatever reason,
glGetString returns a null pointer."

- Thanks to Brandon!

**/
static int SOIL_internal_has_OGL_capability(const char * cap)
{
int i;
GLint num_ext;
const GLubyte * ext_string;
int major_version;

const GLubyte * ver_string = glGetString(GL_VERSION);
if (ver_string)
major_version = atoi((const char *) ver_string);
else
major_version = 0;

P_SOIL_GLGETSTRINGIPROC soilGlGetStringi =
(P_SOIL_GLGETSTRINGIPROC) glXGetProcAddressARB((const GLubyte *) "glGetStringi");

if (major_version >= 3 && soilGlGetStringi) {
// OpenGL 3.0+
glGetIntegerv(GL_NUM_EXTENSIONS, &num_ext);
for (i = 0; i < num_ext; i++) {
ext_string = soilGlGetStringi(GL_EXTENSIONS, i);
if (ext_string && !strcmp((const char *) ext_string, cap)) {
return GL_TRUE;
}
}
}
else {
// OpenGL < 3.0
ext_string = glGetString(GL_EXTENSIONS);
if (ext_string && strstr((const char *) ext_string, cap)) {
return GL_TRUE;
}
}
return GL_FALSE;
}


unsigned int SOIL_direct_load_DDS(
const char *filename,
unsigned int reuse_texture_ID,
Expand Down Expand Up @@ -1878,19 +1931,14 @@ unsigned int SOIL_direct_load_DDS(
return tex_ID;
}

// GL_ARB_texture_non_power_of_two is a core feature in OpenGL 2.0
int query_NPOT_capability( void )
{
/* check for the capability */
if( has_NPOT_capability == SOIL_CAPABILITY_UNKNOWN )
{
/* we haven't yet checked for the capability, do so */
if(
(NULL == strstr( (char const*)glGetString( GL_EXTENSIONS ),
"GL_ARB_texture_non_power_of_two" ) )
&&
(NULL == strstr( (char const*)glGetString( GL_EXTENSIONS ),
"GL_OES_texture_npot" ) )
)
if( !SOIL_internal_has_OGL_capability( "GL_ARB_texture_non_power_of_two" ))
{
/* not there, flag the failure */
has_NPOT_capability = SOIL_CAPABILITY_NONE;
Expand All @@ -1904,22 +1952,16 @@ int query_NPOT_capability( void )
return has_NPOT_capability;
}

// GL_ARB_texture_rectangle is a core feature in OpenGL 3.1
int query_tex_rectangle_capability( void )
{
/* check for the capability */
if( has_tex_rectangle_capability == SOIL_CAPABILITY_UNKNOWN )
{
/* we haven't yet checked for the capability, do so */
if(
(NULL == strstr( (char const*)glGetString( GL_EXTENSIONS ),
"GL_ARB_texture_rectangle" ) )
&&
(NULL == strstr( (char const*)glGetString( GL_EXTENSIONS ),
"GL_EXT_texture_rectangle" ) )
&&
(NULL == strstr( (char const*)glGetString( GL_EXTENSIONS ),
"GL_NV_texture_rectangle" ) )
)
if( !SOIL_internal_has_OGL_capability( "GL_ARB_texture_rectangle" ) &&
!SOIL_internal_has_OGL_capability( "GL_EXT_texture_rectangle" ) &&
!SOIL_internal_has_OGL_capability( "GL_NV_texture_rectangle" ) )
{
/* not there, flag the failure */
has_tex_rectangle_capability = SOIL_CAPABILITY_NONE;
Expand All @@ -1933,18 +1975,15 @@ int query_tex_rectangle_capability( void )
return has_tex_rectangle_capability;
}

// GL_ARB_texture_cube_map is a core feature in OpenGL 1.3
int query_cubemap_capability( void )
{
/* check for the capability */
if( has_cubemap_capability == SOIL_CAPABILITY_UNKNOWN )
{
/* we haven't yet checked for the capability, do so */
if(
(NULL == strstr( (char const*)glGetString( GL_EXTENSIONS ),
"GL_ARB_texture_cube_map" ) )
&&
(NULL == strstr( (char const*)glGetString( GL_EXTENSIONS ),
"GL_EXT_texture_cube_map" ) )
if( !SOIL_internal_has_OGL_capability( "GL_ARB_texture_cube_map" ) &&
!SOIL_internal_has_OGL_capability( "GL_EXT_texture_cube_map" )
#ifdef GL_ES_VERSION_2_0
&& (0) /* GL ES 2.0 supports cubemaps, always enable */
#endif
Expand All @@ -1962,15 +2001,15 @@ int query_cubemap_capability( void )
return has_cubemap_capability;
}

// GL_EXT_texture_compression_s3tc does not appear to be a core feature in any
// version of OpenGL up to 4.4
int query_DXT_capability( void )
{
/* check for the capability */
if( has_DXT_capability == SOIL_CAPABILITY_UNKNOWN )
{
/* we haven't yet checked for the capability, do so */
if( NULL == strstr(
(char const*)glGetString( GL_EXTENSIONS ),
"GL_EXT_texture_compression_s3tc" ) )
if( !SOIL_internal_has_OGL_capability( "GL_EXT_texture_compression_s3tc" ) )
{
/* not there, flag the failure */
has_DXT_capability = SOIL_CAPABILITY_NONE;
Expand Down