Browse Source

Phong

Signed-off-by: Squareys <squareys@googlemail.com>
pull/444/head
Squareys 6 years ago
parent
commit
68834eb9a8
  1. 4
      src/Magnum/Shaders/Generic.h
  2. 44
      src/Magnum/Shaders/Phong.cpp
  3. 85
      src/Magnum/Shaders/Phong.h
  4. 45
      src/Magnum/Shaders/Phong.vert
  5. 5
      src/Magnum/Shaders/generic.glsl

4
src/Magnum/Shaders/Generic.h

@ -470,10 +470,10 @@ struct BaseGeneric {
typedef GL::Attribute<4, UnsignedInt> ObjectId;
#endif
typedef GL::Attribute<6, Vector4> Weights;
typedef GL::Attribute<7, Vector4> JointIds;
typedef GL::Attribute<7, Vector4ui> JointIds;
typedef GL::Attribute<10, Vector4> SecondaryWeights;
typedef GL::Attribute<11, Vector4> SecondaryJointIds;
typedef GL::Attribute<11, Vector4ui> SecondaryJointIds;
typedef GL::Attribute<15, Vector2> TextureOffset;

44
src/Magnum/Shaders/Phong.cpp

@ -54,9 +54,13 @@ namespace {
};
}
Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _lightCount{lightCount}, _lightColorsUniform{_lightPositionsUniform + Int(lightCount)} {
Phong::Phong(const Flags flags, const UnsignedInt lightCount, const UnsignedInt jointCount, const UnsignedInt jointsPerVertex): _flags{flags}, _lightCount{lightCount}, _jointCount{jointCount}, _jointsPerVertex{jointsPerVertex}, _lightColorsUniform{_lightPositionsUniform + Int(lightCount)}, _jointMatricesUniform{_lightPositionsUniform + 2*Int(lightCount)} {
CORRADE_ASSERT(!(flags & Flag::TextureTransformation) || (flags & (Flag::AmbientTexture|Flag::DiffuseTexture|Flag::SpecularTexture|Flag::NormalTexture)),
"Shaders::Phong: texture transformation enabled but the shader is not textured", );
CORRADE_ASSERT(!(flags & Flag::Skinning) || (jointCount != 0),
"Shaders::Phong: skinning enabled, but jointCount is zero", );
CORRADE_ASSERT(!(flags & Flag::Skinning) || (jointsPerVertex > 0 && jointsPerVertex <= 8),
"Shaders::Phong: skinning enabled, but jointsPerVertex is not in [1;8]", );
#ifdef MAGNUM_BUILD_STATIC
/* Import resources on static build, if not already */
@ -120,7 +124,12 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l
#endif
.addSource(Utility::formatString(
"#define LIGHT_COUNT {}\n"
"#define LIGHT_COLORS_LOCATION {}\n", lightCount, _lightPositionsUniform + lightCount));
"#define LIGHT_COLORS_LOCATION {}\n", lightCount, _lightColorsUniform))
.addSource(flags & Flag::Skinning ? "#define SKINNING\n" : "")
.addSource(Utility::formatString(
"#define JOINT_COUNT {}\n"
"#define JOINTS_PER_VERTEX {}\n"
"#define JOINT_MATRICES_LOCATION {}\n", jointCount, jointsPerVertex, _jointMatricesUniform));
#ifndef MAGNUM_TARGET_GLES
if(lightCount) frag.addSource(std::move(lightInitializer));
#endif
@ -159,6 +168,15 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l
if(flags >= Flag::InstancedTextureOffset)
bindAttributeLocation(TextureOffset::Location, "instancedTextureOffset");
#endif
if(flags & Flag::Skinning) {
bindAttributeLocation(Weights::Location, "weights");
bindAttributeLocation(JointIds::Location, "jointIds");
if(jointCount > 4) {
bindAttributeLocation(SecondaryWeights::Location, "secondaryWeights");
bindAttributeLocation(SecondaryJointIds::Location, "secondaryJointIds");
}
}
}
#endif
@ -185,6 +203,8 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l
#ifndef MAGNUM_TARGET_GLES2
if(flags & Flag::ObjectId) _objectIdUniform = uniformLocation("objectId");
#endif
if(flags & Flag::Skinning)
_jointMatricesUniform = uniformLocation("jointMatrices");
}
#ifndef MAGNUM_TARGET_GLES
@ -353,6 +373,26 @@ Phong& Phong::setLightColor(UnsignedInt id, const Magnum::Color4& color) {
return *this;
}
Phong& Phong::setJointMatrices(const Containers::ArrayView<const Matrix4> matrices) {
CORRADE_ASSERT(_jointCount == matrices.size(),
"Shaders::Phong::setJointMatrices(): expected" << _jointCount << "items but got" << matrices.size(), *this);
if(_jointCount) setUniform(_jointMatricesUniform, matrices);
return *this;
}
Phong& Phong::setJointMatrix(UnsignedInt id, const Matrix4& matrix) {
CORRADE_ASSERT(id < _jointCount,
"Shaders::Phong::setJointMatrix(): joint ID" << id << "is out of bounds for" << _jointCount << "joints", *this);
setUniform(_jointMatricesUniform + id, matrix);
return *this;
}
/* It's light, but can't be in the header because MSVC needs to know the size
of Matrix4 for the initializer list use */
Phong& Phong::setJointMatrices(std::initializer_list<Matrix4> matrices) {
return setJointMatrices({matrices.begin(), matrices.size()});
}
Debug& operator<<(Debug& debug, const Phong::Flag value) {
debug << "Shaders::Phong::Flag" << Debug::nospace;

85
src/Magnum/Shaders/Phong.h

@ -207,6 +207,42 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
*/
typedef Generic3D::Color4 Color4;
/**
* @brief Joint ids
* @m_since_latest
*
* @ref shaders-generic "Generic attribute", @ref Magnum::Vector4ui.
* Used only if @ref Flag::Skinning is set.
*/
typedef Generic3D::JointIds JointIds;
/**
* @brief Weights
* @m_since_latest
*
* @ref shaders-generic "Generic attribute", @ref Magnum::Vector4.
* Used only if @ref Flag::Skinning is set.
*/
typedef Generic3D::Weights Weights;
/**
* @brief Secondary joint ids
* @m_since_latest
*
* @ref shaders-generic "Generic attribute", @ref Magnum::Vector4ui.
* Used only if @ref Flag::Skinning is set and @cpp jointCount > 4 @ce.
*/
typedef Generic3D::SecondaryJointIds SecondaryJointIds;
/**
* @brief Secondary weights
* @m_since_latest
*
* @ref shaders-generic "Generic attribute", @ref Magnum::Vector4.
* Used only if @ref Flag::Skinning is set and @cpp jointCount > 4 @ce.
*/
typedef Generic3D::Weights SecondaryWeights;
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief (Instanced) object ID
@ -416,7 +452,14 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
* in WebGL 1.0.
* @m_since_latest
*/
InstancedTextureOffset = (1 << 10)|TextureTransformation
InstancedTextureOffset = (1 << 10)|TextureTransformation,
/**
* Skinning.
* @TODO docs
* @m_since_latest
*/
Skinning = 1 << 11
};
/**
@ -428,10 +471,13 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
/**
* @brief Constructor
* @param flags Flags
* @param lightCount Count of light sources
* @param flags Flags
* @param lightCount Count of light sources
* @param jointCount Count of joints for skinning (see @ref Flag::Skinning)
* @param jointsPerVertex Max count of joints that may influence a vertex
* default @cpp 4 @ce (see @ref Flag::Skinning)
*/
explicit Phong(Flags flags = {}, UnsignedInt lightCount = 1);
explicit Phong(Flags flags = {}, UnsignedInt lightCount = 1, UnsignedInt jointCount = 0, UnsignedInt jointsPerVertex = 4);
/**
* @brief Construct without creating the underlying OpenGL object
@ -465,6 +511,12 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
/** @brief Light count */
UnsignedInt lightCount() const { return _lightCount; }
/** @brief Joint count */
UnsignedInt jointCount() const { return _jointCount; }
/** @brief Joints per vertex */
UnsignedInt jointsPerVertex() const { return _jointsPerVertex; }
/**
* @brief Set ambient color
* @return Reference to self (for method chaining)
@ -719,6 +771,28 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
return setLightColors({&color, 1});
}
/**
* @brief Set joint matrices
* @return Reference to self (for method chaining)
*
* Initial values are identity transformations. Expects that the size
* of the @p matrices array is the same as @ref jointCount().
* @see @ref setJointMatrix(UnsignedInt, const Matrix4&)
*/
Phong& setJointMatrices(const Containers::ArrayView<const Matrix4> matrices);
/** @overload */
Phong& setJointMatrices(std::initializer_list<Matrix4> matrices);
/**
* @brief Set joint matrix for given joint
* @return Reference to self (for method chaining)
*
* Unlike @ref setJointMatrices() updates just a single joint matrix.
* Expects that @p id is less than @ref joinCount().
*/
Phong& setJointMatrix(UnsignedInt id, const Matrix4& matrix);
private:
/* Prevent accidentally calling irrelevant functions */
#ifndef MAGNUM_TARGET_GLES
@ -730,6 +804,8 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
Flags _flags;
UnsignedInt _lightCount;
UnsignedInt _jointCount;
UnsignedInt _jointsPerVertex;
Int _transformationMatrixUniform{0},
_projectionMatrixUniform{1},
_normalMatrixUniform{2},
@ -744,6 +820,7 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
#endif
Int _lightPositionsUniform{10},
_lightColorsUniform; /* 10 + lightCount, set in the constructor */
Int _jointMatricesUniform; /* 10 + 2*lightCount, set in the constructor */
};
/** @debugoperatorclassenum{Phong,Phong::Flag} */

