/// <summary> /// Render all meshes we collected this frame sorted by techniques /// and materials. This method is about 3-5 times faster than just /// using Model's Mesh.Draw method (see commented out code there). /// The reason for that is that we require only very few state changes /// and render everthing down as fast as we can. The only optimization /// left would be to put vertices of several meshes together if they /// are static and use the same technique and material. But since /// meshes have WriteOnly vertex and index buffers, we can't do that /// without using a custom model format. /// </summary> public void Render() { // Make sure z buffer is on BaseGame.Device.RenderState.DepthBufferEnable = true; BaseGame.Device.RenderState.DepthBufferWriteEnable = true; // We always use the normalMapping shader here. Effect effect = ShaderEffect.normalMapping.Effect; // Set general parameters for the shader ShaderEffect.normalMapping.SetParametersOptimizedGeneral(); // Don't set vertex buffer again if it does not change this frame. // Clear these remember settings. lastVertexBufferSet = null; lastIndexBufferSet = null; for (int listNum = 0; listNum < sortedMeshes.Count; listNum++) { MeshesPerMaterialPerTechniques list = sortedMeshes[listNum]; if (list.NumberOfRenderMatrices > 0) { list.Render(effect); } } }
} // Add(vertexBuffer, indexBuffer, part) #endregion #region Render /// <summary> /// Render all meshes we collected this frame sorted by techniques /// and materials. This method is about 3-5 times faster than just /// using Model's Mesh.Draw method (see commented out code there). /// The reason for that is that we require only very few state changes /// and render everthing down as fast as we can. The only optimization /// left would be to put vertices of several meshes together if they /// are static and use the same technique and material. But since /// meshes have WriteOnly vertex and index buffers, we can't do that /// without using a custom model format. /// </summary> public void Render() { // Copy over last frame's object to this frame for (int listNum = 0; listNum < sortedMeshes.Count; listNum++) { MeshesPerMaterialPerTechniques list = sortedMeshes[listNum]; for (int meshNum = 0; meshNum < list.meshesPerMaterials.Count; meshNum++) { MeshesPerMaterial list2 = list.meshesPerMaterials[meshNum]; for (int num = 0; num < list2.meshes.Count; num++) { RenderableMesh mesh = list2.meshes[num]; // Copy over last frame matrices for rendering now! mesh.lastFrameRenderMatricesAndAlpha = mesh.thisFrameRenderMatricesAndAlpha; // Clear list for this frame mesh.thisFrameRenderMatricesAndAlpha = new List <MatrixAndAlpha>(); } // for } // for } // for // Make sure z buffer is on for 3D content BaseGame.Device.RenderState.DepthBufferEnable = true; BaseGame.Device.RenderState.DepthBufferWriteEnable = true; // We always use the normalMapping shader here. Effect effect = BaseGame.ParallaxShader.Effect; // Set general parameters for the shader BaseGame.ParallaxShader.SetParametersOptimizedGeneral(); // Don't set vertex buffer again if it does not change this frame. // Clear these remember settings. lastVertexBufferSet = null; lastIndexBufferSet = null; //obs: foreach (MeshesPerMaterialPerTechniques list in sortedMeshes) for (int listNum = 0; listNum < sortedMeshes.Count; listNum++) { MeshesPerMaterialPerTechniques list = sortedMeshes[listNum]; if (list.NumberOfRenderMatrices > 0) { list.Render(effect); } } // for (listNum) } // Render()
} // Render() #endregion #region ClearAll /// <summary> /// Clear all objects in the render list in case our device got lost. /// </summary> public void ClearAll() { // Copy over last frame's object to this frame for (int listNum = 0; listNum < sortedMeshes.Count; listNum++) { MeshesPerMaterialPerTechniques list = sortedMeshes[listNum]; for (int meshNum = 0; meshNum < list.meshesPerMaterials.Count; meshNum++) { MeshesPerMaterial list2 = list.meshesPerMaterials[meshNum]; for (int num = 0; num < list2.meshes.Count; num++) { RenderableMesh mesh = list2.meshes[num]; // Clear all mesh.lastFrameRenderMatricesAndAlpha.Clear(); mesh.thisFrameRenderMatricesAndAlpha.Clear(); } // for } // for } // for } // ClearAll()
/// <summary> /// Add model mesh part with the used effect to our sortedMeshes list. /// Neither the model mesh part nor the effect is directly used, /// we will extract all data from the model and only render the /// index and vertex buffers later. /// The model mesh part must use the TangentVertex format. /// </summary> /// <param name="vertexBuffer">Vertex buffer</param> /// <param name="indexBuffer">Index buffer</param> /// <param name="part">Part</param> /// <param name="effect">Effect</param> /// <returns>Renderable mesh</returns> public RenderableMesh Add(VertexBuffer vertexBuffer, IndexBuffer indexBuffer, ModelMeshPart part, Effect effect) { string techniqueName = effect.CurrentTechnique.Name; // Does this technique already exists? MeshesPerMaterialPerTechniques foundList = null; //obs: foreach (MeshesPerMaterialPerTechniques list in sortedMeshes) for (int listNum = 0; listNum < sortedMeshes.Count; listNum++) { MeshesPerMaterialPerTechniques list = sortedMeshes[listNum]; if (list.technique != null && list.technique.Name == techniqueName) { foundList = list; break; } // if (list.technique.Name) } // for (listNum) // Did not found list? Create new one if (foundList == null) { EffectTechnique technique = BaseGame.ParallaxShader.GetTechnique(techniqueName); // Make sure we always have a valid technique if (technique == null) { if (BaseGame.CanUsePS20) techniqueName = "Diffuse20";//"Specular20"; else techniqueName = "Diffuse";//"Specular"; technique = BaseGame.ParallaxShader.GetTechnique(techniqueName); } // if foundList = new MeshesPerMaterialPerTechniques(technique); sortedMeshes.Add(foundList); } // if (foundList) // Create new material from the current effect parameters. // This will create duplicate materials if the same material is used // multiple times, we check this later. Material material = new Material(effect); // Search for material inside foundList. //obs: foreach (MeshesPerMaterial innerList in foundList.meshesPerMaterials) for (int innerListNum = 0; innerListNum < foundList.meshesPerMaterials.Count; innerListNum++) { MeshesPerMaterial innerList = foundList.meshesPerMaterials[innerListNum]; // Check if this is the same material and we can use it instead. // For our purposes it is sufficiant if we check textures and colors. if (innerList.material.diffuseTexture == material.diffuseTexture && innerList.material.normalTexture == material.normalTexture && innerList.material.ambientColor == material.ambientColor && innerList.material.diffuseColor == material.diffuseColor && innerList.material.specularColor == material.specularColor && innerList.material.specularPower == material.specularPower) { // Reuse this material and quit this search material = innerList.material; break; } // if (innerList.material.diffuseTexture) } // foreach (innerList) // Build new RenderableMesh object RenderableMesh mesh = new RenderableMesh( vertexBuffer, indexBuffer, material, foundList.technique, part.VertexDeclaration, part.StreamOffset, part.VertexStride, part.BaseVertex, part.NumVertices, part.StartIndex, part.PrimitiveCount); foundList.Add(mesh); return mesh; }
/// <summary> /// Add model mesh part with the used effect to our sortedMeshes list. /// Neither the model mesh part nor the effect is directly used, /// we will extract all data from the model and only render the /// index and vertex buffers later. /// The model mesh part must use the TangentVertex format. /// </summary> /// <param name="vertexBuffer">Vertex buffer</param> /// <param name="indexBuffer">Index buffer</param> /// <param name="part">Part</param> /// <param name="effect">Effect</param> /// <returns>Renderable mesh</returns> public RenderableMesh Add(VertexBuffer vertexBuffer, IndexBuffer indexBuffer, ModelMeshPart part, Effect effect) { string techniqueName = effect.CurrentTechnique.Name; // Does this technique already exists? MeshesPerMaterialPerTechniques foundList = null; for (int listNum = 0; listNum < sortedMeshes.Count; listNum++) { MeshesPerMaterialPerTechniques list = sortedMeshes[listNum]; if (list.technique.Name == techniqueName) { foundList = list; break; } } // Did not found list? Create new one if (foundList == null) { foundList = new MeshesPerMaterialPerTechniques( ShaderEffect.normalMapping.GetTechnique(techniqueName)); sortedMeshes.Add(foundList); } // Create new material from the current effect parameters. // This will create duplicate materials if the same material is used // multiple times, we check this later. Material material = new Material(effect); // Search for material inside foundList. for (int innerListNum = 0; innerListNum < foundList.meshesPerMaterials.Count; innerListNum++) { MeshesPerMaterial innerList = foundList.meshesPerMaterials[innerListNum]; // Check if this is the same material and we can use it instead. // For our purposes it is sufficiant if we check textures and colors. if (innerList.material.diffuseTexture == material.diffuseTexture && innerList.material.normalTexture == material.normalTexture && innerList.material.ambientColor == material.ambientColor && innerList.material.diffuseColor == material.diffuseColor && innerList.material.specularColor == material.specularColor && innerList.material.specularPower == material.specularPower) { // Reuse this material and quit this search material = innerList.material; break; } } // Build new RenderableMesh object RenderableMesh mesh = new RenderableMesh( vertexBuffer, indexBuffer, material, foundList.technique, ShaderEffect.normalMapping.WorldParameter, part.VertexDeclaration, part.StreamOffset, part.VertexStride, part.BaseVertex, part.NumVertices, part.StartIndex, part.PrimitiveCount); foundList.Add(mesh); return(mesh); }
/// <summary> /// Add model mesh part with the used effect to our sortedMeshes list. /// Neither the model mesh part nor the effect is directly used, /// we will extract all data from the model and only render the /// index and vertex buffers later. /// The model mesh part must use the TangentVertex format. /// </summary> /// <param name="vertexBuffer">Vertex buffer</param> /// <param name="indexBuffer">Index buffer</param> /// <param name="part">Part</param> /// <param name="effect">Effect</param> /// <returns>Renderable mesh</returns> public RenderableMesh Add(VertexBuffer vertexBuffer, IndexBuffer indexBuffer, ModelMeshPart part, Effect effect) { string techniqueName = effect.CurrentTechnique.Name; // Does this technique already exists? MeshesPerMaterialPerTechniques foundList = null; //obs: foreach (MeshesPerMaterialPerTechniques list in sortedMeshes) for (int listNum = 0; listNum < sortedMeshes.Count; listNum++) { MeshesPerMaterialPerTechniques list = sortedMeshes[listNum]; if (list.technique != null && list.technique.Name == techniqueName) { foundList = list; break; } // if (list.technique.Name) } // for (listNum) // Did not found list? Create new one if (foundList == null) { EffectTechnique technique = BaseGame.ParallaxShader.GetTechnique(techniqueName); // Make sure we always have a valid technique if (technique == null) { if (BaseGame.CanUsePS20) { techniqueName = "Diffuse20"; //"Specular20"; } else { techniqueName = "Diffuse"; //"Specular"; } technique = BaseGame.ParallaxShader.GetTechnique(techniqueName); } // if foundList = new MeshesPerMaterialPerTechniques(technique); sortedMeshes.Add(foundList); } // if (foundList) // Create new material from the current effect parameters. // This will create duplicate materials if the same material is used // multiple times, we check this later. Material material = new Material(effect); // Search for material inside foundList. //obs: foreach (MeshesPerMaterial innerList in foundList.meshesPerMaterials) for (int innerListNum = 0; innerListNum < foundList.meshesPerMaterials.Count; innerListNum++) { MeshesPerMaterial innerList = foundList.meshesPerMaterials[innerListNum]; // Check if this is the same material and we can use it instead. // For our purposes it is sufficiant if we check textures and colors. if (innerList.material.diffuseTexture == material.diffuseTexture && innerList.material.normalTexture == material.normalTexture && innerList.material.ambientColor == material.ambientColor && innerList.material.diffuseColor == material.diffuseColor && innerList.material.specularColor == material.specularColor && innerList.material.specularPower == material.specularPower) { // Reuse this material and quit this search material = innerList.material; break; } // if (innerList.material.diffuseTexture) } // foreach (innerList) // Build new RenderableMesh object RenderableMesh mesh = new RenderableMesh( vertexBuffer, indexBuffer, material, foundList.technique, part.VertexDeclaration, part.StreamOffset, part.VertexStride, part.BaseVertex, part.NumVertices, part.StartIndex, part.PrimitiveCount); foundList.Add(mesh); return(mesh); } // Add(vertexBuffer, indexBuffer, part)
/// <summary> /// Add model mesh part with the used effect to our sortedMeshes list. /// Neither the model mesh part nor the effect is directly used, /// we will extract all data from the model and only render the /// index and vertex buffers later. /// The model mesh part must use the TangentVertex format. /// </summary> /// <param name="vertexBuffer">Vertex buffer</param> /// <param name="indexBuffer">Index buffer</param> /// <param name="part">Part</param> /// <param name="effect">Effect</param> /// <returns>Renderable mesh</returns> public RenderableMesh Add(VertexBuffer vertexBuffer, IndexBuffer indexBuffer, ModelMeshPart part, Effect effect) { string techniqueName = effect.CurrentTechnique.Name; // Does this technique already exists? MeshesPerMaterialPerTechniques foundList = null; for (int listNum = 0; listNum < sortedMeshes.Count; listNum++) { MeshesPerMaterialPerTechniques list = sortedMeshes[listNum]; if (list.technique.Name == techniqueName) { foundList = list; break; } } // Did not found list? Create new one if (foundList == null) { foundList = new MeshesPerMaterialPerTechniques( ShaderEffect.normalMapping.GetTechnique(techniqueName)); sortedMeshes.Add(foundList); } // Create new material from the current effect parameters. // This will create duplicate materials if the same material is used // multiple times, we check this later. Material material = new Material(effect); // Search for material inside foundList. for (int innerListNum = 0; innerListNum < foundList.meshesPerMaterials.Count; innerListNum++) { MeshesPerMaterial innerList = foundList.meshesPerMaterials[innerListNum]; // Check if this is the same material and we can use it instead. // For our purposes it is sufficiant if we check textures and colors. if (innerList.material.diffuseTexture == material.diffuseTexture && innerList.material.normalTexture == material.normalTexture && innerList.material.ambientColor == material.ambientColor && innerList.material.diffuseColor == material.diffuseColor && innerList.material.specularColor == material.specularColor && innerList.material.specularPower == material.specularPower) { // Reuse this material and quit this search material = innerList.material; break; } } // Build new RenderableMesh object RenderableMesh mesh = new RenderableMesh( vertexBuffer, indexBuffer, material, foundList.technique, ShaderEffect.normalMapping.WorldParameter, part.VertexOffset, part.NumVertices, part.StartIndex, part.PrimitiveCount); foundList.Add(mesh); return mesh; }