public D3DMesh(Device device, DeviceContext context, Mesh mesh)
        {
            // Store variables
            this.mesh = mesh;
            this.device = device;
            this.context = context;

            // Defaults
            Topology = PrimitiveTopology.TriangleList;
        }
        private static void ExportSBM(Stream strm, Mesh mesh, string[] materials)
        {
            BinaryWriter wtr = new BinaryWriter(strm);
            wtr.Write(new char[] { 'S', 'B', 'M', '\0' });
            wtr.Write(1);
            wtr.Write(materials.Length);
            wtr.Write(1);

            for (int i = 0; i < materials.Length; i++)
            {
                string mat = materials[i];
                for (int j = 0; j < mat.Length; j++)
                    wtr.Write(mat[j]);
                wtr.Write((char)'\0');
            }

            wtr.Write(mesh.Positions.Length);
            wtr.Write(mesh.Submeshes.Length);
            for (int i = 0; i < mesh.Positions.Length; i++)
            {
                WriteVector(wtr, mesh.Positions[i]);
                WriteVector(wtr, mesh.Normals[i]);
                WriteVector(wtr, mesh.TextureCoordinates[i]);
                WriteVector(wtr, mesh.Tangents[i]);
            }

            for (int i = 0; i < mesh.Submeshes.Length; i++)
            {
                uint[] indices = mesh.Submeshes[i];
                wtr.Write(indices.Length);
                wtr.Write(i);

                for (int j = 0; j < indices.Length; j++)
                    wtr.Write(indices[j]);
            }
            wtr.Flush();
        }
        /// <summary>
        /// Draws a mesh immediately with no transform setup
        /// </summary>
        /// <param name="mesh"></param>
        /// <param name="submesh"></param>
        public void DrawImmediate(Mesh mesh, int submesh)
        {
            // Sanity check
            if (activematerial == null) return;

            // Setup the material
            activematerial.Shader.Effect.GetTechniqueByIndex(0).GetPassByIndex(0).Apply(context);

            // Setup the mesh
            if (!mesh.Render(activematerial.Shader, submesh))
            {
                mesh.Upload(Device, context);
                mesh.Render(activematerial.Shader, submesh);
            }
        }
        /// <summary>
        /// Draws a mesh immediately
        /// </summary>
        /// <param name="mesh"></param>
        /// <param name="submesh"></param>
        /// <param name="material"></param>
        /// <param name="transform"></param>
        public void DrawImmediate(Mesh mesh, int submesh, Matrix projectionview, Matrix transform)
        {
            // Sanity check
            if (activematerial == null) return;

            // Setup the material
            Shader shader = activematerialshadow ? activematerial.ShadowShader : activematerial.Shader;
            if (shader == null) return;
            shader.SetVariable("projectionview", projectionview);
            shader.SetVariable("transform", transform);
            shader.DefaultPass.Apply(context);

            // Setup the mesh
            if (!mesh.Render(shader, submesh))
            {
                mesh.Upload(Device, context);
                mesh.Render(shader, submesh);
            }
            frame_drawcalls++;
        }
        private static void MergeMeshes(SBMLoader loader, out Mesh result, out string[] materials)
        {
            if (loader.MeshCount == 0)
            {
                result = null;
                materials = null;
                return;
            }
            if (loader.MeshCount == 1)
            {
                loader.GetMesh(0, out result, out materials);
                return;
            }

            List<string> finalmaterials = new List<string>();

            MeshBuilder merged = new MeshBuilder();
            merged.UseNormals = true;
            merged.UseTangents = true;
            merged.UseTexCoords = true;

            int totalsubmeshes = 0;

            for (int i = 0; i < loader.MeshCount; i++)
            {
                Mesh cmesh;
                string[] curmats;
                loader.GetMesh(i, out cmesh, out curmats);

                totalsubmeshes += cmesh.Submeshes.Length;

                int baseindex = merged.CurrentVertexCount;
                merged.AddPositions(cmesh.Positions);
                merged.AddNormals(cmesh.Normals);
                merged.AddTextureCoords(cmesh.TextureCoordinates);
                merged.AddTangents(cmesh.Tangents);

                for (int j = 0; j < cmesh.Submeshes.Length; j++)
                {
                    int submeshindex;
                    if (finalmaterials.Contains(curmats[j]))
                        submeshindex = finalmaterials.IndexOf(curmats[j]);
                    else
                    {
                        submeshindex = finalmaterials.Count;
                        finalmaterials.Add(curmats[j]);
                    }

                    merged.AddIndices(submeshindex, cmesh.Submeshes[j], (uint)baseindex);
                }

            }

            Console.WriteLine("Merged {0} meshes with a total of {1} submeshes into 1 mesh with a total of {2} submeshes.", loader.MeshCount, totalsubmeshes, finalmaterials.Count);

            result = merged.Build();
            materials = finalmaterials.ToArray();
        }
 /// <summary>
 /// Gets the mesh data at the specified index
 /// </summary>
 /// <param name="index"></param>
 /// <param name="mesh"></param>
 /// <param name="materials"></param>
 public void GetMesh(int index, out Mesh mesh, out string[] materials)
 {
     mesh = meshes[index].Mesh;
     materials = meshes[index].Materials;
 }
 public Mesh Build()
 {
     //if (CurrentVertexCount >= uint.MaxValue) throw new Exception("Reached maximum vertex count on mesh");
     Mesh m = new Mesh();
     m.Positions = lstPositions.ToArray();
     if (UseNormals) m.Normals = lstNormals.ToArray();
     if (UseTexCoords) m.TextureCoordinates = lstTexCoords.ToArray();
     if (UseTangents) m.Tangents = lstTangents.ToArray();
     m.Submeshes = new uint[lstIndices.Count][];
     for (int i = 0; i < lstIndices.Count; i++)
         m.Submeshes[i] = lstIndices[i].ToArray();
     m.AABB = BoundingBox.FromPoints(m.Positions);
     m.Topology = MeshTopology.Triangles;
     return m;
 }
 public static Mesh BuildNormalDebugger(Mesh mesh)
 {
     if (mesh.Normals == null) return null;
     MeshBuilder builder = new MeshBuilder();
     for (int i = 0; i < mesh.Normals.Length; i++)
     {
         builder.AddPosition(mesh.Positions[i]);
         builder.AddPosition(mesh.Positions[i] + mesh.Normals[i]);
     }
     return builder.Build();
 }
 public static void BuildGrassPatch(int points, float range, out Mesh high, out Mesh medium, out Mesh low)
 {
     Random rnd = new Random();
     MeshBuilder builder = new MeshBuilder();
     builder.UseNormals = true;
     for (int i = 0; i < points; i++)
     {
         builder.AddPosition(new Vector3((float)rnd.NextDouble() * range, 0.0f, (float)rnd.NextDouble() * range));
         builder.AddNormal(new Vector3((float)(rnd.NextDouble() * Math.PI * 2.0), (float)rnd.NextDouble(), (float)rnd.NextDouble()));
     }
     high = builder.Build();
     builder.RemovePoints(points / 3);
     medium = builder.Build();
     builder.RemovePoints(points / 3);
     low = builder.Build();
 }
        public void OnInitialise(InitialiseMessage msg)
        {
            // Initialise scene manager
            Console.WriteLine("Initialising scene manager...");

            // Initialise messages
            queuemsg = new PopulateRenderQueue();
            queuemsg.SceneManager = this;
            cameramsg = new PopulateCameraList();
            cameramsg.Cameras = new OrderedList<Camera>(new CameraComparer());
            cameramsg.ShadowCasters = new HashSet<ShadowCaster>();
            lightmsg = new PopulateLightList();
            lightmsg.Lights = new OrderedList<Light>(new LightComparer());
            psysmsg = new PopulateParticleSystemList();
            psysmsg.ParticleSystems = new List<ParticleSystem>();

            // Create render queue
            workitempool = new ResourcePool<RenderWorkItem>();
            renderqueue = new OrderedList<RenderWorkItem>(new RenderWorkItemComparer());
            effectqueue = new OrderedList<PostProcessEffect>(new PostProcessEffectComparer());

            // Setup GBuffer
            Renderer renderer = Owner.GetComponent<Renderer>();
            gbuffer = renderer.CreateRenderTarget(1, "GBuffer");
            gbuffer.ClearColour = new Color4(0.0f, 0.0f, 0.0f, 0.0f);
            gbuffer.AddDepthComponent();
            gbuffer_colour = gbuffer.AddTextureComponent();
            gbuffer_normal = gbuffer.AddTextureComponent(SlimDX.DXGI.Format.R32G32B32A32_Float);
            gbuffer_position = gbuffer.AddTextureComponent(SlimDX.DXGI.Format.R32G32B32A32_Float);
            gbuffer_material = gbuffer.AddTextureComponent(SlimDX.DXGI.Format.R32G32B32A32_Float);
            gbuffer.Finish();

            // Setup light accumulation buffer
            lightaccum = renderer.CreateRenderTarget(1, "LightAccum");
            lightaccum.ClearColour = new Color4(1.0f, 0.0f, 0.0f, 0.0f);
            lightaccum_diffuse = lightaccum.AddTextureComponent(SlimDX.DXGI.Format.R32G32B32A32_Float);
            lightaccum_specular = lightaccum.AddTextureComponent(SlimDX.DXGI.Format.R32G32B32A32_Float);
            lightaccum.Finish();

            // Setup particle accumulation buffer
            particleaccum = renderer.CreateRenderTarget(1, "ParticleAccum");
            particleaccum.ClearColour = new Color4(0.0f, 0.0f, 0.0f, 0.0f);
            particleaccum_colour = particleaccum.AddTextureComponent();
            particleaccum.Finish();

            // Setup swap buffers
            swapA = renderer.CreateRenderTarget(1, "SwapA");
            swapA_colour = swapA.AddTextureComponent();
            swapA.Finish();
            swapB = renderer.CreateRenderTarget(1, "SwapB");
            swapB_colour = swapB.AddTextureComponent();
            swapB.Finish();

            // Setup materials
            MaterialSystem matsys = Owner.GetComponent<MaterialSystem>();
            mat_blit = matsys.CreateMaterial("blit", "blit");
            mat_blit.SetParameter("smpTexture", renderer.Sampler_Clamp);
            mat_blitlight = matsys.CreateMaterial("blit_light", "blit_light");
            mat_blitlight.SetParameter("smpTexture", renderer.Sampler_Clamp);
            mat_blitlight.SetParameter("texColour", gbuffer.GetTexture(gbuffer_colour));
            mat_blitlight.SetParameter("texDiffuseLight", lightaccum.GetTexture(lightaccum_diffuse));
            mat_blitlight.SetParameter("texSpecularLight", lightaccum.GetTexture(lightaccum_specular));

            // Setup lights
            mat_lights = new Dictionary<LightType, Material>();
            mat_lights.Add(LightType.Ambient, matsys.CreateMaterial("light_ambient", "light_ambient"));
            mat_lights.Add(LightType.Directional, matsys.CreateMaterial("light_directional", "light_directional"));
            mat_lights.Add(LightType.Point, matsys.CreateMaterial("light_point", "light_point"));
            foreach (Material mat in mat_lights.Values)
            {
                mat.SetParameter("texNormal", gbuffer.GetTexture(gbuffer_normal));
                mat.SetParameter("texPosition", gbuffer.GetTexture(gbuffer_position));
                mat.SetParameter("texMaterial", gbuffer.GetTexture(gbuffer_material));
                mat.SetParameter("smpTexture", renderer.Sampler_Clamp);
            }

            // Setup meshes
            mesh_fs = MeshBuilder.BuildFullscreenQuad();
            mesh_skybox = MeshBuilder.BuildCube();
        }
        /// <summary>
        /// Queues a draw order
        /// </summary>
        /// <param name="mesh"></param>
        /// <param name="submesh"></param>
        /// <param name="material"></param>
        /// <param name="transform"></param>
        public void QueueDraw(Mesh mesh, int submesh, Material material, Matrix transform)
        {
            // Create the work item
            RenderWorkItem item = workitempool.Request();
            item.Mesh = mesh;
            item.SubmeshIndex = submesh;
            item.Material = material;
            item.Transform = transform;

            // Add to queue
            renderqueue.Add(item);
        }