diff --git a/doc/snippets/MagnumShaders.cpp b/doc/snippets/MagnumShaders.cpp index 55b3e5a9f..4e5313f62 100644 --- a/doc/snippets/MagnumShaders.cpp +++ b/doc/snippets/MagnumShaders.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "Magnum/ImageView.h" #include "Magnum/PixelFormat.h" @@ -34,10 +35,12 @@ #include "Magnum/GL/DefaultFramebuffer.h" #include "Magnum/GL/Framebuffer.h" #include "Magnum/GL/Mesh.h" +#include "Magnum/GL/Shader.h" #include "Magnum/GL/Renderbuffer.h" #include "Magnum/GL/RenderbufferFormat.h" #include "Magnum/GL/Texture.h" #include "Magnum/GL/TextureFormat.h" +#include "Magnum/GL/Version.h" #include "Magnum/Math/Color.h" #include "Magnum/Math/Matrix3.h" #include "Magnum/Math/Matrix4.h" @@ -269,6 +272,30 @@ mesh.setInstanceCount(Containers::arraySize(instanceData)) /* [Flat-usage-instancing] */ } +{ +struct: GL::AbstractShaderProgram { +void foo() { +/* [Generic-custom-bind] */ +bindAttributeLocation(Shaders::Generic3D::Position::Location, "position"); +bindAttributeLocation(Shaders::Generic3D::Normal::Location, "normal"); +/* [Generic-custom-bind] */ +} +} shader; +} + +{ +GL::Shader vert{GL::Version::None, GL::Shader::Type::Vertex}; +/* [Generic-custom-preprocessor] */ +vert.addSource(Utility::formatString( + "#define POSITION_ATTRIBUTE_LOCATION {}\n" + "#define NORMAL_ATTRIBUTE_LOCATION {}\n", + Shaders::Generic3D::Position::Location, + Shaders::Generic3D::Normal::Location)) + // … + .addFile("MyShader.vert"); +/* [Generic-custom-preprocessor] */ +} + { GL::Mesh mesh; /* [Phong-usage-instancing] */ diff --git a/src/Magnum/Shaders/Generic.h b/src/Magnum/Shaders/Generic.h index 43858c0cd..0bf5209f7 100644 --- a/src/Magnum/Shaders/Generic.h +++ b/src/Magnum/Shaders/Generic.h @@ -222,11 +222,34 @@ guarantees of the above: exactly one set of texture coordinates (as the additional sets would need additional transformations as well). -Note that while custom shaders don't have to follow the above, it's recommended -to so. If the custom shader diverges from predefined locations of common -attributes, meshes configured for the builtin shaders (for example with +@section Shaders-Generic-custom Generic attributes and custom shaders + +Note that while custom shaders don't *have to* follow the above, it's +recommended to so. If the custom shader diverges from predefined locations of +common attributes, meshes configured for the builtin shaders (for example with @ref MeshTools::compile()) won't work with it and the mesh attribute -configuration has to be done manually. +configuration has to be done manually. It also becomes impossible to render a +mesh configured for a custom shader with for example @ref MeshVisualizer. + +If you're using @ref GL::AbstractShaderProgram::bindAttributeLocation(), it's +rather easy, as you can simply use the @ref GL::Attribute::Location of given +attribute: + +@snippet MagnumShaders.cpp Generic-custom-bind + +For attribute location defined directly in shader code (which is the +recommended way unless you need compatibility with WebGL 1.0 and OpenGL ES +2.0), the attribute locations can be propagated using a preprocessor define. +For example: + +@snippet MagnumShaders.cpp Generic-custom-preprocessor + +Then, the attribute definition in a shader will look like this: + +@code{.glsl} +layout(location = POSITION_ATTRIBUTE_LOCATION) in vec3 position; +layout(location = NORMAL_ATTRIBUTE_LOCATION) in vec3 normal; +@endcode @see @ref shaders, @ref Generic2D, @ref Generic3D */