diff --git a/data/shaders/instanced_skinning.vert b/data/shaders/instanced_skinning.vert index 391bfcda9..49a029361 100644 --- a/data/shaders/instanced_skinning.vert +++ b/data/shaders/instanced_skinning.vert @@ -39,25 +39,32 @@ void main(void) mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin, Orientation, Scale) * InverseViewMatrix); vec4 idle_position = vec4(Position, 1.); vec4 idle_normal = vec4(Normal, 0.); + vec4 idle_tangent = vec4(Data1.z, Data1.w, Data2.x, 0.); + vec4 idle_bitangent = vec4(Data2.y, Data2.z, Data2.w, 0.); vec4 skinned_position = vec4(0.); vec4 skinned_normal = vec4(0.); + vec4 skinned_tangent = vec4(0.); + vec4 skinned_bitangent = vec4(0.); // Note : For normal we assume no scale factor in bone (otherwise we'll have to compute inversematrix for each bones...) for (int i = 0; i < 4; i++) { vec4 single_bone_influenced_position = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_position; single_bone_influenced_position /= single_bone_influenced_position.w; vec4 single_bone_influenced_normal = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_normal; + vec4 single_bone_influenced_tangent = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_tangent; + vec4 single_bone_influenced_bitangent = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_bitangent; skinned_position += Weight[i] * single_bone_influenced_position; skinned_normal += Weight[i] * single_bone_influenced_normal; + skinned_tangent += Weight[i] * single_bone_influenced_tangent; + skinned_bitangent += Weight[i] * single_bone_influenced_bitangent; } gl_Position = ProjectionViewMatrix * ModelMatrix * skinned_position; // Keep orthogonality nor = (TransposeInverseModelView * skinned_normal).xyz; // Keep direction - tangent = (ViewMatrix * ModelMatrix * vec4(Data1.z, Data1.w, Data2.x, 0.)).xyz; - bitangent = (ViewMatrix * ModelMatrix * vec4(Data2.y, Data2.z, Data2.w, 0.)).xyz; - + tangent = (ViewMatrix * ModelMatrix * skinned_tangent).xyz; + bitangent = (ViewMatrix * ModelMatrix * skinned_bitangent).xyz; uv = vec2(Data1.x + misc_data.x, Data1.y + misc_data.y); color = Color.zyxw; color_change = misc_data.zw; diff --git a/data/shaders/skinning.vert b/data/shaders/skinning.vert index d4a0d65e8..44bc95705 100644 --- a/data/shaders/skinning.vert +++ b/data/shaders/skinning.vert @@ -41,23 +41,28 @@ void main(void) vec4 idle_normal = vec4(Normal, 0.); vec4 skinned_position = vec4(0.); vec4 skinned_normal = vec4(0.); + vec4 skinned_tangent = vec4(0.); + vec4 skinned_bitangent = vec4(0.); // Note : For normal we assume no scale factor in bone (otherwise we'll have to compute inversematrix for each bones...) for (int i = 0; i < 4; i++) { vec4 single_bone_influenced_position = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_position; single_bone_influenced_position /= single_bone_influenced_position.w; vec4 single_bone_influenced_normal = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_normal; + vec4 single_bone_influenced_tangent = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_tangent; + vec4 single_bone_influenced_bitangent = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_bitangent; skinned_position += Weight[i] * single_bone_influenced_position; skinned_normal += Weight[i] * single_bone_influenced_normal; + skinned_tangent += Weight[i] * single_bone_influenced_tangent; + skinned_bitangent += Weight[i] * single_bone_influenced_bitangent; } gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * skinned_position; // Keep orthogonality nor = (TransposeInverseModelView * skinned_normal).xyz; // Keep direction - tangent = (ViewMatrix * ModelMatrix * vec4(Data1.z, Data1.w, Data2.x, 0.)).xyz; - bitangent = (ViewMatrix * ModelMatrix * vec4(Data2.y, Data2.z, Data2.w, 0.)).xyz; - + tangent = (ViewMatrix * ModelMatrix * skinned_tangent).xyz; + bitangent = (ViewMatrix * ModelMatrix * skinned_bitangent).xyz; uv = vec2(Data1.x + texture_trans.x, Data1.y + texture_trans.y); color = Color.zyxw; } diff --git a/lib/irrlicht/include/ISkinnedMesh.h b/lib/irrlicht/include/ISkinnedMesh.h index 3fd16ed6e..7a36aa307 100644 --- a/lib/irrlicht/include/ISkinnedMesh.h +++ b/lib/irrlicht/include/ISkinnedMesh.h @@ -73,7 +73,7 @@ namespace scene //! converts the vertex type of all meshbuffers to tangents. /** E.g. used for bump mapping. */ - virtual void convertMeshToTangents() = 0; + virtual void convertMeshToTangents(bool(*predicate)(IMeshBuffer*)) = 0; //! Allows to enable hardware skinning. /* This feature is not implementated in Irrlicht yet */ diff --git a/lib/irrlicht/source/Irrlicht/CMeshManipulator.cpp b/lib/irrlicht/source/Irrlicht/CMeshManipulator.cpp index db9ecf30d..5ad585f45 100644 --- a/lib/irrlicht/source/Irrlicht/CMeshManipulator.cpp +++ b/lib/irrlicht/source/Irrlicht/CMeshManipulator.cpp @@ -646,6 +646,8 @@ SMesh* CMeshManipulator::createMeshCopy(scene::IMesh* mesh) const buffer->drop(); } break; + default: + break; }// end switch }// end for all mesh buffers @@ -751,6 +753,8 @@ IMesh* CMeshManipulator::createMeshUniquePrimitives(IMesh* mesh) const buffer->drop(); } break; + default: + break; }// end switch }// end for all mesh buffers @@ -987,6 +991,8 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNor vNew = v[idx[i]]; } break; + default: + break; } core::map::Node* n = vertMap.find(vNew); if (n) @@ -1075,6 +1081,8 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords); } break; + default: + break; } core::map::Node* n = vertMap.find(vNew); if (n) @@ -1158,6 +1166,8 @@ IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords); } break; + default: + break; } core::map::Node* n = vertMap.find(vNew); if (n) @@ -1805,6 +1815,8 @@ IMesh* CMeshManipulator::createForsythOptimizedMesh(const IMesh *mesh) const buf->drop(); } break; + default: + break; } delete [] vc; diff --git a/lib/irrlicht/source/Irrlicht/COctreeSceneNode.cpp b/lib/irrlicht/source/Irrlicht/COctreeSceneNode.cpp index eb105dd1f..04e221312 100644 --- a/lib/irrlicht/source/Irrlicht/COctreeSceneNode.cpp +++ b/lib/irrlicht/source/Irrlicht/COctreeSceneNode.cpp @@ -276,6 +276,8 @@ void COctreeSceneNode::render() } } break; + default: + break; } } @@ -371,6 +373,8 @@ bool COctreeSceneNode::createTree(IMesh* mesh) for (v=0; vgetVertexCount(); ++v) nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); break; + default: + break; } polyCount += b->getIndexCount(); @@ -424,6 +428,8 @@ bool COctreeSceneNode::createTree(IMesh* mesh) for (v=0; vgetVertexCount(); ++v) nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); break; + default: + break; } polyCount += b->getIndexCount(); @@ -474,6 +480,8 @@ bool COctreeSceneNode::createTree(IMesh* mesh) for (v=0; vgetVertexCount(); ++v) nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); break; + default: + break; } polyCount += b->getIndexCount(); @@ -487,6 +495,8 @@ bool COctreeSceneNode::createTree(IMesh* mesh) nodeCount = TangentsOctree->getNodeCount(); } break; + default: + break; } } diff --git a/lib/irrlicht/source/Irrlicht/COpenGLDriver.cpp b/lib/irrlicht/source/Irrlicht/COpenGLDriver.cpp index e866c7215..3bf8a5894 100644 --- a/lib/irrlicht/source/Irrlicht/COpenGLDriver.cpp +++ b/lib/irrlicht/source/Irrlicht/COpenGLDriver.cpp @@ -1581,6 +1581,8 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun case EVT_TANGENTS: glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), &(static_cast(vertices))[0].Color); break; + default: + break; } } else @@ -1676,6 +1678,8 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(48)); } break; + default: + break; } renderArray(indexList, primitiveCount, pType, iType); @@ -1740,6 +1744,8 @@ void COpenGLDriver::getColorBuffer(const void* vertices, u32 vertexCount, E_VERT } } break; + default: + break; } } @@ -1913,6 +1919,8 @@ void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCo case EVT_TANGENTS: glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), &(static_cast(vertices))[0].Color); break; + default: + break; } } else @@ -1984,6 +1992,8 @@ void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCo glVertexPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(0)); } + break; + default: break; } diff --git a/lib/irrlicht/source/Irrlicht/CSkinnedMesh.cpp b/lib/irrlicht/source/Irrlicht/CSkinnedMesh.cpp index 981584e83..429ef82b2 100644 --- a/lib/irrlicht/source/Irrlicht/CSkinnedMesh.cpp +++ b/lib/irrlicht/source/Irrlicht/CSkinnedMesh.cpp @@ -9,6 +9,7 @@ #include "CBoneSceneNode.h" #include "IAnimatedMeshSceneNode.h" #include "os.h" +#include "irrMap.h" namespace irr { @@ -751,28 +752,28 @@ bool CSkinnedMesh::setHardwareSkinning(bool on) if (HardwareSkinning!=on) { if (on) - { - - //set mesh to static pose... - for (u32 i=0; iWeights.size(); ++j) - { - const u16 buffer_id=joint->Weights[j].buffer_id; - const u32 vertex_id=joint->Weights[j].vertex_id; - LocalBuffers[buffer_id]->getVertex(vertex_id)->Pos = joint->Weights[j].StaticPos; - LocalBuffers[buffer_id]->getVertex(vertex_id)->Normal = joint->Weights[j].StaticNormal; - LocalBuffers[buffer_id]->boundingBoxNeedsRecalculated(); - } - } - } + toStaticPose(); HardwareSkinning=on; } return HardwareSkinning; } +void CSkinnedMesh::toStaticPose() +{ + for (u32 i=0; iWeights.size(); ++j) + { + const u16 buffer_id=joint->Weights[j].buffer_id; + const u32 vertex_id=joint->Weights[j].vertex_id; + LocalBuffers[buffer_id]->getVertex(vertex_id)->Pos = joint->Weights[j].StaticPos; + LocalBuffers[buffer_id]->getVertex(vertex_id)->Normal = joint->Weights[j].StaticNormal; + LocalBuffers[buffer_id]->boundingBoxNeedsRecalculated(); + } + } +} void CSkinnedMesh::calculateGlobalMatrices(SJoint *joint,SJoint *parentJoint) { @@ -1491,25 +1492,51 @@ void CSkinnedMesh::computeWeightInfluence(SJoint *joint, size_t &index, WeightIn computeWeightInfluence(joint->Children[j], index, wi); } -void CSkinnedMesh::convertMeshToTangents() +void CSkinnedMesh::convertMeshToTangents(bool(*predicate)(IMeshBuffer*)) { - // now calculate tangents - for (u32 b=0; b < LocalBuffers.size(); ++b) + bool recalculate_animation = false; + toStaticPose(); + for (u32 b = 0; b < LocalBuffers.size(); b++) { - if (LocalBuffers[b]) + bool recalculate_joints = false; + core::map vert_loc_map; + SSkinMeshBuffer* ssmb = LocalBuffers[b]; + if (ssmb) { - LocalBuffers[b]->convertToTangents(); + if (!predicate(ssmb)) continue; - const s32 idxCnt = LocalBuffers[b]->getIndexCount(); - - u16* idx = LocalBuffers[b]->getIndices(); - video::S3DVertexTangents* v = - (video::S3DVertexTangents*)LocalBuffers[b]->getVertices(); - - for (s32 i=0; i vert_map; + core::array tmp_indices; + for (u32 i = 0; i < ssmb->Indices.size(); i++) + { + u32 vert_location = 0; + const u32 cur_ver_loc = ssmb->Indices[i]; + const video::S3DVertex& v_old = ssmb->Vertices_Standard[cur_ver_loc]; + video::S3DVertexTangents v(v_old.Pos, v_old.Normal, v_old.Color, v_old.TCoords); + core::map::Node *n = vert_map.find(v); + if (n) + { + vert_location = n->getValue(); + } + else + { + vert_location = ssmb->Vertices_Tangents.size(); + ssmb->Vertices_Tangents.push_back(v); + vert_map.insert(v, vert_location); + } + vert_loc_map[cur_ver_loc] = vert_location; + tmp_indices.push_back(vert_location); + } + const s32 index_count = tmp_indices.size(); + u16* idx = tmp_indices.pointer(); + video::S3DVertexTangents* v = ssmb->Vertices_Tangents.pointer(); + core::vector3df local_normal; + for (s32 i = 0; i < index_count; i += 3) { calculateTangents( - v[idx[i+0]].Normal, + local_normal, v[idx[i+0]].Tangent, v[idx[i+0]].Binormal, v[idx[i+0]].Pos, @@ -1520,7 +1547,7 @@ void CSkinnedMesh::convertMeshToTangents() v[idx[i+2]].TCoords); calculateTangents( - v[idx[i+1]].Normal, + local_normal, v[idx[i+1]].Tangent, v[idx[i+1]].Binormal, v[idx[i+1]].Pos, @@ -1531,7 +1558,7 @@ void CSkinnedMesh::convertMeshToTangents() v[idx[i+0]].TCoords); calculateTangents( - v[idx[i+2]].Normal, + local_normal, v[idx[i+2]].Tangent, v[idx[i+2]].Binormal, v[idx[i+2]].Pos, @@ -1541,11 +1568,38 @@ void CSkinnedMesh::convertMeshToTangents() v[idx[i+0]].TCoords, v[idx[i+1]].TCoords); } + ssmb->Indices = tmp_indices; + ssmb->Vertices_Standard.clear(); + ssmb->VertexType = video::EVT_TANGENTS; + } + if (recalculate_joints) + { + Vertices_Moved[b].set_used(ssmb->getVertexCount()); + for (u32 i = 0; i < AllJoints.size(); i++) + { + SJoint *joint = AllJoints[i]; + for (u32 j = 0; j Weights.size(); j++) + { + if (joint->Weights[j].buffer_id == b) + { + core::map::Node *n = + vert_loc_map.find(joint->Weights[j].vertex_id); + if (n) + { + joint->Weights[j].vertex_id = n->getValue(); + } + } + } + } } } + if (recalculate_animation) + { + PreparedForSkinning = false; + checkForAnimation(); + } } - void CSkinnedMesh::calculateTangents( core::vector3df& normal, core::vector3df& tangent, diff --git a/lib/irrlicht/source/Irrlicht/CSkinnedMesh.h b/lib/irrlicht/source/Irrlicht/CSkinnedMesh.h index 00d924d09..0dd3a43bf 100644 --- a/lib/irrlicht/source/Irrlicht/CSkinnedMesh.h +++ b/lib/irrlicht/source/Irrlicht/CSkinnedMesh.h @@ -114,7 +114,7 @@ namespace scene virtual void setInterpolationMode(E_INTERPOLATION_MODE mode); //! Convertes the mesh to contain tangent information - virtual void convertMeshToTangents(); + virtual void convertMeshToTangents(bool(*predicate)(IMeshBuffer*)); //! Does the mesh have no animation virtual bool isStatic(); @@ -176,6 +176,8 @@ namespace scene u32 getTotalJoints() const { return m_total_joints; } private: + void toStaticPose(); + void checkForAnimation(); void normalizeWeights(); diff --git a/src/graphics/command_buffer.cpp b/src/graphics/command_buffer.cpp index 86766ee06..a7e4a624b 100644 --- a/src/graphics/command_buffer.cpp +++ b/src/graphics/command_buffer.cpp @@ -172,14 +172,16 @@ void SolidCommandBuffer::fill(SolidPassMeshMap *mesh_map) Material::SHADERTYPE_SPHERE_MAP, Material::SHADERTYPE_VEGETATION, Material::SHADERTYPE_SOLID_SKINNED_MESH, - Material::SHADERTYPE_ALPHA_TEST_SKINNED_MESH); + Material::SHADERTYPE_ALPHA_TEST_SKINNED_MESH, + Material::SHADERTYPE_SOLID_UNLIT_SKINNED_MESH); fillInstanceData (mesh_map, three_tex_material_list, InstanceTypeThreeTex); std::vector four_tex_material_list = createVector(Material::SHADERTYPE_DETAIL_MAP, - Material::SHADERTYPE_NORMAL_MAP); + Material::SHADERTYPE_NORMAL_MAP, + Material::SHADERTYPE_NORMAL_MAP_SKINNED_MESH); fillInstanceData (mesh_map, four_tex_material_list, InstanceTypeFourTex); @@ -204,10 +206,6 @@ void ShadowCommandBuffer::fill(OtherMeshMap *mesh_map) std::vector shadow_tex_material_list; for(int cascade=0; cascade<4; cascade++) { - shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT - + Material::SHADERTYPE_SOLID_SKINNED_MESH); - shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT - + Material::SHADERTYPE_ALPHA_TEST_SKINNED_MESH); shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT + Material::SHADERTYPE_SOLID); shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT @@ -224,6 +222,14 @@ void ShadowCommandBuffer::fill(OtherMeshMap *mesh_map) + Material::SHADERTYPE_VEGETATION); shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT + Material::SHADERTYPE_SPLATTING); + shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT + + Material::SHADERTYPE_SOLID_SKINNED_MESH); + shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT + + Material::SHADERTYPE_ALPHA_TEST_SKINNED_MESH); + shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT + + Material::SHADERTYPE_SOLID_UNLIT_SKINNED_MESH); + shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT + + Material::SHADERTYPE_NORMAL_MAP_SKINNED_MESH); } fillInstanceData diff --git a/src/graphics/draw_calls.cpp b/src/graphics/draw_calls.cpp index 0f6f10dc5..18ddd6b9f 100644 --- a/src/graphics/draw_calls.cpp +++ b/src/graphics/draw_calls.cpp @@ -712,15 +712,20 @@ void DrawCalls::renderParticlesList() const void DrawCalls::drawIndirectSolidFirstPass() const { m_solid_cmd_buffer->bind(); - m_solid_cmd_buffer->drawIndirectFirstPass(); - m_solid_cmd_buffer->drawIndirectFirstPass(); + m_solid_cmd_buffer->drawIndirectFirstPass(); m_solid_cmd_buffer->drawIndirectFirstPass(); m_solid_cmd_buffer->drawIndirectFirstPass(); m_solid_cmd_buffer->drawIndirectFirstPass(); m_solid_cmd_buffer->drawIndirectFirstPass(m_wind_dir); m_solid_cmd_buffer->drawIndirectFirstPass(); - m_solid_cmd_buffer->drawIndirectFirstPass(); + m_solid_cmd_buffer->drawIndirectFirstPass(); + + if (!CVS->supportsHardwareSkinning()) return; + m_solid_cmd_buffer->drawIndirectFirstPass(); + m_solid_cmd_buffer->drawIndirectFirstPass(); + m_solid_cmd_buffer->drawIndirectFirstPass(); + m_solid_cmd_buffer->drawIndirectFirstPass(); } // ---------------------------------------------------------------------------- @@ -730,15 +735,19 @@ void DrawCalls::drawIndirectSolidFirstPass() const void DrawCalls::multidrawSolidFirstPass() const { m_solid_cmd_buffer->bind(); - m_solid_cmd_buffer->multidrawFirstPass(); - m_solid_cmd_buffer->multidrawFirstPass(); m_solid_cmd_buffer->multidrawFirstPass(); m_solid_cmd_buffer->multidrawFirstPass(); m_solid_cmd_buffer->multidrawFirstPass(); m_solid_cmd_buffer->multidrawFirstPass(); m_solid_cmd_buffer->multidrawFirstPass(m_wind_dir); m_solid_cmd_buffer->multidrawFirstPass(); - m_solid_cmd_buffer->multidrawFirstPass(); + m_solid_cmd_buffer->multidrawFirstPass(); + + if (!CVS->supportsHardwareSkinning()) return; + m_solid_cmd_buffer->multidrawFirstPass(); + m_solid_cmd_buffer->multidrawFirstPass(); + m_solid_cmd_buffer->multidrawFirstPass(); + m_solid_cmd_buffer->multidrawFirstPass(); } // ---------------------------------------------------------------------------- @@ -751,8 +760,6 @@ void DrawCalls::multidrawSolidFirstPass() const void DrawCalls::drawIndirectSolidSecondPass(const std::vector &prefilled_tex) const { m_solid_cmd_buffer->bind(); - m_solid_cmd_buffer->drawIndirectSecondPass(prefilled_tex); - m_solid_cmd_buffer->drawIndirectSecondPass(prefilled_tex); m_solid_cmd_buffer->drawIndirectSecondPass(prefilled_tex); m_solid_cmd_buffer->drawIndirectSecondPass(prefilled_tex); m_solid_cmd_buffer->drawIndirectSecondPass(prefilled_tex); @@ -760,6 +767,12 @@ void DrawCalls::drawIndirectSolidSecondPass(const std::vector &prefilled m_solid_cmd_buffer->drawIndirectSecondPass(prefilled_tex, m_wind_dir); m_solid_cmd_buffer->drawIndirectSecondPass(prefilled_tex); m_solid_cmd_buffer->drawIndirectSecondPass(prefilled_tex); + + if (!CVS->supportsHardwareSkinning()) return; + m_solid_cmd_buffer->drawIndirectSecondPass(prefilled_tex); + m_solid_cmd_buffer->drawIndirectSecondPass(prefilled_tex); + m_solid_cmd_buffer->drawIndirectSecondPass(prefilled_tex); + m_solid_cmd_buffer->drawIndirectSecondPass(prefilled_tex); } // ---------------------------------------------------------------------------- @@ -771,8 +784,6 @@ void DrawCalls::drawIndirectSolidSecondPass(const std::vector &prefilled void DrawCalls::multidrawSolidSecondPass(const std::vector &handles) const { m_solid_cmd_buffer->bind(); - m_solid_cmd_buffer->multidraw2ndPass(handles); - m_solid_cmd_buffer->multidraw2ndPass(handles); m_solid_cmd_buffer->multidraw2ndPass(handles); m_solid_cmd_buffer->multidraw2ndPass(handles); m_solid_cmd_buffer->multidraw2ndPass(handles); @@ -780,6 +791,12 @@ void DrawCalls::multidrawSolidSecondPass(const std::vector &handles) c m_solid_cmd_buffer->multidraw2ndPass(handles); m_solid_cmd_buffer->multidraw2ndPass(handles); m_solid_cmd_buffer->multidraw2ndPass(handles, m_wind_dir); + + if (!CVS->supportsHardwareSkinning()) return; + m_solid_cmd_buffer->multidraw2ndPass(handles); + m_solid_cmd_buffer->multidraw2ndPass(handles); + m_solid_cmd_buffer->multidraw2ndPass(handles); + m_solid_cmd_buffer->multidraw2ndPass(handles); } // ---------------------------------------------------------------------------- @@ -822,8 +839,6 @@ void DrawCalls::multidrawNormals() const void DrawCalls::drawIndirectShadows(unsigned cascade) const { m_shadow_cmd_buffer->bind(); - m_shadow_cmd_buffer->drawIndirect(cascade); - m_shadow_cmd_buffer->drawIndirect(cascade); m_shadow_cmd_buffer->drawIndirect(cascade); m_shadow_cmd_buffer->drawIndirect(cascade); m_shadow_cmd_buffer->drawIndirect(cascade); @@ -832,6 +847,12 @@ void DrawCalls::drawIndirectShadows(unsigned cascade) const m_shadow_cmd_buffer->drawIndirect(cascade); m_shadow_cmd_buffer->drawIndirect(cascade); m_shadow_cmd_buffer->drawIndirect(cascade); + + if (!CVS->supportsHardwareSkinning()) return; + m_shadow_cmd_buffer->drawIndirect(cascade); + m_shadow_cmd_buffer->drawIndirect(cascade); + m_shadow_cmd_buffer->drawIndirect(cascade); + m_shadow_cmd_buffer->drawIndirect(cascade); } // ---------------------------------------------------------------------------- @@ -842,8 +863,6 @@ void DrawCalls::drawIndirectShadows(unsigned cascade) const void DrawCalls::multidrawShadows(unsigned cascade) const { m_shadow_cmd_buffer->bind(); - m_shadow_cmd_buffer->multidrawShadow(cascade); - m_shadow_cmd_buffer->multidrawShadow(cascade); m_shadow_cmd_buffer->multidrawShadow(cascade); m_shadow_cmd_buffer->multidrawShadow(cascade); m_shadow_cmd_buffer->multidrawShadow(cascade); @@ -852,6 +871,12 @@ void DrawCalls::multidrawShadows(unsigned cascade) const m_shadow_cmd_buffer->multidrawShadow(cascade, m_wind_dir); m_shadow_cmd_buffer->multidrawShadow(cascade); m_shadow_cmd_buffer->multidrawShadow(cascade); + + if (!CVS->supportsHardwareSkinning()) return; + m_shadow_cmd_buffer->multidrawShadow(cascade); + m_shadow_cmd_buffer->multidrawShadow(cascade); + m_shadow_cmd_buffer->multidrawShadow(cascade); + m_shadow_cmd_buffer->multidrawShadow(cascade); } // ---------------------------------------------------------------------------- diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index d59393448..e150bb06f 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -151,7 +151,7 @@ public: glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitchFromType(tp), (GLvoid*)24); glEnableVertexAttribArray(3); glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)28); - glEnableVertexAttribArray(3); + glEnableVertexAttribArray(4); glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)44); glEnableVertexAttribArray(5); glVertexAttribIPointer(5, 4, GL_INT, getVertexPitchFromType(tp), (GLvoid*)60); diff --git a/src/graphics/materials.cpp b/src/graphics/materials.cpp index 326b53d7f..38ef4aea7 100644 --- a/src/graphics/materials.cpp +++ b/src/graphics/materials.cpp @@ -20,20 +20,35 @@ #ifndef SERVER_ONLY const STK::Tuple SkinnedSolid::FirstPassTextures -= STK::Tuple(1); + = STK::Tuple(1); const STK::Tuple SkinnedSolid::SecondPassTextures -= STK::Tuple(0, 1, 2); + = STK::Tuple(0, 1, 2); const STK::Tuple<> SkinnedSolid::ShadowTextures; const STK::Tuple SkinnedSolid::RSMTextures = STK::Tuple(0); // ---------------------------------------------------------------------------- const STK::Tuple SkinnedAlphaRef::FirstPassTextures -= STK::Tuple(0, 1); + = STK::Tuple(0, 1); const STK::Tuple SkinnedAlphaRef::SecondPassTextures -= STK::Tuple(0, 1, 2); + = STK::Tuple(0, 1, 2); const STK::Tuple SkinnedAlphaRef::ShadowTextures = STK::Tuple(0); const STK::Tuple SkinnedAlphaRef::RSMTextures = STK::Tuple(0); +// ---------------------------------------------------------------------------- +const STK::Tuple SkinnedUnlitMat::FirstPassTextures + = STK::Tuple(0, 1); +const STK::Tuple SkinnedUnlitMat::SecondPassTextures = STK::Tuple(0); +const STK::Tuple SkinnedUnlitMat::ShadowTextures = STK::Tuple(0); +const STK::Tuple SkinnedUnlitMat::RSMTextures = STK::Tuple(0); + +// ---------------------------------------------------------------------------- +const STK::Tuple SkinnedNormalMat::FirstPassTextures + = STK::Tuple(3, 1); +const STK::Tuple SkinnedNormalMat::SecondPassTextures + = STK::Tuple(0, 1, 2); +const STK::Tuple<> SkinnedNormalMat::ShadowTextures; +const STK::Tuple SkinnedNormalMat::RSMTextures = STK::Tuple(0); + // ---------------------------------------------------------------------------- const STK::Tuple DefaultMaterial::FirstPassTextures = STK::Tuple(1); diff --git a/src/graphics/materials.hpp b/src/graphics/materials.hpp index 79fd0a6cb..6355fcc96 100644 --- a/src/graphics/materials.hpp +++ b/src/graphics/materials.hpp @@ -687,6 +687,38 @@ public: } // InstancedSkinnedMeshRefPass2Shader }; // InstancedSkinnedMeshRefPass2Shader +// ============================================================================ +class InstancedSkinnedMeshUnlitShader : public TextureShader +{ +public: + InstancedSkinnedMeshUnlitShader() + { + if (!CVS->supportsHardwareSkinning()) return; + loadProgram(OBJECT, GL_VERTEX_SHADER, "instanced_skinning.vert", + GL_FRAGMENT_SHADER, "instanced_object_unlit.frag"); + assignUniforms(); + assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED, + 1, "SpecularMap", ST_NEAREST_FILTERED, + 2, "SSAO", ST_BILINEAR_FILTERED, + 3, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED); + } // InstancedSkinnedMeshUnlitShader +}; // InstancedSkinnedMeshUnlitShader + +// ============================================================================ +class InstancedSkinnedNormalMapShader : public TextureShader +{ +public: + InstancedSkinnedNormalMapShader() + { + if (!CVS->supportsHardwareSkinning()) return; + loadProgram(OBJECT, GL_VERTEX_SHADER, "instanced_skinning.vert", + GL_FRAGMENT_SHADER, "instanced_normalmap.frag"); + assignUniforms(); + assignSamplerNames(0, "normalMap", ST_TRILINEAR_ANISOTROPIC_FILTERED, + 1, "glossMap", ST_TRILINEAR_ANISOTROPIC_FILTERED); + } // InstancedSkinnedNormalMapShader +}; // InstancedSkinnedNormalMapShader + // ============================================================================ class InstancedSkinnedShadowShader : public TextureShader { @@ -749,11 +781,10 @@ struct SkinnedSolid typedef InstancedSkinnedMeshPass1Shader InstancedFirstPassShader; typedef InstancedSkinnedMeshPass2Shader InstancedSecondPassShader; typedef InstancedSkinnedShadowShader InstancedShadowPassShader; - //typedef CInstancedRSMShader InstancedRSMShader; typedef Shaders::SkinnedMeshPass1Shader FirstPassShader; typedef Shaders::SkinnedMeshPass2Shader SecondPassShader; //typedef ShadowShader ShadowPassShader; - //typedef CRSMShader RSMShader; + // Todo: RSMs typedef ListSkinnedSolid List; static const enum video::E_VERTEX_TYPE VertexType = video::EVT_SKINNED_MESH; static const enum Material::ShaderType MaterialType @@ -771,11 +802,10 @@ struct SkinnedAlphaRef typedef InstancedSkinnedMeshRefPass1Shader InstancedFirstPassShader; typedef InstancedSkinnedMeshRefPass2Shader InstancedSecondPassShader; typedef InstancedSkinnedRefShadowShader InstancedShadowPassShader; - //typedef CInstancedRSMShader InstancedRSMShader; //typedef ObjectRefPass1Shader FirstPassShader; //typedef ObjectRefPass2Shader SecondPassShader; //typedef RefShadowShader ShadowPassShader; - //typedef CRSMShader RSMShader; + // Todo: RSMs typedef ListSkinnedAlphaRef List; static const enum video::E_VERTEX_TYPE VertexType = video::EVT_SKINNED_MESH; static const enum Material::ShaderType MaterialType = @@ -787,6 +817,48 @@ struct SkinnedAlphaRef static const STK::Tuple RSMTextures; }; // struct SkinnedAlphaRef +// ---------------------------------------------------------------------------- +struct SkinnedNormalMat +{ + typedef InstancedSkinnedNormalMapShader InstancedFirstPassShader; + typedef InstancedSkinnedMeshPass2Shader InstancedSecondPassShader; + typedef InstancedSkinnedShadowShader InstancedShadowPassShader; + //typedef ObjectRefPass1Shader FirstPassShader; + //typedef ObjectRefPass2Shader SecondPassShader; + //typedef RefShadowShader ShadowPassShader; + // Todo: RSMs + typedef ListSkinnedNormalMap List; + static const enum video::E_VERTEX_TYPE VertexType = video::EVT_SKINNED_MESH; + static const enum Material::ShaderType MaterialType = + Material::SHADERTYPE_NORMAL_MAP_SKINNED_MESH; + static const enum InstanceType Instance = InstanceTypeFourTex; + static const STK::Tuple FirstPassTextures; + static const STK::Tuple SecondPassTextures; + static const STK::Tuple<> ShadowTextures; + static const STK::Tuple RSMTextures; +}; // struct SkinnedNormalMat + +// ---------------------------------------------------------------------------- +struct SkinnedUnlitMat +{ + typedef InstancedSkinnedMeshRefPass1Shader InstancedFirstPassShader; + typedef InstancedSkinnedMeshUnlitShader InstancedSecondPassShader; + typedef InstancedSkinnedRefShadowShader InstancedShadowPassShader; + //typedef ObjectRefPass1Shader FirstPassShader; + //typedef ObjectRefPass2Shader SecondPassShader; + //typedef RefShadowShader ShadowPassShader; + // Todo: RSMs + typedef ListSkinnedUnlit List; + static const enum video::E_VERTEX_TYPE VertexType = video::EVT_SKINNED_MESH; + static const enum Material::ShaderType MaterialType = + Material::SHADERTYPE_SOLID_UNLIT_SKINNED_MESH; + static const enum InstanceType Instance = InstanceTypeThreeTex; + static const STK::Tuple FirstPassTextures; + static const STK::Tuple SecondPassTextures; + static const STK::Tuple ShadowTextures; + static const STK::Tuple RSMTextures; +}; // struct SkinnedUnlitMat + // ---------------------------------------------------------------------------- struct DefaultMaterial { diff --git a/src/graphics/mesh_tools.cpp b/src/graphics/mesh_tools.cpp index cbc1f83a7..d7f0e78c1 100644 --- a/src/graphics/mesh_tools.cpp +++ b/src/graphics/mesh_tools.cpp @@ -421,6 +421,8 @@ scene::IMesh* MeshTools::createMeshWithTangents(scene::IMesh* mesh, vNew = v[idx[i]]; } break; + default: + break; } core::map::Node* n = vertMap.find(vNew); if (n) @@ -479,54 +481,5 @@ scene::IMesh* MeshTools::createMeshWithTangents(scene::IMesh* mesh, void MeshTools::createSkinnedMeshWithTangents(scene::ISkinnedMesh* mesh, bool(*predicate)(scene::IMeshBuffer*)) { - core::array& all_mb = mesh->getMeshBuffers(); - const int all_mb_size = all_mb.size(); - for (int i = 0; i < all_mb_size; i++) - { - scene::SSkinMeshBuffer* mb = all_mb[i]; - if (mb && predicate(mb)) - { - mb->convertToTangents(); - const int index_count = mb->getIndexCount(); - uint16_t* idx = mb->getIndices(); - video::S3DVertexTangents* v = - (video::S3DVertexTangents*)mb->getVertices(); - - for (int i = 0; i < index_count; i += 3) - { - calculateTangents( - v[idx[i+0]].Normal, - v[idx[i+0]].Tangent, - v[idx[i+0]].Binormal, - v[idx[i+0]].Pos, - v[idx[i+1]].Pos, - v[idx[i+2]].Pos, - v[idx[i+0]].TCoords, - v[idx[i+1]].TCoords, - v[idx[i+2]].TCoords); - - calculateTangents( - v[idx[i+1]].Normal, - v[idx[i+1]].Tangent, - v[idx[i+1]].Binormal, - v[idx[i+1]].Pos, - v[idx[i+2]].Pos, - v[idx[i+0]].Pos, - v[idx[i+1]].TCoords, - v[idx[i+2]].TCoords, - v[idx[i+0]].TCoords); - - calculateTangents( - v[idx[i+2]].Normal, - v[idx[i+2]].Tangent, - v[idx[i+2]].Binormal, - v[idx[i+2]].Pos, - v[idx[i+0]].Pos, - v[idx[i+1]].Pos, - v[idx[i+2]].TCoords, - v[idx[i+0]].TCoords, - v[idx[i+1]].TCoords); - } - } - } + mesh->convertMeshToTangents(predicate); } diff --git a/src/graphics/stk_mesh.cpp b/src/graphics/stk_mesh.cpp index 02dd61f8b..a42337694 100644 --- a/src/graphics/stk_mesh.cpp +++ b/src/graphics/stk_mesh.cpp @@ -44,13 +44,13 @@ Material::ShaderType getMeshMaterialFromType(video::E_MATERIAL_TYPE material_typ { switch (material->getShaderType()) { - //case Material::SHADERTYPE_SOLID: - // if (material_type == Shaders::getShader(ES_NORMAL_MAP)) - // return Material::SHADERTYPE_NORMAL_MAP_SKINNED_MESH; + case Material::SHADERTYPE_SOLID: + if (material_type == Shaders::getShader(ES_NORMAL_MAP)) + return Material::SHADERTYPE_NORMAL_MAP_SKINNED_MESH; case Material::SHADERTYPE_ALPHA_TEST: return Material::SHADERTYPE_ALPHA_TEST_SKINNED_MESH; - //case Material::SHADERTYPE_SOLID_UNLIT: - // return Material::SHADERTYPE_SOLID_UNLIT_SKINNED_MESH; + case Material::SHADERTYPE_SOLID_UNLIT: + return Material::SHADERTYPE_SOLID_UNLIT_SKINNED_MESH; default: return Material::SHADERTYPE_SOLID_SKINNED_MESH; } @@ -182,7 +182,7 @@ GLuint createVAO(GLuint vbo, GLuint idx, video::E_VERTEX_TYPE type) glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitchFromType(type), (GLvoid*)24); glEnableVertexAttribArray(3); glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, getVertexPitchFromType(type), (GLvoid*)28); - glEnableVertexAttribArray(3); + glEnableVertexAttribArray(4); glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, getVertexPitchFromType(type), (GLvoid*)44); glEnableVertexAttribArray(5); glVertexAttribIPointer(5, 4, GL_INT, getVertexPitchFromType(type), (GLvoid*)60);