示例#1
0
        public void GenerateInstanceInfo(GraphicsDevice device)
        {
            if (_subMeshes.Count == 0)
            {
                return;
            }
            if (_instanceTransforms.Length < _subMeshes.Count)
            {
                _instanceTransforms = new Matrix[_subMeshes.Count * 2];
            }
            for (int index = 0; index < _subMeshes.Count; index++)
            {
                Mesh.SubMesh subMesh = _subMeshes[index];
                _instanceTransforms[index] = subMesh.GlobalTransform;
            }

            // If we have more instances than room in our vertex buffer, grow it to the necessary size.
            if ((_instanceVertexBuffer == null) ||
                (_instanceTransforms.Length > _instanceVertexBuffer.VertexCount))
            {
                if (_instanceVertexBuffer != null)
                {
                    _instanceVertexBuffer.Dispose();
                }

                _instanceVertexBuffer = new DynamicVertexBuffer(device, _instanceVertexDeclaration,
                                                                _instanceTransforms.Length, BufferUsage.WriteOnly);
            }
            // Transfer the latest instance transform matrices into the instanceVertexBuffer.
            _instanceVertexBuffer.SetData(_instanceTransforms, 0, _subMeshes.Count, SetDataOptions.Discard);
        }
示例#2
0
        public void RenderToGBuffer(Camera camera, GraphicsDevice graphicsDevice)
        {
            if (_subMeshes.Count == 0)
            {
                return;
            }

            // Tell the GPU to read from both the model vertex buffer plus our instanceVertexBuffer.
            Mesh.SubMesh  subMesh  = _subMeshes[0];
            ModelMeshPart meshPart = subMesh._meshPart;

            graphicsDevice.SetVertexBuffers(
                new VertexBufferBinding(meshPart.VertexBuffer, meshPart.VertexOffset, 0),
                new VertexBufferBinding(_instanceVertexBuffer, 0, 1)
                );

            subMesh.RenderEffect.SetCurrentTechnique(3);
            subMesh.RenderEffect.SetMatrices(Matrix.Identity, camera.EyeTransform, camera.ProjectionTransform);
            //our first pass is responsible for rendering into GBuffer
            subMesh.RenderEffect.SetFarClip(camera.FarClip);

            //no individual skinned models for now
            if (subMesh._parent.BoneMatrixes != null)
            {
                subMesh.RenderEffect.SetBones(subMesh._parent.BoneMatrixes);
            }

            subMesh.RenderEffect.Apply();

            graphicsDevice.Indices = meshPart.IndexBuffer;

            graphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0,
                                                   meshPart.NumVertices, meshPart.StartIndex,
                                                   meshPart.PrimitiveCount, _subMeshes.Count);
        }
示例#3
0
        public void ReconstructShading(Camera camera, GraphicsDevice graphicsDevice)
        {
            if (_subMeshes.Count == 0)
            {
                return;
            }

            // Tell the GPU to read from both the model vertex buffer plus our instanceVertexBuffer.
            Mesh.SubMesh  subMesh  = _subMeshes[0];
            ModelMeshPart meshPart = subMesh._meshPart;

            graphicsDevice.SetVertexBuffers(
                new VertexBufferBinding(meshPart.VertexBuffer, meshPart.VertexOffset, 0),
                new VertexBufferBinding(_instanceVertexBuffer, 0, 1)
                );

            subMesh.RenderEffect.SetCurrentTechnique(4);

            subMesh.RenderEffect.Apply();

            graphicsDevice.Indices = meshPart.IndexBuffer;

            graphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0,
                                                   meshPart.NumVertices, meshPart.StartIndex,
                                                   meshPart.PrimitiveCount, _subMeshes.Count);
        }
示例#4
0
        /// <summary>
        /// Call this for every mesh you create, so it sets the GBuffer textures only once
        /// </summary>
        /// <param name="mesh"></param>
        public void SetupSubMesh(Mesh.SubMesh subMesh)
        {
            subMesh.RenderEffect.SetLightBuffer(_lightBuffer, _lightSpecularBuffer);

            subMesh.RenderEffect.SetLightBufferPixelSize(new Vector2(0.5f / _lightBuffer.Width, 0.5f / _lightBuffer.Height));
            subMesh.RenderEffect.SetDepthBuffer(_depthBuffer);
            subMesh.RenderEffect.SetNormalBuffer(_normalBuffer);
        }
示例#5
0
        private void DrawOpaqueObjects(Camera camera)
        {
            List <Mesh.SubMesh> meshes = _visibleMeshes[(int)MeshMetadata.ERenderQueue.SkipGbuffer];

            for (int index = 0; index < meshes.Count; index++)
            {
                Mesh.SubMesh visibleMesh = meshes[index];
                visibleMesh.GenericRender(camera, GraphicsDevice);
            }
        }
示例#6
0
        private InstancingGroup GetInstanceGroupForSubMesh(Mesh.SubMesh subMesh)
        {
            for (int index = 0; index < _instancingGroups.Count; index++)
            {
                InstancingGroup instancingGroup = _instancingGroups[index];
                ModelMeshPart   firstMeshPart   = instancingGroup.GetModelMeshPart();
                if (firstMeshPart == subMesh._meshPart || firstMeshPart == null)
                {
                    return(instancingGroup);
                }
            }
            InstancingGroup newGroup = new InstancingGroup();

            _instancingGroups.Add(newGroup);
            return(newGroup);
        }