45
src/Magnum/Shaders/Phong.vert

@ -80,6 +80,13 @@ layout(location = 10)
uniform highp vec3 lightPositions[LIGHT_COUNT]; /* defaults to zero */
#endif
#ifdef SKINNING
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = JOINT_MATRICES_LOCATION)
#endif
uniform mat4 jointMatrices[JOINT_COUNT];
#endif
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = POSITION_ATTRIBUTE_LOCATION)
#endif
@ -117,6 +124,30 @@ in lowp vec4 vertexColor;
out lowp vec4 interpolatedVertexColor;
#endif
#ifdef SKINNING
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = WEIGHTS_ATTRIBUTE_LOCATION)
#endif
in mediump vec4 weights;
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = JOINTIDS_ATTRIBUTE_LOCATION)
#endif
in mediump uvec4 jointIds;
#if JOINTS_PER_VERTEX > 4
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = SECONDARY_WEIGHTS_ATTRIBUTE_LOCATION)
#endif
in mediump vec4 secondaryWeights;
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = SECONDARY_JOINTIDS_ATTRIBUTE_LOCATION)
#endif
in mediump vec4 secondaryJointIds;
#endif
#endif
#ifdef INSTANCED_OBJECT_ID
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = OBJECT_ID_ATTRIBUTE_LOCATION)
@ -155,11 +186,25 @@ out highp vec3 cameraDirection;
#endif
void main() {
#ifdef SKINNING
mat4 skinMatrix;
int i = 0;
for(; i != JOINTS_PER_VERTEX && i != 4; ++i)
skinMatrix += weights[i]*jointMatrices[int(jointIds[i])];
#if JOINTS_PER_VERTEX > 4
for(i = 0; i != JOINTS_PER_VERTEX - 4 && i != 4; ++i)
skinMatrix += secondaryWeights[i]*jointMatrices[int(secondaryJointIds[i])];
#endif
#endif
/* Transformed vertex position */
highp vec4 transformedPosition4 = transformationMatrix*
#ifdef INSTANCED_TRANSFORMATION
instancedTransformationMatrix*
#endif
#ifdef SKINNING
skinMatrix*
#endif
position;
highp vec3 transformedPosition = transformedPosition4.xyz/transformedPosition4.w;

5
src/Magnum/Shaders/generic.glsl

@ -37,6 +37,11 @@
#define NORMAL_MATRIX_ATTRIBUTE_LOCATION 12
#define TEXTURE_OFFSET_ATTRIBUTE_LOCATION 15
#define WEIGHTS_ATTRIBUTE_LOCATION 6
#define JOINTIDS_ATTRIBUTE_LOCATION 7
#define SECONDARY_WEIGHTS_ATTRIBUTE_LOCATION 10
#define SECONDARY_JOINTIDS_ATTRIBUTE_LOCATION 11
/* Outputs */
#define COLOR_OUTPUT_ATTRIBUTE_LOCATION 0
#define OBJECT_ID_OUTPUT_ATTRIBUTE_LOCATION 1

Loading…
Cancel
Save