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++;
 }