示例#7
0
        private void ReconstructShading(Camera camera)
        {
            List <Mesh.SubMesh> meshes = _visibleMeshes[(int)MeshMetadata.ERenderQueue.Default];

            for (int index = 0; index < meshes.Count; index++)
            {
                Mesh.SubMesh visibleMesh = meshes[index];

                if (!visibleMesh.InstanceEnabled)
                {
                    visibleMesh.ReconstructShading(camera, GraphicsDevice);
                }
            }
            //reuse the instance groups
            InstancingGroupManager.ReconstructShading(camera, GraphicsDevice);
        }
示例#8
0
        private void RenderToGbuffer(Camera camera)
        {
            List <Mesh.SubMesh> meshes = _visibleMeshes[(int)MeshMetadata.ERenderQueue.Default];

            for (int index = 0; index < meshes.Count; index++)
            {
                Mesh.SubMesh mesh = meshes[index];
                if (!mesh.InstanceEnabled)
                {
                    mesh.RenderToGBuffer(camera, GraphicsDevice);
                }
                else
                {
                    InstancingGroupManager.AddInstancedSubMesh(mesh);
                }
            }
            InstancingGroupManager.GenerateInstanceInfo(GraphicsDevice);
            InstancingGroupManager.RenderToGBuffer(camera, GraphicsDevice);
        }
示例#9
0
        private void DrawBlendObjects(Camera camera)
        {
            _graphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
            _graphicsDevice.BlendState        = BlendState.Additive;

            List <Mesh.SubMesh> meshes = _visibleMeshes[(int)MeshMetadata.ERenderQueue.Blend];

            for (int index = 0; index < meshes.Count; index++)
            {
                Mesh.SubMesh visibleMesh = meshes[index];
                visibleMesh.GenericRender(camera, GraphicsDevice);
            }

            //reset states, since the custom shaders could have overriden them
            _graphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
            _graphicsDevice.BlendState        = BlendState.Additive;
            _graphicsDevice.BlendFactor       = Color.White;
            _graphicsDevice.RasterizerState   = RasterizerState.CullCounterClockwise;

            Matrix projectionTransform = camera.ProjectionTransform;
            Matrix eyeTransform        = camera.EyeTransform;
        }
示例#10
0
        public virtual void RenderShadowMap(ref Matrix viewProj, GraphicsDevice graphicsDevice)
        {
            if (_subMeshes.Count == 0)
            {
                return;
            }

            // Tell the GPU to read from both the model vertex buffer plus our instanceVertexBuffer.
            Mesh.SubMesh  subMesh  = _subMeshes[0];
            ModelMeshPart meshPart = subMesh._meshPart;

            graphicsDevice.SetVertexBuffers(
                new VertexBufferBinding(meshPart.VertexBuffer, meshPart.VertexOffset, 0),
                new VertexBufferBinding(_instanceVertexBuffer, 0, 1)
                );

            subMesh.RenderEffect.SetCurrentTechnique(5);
            subMesh.RenderEffect.SetLightViewProj(viewProj);


            //we need to set this every frame, there are situations where the object is not on screen but it still cast shadows
            subMesh.RenderEffect.SetWorld(Matrix.Identity);
            //no individual skinned models for now
            if (subMesh._parent.BoneMatrixes != null)
            {
                subMesh.RenderEffect.SetBones(subMesh._parent.BoneMatrixes);
            }


            subMesh.RenderEffect.Apply();

            graphicsDevice.Indices = meshPart.IndexBuffer;

            graphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0,
                                                   meshPart.NumVertices, meshPart.StartIndex,
                                                   meshPart.PrimitiveCount, _subMeshes.Count);
        }
示例#11
0
        /// <summary>
        /// Generate the shadow map for a given spot light
        /// </summary>
        /// <param name="renderer"></param>
        /// <param name="meshes"></param>
        /// <param name="light"></param>
        /// <param name="shadowMap"></param>
        public void GenerateShadowTextureSpotLight(Renderer renderer, BaseSceneGraph renderWorld, Light light, SpotShadowMapEntry shadowMap)
        {
            //bind the render target
            renderer.GraphicsDevice.SetRenderTarget(shadowMap.Texture);
            //clear it to white, ie, far far away
            renderer.GraphicsDevice.Clear(Color.White);
            renderer.GraphicsDevice.BlendState        = BlendState.Opaque;
            renderer.GraphicsDevice.DepthStencilState = DepthStencilState.Default;


            Matrix viewProj = light.ViewProjection;

            shadowMap.LightViewProjection = viewProj;

            BoundingFrustum frustum = light.Frustum;

            _visibleMeshes.Clear();
            //cull meshes outside the light volume
            renderWorld.GetShadowCasters(frustum, _visibleMeshes);

            renderer.InstancingGroupManager.Reset();
            for (int index = 0; index < _visibleMeshes.Count; index++)
            {
                Mesh.SubMesh subMesh = _visibleMeshes[index];
                //render it
                if (!subMesh.InstanceEnabled)
                {
                    subMesh.RenderShadowMap(ref viewProj, renderer.GraphicsDevice);
                }
                else
                {
                    renderer.InstancingGroupManager.AddInstancedSubMesh(subMesh);
                }
            }
            renderer.InstancingGroupManager.GenerateInstanceInfo(renderer.GraphicsDevice);
            renderer.InstancingGroupManager.RenderShadowMap(ref viewProj, renderer.GraphicsDevice);
        }
示例#12
0
 public void AddSubMesh(Mesh.SubMesh subMesh)
 {
     _subMeshes.Add(subMesh);
 }
示例#13
0
 public void AddInstancedSubMesh(Mesh.SubMesh subMesh)
 {
     GetInstanceGroupForSubMesh(subMesh).AddSubMesh(subMesh);
 }