public static List<Mesh> SplitMeshes(List<Mesh> meshes, bool can32bitIndex) { var finalList = new List<Mesh>(); foreach (var mesh in meshes) { var drawDatas = SplitMesh(mesh.Draw, can32bitIndex); if (drawDatas.Count <= 1) { finalList.Add(mesh); } else { foreach (var draw in drawDatas) { var newMeshData = new Mesh(draw, mesh.Parameters) { MaterialIndex = mesh.MaterialIndex, Name = mesh.Name, NodeIndex = mesh.NodeIndex, Skinning = mesh.Skinning, }; finalList.Add(newMeshData); } } } return finalList; }
/// <summary> /// Initializes a new instance of the <see cref="Mesh"/> class using a shallow copy constructor. /// </summary> /// <param name="mesh">The mesh.</param> public Mesh(Mesh mesh) { if (mesh == null) throw new ArgumentNullException("mesh"); Draw = mesh.Draw; Parameters = mesh.Parameters.Clone(); MaterialIndex = mesh.MaterialIndex; NodeIndex = mesh.NodeIndex; Name = mesh.Name; BoundingBox = mesh.BoundingBox; Skinning = mesh.Skinning; }
protected override async Task LoadContent() { await base.LoadContent(); pipelineState = new MutablePipelineState(GraphicsDevice); var vertices = new Vertex[4]; vertices[0] = new Vertex { Position = new Vector3(-1, -1, 0.5f), TexCoords = new Vector2(0, 0) }; vertices[1] = new Vertex { Position = new Vector3(-1, 1, 0.5f), TexCoords = new Vector2(3, 0) }; vertices[2] = new Vertex { Position = new Vector3(1, 1, 0.5f), TexCoords = new Vector2(3, 3) }; vertices[3] = new Vertex { Position = new Vector3(1, -1, 0.5f), TexCoords = new Vector2(0, 3) }; var indices = new short[] { 0, 1, 2, 0, 2, 3 }; var vertexBuffer = Buffer.Vertex.New(GraphicsDevice, vertices, GraphicsResourceUsage.Default); var indexBuffer = Buffer.Index.New(GraphicsDevice, indices, GraphicsResourceUsage.Default); var meshDraw = new MeshDraw { DrawCount = 4, PrimitiveType = PrimitiveType.TriangleList, VertexBuffers = new[] { new VertexBufferBinding(vertexBuffer, new VertexDeclaration(VertexElement.Position<Vector3>(), VertexElement.TextureCoordinate<Vector2>()), 4) }, IndexBuffer = new IndexBufferBinding(indexBuffer, false, indices.Length), }; mesh = new Mesh { Draw = meshDraw, }; simpleEffect = new EffectInstance(new Effect(GraphicsDevice, SpriteEffect.Bytecode)); simpleEffect.Parameters.Set(TexturingKeys.Texture0, UVTexture); simpleEffect.UpdateEffect(GraphicsDevice); // TODO GRAPHICS REFACTOR //vao = VertexArrayObject.New(GraphicsDevice, mesh.Draw.IndexBuffer, mesh.Draw.VertexBuffers); myDraws = new DrawOptions[3]; myDraws[0] = new DrawOptions { Sampler = GraphicsDevice.SamplerStates.LinearClamp, Transform = Matrix.Multiply(Matrix.Scaling(0.4f), Matrix.Translation(-0.5f, 0.5f, 0f)) }; myDraws[1] = new DrawOptions { Sampler = GraphicsDevice.SamplerStates.LinearWrap, Transform = Matrix.Multiply(Matrix.Scaling(0.4f), Matrix.Translation(0.5f, 0.5f, 0f)) }; myDraws[2] = new DrawOptions { Sampler = SamplerState.New(GraphicsDevice, new SamplerStateDescription(TextureFilter.Linear, TextureAddressMode.Mirror)), Transform = Matrix.Multiply(Matrix.Scaling(0.4f), Matrix.Translation(0.5f, -0.5f, 0f)) }; //var borderDescription = new SamplerStateDescription(TextureFilter.Linear, TextureAddressMode.Border) { BorderColor = Color.Purple }; //var border = SamplerState.New(GraphicsDevice, borderDescription); //myDraws[3] = new DrawOptions { Sampler = border, Transform = Matrix.Multiply(Matrix.Scale(0.3f), Matrix.Translation(-0.5f, -0.5f, 0f)) }; }
/// <summary> /// Initializes a new instance of the <see cref="RenderMesh" /> class. /// </summary> /// <param name="renderModel">The render model.</param> /// <param name="mesh">The mesh data.</param> /// <exception cref="System.ArgumentNullException">mesh</exception> public RenderMesh(RenderModel renderModel, Mesh mesh) { if (renderModel == null) throw new ArgumentNullException("renderModel"); if (mesh == null) throw new ArgumentNullException("mesh"); RenderModel = renderModel; Mesh = mesh; Enabled = true; parameterCollections = new FastListStruct<ParameterCollection>(8); previousParameterCollections = new FastListStruct<ParameterCollection>(8); UpdateMaterial(); // A RenderMesh is inheriting values from Mesh.Parameters // We are considering that Mesh.Parameters is not updated frequently (should be almost immutable) parameters = new ParameterCollection(); if (mesh.Parameters != null) { parameters.AddSources(mesh.Parameters); } }
/// <summary> /// Compares the shadow options between the two meshes. /// </summary> /// <param name="baseMesh">The base mesh.</param> /// <param name="newMesh">The mesh to compare.</param> /// <param name="extra">Unused parameter.</param> /// <returns>True if the options are the same, false otherwise.</returns> private static bool CompareShadowOptions(Rendering.Model model, Mesh baseMesh, Mesh newMesh) { // TODO: Check is Model the same for the two mesh? var material1 = model.Materials.GetItemOrNull(baseMesh.MaterialIndex); var material2 = model.Materials.GetItemOrNull(newMesh.MaterialIndex); return material1 == material2 || (material1 != null && material2 != null && material1.IsShadowCaster == material2.IsShadowCaster && material1.IsShadowReceiver == material2.IsShadowReceiver); }
/// <summary> /// Compares the parameters of the two meshes. /// </summary> /// <param name="baseMesh">The base mesh.</param> /// <param name="newMesh">The mesh to compare.</param> /// <param name="extra">Unused parameter.</param> /// <returns>True if all the parameters are the same, false otherwise.</returns> private static bool CompareParameters(Rendering.Model model, Mesh baseMesh, Mesh newMesh) { var localParams = baseMesh.Parameters; if (localParams == null && newMesh.Parameters == null) return true; if (localParams == null || newMesh.Parameters == null) return false; return IsSubsetOf(localParams, newMesh.Parameters) && IsSubsetOf(newMesh.Parameters, localParams); }
/// <summary> /// Create a clone with its own ParameterCollection. /// It allows reuse of a single Model for multiple ModelComponent. /// </summary> public Model Instantiate() { var result = new Model(); if (Children != null) { result.Children = new List<Model>(); foreach (var child in Children) { result.Children.Add(child.Instantiate()); } } foreach (var mesh in Meshes) { var meshCopy = new Mesh(mesh); result.Meshes.Add(meshCopy); } result.Skeleton = Skeleton; result.BoundingBox = BoundingBox; return result; }
/// <summary> /// Adds the specified mesh (for collection Initializers). /// </summary> /// <param name="mesh">The mesh.</param> public void Add(Mesh mesh) { Meshes.Add(mesh); }
public override void Load() { base.Load(); slideShowEffect = this.EffectSystemOld.BuildEffect("SlideShow") .Using(new StateShaderPlugin() { RenderPassPlugin = this, UseDepthStencilState = true}) .Using(new BasicShaderPlugin(new ShaderClassSource("PostEffectTransition")) { RenderPassPlugin = this }) .InstantiatePermutation(); if (OfflineCompilation) return; RenderPass.StartPass += (context) => { if (RenderPass.Enabled) { // Setup the Viewport context.GraphicsDevice.SetViewport(MainTargetPlugin.Viewport); // Setup the depth stencil and main render target. context.GraphicsDevice.SetRenderTarget(RenderTarget); } }; RenderPass.EndPass += (context) => { if (RenderPass.Enabled) { context.GraphicsDevice.UnsetRenderTargets(); } }; // Generates a quad for post effect rendering (should be utility function) var vertices = new[] { -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, }; // Use the quad for this effectMesh var quadData = new Mesh(); quadData.Draw = new MeshDraw { DrawCount = 4, PrimitiveType = PrimitiveType.TriangleStrip, VertexBuffers = new[] { new VertexBufferBinding(Buffer.Vertex.New(GraphicsDevice, vertices), new VertexDeclaration(VertexElement.Position<Vector2>()), 4) } }; var textureMesh = new EffectMesh(slideShowEffect, quadData).KeepAliveBy(this); textureMesh.Parameters.Set(EffectPlugin.DepthStencilStateKey, GraphicsDevice.DepthStencilStates.None); textureMesh.Parameters.AddSources(this.Parameters); RenderSystem.GlobalMeshes.AddMesh(textureMesh); }
public override void Load() { base.Load(); skyboxEffect = this.EffectSystemOld.BuildEffect("Skybox") .Using(new StateShaderPlugin() { RenderPassPlugin = this, UseDepthStencilState = true }) .Using(new BasicShaderPlugin( new ShaderMixinSource() { Mixins = new List<ShaderClassSource>() { new ShaderClassSource("SkyBox")}, Compositions = new Dictionary<string, ShaderSource>() { {"color", SkyBoxColor}} }) { RenderPassPlugin = this }) .InstantiatePermutation(); if (OfflineCompilation) return; Parameters.AddSources(MainPlugin.ViewParameters); var zBackgroundValue = MainTargetPlugin.ClearDepth; // Generates a quad for post effect rendering (should be utility function) var vertices = new[] { -1.0f, 1.0f, zBackgroundValue, 1.0f, 1.0f, 1.0f, zBackgroundValue, 1.0f, -1.0f, -1.0f, zBackgroundValue, 1.0f, 1.0f, -1.0f, zBackgroundValue, 1.0f, }; Parameters.RegisterParameter(EffectPlugin.DepthStencilStateKey); Parameters.Set(TexturingKeys.Sampler, GraphicsDevice.SamplerStates.LinearWrap); // Use the quad for this effectMesh var quadData = new Mesh(); quadData.Draw = new MeshDraw { DrawCount = 4, PrimitiveType = PrimitiveType.TriangleStrip, VertexBuffers = new[] { new VertexBufferBinding(Buffer.Vertex.New(GraphicsDevice, vertices), new VertexDeclaration(VertexElement.Position<Vector4>()), 4) } }; RenderPass.StartPass += (context) => { // Setup the Viewport context.GraphicsDevice.SetViewport(MainTargetPlugin.Viewport); // Setup the depth stencil and main render target. context.GraphicsDevice.SetRenderTarget(MainTargetPlugin.DepthStencil, MainTargetPlugin.RenderTarget); }; RenderPass.EndPass += (context) => context.GraphicsDevice.UnsetRenderTargets(); var skyboxMesh = new EffectMesh(skyboxEffect, quadData).KeepAliveBy(this); // If the main target plugin is not clearing anything, we assume that this is the job of the skybox plugin if (!MainTargetPlugin.EnableClearTarget && !MainTargetPlugin.EnableClearDepth) { var description = new DepthStencilStateDescription().Default(); description.DepthBufferFunction = CompareFunction.Always; var alwaysWrite = DepthStencilState.New(GraphicsDevice, description); skyboxMesh.Parameters.Set(EffectPlugin.DepthStencilStateKey, alwaysWrite); } else { skyboxMesh.Parameters.Set(EffectPlugin.DepthStencilStateKey, MainTargetPlugin.DepthStencilState); } skyboxMesh.Parameters.AddSources(this.Parameters); RenderSystem.GlobalMeshes.AddMesh(skyboxMesh); }
/// <summary> /// Creates an Entity that contains our dynamic Vertex and Index buffers. /// This Entity will be rendered by the model renderer. /// </summary> /// <param name="verticesCount"></param> /// <param name="indicesCount"></param> private void CreateTerrainModelEntity(int verticesCount, int indicesCount) { // Compute sizes var vertexDeclaration = VertexNormalTexture.VertexDeclaration; var vertexBufferSize = verticesCount * vertexDeclaration.CalculateSize(); var indexBufferSize = indicesCount * sizeof(short); // Create Vertex and Index buffers terrainVertexBuffer = Buffer.Vertex.New(GraphicsDevice, vertexBufferSize, GraphicsResourceUsage.Dynamic); terrainIndexBuffer = Buffer.New(GraphicsDevice, indexBufferSize, BufferFlags.IndexBuffer, GraphicsResourceUsage.Dynamic); // Prepare mesh and entity var meshDraw = new MeshDraw { PrimitiveType = PrimitiveType.TriangleStrip, VertexBuffers = new[] { new VertexBufferBinding(terrainVertexBuffer, vertexDeclaration, verticesCount) }, IndexBuffer = new IndexBufferBinding(terrainIndexBuffer, false, indicesCount), }; // Load the material and set parameters TerrainMaterial.Parameters.Set(VertexTextureTerrainKeys.MeshTexture0, WaterTexture); TerrainMaterial.Parameters.Set(VertexTextureTerrainKeys.MeshTexture1, GrassTexture); TerrainMaterial.Parameters.Set(VertexTextureTerrainKeys.MeshTexture2, MountainTexture); // Set up material regions TerrainMaterial.Parameters.Set(VertexTextureTerrainKeys.MinimumHeight0, -10); TerrainMaterial.Parameters.Set(VertexTextureTerrainKeys.OptimalHeight0, 40); TerrainMaterial.Parameters.Set(VertexTextureTerrainKeys.MaximumHeight0, 70); TerrainMaterial.Parameters.Set(VertexTextureTerrainKeys.MinimumHeight1, 60); TerrainMaterial.Parameters.Set(VertexTextureTerrainKeys.OptimalHeight1, 80); TerrainMaterial.Parameters.Set(VertexTextureTerrainKeys.MaximumHeight1, 90); TerrainMaterial.Parameters.Set(VertexTextureTerrainKeys.MinimumHeight2, 85); TerrainMaterial.Parameters.Set(VertexTextureTerrainKeys.OptimalHeight2, 95); TerrainMaterial.Parameters.Set(VertexTextureTerrainKeys.MaximumHeight2, 125); terrainMesh = new Mesh { Draw = meshDraw, MaterialIndex = 0 }; TerrainEntity.GetOrCreate<ModelComponent>().Model = new Model { terrainMesh, TerrainMaterial }; }
/// <summary> /// Compares the parameters of the two meshes. /// </summary> /// <param name="baseMesh">The base mesh.</param> /// <param name="newMesh">The mesh to compare.</param> /// <param name="extra">Unused parameter.</param> /// <returns>True if all the parameters are the same, false otherwise.</returns> private static bool CompareParameters(Rendering.Model model, Mesh baseMesh, Mesh newMesh) { var localParams = baseMesh.Parameters; if (localParams == null && newMesh.Parameters == null) return true; if (localParams == null || newMesh.Parameters == null) return false; return AreCollectionsEqual(localParams, newMesh.Parameters); }