static RasterizerState() { CullClockwise = new RasterizerState() { CullMode = Cull.Clockwise }; CullCounterClockwise = new RasterizerState() { CullMode = Cull.Counterclockwise }; CullNone = new RasterizerState() { CullMode = Cull.None }; }
private static void DrawModels(MySortedElements sortedElements, MyLodTypeEnum lod, ref int ibChangesStats) { for (int i = 0; i < MySortedElements.DrawTechniqueCount; i++) { var technique = (MyMeshDrawTechnique)i; int index = sortedElements.GetModelIndex(lod, technique); var matDict = sortedElements.Models[index]; if (matDict.RenderElementCount == 0) continue; // Technique start var tech = GetTechnique(technique); var shader = tech.PrepareAndBeginShader(m_currentSetup, m_currentLodDrawPass); RasterizerState currentRasterizer = RasterizerState.Current; bool doubleSided = tech.GetType() == typeof(MyDrawTechniqueAlphaMasked) || tech.GetType() == typeof(MyDrawTechniqueMeshInstancedGenericMasked); if (doubleSided) { RasterizerState alphaMaskedRasterizer = new RasterizerState { CullMode = Cull.None }; alphaMaskedRasterizer.Apply(); } MyPerformanceCounter.PerCameraDrawWrite.TechniqueChanges[(int)lod]++; foreach (var mat in matDict.Models) { if (mat.Value.RenderElementCount == 0) continue; // Setup material tech.SetupMaterial(shader, mat.Key); MyPerformanceCounter.PerCameraDrawWrite.MaterialChanges[(int)lod]++; #if !ATI_INSTANCES foreach (var vb in mat.Value.Models) { // Set vb var firstElement = vb.Value.FirstOrDefault(); if (firstElement == null) continue; GraphicsDevice.Indices = firstElement.IndexBuffer; GraphicsDevice.SetStreamSource(0, firstElement.VertexBuffer, 0, firstElement.VertexStride); GraphicsDevice.VertexDeclaration = firstElement.VertexDeclaration; MyPerformanceCounter.PerCameraDrawWrite.VertexBufferChanges[(int)lod]++; ibChangesStats++; MyRenderObject lastRenderObject = null; int[] lastBonesSet = null; foreach (var renderElement in vb.Value) { if (renderElement.InstanceBuffer == null) { MyRender.GraphicsDevice.ResetStreamSourceFrequency(0); MyRender.GraphicsDevice.ResetStreamSourceFrequency(1); } else { GraphicsDevice.VertexDeclaration = renderElement.VertexDeclaration; GraphicsDevice.SetStreamSourceFrequency(0, renderElement.InstanceCount, StreamSource.IndexedData); GraphicsDevice.SetStreamSource(0, renderElement.VertexBuffer, 0, renderElement.VertexStride); GraphicsDevice.SetStreamSourceFrequency(1, 1, StreamSource.InstanceData); GraphicsDevice.SetStreamSource(1, renderElement.InstanceBuffer, renderElement.InstanceStride * renderElement.InstanceStart, renderElement.InstanceStride); } if (lastRenderObject != renderElement.RenderObject || lastBonesSet != renderElement.BonesUsed) { lastRenderObject = renderElement.RenderObject; lastBonesSet = renderElement.BonesUsed; MyPerformanceCounter.PerCameraDrawWrite.EntityChanges[(int)lod]++; tech.SetupEntity(shader, renderElement); if(doubleSided == false) { currentRasterizer.Apply(); BlendState.Opaque.Apply(); } shader.D3DEffect.CommitChanges(); } GraphicsDevice.DrawIndexedPrimitive(PrimitiveType.TriangleList, 0, 0, renderElement.VertexCount, renderElement.IndexStart, renderElement.TriCount); MyPerformanceCounter.PerCameraDrawWrite.TotalDrawCalls++; } #else foreach (var vb in mat.Value.Models) { // Set vb var firstElement = vb.Value.FirstOrDefault(); if (firstElement == null) continue; GraphicsDevice.Indices = firstElement.IndexBuffer; GraphicsDevice.SetStreamSource(0, firstElement.VertexBuffer, 0, firstElement.VertexStride); GraphicsDevice.VertexDeclaration = firstElement.VertexDeclaration; MyPerformanceCounter.PerCameraDrawWrite.VertexBufferChanges[(int)lod]++; ibChangesStats++; MyRenderObject lastRenderObject = null; foreach (var renderElement in vb.Value) { if (renderElement.InstanceBuffer == null) { MyRender.GraphicsDevice.ResetStreamSourceFrequency(0); MyRender.GraphicsDevice.ResetStreamSourceFrequency(1); } else { GraphicsDevice.VertexDeclaration = renderElement.VertexDeclaration; int totalInstCount = renderElement.InstanceCount; int maxbuff = 1024; int offset = 0; while (totalInstCount > 0) { int count = totalInstCount >= maxbuff ? maxbuff : totalInstCount; totalInstCount -= count; GraphicsDevice.SetStreamSourceFrequency(0, count, StreamSource.IndexedData); GraphicsDevice.SetStreamSource(0, renderElement.VertexBuffer, 0, renderElement.VertexStride); GraphicsDevice.SetStreamSourceFrequency(1, 1, StreamSource.InstanceData); GraphicsDevice.SetStreamSource(1, renderElement.InstanceBuffer, renderElement.InstanceStride * (renderElement.InstanceStart + offset), renderElement.InstanceStride); offset += count; if (lastRenderObject != renderElement.RenderObject) { lastRenderObject = renderElement.RenderObject; MyPerformanceCounter.PerCameraDrawWrite.EntityChanges[(int)lod]++; tech.SetupEntity(shader, renderElement); shader.D3DEffect.CommitChanges(); } GraphicsDevice.DrawIndexedPrimitive(PrimitiveType.TriangleList, 0, 0, renderElement.VertexCount, renderElement.IndexStart, renderElement.TriCount); MyPerformanceCounter.PerCameraDrawWrite.TotalDrawCalls++; } } } #endif } } MyRender.GraphicsDevice.ResetStreamSourceFrequency(0); MyRender.GraphicsDevice.ResetStreamSourceFrequency(1); shader.End(); // Technique End if (doubleSided) { currentRasterizer.Apply(); } } } }
internal static void BeginSpriteBatch(BlendState blendState, DepthStencilState depthState, RasterizerState rasterizerState) { if (m_spriteBatchUsageCount == 0) { // Deferred means that draw call will be send to GPU not on every Draw(), but only at the End() or if we change // a texture between Begin/End. It's faster than Immediate mode. m_spriteBatch.Begin(SpriteSortMode.Deferred, blendState, VRageRender.Graphics.SamplerState.LinearClamp, depthState, rasterizerState); } m_spriteBatchUsageCount++; }