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); }
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); }
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); }
/// <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); }
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); } }
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); }
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); }
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); }
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; }
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); }
/// <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); }
public void AddSubMesh(Mesh.SubMesh subMesh) { _subMeshes.Add(subMesh); }
public void AddInstancedSubMesh(Mesh.SubMesh subMesh) { GetInstanceGroupForSubMesh(subMesh).AddSubMesh(subMesh); }