@ -29,12 +29,14 @@
# include <Corrade/Containers/Array.h>
# include <Corrade/Containers/Array.h>
# include <Corrade/Containers/Iterable.h>
# include <Corrade/Containers/Iterable.h>
# include <Corrade/Containers/Pair.h>
# include <Corrade/Containers/StridedArrayView.h>
# include <Corrade/Containers/StridedArrayView.h>
# ifndef MAGNUM_TARGET_WEBGL
# ifndef MAGNUM_TARGET_WEBGL
# include <Corrade/Containers/String.h>
# include <Corrade/Containers/String.h>
# endif
# endif
# include <Corrade/Containers/StringStl.h> /** @todo remove once <string>-free */
# include <Corrade/Containers/StringStl.h> /** @todo remove once <string>-free */
# include <Corrade/Containers/Reference.h>
# include <Corrade/Containers/Reference.h>
# include <Corrade/Utility/Algorithms.h>
# include <Corrade/Utility/DebugStl.h>
# include <Corrade/Utility/DebugStl.h>
# include "Magnum/GL/Context.h"
# include "Magnum/GL/Context.h"
@ -340,7 +342,7 @@ AbstractShaderProgram& AbstractShaderProgram::setLabel(const Containers::StringV
}
}
# endif
# endif
std : : p air< bool , std : : s tring> AbstractShaderProgram : : validate ( ) {
Container s: : P air< bool , Container s: : S tring> AbstractShaderProgram : : validate ( ) {
glValidateProgram ( _id ) ;
glValidateProgram ( _id ) ;
/* Check validation status */
/* Check validation status */
@ -350,12 +352,11 @@ std::pair<bool, std::string> AbstractShaderProgram::validate() {
/* Error or warning message. The string is returned null-terminated, scrap
/* Error or warning message. The string is returned null-terminated, scrap
the \ 0 at the end afterwards */
the \ 0 at the end afterwards */
std : : string message ( logLength , ' \n ' ) ;
Container s: : String message ( ValueInit , Math : : max ( logLength , 1 ) - 1 ) ;
if ( message . size ( ) > 1 )
if ( message . size ( ) > 1 )
glGetProgramInfoLog ( _id , message . size ( ) , nullptr , & message [ 0 ] ) ;
glGetProgramInfoLog ( _id , message . size ( ) , nullptr , & message [ 0 ] ) ;
message . resize ( Math : : max ( logLength , 1 ) - 1 ) ;
return { success , std : : move ( message ) } ;
return { bool ( success ) , std : : move ( message ) } ;
}
}
AbstractShaderProgram & AbstractShaderProgram : : draw ( Mesh & mesh ) {
AbstractShaderProgram & AbstractShaderProgram : : draw ( Mesh & mesh ) {
@ -554,32 +555,35 @@ void AbstractShaderProgram::bindFragmentDataLocationIndexedInternal(const Unsign
# endif
# endif
# ifndef MAGNUM_TARGET_GLES2
# ifndef MAGNUM_TARGET_GLES2
void AbstractShaderProgram : : setTransformFeedbackOutputs ( const Containers : : ArrayView < const std : : s tring> outputs , const TransformFeedbackBufferMode bufferMode ) {
void AbstractShaderProgram : : setTransformFeedbackOutputs ( const Containers : : ArrayView < const Container s: : S tring> outputs , const TransformFeedbackBufferMode bufferMode ) {
( this - > * Context : : current ( ) . state ( ) . shaderProgram . transformFeedbackVaryingsImplementation ) ( outputs , bufferMode ) ;
( this - > * Context : : current ( ) . state ( ) . shaderProgram . transformFeedbackVaryingsImplementation ) ( outputs , bufferMode ) ;
}
}
void AbstractShaderProgram : : setTransformFeedbackOutputs ( const std : : initializer_list < std : : s tring> outputs , const TransformFeedbackBufferMode bufferMode ) {
void AbstractShaderProgram : : setTransformFeedbackOutputs ( const std : : initializer_list < Container s: : S tring> outputs , const TransformFeedbackBufferMode bufferMode ) {
setTransformFeedbackOutputs ( Containers : : arrayView ( outputs ) , bufferMode ) ;
setTransformFeedbackOutputs ( Containers : : arrayView ( outputs ) , bufferMode ) ;
}
}
void AbstractShaderProgram : : transformFeedbackVaryingsImplementationDefault ( const Containers : : ArrayView < const std : : s tring> outputs , const TransformFeedbackBufferMode bufferMode ) {
void AbstractShaderProgram : : transformFeedbackVaryingsImplementationDefault ( const Containers : : ArrayView < const Container s: : S tring> outputs , const TransformFeedbackBufferMode bufferMode ) {
/** @todo VLAs */
/** @todo VLAs */
Containers : : Array < const char * > names { outputs . size ( ) } ;
Containers : : Array < const char * > names { outputs . size ( ) } ;
Int i = 0 ;
Int i = 0 ;
for ( const std : : s tring& output : outputs ) names [ i + + ] = output . data ( ) ;
for ( const Container s: : S tring& output : outputs ) names [ i + + ] = output . data ( ) ;
glTransformFeedbackVaryings ( _id , outputs . size ( ) , names , GLenum ( bufferMode ) ) ;
glTransformFeedbackVaryings ( _id , outputs . size ( ) , names , GLenum ( bufferMode ) ) ;
}
}
# ifdef CORRADE_TARGET_WINDOWS
# ifdef CORRADE_TARGET_WINDOWS
void AbstractShaderProgram : : transformFeedbackVaryingsImplementationDanglingWorkaround ( const Containers : : ArrayView < const std : : s tring> outputs , const TransformFeedbackBufferMode bufferMode ) {
void AbstractShaderProgram : : transformFeedbackVaryingsImplementationDanglingWorkaround ( const Containers : : ArrayView < const Container s: : S tring> outputs , const TransformFeedbackBufferMode bufferMode ) {
/* NVidia on Windows doesn't copy the names when calling
/* NVidia on Windows doesn't copy the names when calling
glTransformFeedbackVaryings ( ) so it then fails at link time because the
glTransformFeedbackVaryings ( ) so it then fails at link time because the
char * are dangling . We have to do the copy on the engine side and keep
char * are dangling . We have to do the copy on the engine side and keep
the values until link time ( which can happen any time and multiple
the values until link time ( which can happen any time and multiple
times , so basically for the remaining lifetime of the shader program ) */
times , so basically for the remaining lifetime of the shader program ) */
_transformFeedbackVaryingNames . assign ( outputs . begin ( ) , outputs . end ( ) ) ;
_transformFeedbackVaryingNames =
Containers : : Array < Containers : : String > { ValueInit , outputs . size ( ) } ;
for ( size_t i = 0 ; i < outputs . size ( ) ; + + i )
_transformFeedbackVaryingNames [ i ] = outputs [ i ] ;
transformFeedbackVaryingsImplementationDefault ( { _transformFeedbackVaryingNames . data ( ) , _transformFeedbackVaryingNames . size ( ) } , bufferMode ) ;
transformFeedbackVaryingsImplementationDefault ( { _transformFeedbackVaryingNames . data ( ) , _transformFeedbackVaryingNames . size ( ) } , bufferMode ) ;
}
}
@ -608,10 +612,9 @@ bool AbstractShaderProgram::checkLink(const Containers::Iterable<Shader>& shader
/* Error or warning message. The string is returned null-terminated,
/* Error or warning message. The string is returned null-terminated,
strip the \ 0 at the end afterwards . */
strip the \ 0 at the end afterwards . */
std : : string message ( logLength , ' \n ' ) ;
Container s: : String message ( ValueInit , Math : : max ( logLength , 1 ) - 1 ) ;
if ( message . size ( ) > 1 )
if ( message . size ( ) > 1 )
glGetProgramInfoLog ( _id , message . size ( ) , nullptr , & message [ 0 ] ) ;
glGetProgramInfoLog ( _id , message . size ( ) , nullptr , & message [ 0 ] ) ;
message . resize ( Math : : max ( logLength , 1 ) - 1 ) ;
/* Some drivers are chatty and can't keep shut when there's nothing to
/* Some drivers are chatty and can't keep shut when there's nothing to
be said , handle that as well . */
be said , handle that as well . */
@ -655,16 +658,16 @@ bool AbstractShaderProgram::isLinkFinished() {
return success = = GL_TRUE ;
return success = = GL_TRUE ;
}
}
void AbstractShaderProgram : : cleanLogImplementationNoOp ( std : : s tring& ) { }
void AbstractShaderProgram : : cleanLogImplementationNoOp ( Container s: : S tring& ) { }
# if defined(CORRADE_TARGET_WINDOWS) && !defined(MAGNUM_TARGET_GLES)
# if defined(CORRADE_TARGET_WINDOWS) && !defined(MAGNUM_TARGET_GLES)
void AbstractShaderProgram : : cleanLogImplementationIntelWindows ( std : : s tring& message ) {
void AbstractShaderProgram : : cleanLogImplementationIntelWindows ( Container s: : S tring& message ) {
if ( message = = " No errors. \n " ) message = { } ;
if ( message = = " No errors. \n " ) message = { } ;
}
}
# endif
# endif
# if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL)
# if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL)
void AbstractShaderProgram : : cleanLogImplementationAngle ( std : : s tring& message ) {
void AbstractShaderProgram : : cleanLogImplementationAngle ( Container s: : S tring& message ) {
if ( message = = " \n " ) message = { } ;
if ( message = = " \n " ) message = { } ;
}
}
# endif
# endif
@ -676,7 +679,7 @@ void AbstractShaderProgram::completionStatusImplementationFallback(GLuint, GLenu
Int AbstractShaderProgram : : uniformLocationInternal ( const Containers : : ArrayView < const char > name ) {
Int AbstractShaderProgram : : uniformLocationInternal ( const Containers : : ArrayView < const char > name ) {
const GLint location = glGetUniformLocation ( _id , name ) ;
const GLint location = glGetUniformLocation ( _id , name ) ;
if ( location = = - 1 )
if ( location = = - 1 )
Warning { } < < " GL::AbstractShaderProgram: location of uniform \' " < < Debug : : nospace < < std : : s tring{ name , name . size ( ) } < < Debug : : nospace < < " \' cannot be retrieved " ;
Warning { } < < " GL::AbstractShaderProgram: location of uniform \' " < < Debug : : nospace < < Container s: : S tring{ name , name . size ( ) } < < Debug : : nospace < < " \' cannot be retrieved " ;
return location ;
return location ;
}
}
@ -684,7 +687,7 @@ Int AbstractShaderProgram::uniformLocationInternal(const Containers::ArrayView<c
UnsignedInt AbstractShaderProgram : : uniformBlockIndexInternal ( const Containers : : ArrayView < const char > name ) {
UnsignedInt AbstractShaderProgram : : uniformBlockIndexInternal ( const Containers : : ArrayView < const char > name ) {
const GLuint index = glGetUniformBlockIndex ( _id , name ) ;
const GLuint index = glGetUniformBlockIndex ( _id , name ) ;
if ( index = = GL_INVALID_INDEX )
if ( index = = GL_INVALID_INDEX )
Warning { } < < " GL::AbstractShaderProgram: index of uniform block \' " < < Debug : : nospace < < std : : s tring{ name , name . size ( ) } < < Debug : : nospace < < " \' cannot be retrieved " ;
Warning { } < < " GL::AbstractShaderProgram: index of uniform block \' " < < Debug : : nospace < < Container s: : S tring{ name , name . size ( ) } < < Debug : : nospace < < " \' cannot be retrieved " ;
return index ;
return index ;
}
}
# endif
# endif