diff --git a/include/ModelIo.h b/include/ModelIo.h index 360cb66..0d717d5 100644 --- a/include/ModelIo.h +++ b/include/ModelIo.h @@ -34,7 +34,7 @@ struct MaterialInfo class BoneWeights { public: - BoneWeights() : mActiveNbWeights( 0 ) { } + BoneWeights() : mActiveNbWeights( 0 ), mWeights({}) { } static const int NB_WEIGHTS = 4; void addWeight( const std::shared_ptr& bone, float weight ); float getWeight( int index ) const { return mWeights[index]; } diff --git a/include/ModelTargetSkinnedVboMesh.h b/include/ModelTargetSkinnedVboMesh.h index f989dfc..8470a77 100644 --- a/include/ModelTargetSkinnedVboMesh.h +++ b/include/ModelTargetSkinnedVboMesh.h @@ -27,10 +27,14 @@ class ModelTargetSkinnedVboMesh : public ModelTarget { private: SkinnedVboMesh* mSkinnedVboMesh; - template void bufferSubData( const T& buffer, size_t dim); - void setCustomAttribute( const std::string& name, int location ); + void incrementOffsets( size_t dataSize ); + void resetOffsets(); - int mOffset; + template void bufferSubData( const T& buffer, size_t dataSize); + void setCustomAttribute( const std::string& name, GLuint location ); + + GLuint mAttribLocation; + ptrdiff_t mSubDataOffset; }; } //end namespace model \ No newline at end of file diff --git a/resources/skinning_frag_no_normals.glsl b/resources/skinning_frag_no_normals.glsl new file mode 100644 index 0000000..b0f78af --- /dev/null +++ b/resources/skinning_frag_no_normals.glsl @@ -0,0 +1,21 @@ +#ifdef GL_ES +precision highp float; +#endif + +varying vec2 Tc; +varying vec3 V; + +uniform sampler2D texture; + +void main (void) +{ + vec4 Dm = texture2D( texture, Tc ); + + vec3 L = normalize(gl_LightSource[0].position.xyz); + vec3 E = normalize(-V); + + vec4 Iamb = gl_FrontLightProduct[0].ambient * Dm; + vec4 Idiff = gl_FrontLightProduct[0].diffuse * Dm; + + gl_FragColor = gl_FrontMaterial.emission + Iamb + Idiff; +} \ No newline at end of file diff --git a/resources/skinning_frag_normals.glsl b/resources/skinning_frag_normals.glsl index 1afe5e3..96e541a 100644 --- a/resources/skinning_frag_normals.glsl +++ b/resources/skinning_frag_normals.glsl @@ -3,7 +3,7 @@ precision highp float; #endif varying vec2 Tc; -varying vec3 N, L, V; +varying vec3 V, N, L; uniform sampler2D texture; diff --git a/resources/skinning_vert_no_normals.glsl b/resources/skinning_vert_no_normals.glsl new file mode 100644 index 0000000..14b777e --- /dev/null +++ b/resources/skinning_vert_no_normals.glsl @@ -0,0 +1,29 @@ +const int MAXBONES = 92; + +attribute vec3 position; +attribute vec2 texcoord; +attribute vec4 boneWeights; +attribute vec4 boneIndices; + +uniform bool isAnimated; +uniform mat4 boneMatrices[MAXBONES]; +uniform mat4 invTransposeMatrices[MAXBONES]; + +varying vec2 Tc; +varying vec3 V; + +void main() +{ + vec4 pos = vec4(position, 1.0); + if( isAnimated ) { + pos = boneMatrices[int(boneIndices.x)] * pos * boneWeights.x + + boneMatrices[int(boneIndices.y)] * pos * boneWeights.y + + boneMatrices[int(boneIndices.z)] * pos * boneWeights.z + + boneMatrices[int(boneIndices.w)] * pos * boneWeights.w ; + + pos.w = 1.0; + } + V = (gl_ModelViewMatrix * pos).xyz; + Tc = texcoord; + gl_Position = gl_ModelViewProjectionMatrix * pos; +} \ No newline at end of file diff --git a/resources/skinning_vert_normals.glsl b/resources/skinning_vert_normals.glsl index 85f5241..ad1af5e 100644 --- a/resources/skinning_vert_normals.glsl +++ b/resources/skinning_vert_normals.glsl @@ -11,7 +11,7 @@ uniform mat4 boneMatrices[MAXBONES]; uniform mat4 invTransposeMatrices[MAXBONES]; varying vec2 Tc; -varying vec3 N, L, V; +varying vec3 V, N, L; void main() { diff --git a/samples/SeymourDemo/include/Resources.h b/samples/SeymourDemo/include/Resources.h index a059f7e..5bfb375 100755 --- a/samples/SeymourDemo/include/Resources.h +++ b/samples/SeymourDemo/include/Resources.h @@ -1,5 +1,7 @@ #pragma once #include "cinder/CinderResources.h" -#define RES_SKINNING_VERT CINDER_RESOURCE( ../../../resources/, skinning_vert_normals.glsl, 128, GLSL ) -#define RES_SKINNING_FRAG CINDER_RESOURCE( ../../../resources/, skinning_frag_normals.glsl, 129, GLSL ) +#define RES_SKINNING_VERT CINDER_RESOURCE( ../../../resources/, skinning_vert_normals.glsl, 128, GLSL ) +#define RES_SKINNING_FRAG CINDER_RESOURCE( ../../../resources/, skinning_frag_normals.glsl, 129, GLSL ) +#define RES_SKINNING_VERT_NO_NORMALS CINDER_RESOURCE( ../../../resources/, skinning_vert_no_normals.glsl, 130, GLSL ) +#define RES_SKINNING_FRAG_NO_NORMALS CINDER_RESOURCE( ../../../resources/, skinning_frag_no_normals.glsl, 131, GLSL ) \ No newline at end of file diff --git a/samples/SeymourDemo/xcode/SeymourDemo.xcodeproj/project.pbxproj b/samples/SeymourDemo/xcode/SeymourDemo.xcodeproj/project.pbxproj index 9d4b705..7408d0b 100755 --- a/samples/SeymourDemo/xcode/SeymourDemo.xcodeproj/project.pbxproj +++ b/samples/SeymourDemo/xcode/SeymourDemo.xcodeproj/project.pbxproj @@ -25,6 +25,8 @@ B00A7FAF17412BCF00131FD9 /* Actor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B00A7FAE17412BCF00131FD9 /* Actor.cpp */; }; B035754E16F92F41006B03A1 /* skinning_frag_normals.glsl in Resources */ = {isa = PBXBuildFile; fileRef = B035754C16F92F41006B03A1 /* skinning_frag_normals.glsl */; }; B035754F16F92F41006B03A1 /* skinning_vert_normals.glsl in Resources */ = {isa = PBXBuildFile; fileRef = B035754D16F92F41006B03A1 /* skinning_vert_normals.glsl */; }; + B051926A1744ED95007A921C /* skinning_vert_no_normals.glsl in Resources */ = {isa = PBXBuildFile; fileRef = B01F84961744EA1700AA62D4 /* skinning_vert_no_normals.glsl */; }; + B051926B1744ED95007A921C /* skinning_frag_no_normals.glsl in Resources */ = {isa = PBXBuildFile; fileRef = B01F84971744EA1700AA62D4 /* skinning_frag_no_normals.glsl */; }; B999A80CA3924F5A9E8F61DC /* Skeleton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9DDE6E7EAA6496D8D7E3844 /* Skeleton.cpp */; }; BFB888FB70554572B0D0D39A /* ModelTargetSkinnedMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 05F4ABBFD6AC47A2A3C7D2D6 /* ModelTargetSkinnedMesh.cpp */; }; D1AE18B1746240DFB8BC018E /* ModelTargetSkinnedVboMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BC06C948E8B4006AD29A071 /* ModelTargetSkinnedVboMesh.cpp */; }; @@ -66,6 +68,8 @@ B00A7FAC17412BC500131FD9 /* AnimTrack.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AnimTrack.h; path = ../../../include/AnimTrack.h; sourceTree = ""; }; B00A7FAD17412BC500131FD9 /* Actor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Actor.h; path = ../../../include/Actor.h; sourceTree = ""; }; B00A7FAE17412BCF00131FD9 /* Actor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Actor.cpp; path = ../../../src/Actor.cpp; sourceTree = ""; }; + B01F84961744EA1700AA62D4 /* skinning_vert_no_normals.glsl */ = {isa = PBXFileReference; explicitFileType = sourcecode.glsl; name = skinning_vert_no_normals.glsl; path = ../../../resources/skinning_vert_no_normals.glsl; sourceTree = ""; }; + B01F84971744EA1700AA62D4 /* skinning_frag_no_normals.glsl */ = {isa = PBXFileReference; explicitFileType = sourcecode.glsl; name = skinning_frag_no_normals.glsl; path = ../../../resources/skinning_frag_no_normals.glsl; sourceTree = ""; }; B035754C16F92F41006B03A1 /* skinning_frag_normals.glsl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = skinning_frag_normals.glsl; path = ../../../resources/skinning_frag_normals.glsl; sourceTree = ""; }; B035754D16F92F41006B03A1 /* skinning_vert_normals.glsl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = skinning_vert_normals.glsl; path = ../../../resources/skinning_vert_normals.glsl; sourceTree = ""; }; BBEA026A1577471A89F8FB62 /* ModelTargetSkinnedMesh.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ModelTargetSkinnedMesh.h; path = ../../../include/ModelTargetSkinnedMesh.h; sourceTree = ""; }; @@ -225,6 +229,8 @@ 4D9769CC73854B94826B2591 /* resources */ = { isa = PBXGroup; children = ( + B01F84961744EA1700AA62D4 /* skinning_vert_no_normals.glsl */, + B01F84971744EA1700AA62D4 /* skinning_frag_no_normals.glsl */, B035754C16F92F41006B03A1 /* skinning_frag_normals.glsl */, B035754D16F92F41006B03A1 /* skinning_vert_normals.glsl */, ); @@ -291,6 +297,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + B051926A1744ED95007A921C /* skinning_vert_no_normals.glsl in Resources */, + B051926B1744ED95007A921C /* skinning_frag_no_normals.glsl in Resources */, 0F4795547ED4410E962DE84E /* CinderApp.icns in Resources */, B035754E16F92F41006B03A1 /* skinning_frag_normals.glsl in Resources */, B035754F16F92F41006B03A1 /* skinning_vert_normals.glsl in Resources */, diff --git a/src/ModelSourceAssimp.cpp b/src/ModelSourceAssimp.cpp index e67fb74..50a3d4c 100644 --- a/src/ModelSourceAssimp.cpp +++ b/src/ModelSourceAssimp.cpp @@ -22,7 +22,6 @@ namespace ai { aiProcess_ImproveCacheLocality | aiProcess_LimitBoneWeights | aiProcess_RemoveRedundantMaterials | - aiProcess_Triangulate | aiProcess_GenUVCoords | aiProcess_SortByPType | aiProcess_FindDegenerates | @@ -340,7 +339,8 @@ ModelSourceAssimp::ModelSourceAssimp( const ci::fs::path& modelPath, const ci::f mRootAssetFolderPath = rootAssetFolderPath; mImporter = std::unique_ptr( new Assimp::Importer() ); - mImporter->SetIOHandler( new CustomIOSystem() ); + mImporter->SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_POINT | aiPrimitiveType_LINE); +// mImporter->SetIOHandler( new CustomIOSystem() ); mAiScene = mImporter->ReadFile( mModelPath.string(), ai::flags ); //TODO: make own exception class to catch @@ -355,7 +355,7 @@ ModelSourceAssimp::ModelSourceAssimp( const ci::fs::path& modelPath, const ci::f for( unsigned int m=0; m < mAiScene->mNumMeshes; ++m ) { aiMesh * mesh = mAiScene->mMeshes[m]; numBones += mesh->mNumBones; - mModelInfo.mHasNormals = mModelInfo.mHasNormals || mesh->HasNormals(); +// mModelInfo.mHasNormals = mModelInfo.mHasNormals || mesh->HasNormals(); mModelInfo.mNumVertices.push_back( mesh->mNumVertices ); mModelInfo.mNumIndices.push_back( 3 * mesh->mNumFaces ); diff --git a/src/ModelTargetSkinnedVboMesh.cpp b/src/ModelTargetSkinnedVboMesh.cpp index 8e3361e..0cc411a 100644 --- a/src/ModelTargetSkinnedVboMesh.cpp +++ b/src/ModelTargetSkinnedVboMesh.cpp @@ -7,32 +7,39 @@ namespace model { ModelTargetSkinnedVboMesh::ModelTargetSkinnedVboMesh( SkinnedVboMesh * mesh ) : mSkinnedVboMesh( mesh ) -, mOffset(0) +, mSubDataOffset(0) +, mAttribLocation(0) { } +void ModelTargetSkinnedVboMesh::incrementOffsets( size_t dataSize ) +{ + mSubDataOffset += dataSize; + mAttribLocation++; +} + template -void ModelTargetSkinnedVboMesh::bufferSubData( const T& buffer, size_t dim ) +void ModelTargetSkinnedVboMesh::bufferSubData( const T& buffer, size_t dataSize ) { - size_t dataSize = sizeof(GLfloat) * dim * buffer.size(); ci::gl::VboMesh& vboMesh = mSkinnedVboMesh->getActiveSection()->getVboMesh(); - vboMesh.getStaticVbo().bufferSubData(mOffset, dataSize, buffer.data()); + vboMesh.getStaticVbo().bufferSubData( mSubDataOffset, dataSize, buffer.data() ); vboMesh.getStaticVbo().unbind(); - mOffset += dataSize; } -void ModelTargetSkinnedVboMesh::setCustomAttribute( const std::string& name, int location ) +void ModelTargetSkinnedVboMesh::setCustomAttribute( const std::string& name, GLuint location ) { - mSkinnedVboMesh->getActiveSection()->getShader().bind(); - mSkinnedVboMesh->getActiveSection()->getVboMesh().setCustomStaticLocation( location, mSkinnedVboMesh->getActiveSection()->getShader().getAttribLocation( name ) ); - mSkinnedVboMesh->getActiveSection()->getShader().unbind(); + MeshVboSectionRef sect = mSkinnedVboMesh->getActiveSection(); + sect->getShader().bind(); + sect->getVboMesh().setCustomStaticLocation( location, sect->getShader().getAttribLocation( name ) ); + sect->getShader().unbind(); } void ModelTargetSkinnedVboMesh::setActiveSection( int index ) { mSkinnedVboMesh->setActiveSection( index ); - mOffset = 0; + mSubDataOffset = 0; + mAttribLocation = 0; } std::shared_ptr ModelTargetSkinnedVboMesh::getSkeleton() const @@ -42,16 +49,20 @@ std::shared_ptr ModelTargetSkinnedVboMesh::getSkeleton() const void ModelTargetSkinnedVboMesh::loadVertexPositions( const std::vector& positions ) { - bufferSubData< std::vector >( positions, ci::Vec3f::DIM ); - setCustomAttribute( "position", 0 ); + size_t dataSize = sizeof(GLfloat) * ci::Vec3f::DIM * positions.size(); + bufferSubData< std::vector >( positions, dataSize ); + setCustomAttribute( "position", mAttribLocation ); + incrementOffsets( dataSize ); } void ModelTargetSkinnedVboMesh::loadVertexNormals( const std::vector& normals ) { mSkinnedVboMesh->getActiveSection()->setHasNormals( true ); //FIXME: remove this - - bufferSubData< std::vector >( normals, ci::Vec3f::DIM ); - setCustomAttribute( "normal", 1 ); + + size_t dataSize = sizeof(GLfloat) * ci::Vec3f::DIM * normals.size(); + bufferSubData< std::vector >( normals, dataSize ); + setCustomAttribute( "normal", mAttribLocation ); + incrementOffsets( dataSize ); } void ModelTargetSkinnedVboMesh::loadIndices( const std::vector& indices ) @@ -64,9 +75,11 @@ void ModelTargetSkinnedVboMesh::loadIndices( const std::vector& indice void ModelTargetSkinnedVboMesh::loadTex( const std::vector& texCoords, const MaterialInfo& matInfo ) { mSkinnedVboMesh->getActiveSection()->setMatInfo( matInfo ); - - bufferSubData< std::vector >( texCoords, ci::Vec2f::DIM ); - setCustomAttribute( "texcoord", 2 ); + + size_t dataSize = sizeof(GLfloat) * ci::Vec2f::DIM * texCoords.size(); + bufferSubData< std::vector >( texCoords, dataSize); + setCustomAttribute( "texcoord", mAttribLocation ); + incrementOffsets( dataSize ); } void ModelTargetSkinnedVboMesh::loadSkeleton( const SkeletonRef& skeleton ) @@ -95,10 +108,15 @@ void ModelTargetSkinnedVboMesh::loadBoneWeights( const std::vector& boneIndicesBuffer.push_back( vIndices ); } - bufferSubData< std::vector >( boneWeightsBuffer, ci::Vec4f::DIM ); - bufferSubData< std::vector >( boneIndicesBuffer, ci::Vec4f::DIM ); - setCustomAttribute( "boneWeights", 3 ); - setCustomAttribute( "boneIndices", 4 ); + size_t dataSize = sizeof(GLfloat) * ci::Vec4f::DIM * boneWeightsBuffer.size(); + + bufferSubData< std::vector >( boneWeightsBuffer, dataSize ); + setCustomAttribute( "boneWeights", mAttribLocation ); + incrementOffsets( dataSize ); + + bufferSubData< std::vector >( boneIndicesBuffer, dataSize); + setCustomAttribute( "boneIndices", mAttribLocation ); + incrementOffsets( dataSize ); mSkinnedVboMesh->getActiveSection()->boneMatrices = &mSkinnedVboMesh->mBoneMatrices; mSkinnedVboMesh->getActiveSection()->invTransposeMatrices = &mSkinnedVboMesh->mInvTransposeMatrices; diff --git a/src/SkinnedVboMesh.cpp b/src/SkinnedVboMesh.cpp index b879145..34917a9 100644 --- a/src/SkinnedVboMesh.cpp +++ b/src/SkinnedVboMesh.cpp @@ -18,7 +18,7 @@ SkinnedVboMesh::MeshSection::MeshSection() : ASkinnedMesh() { try { - mSkinningShader = ci::gl::GlslProg( ci::app::loadResource(RES_SKINNING_VERT), ci::app::loadResource(RES_SKINNING_FRAG) ); + mSkinningShader = ci::gl::GlslProg( ci::app::loadResource(RES_SKINNING_VERT_NO_NORMALS), ci::app::loadResource(RES_SKINNING_FRAG_NO_NORMALS) ); } catch( ci::gl::GlslProgCompileExc &exc ) { std::cout << "Shader compile error: " << std::endl;