@ -622,57 +622,75 @@ Shader& Shader::addFile(const std::string& filename) {
return * this ;
return * this ;
}
}
bool Shader : : compile ( ) {
bool Shader : : compile ( std : : initializer_list < std : : reference_wrapper < Shader > > shaders ) {
CORRADE_ASSERT ( _sources . size ( ) > 1 , " Shader::compile(): no files added " , false ) ;
bool allSuccess = true ;
/* Array of source string pointers and their lengths */
/* Allocate large enough array for source pointers and sizes (to avoid
/** @todo Use `Containers::ArrayTuple` to avoid one allocation if it ever
reallocating it for each of them ) */
gets to be implemented ( we need properly aligned memory too ) */
std : : size_t maxSourceCount = 0 ;
Containers : : Array < const GLchar * > pointers ( _sources . size ( ) ) ;
for ( Shader & shader : shaders ) {
Containers : : Array < GLint > sizes ( _sources . size ( ) ) ;
CORRADE_ASSERT ( shader . _sources . size ( ) > 1 , " Shader::compile(): no files added " , false ) ;
for ( std : : size_t i = 0 ; i ! = _sources . size ( ) ; + + i ) {
maxSourceCount = std : : max ( shader . _sources . size ( ) , maxSourceCount ) ;
pointers [ i ] = static_cast < const GLchar * > ( _sources [ i ] . data ( ) ) ;
sizes [ i ] = _sources [ i ] . size ( ) ;
}
}
Containers : : Array < const GLchar * > pointers ( maxSourceCount ) ;
Containers : : Array < GLint > sizes ( maxSourceCount ) ;
/* Create shader and set its source */
/* Upload sources of all shaders */
glShaderSource ( _id , _sources . size ( ) , pointers , sizes ) ;
for ( Shader & shader : shaders ) {
for ( std : : size_t i = 0 ; i ! = shader . _sources . size ( ) ; + + i ) {
/* Compile shader */
pointers [ i ] = static_cast < const GLchar * > ( shader . _sources [ i ] . data ( ) ) ;
glCompileShader ( _id ) ;
sizes [ i ] = shader . _sources [ i ] . size ( ) ;
}
/* Check compilation status */
GLint success , logLength ;
glShaderSource ( shader . _id , shader . _sources . size ( ) , pointers , sizes ) ;
glGetShaderiv ( _id , GL_COMPILE_STATUS , & success ) ;
}
glGetShaderiv ( _id , GL_INFO_LOG_LENGTH , & logLength ) ;
/* Invoke (possibly parallel) compilation on all shaders */
/* Error or warning message. The string is returned null-terminated, scrap
for ( Shader & shader : shaders ) glCompileShader ( shader . _id ) ;
the \ 0 at the end afterwards */
std : : string message ( logLength , ' \0 ' ) ;
/* After compilation phase, check status of all shaders */
if ( message . size ( ) > 1 )
Int i = 1 ;
glGetShaderInfoLog ( _id , message . size ( ) , nullptr , & message [ 0 ] ) ;
for ( Shader & shader : shaders ) {
message . resize ( std : : max ( logLength , 1 ) - 1 ) ;
GLint success , logLength ;
glGetShaderiv ( shader . _id , GL_COMPILE_STATUS , & success ) ;
/* Show error log */
glGetShaderiv ( shader . _id , GL_INFO_LOG_LENGTH , & logLength ) ;
if ( ! success ) {
Error out ;
/* Error or warning message. The string is returned null-terminated,
out . setFlag ( Debug : : NewLineAtTheEnd , false ) ;
scrap the \ 0 at the end afterwards */
out . setFlag ( Debug : : SpaceAfterEachValue , false ) ;
std : : string message ( logLength , ' \0 ' ) ;
out < < " Shader: " < < shaderName ( _type )
if ( message . size ( ) > 1 )
< < " shader failed to compile with the following message: \n "
glGetShaderInfoLog ( shader . _id , message . size ( ) , nullptr , & message [ 0 ] ) ;
< < message ;
message . resize ( std : : max ( logLength , 1 ) - 1 ) ;
/* Or just message, if any */
/* Show error log */
} else if ( ! message . empty ( ) ) {
if ( ! success ) {
Error out ;
Error out ;
out . setFlag ( Debug : : NewLineAtTheEnd , false ) ;
out . setFlag ( Debug : : NewLineAtTheEnd , false ) ;
out . setFlag ( Debug : : SpaceAfterEachValue , false ) ;
out . setFlag ( Debug : : SpaceAfterEachValue , false ) ;
out < < " Shader: " < < shaderName ( _type )
out < < " Shader::compile(): compilation of " < < shaderName ( shader . _type )
< < " shader was successfully compiled with the following message: \n "
< < " shader " ;
< < message ;
if ( shaders . size ( ) ! = 1 ) out < < ' ' < < std : : to_string ( i ) ;
out < < " failed with the following message: \n "
< < message ;
/* Or just warnings, if any */
} else if ( ! message . empty ( ) ) {
Error out ;
out . setFlag ( Debug : : NewLineAtTheEnd , false ) ;
out . setFlag ( Debug : : SpaceAfterEachValue , false ) ;
out < < " Shader::compile(): compilation of " < < shaderName ( shader . _type )
< < " shader " ;
if ( shaders . size ( ) ! = 1 ) out < < ' ' < < std : : to_string ( i ) ;
out < < " succeeded with the following message: \n "
< < message ;
}
/* Success of all depends on each of them */
allSuccess = allSuccess & & success ;
+ + i ;
}
}
return success ;
return allS uccess;
}
}
# ifndef DOXYGEN_GENERATING_OUTPUT
# ifndef DOXYGEN_GENERATING_OUTPUT