Esempio n. 1
0
        public void Apply(CommandList commandList, ResourceGroup[] resourceGroups, int resourceGroupsOffset)
        {
            if (resourceGroupBindings.Length == 0)
                return;

            var resourceGroupBinding = Interop.Pin(ref resourceGroupBindings[0]);
            for (int i = 0; i < resourceGroupBindings.Length; i++, resourceGroupBinding = Interop.IncrementPinned(resourceGroupBinding))
            {
                var resourceGroup = resourceGroups[resourceGroupsOffset + i];

                // Upload cbuffer (if not done yet)
                if (resourceGroupBinding.ConstantBufferSlot != -1 && resourceGroup != null && resourceGroup.ConstantBuffer.Data != IntPtr.Zero)
                {
                    var preallocatedBuffer = resourceGroup.ConstantBuffer.Buffer;
                    bool needUpdate = true;
                    if (preallocatedBuffer == null)
                        preallocatedBuffer = resourceGroupBinding.ConstantBufferPreallocated; // If it's preallocated buffer, we always upload
                    else if (resourceGroup.ConstantBuffer.Uploaded)
                        needUpdate = false; // If it's not preallocated and already uploaded, we can avoid uploading it again
                    else
                        resourceGroup.ConstantBuffer.Uploaded = true; // First time it is uploaded

                    if (needUpdate)
                    {
                        var mappedConstantBuffer = commandList.MapSubresource(preallocatedBuffer, 0, MapMode.WriteDiscard);
                        Utilities.CopyMemory(mappedConstantBuffer.DataBox.DataPointer, resourceGroup.ConstantBuffer.Data, resourceGroup.ConstantBuffer.Size);
                        commandList.UnmapSubresource(mappedConstantBuffer);
                    }

                    resourceGroup.DescriptorSet.SetConstantBuffer(resourceGroupBinding.ConstantBufferSlot, preallocatedBuffer, 0, resourceGroup.ConstantBuffer.Size);
                }
            }
        }
Esempio n. 2
0
        public override void UpdateSurface(CommandList commandList, Texture texture)
        {
            OculusOvr.SetQuadLayerParams(OverlayPtr, ref Position, ref Rotation, ref SurfaceSize, FollowHeadRotation);
            var index = OculusOvr.GetCurrentQuadLayerTargetIndex(ovrSession, OverlayPtr);

            commandList.Copy(texture, textures[index]);
        }
Esempio n. 3
0
        public override void Commit(CommandList commandList, Texture renderFrame)
        {
            var index = OculusOvr.GetCurrentTargetIndex(ovrSession);

            commandList.Copy(renderFrame, textures[index]);
            overlayPtrs = overlays.Where(x => x.Enabled).Select(x => x.OverlayPtr).ToArray();
            OculusOvr.CommitFrame(ovrSession, overlayPtrs.Length, overlayPtrs);
        }
        public ResourceGroupAllocator(GraphicsResourceAllocator allocator, CommandList commandList)
        {
            this.allocator = allocator;
            this.commandList = commandList;
            this.graphicsDevice = commandList.GraphicsDevice;

            SetupNextDescriptorPool();
        }
Esempio n. 5
0
 public void Map(CommandList commandList)
 {
     if (useBufferOffsets)
     {
         using (new DefaultCommandListLock(commandList))
         {
             this.commandList = commandList;
             mappedConstantBuffer = commandList.MapSubresource(constantBuffer, 0, MapMode.WriteNoOverwrite);
             Data = mappedConstantBuffer.DataBox.DataPointer;
         }
     }
 }
        public override void EndDraw(CommandList commandList, bool present)
        {
            if (present)
            {
                // If we made a fake render target to avoid OpenGL limitations on window-provided back buffer, let's copy the rendering result to it
                commandList.CopyScaler2D(backBuffer, GraphicsDevice.WindowProvidedRenderTexture,
                    new Rectangle(0, 0, backBuffer.Width, backBuffer.Height),
                    new Rectangle(0, 0, GraphicsDevice.WindowProvidedRenderTexture.Width, GraphicsDevice.WindowProvidedRenderTexture.Height), true);

                gameWindow.SwapBuffers();
            }
        }
        public void PrepareAsRenderTarget(CommandList commandList)
        {
            // Switch to render target
            commandList.ResourceBarrierTransition(Texture, GraphicsResourceState.DepthWrite);

            if (clearNeeded)
            {
                // TODO GRAPHICS REFACTOR
                commandList.Clear(Texture, DepthStencilClearOptions.DepthBuffer);
                clearNeeded = false;
            }
        }
 public DefaultCommandListLock(CommandList lockObject)
 {
     if (lockObject.GraphicsDevice.InternalMainCommandList == lockObject)
     {
         this.lockObject = lockObject;
         lockTaken = false;
         Monitor.Enter(lockObject, ref lockTaken);
     }
     else
     {
         this.lockTaken = false;
         this.lockObject = null;
     }
 }
        public override void EndDraw(CommandList commandList, bool present)
        {
            if (present)
            {
                // If we made a fake render target to avoid OpenGL limitations on window-provided back buffer, let's copy the rendering result to it
                commandList.CopyScaler2D(backBuffer, GraphicsDevice.WindowProvidedRenderTexture,
                    new Rectangle(0, 0, backBuffer.Width, backBuffer.Height),
                    new Rectangle(0, 0, GraphicsDevice.WindowProvidedRenderTexture.Width, GraphicsDevice.WindowProvidedRenderTexture.Height), true);

                // On macOS, `SwapBuffers` will swap whatever framebuffer is active and in our case it is not the window provided
                // framebuffer, and in addition if the active framebuffer is single buffered, it won't do anything. Forcing a bind
                // will ensure the window is updated.
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, GraphicsDevice.WindowProvidedFrameBuffer);
                OpenTK.Graphics.GraphicsContext.CurrentContext.SwapBuffers();
            }
        }
Esempio n. 10
0
        public void BindResources(CommandList commandList, DescriptorSet[] descriptorSets)
        {
            for (int setIndex = 0; setIndex < descriptorSetBindings.Length; setIndex++)
            {
                var bindingOperations = descriptorSetBindings[setIndex];
                if (bindingOperations == null)
                    continue;

                var descriptorSet = descriptorSets[setIndex];

                var bindingOperation = Interop.Pin(ref bindingOperations[0]);
                for (int index = 0; index < bindingOperations.Length; index++, bindingOperation = Interop.IncrementPinned(bindingOperation))
                {
                    var value = descriptorSet.HeapObjects[descriptorSet.DescriptorStartOffset + bindingOperation.EntryIndex];
                    switch (bindingOperation.Class)
                    {
                        case EffectParameterClass.ConstantBuffer:
                            {
                                //commandList.SetConstantBuffer(bindingOperation.Stage, bindingOperation.SlotStart, (Buffer)value.Value);
                                commandList.SetConstantBuffer(bindingOperation.Stage, bindingOperation.SlotStart, (Buffer)value.Value);
                                break;
                            }
                        case EffectParameterClass.Sampler:
                            {
                                commandList.SetSamplerState(bindingOperation.Stage, bindingOperation.SlotStart, bindingOperation.ImmutableSampler ?? (SamplerState)value.Value);
                                break;
                            }
                        case EffectParameterClass.ShaderResourceView:
                            {
                                commandList.SetShaderResourceView(bindingOperation.Stage, bindingOperation.SlotStart, (GraphicsResource)value.Value);
                                break;
                            }
                        case EffectParameterClass.UnorderedAccessView:
                            {
                                commandList.SetUnorderedAccessView(bindingOperation.Stage, bindingOperation.SlotStart, (GraphicsResource)value.Value);
                                break;
                            }
                        default:
                            throw new ArgumentOutOfRangeException();
                    }
                }
            }
        }
        public UseOpenGLCreationContext(GraphicsDevice graphicsDevice)
            : this()
        {
            if (OpenTK.Graphics.GraphicsContext.CurrentContextHandle.Handle == IntPtr.Zero)
            {
                needUnbindContext = true;
                useDeviceCreationContext = true;

#if SILICONSTUDIO_PLATFORM_ANDROID
                tegraWorkaround = graphicsDevice.Workaround_Context_Tegra2_Tegra3;

                // Notify main rendering thread there is some pending async work to do
                if (tegraWorkaround)
                {
                    useDeviceCreationContext = false; // We actually use real main context, so states will be kept
                    graphicsDevice.AsyncPendingTaskWaiting = true;
                }
#endif

                // Lock, since there is only one deviceCreationContext.
                // TODO: Support multiple deviceCreationContext (TLS creation of context was crashing, need to investigate why)
                asyncCreationLockObject = graphicsDevice.asyncCreationLockObject;
                Monitor.Enter(graphicsDevice.asyncCreationLockObject, ref asyncCreationLockTaken);

#if SILICONSTUDIO_PLATFORM_ANDROID
                if (tegraWorkaround)
                    graphicsDevice.AsyncPendingTaskWaiting = false;
#endif

                // Bind the context
                deviceCreationContext = graphicsDevice.deviceCreationContext;
                deviceCreationContext.MakeCurrent(graphicsDevice.deviceCreationWindowInfo);
            }
            else
            {
                // TODO Hardcoded to the fact it uses only one command list, this should be fixed
                CommandList = graphicsDevice.MainCommandList;
            }
        }
        public void Reset(CommandList commandList)
        {
            this.commandList = commandList;

            foreach (var descriptorPool in descriptorPools)
            {
                descriptorPool.Reset();
            }

            foreach (var bufferPool in bufferPools)
            {
                bufferPool.Reset();
            }

            currentResourceGroupPoolIndex = -1;

            currentDescriptorPool = descriptorPools[0];
            currentDescriptorPoolIndex = 0;

            currentBufferPool = null;
            currentBufferPoolIndex = -1;
        }
        public void Apply(CommandList commandList, BlendState oldBlendState)
        {
            // note: need to update blend equation, blend function and color mask even when the blend state is disable in order to keep the hash based caching system valid

            if (blendEnable && !oldBlendState.blendEnable)
                GL.Enable(EnableCap.Blend);

            if (blendEquationHash != oldBlendState.blendEquationHash)
                GL.BlendEquationSeparate(blendEquationModeColor, blendEquationModeAlpha);

            if (blendFuncHash != oldBlendState.blendFuncHash)
                GL.BlendFuncSeparate(blendFactorSrcColor, blendFactorDestColor, blendFactorSrcAlpha, blendFactorDestAlpha);

            if (commandList.NewBlendFactor != commandList.BoundBlendFactor)
            {
                commandList.BoundBlendFactor = commandList.NewBlendFactor;
                GL.BlendColor(commandList.NewBlendFactor.R, commandList.NewBlendFactor.G, commandList.NewBlendFactor.B, commandList.NewBlendFactor.A);
            }

            if (ColorWriteChannels != oldBlendState.ColorWriteChannels)
            {
                RestoreColorMask();
            }

            if(!blendEnable && oldBlendState.blendEnable)
                GL.Disable(EnableCap.Blend);
        }
Esempio n. 14
0
 public virtual void BeginDraw(CommandList commandList)
 {
 }
Esempio n. 15
0
 /// <summary>
 /// Gets the DX11 native device context
 /// </summary>
 /// <param name="commandList">The Xenko CommandList</param>
 /// <returns></returns>
 public static DeviceContext GetNativeDeviceContext(CommandList commandList)
 {
     return(commandList.NativeDeviceContext);
 }
 public override void BeginDraw(CommandList commandList)
 {
 }
 public void PrepareAsShaderResourceView(CommandList commandList)
 {
     commandList.ResourceBarrierTransition(Texture, GraphicsResourceState.PixelShaderResource);
 }
Esempio n. 18
0
 private Vector3 GetCurrentResolution(CommandList commandList)
 {
     return(VirtualResolution.HasValue ? VirtualResolution.Value: new Vector3(commandList.Viewport.Width, commandList.Viewport.Height, DefaultDepth));
 }
Esempio n. 19
0
 /// <summary>
 /// Return the glyph associated to provided character at the given size.
 /// </summary>
 /// <param name="commandList">The command list in case we upload gpu resources</param>
 /// <param name="character">The character we want the glyph of</param>
 /// <param name="fontSize">The font size in pixel</param>
 /// <param name="uploadGpuResources">Indicate if the GPU resource should be uploaded or not.</param>
 /// <param name="auxiliaryScaling">If the requested font size isn't available, the closest one is chosen and an auxiliary scaling is returned</param>
 /// <returns>The glyph corresponding to the request or null if not existing</returns>
 protected virtual Glyph GetGlyph(CommandList commandList, char character, ref Vector2 fontSize, bool uploadGpuResources, out Vector2 auxiliaryScaling)
 {
     auxiliaryScaling = new Vector2(1, 1);
     return(null);
 }
 public override void BeginDraw(CommandList commandList)
 {
     // Backbuffer needs to be cleared
     backbuffer.IsInitialized = false;
 }
Esempio n. 21
0
 /// <summary>
 /// Draws a quad. The effect must have been applied before calling this method with pixel shader having the signature float2:TEXCOORD.
 /// </summary>
 /// <param name="texture"></param>
 public void Draw(CommandList commandList)
 {
     commandList.SetVertexBuffer(0, sharedData.VertexBuffer.Buffer, sharedData.VertexBuffer.Offset, sharedData.VertexBuffer.Stride);
     commandList.Draw(QuadCount);
 }
        public void Apply(CommandList commandList)
        {
            if (commandList.DepthStencilBoundState.DepthBufferEnable != state.DepthBufferEnable)
            {
                commandList.DepthStencilBoundState.DepthBufferEnable = state.DepthBufferEnable;

                if (state.DepthBufferEnable)
                    GL.Enable(EnableCap.DepthTest);
                else
                    GL.Disable(EnableCap.DepthTest);
            }

            if (state.DepthBufferEnable && commandList.DepthStencilBoundState.DepthFunction != state.DepthFunction)
            {
                commandList.DepthStencilBoundState.DepthFunction = state.DepthFunction;
                GL.DepthFunc(state.DepthFunction);
            }

            if (commandList.DepthStencilBoundState.DepthBufferWriteEnable != state.DepthBufferWriteEnable)
            {
                commandList.DepthStencilBoundState.DepthBufferWriteEnable = state.DepthBufferWriteEnable;
                GL.DepthMask(state.DepthBufferWriteEnable);
            }

            if (commandList.DepthStencilBoundState.StencilEnable != state.StencilEnable)
            {
                commandList.DepthStencilBoundState.StencilEnable = state.StencilEnable;

                if (state.StencilEnable)
                    GL.Enable(EnableCap.StencilTest);
                else
                    GL.Disable(EnableCap.StencilTest);
            }

            if (state.StencilEnable && commandList.DepthStencilBoundState.StencilWriteMask != state.StencilWriteMask)
            {
                commandList.DepthStencilBoundState.StencilWriteMask = state.StencilWriteMask;
                GL.StencilMask(state.StencilWriteMask);
            }

            // TODO: Properly handle stencil reference
            if (state.StencilEnable && (commandList.DepthStencilBoundState.Faces != state.Faces || commandList.NewStencilReference != commandList.BoundStencilReference))
            {
                commandList.DepthStencilBoundState.Faces = state.Faces;
                commandList.BoundStencilReference = commandList.NewStencilReference;

                GL.StencilFuncSeparate(StencilFace.Front, state.Faces.FrontFaceStencilFunction, commandList.BoundStencilReference, state.StencilWriteMask); // set both faces
                GL.StencilFuncSeparate(StencilFace.Back, state.Faces.BackFaceStencilFunction, commandList.BoundStencilReference, state.StencilWriteMask); // override back face
                GL.StencilOpSeparate(StencilFace.Front, state.Faces.FrontFaceDepthFailOp, state.Faces.FrontFaceFailOp, state.Faces.FrontFacePassOp);
                GL.StencilOpSeparate(StencilFace.Back, state.Faces.BackFaceDepthFailOp, state.Faces.BackFaceFailOp, state.Faces.BackFacePassOp);
            }
        }
 public override void EndDraw(CommandList commandList, bool present)
 {
 }
 public override void BeginDraw(CommandList commandList)
 {
 }
Esempio n. 25
0
 /// <summary>
 /// Return the glyph associated to provided character at the given size.
 /// </summary>
 /// <param name="commandList">The command list in case we upload gpu resources</param>
 /// <param name="character">The character we want the glyph of</param>
 /// <param name="fontSize">The font size in pixel</param>
 /// <param name="uploadGpuResources">Indicate if the GPU resource should be uploaded or not.</param>
 /// <returns>The glyph corresponding to the request or null if not existing</returns>
 protected virtual Glyph GetGlyph(CommandList commandList, char character, ref Vector2 fontSize, bool uploadGpuResources)
 {
     return(null);
 }
Esempio n. 26
0
 private void UpdateProjection(CommandList commandList)
 {
     bool sameViewport = activeViewportSize.Width == commandList.Viewport.Width && activeViewportSize.Height == commandList.Viewport.Height;
     if (!sameViewport)
     {
         activeViewportSize = new Size(commandList.Viewport.Width, commandList.Viewport.Height);
         projection = Matrix.OrthoOffCenterRH(0, commandList.Viewport.Width, commandList.Viewport.Height, 0, 1.0f, 1000.0f);
     }
 }
Esempio n. 27
0
 public GraphicsContext(GraphicsDevice graphicsDevice, GraphicsResourceAllocator allocator = null, CommandList commandList = null)
 {
     CommandList = commandList ?? graphicsDevice.InternalMainCommandList ?? CommandList.New(graphicsDevice);
     Allocator = allocator ?? new GraphicsResourceAllocator(graphicsDevice).DisposeBy(graphicsDevice);
     ResourceGroupAllocator = new ResourceGroupAllocator(Allocator, CommandList);
 }
 public virtual void EndDraw(CommandList commandList, bool present)
 {
 }
 public override void BeginDraw(CommandList commandList)
 {
     // Backbuffer needs to be cleared
     backbuffer.IsInitialized = false;
 }
Esempio n. 30
0
 /// <summary>
 /// Executes a deferred command list.
 /// </summary>
 /// <param name="commandList">The deferred command list.</param>
 public void ExecuteCommandList(CommandList commandList)
 {
     //if (commandList == null) throw new ArgumentNullException("commandList");
     //
     //NativeDeviceContext.ExecuteCommandList(((CommandList)commandList).NativeCommandList, false);
     //commandList.Dispose();
 }
Esempio n. 31
0
        private void UpdateDefaultProjectionMatrix(CommandList commandList)
        {
            var resolution = GetCurrentResolution(commandList);

            CalculateDefaultProjection(ref resolution, out defaultProjectionMatrix);
        }
 private void InitializePostFeatures()
 {
     // Create the main command list
     InternalMainCommandList = new CommandList(this);
 }
Esempio n. 33
0
        /// <summary>
        /// Build the vertex buffer from particle data
        /// Should come before <see cref="KickVertexBuffer"/>
        /// </summary>
        /// <param name="device">The graphics device, used to rebuild vertex layouts and shaders if needed</param>
        /// <param name="invViewMatrix">The current camera's inverse view matrix</param>
        public void BuildVertexBuffer(CommandList commandList, ref Matrix invViewMatrix)
        {
            // Get camera-space X and Y axes for billboard expansion and sort the particles if needed
            var unitX = new Vector3(invViewMatrix.M11, invViewMatrix.M12, invViewMatrix.M13);
            var unitY = new Vector3(invViewMatrix.M21, invViewMatrix.M22, invViewMatrix.M23);
            depthSortVector = Vector3.Cross(unitX, unitY);
            ParticleSorter.Sort();


            // If the particles are in world space they don't need to be fixed as their coordinates are already in world space
            // If the particles are in local space they need to be drawn in world space using the emitter's current location matrix
            var posIdentity = new Vector3(0, 0, 0);
            var rotIdentity = Quaternion.Identity;
            var scaleIdentity = 1f;
            if (simulationSpace == EmitterSimulationSpace.Local)
            {
                posIdentity = drawTransform.WorldPosition;
                rotIdentity = drawTransform.WorldRotation;
                scaleIdentity = drawTransform.WorldScale.X;
            }

            VertexBuilder.MapBuffer(commandList);

            ShapeBuilder.BuildVertexBuffer(VertexBuilder, unitX, unitY, ref posIdentity, ref rotIdentity, scaleIdentity, ParticleSorter);

            VertexBuilder.RestartBuffer();

            ShapeBuilder.SetRequiredQuads(ShapeBuilder.QuadsPerParticle, pool.LivingParticles, pool.ParticleCapacity);
            Material.PatchVertexBuffer(VertexBuilder, unitX, unitY, ParticleSorter);

            VertexBuilder.UnmapBuffer(commandList);
        }
Esempio n. 34
0
 public virtual void EndDraw(CommandList commandList, bool present)
 {
 }
        public void Apply(CommandList commandList)
        {
#if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
            if (commandList.RasterizerBoundState.PolygonMode != State.PolygonMode)
            {
                commandList.RasterizerBoundState.PolygonMode = State.PolygonMode;
                GL.PolygonMode(MaterialFace.FrontAndBack, State.PolygonMode);
            }
#endif

            if (commandList.RasterizerBoundState.DepthBias != State.DepthBias || commandList.RasterizerBoundState.SlopeScaleDepthBias != State.SlopeScaleDepthBias)
            {
                commandList.RasterizerBoundState.DepthBias = State.DepthBias;
                commandList.RasterizerBoundState.SlopeScaleDepthBias = State.SlopeScaleDepthBias;
                GL.PolygonOffset(State.DepthBias, State.SlopeScaleDepthBias);
            }

            if (commandList.RasterizerBoundState.FrontFaceDirection != State.FrontFaceDirection)
            {
                commandList.RasterizerBoundState.FrontFaceDirection = State.FrontFaceDirection;
                GL.FrontFace(State.FrontFaceDirection);
            }

            if (commandList.GraphicsDevice.HasDepthClamp)
            {
                if (commandList.RasterizerBoundState.DepthClamp != State.DepthClamp)
                {
                    commandList.RasterizerBoundState.DepthClamp = State.DepthClamp;
                    if (State.DepthClamp)
                        GL.Enable(DepthClamp);
                    else
                        GL.Disable(DepthClamp);
                }
            }

            if (commandList.RasterizerBoundState.NeedCulling != State.NeedCulling)
            {
                commandList.RasterizerBoundState.NeedCulling = State.NeedCulling;
                if (State.NeedCulling)
                {
                    GL.Enable(EnableCap.CullFace);
                }
                else
                {
                    GL.Disable(EnableCap.CullFace);
                }
            }

            if (commandList.RasterizerBoundState.CullMode != State.CullMode)
            {
                commandList.RasterizerBoundState.CullMode = State.CullMode;
                GL.CullFace(State.CullMode);
            }

            if (commandList.RasterizerBoundState.ScissorTestEnable != State.ScissorTestEnable)
            {
                commandList.RasterizerBoundState.ScissorTestEnable = State.ScissorTestEnable;

                if (State.ScissorTestEnable)
                    GL.Enable(EnableCap.ScissorTest);
                else
                    GL.Disable(EnableCap.ScissorTest);
            }
        }
Esempio n. 36
0
        public void Apply(CommandList commandList)
        {
#if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
            if (commandList.RasterizerBoundState.PolygonMode != State.PolygonMode)
            {
                commandList.RasterizerBoundState.PolygonMode = State.PolygonMode;
                GL.PolygonMode(MaterialFace.FrontAndBack, State.PolygonMode);
            }
#endif

            if (commandList.RasterizerBoundState.DepthBias != State.DepthBias || commandList.RasterizerBoundState.SlopeScaleDepthBias != State.SlopeScaleDepthBias)
            {
                commandList.RasterizerBoundState.DepthBias           = State.DepthBias;
                commandList.RasterizerBoundState.SlopeScaleDepthBias = State.SlopeScaleDepthBias;
                GL.PolygonOffset(State.DepthBias, State.SlopeScaleDepthBias);
            }

            if (commandList.RasterizerBoundState.FrontFaceDirection != State.FrontFaceDirection)
            {
                commandList.RasterizerBoundState.FrontFaceDirection = State.FrontFaceDirection;
                GL.FrontFace(State.FrontFaceDirection);
            }

            if (commandList.GraphicsDevice.HasDepthClamp)
            {
                if (commandList.RasterizerBoundState.DepthClamp != State.DepthClamp)
                {
                    commandList.RasterizerBoundState.DepthClamp = State.DepthClamp;
                    if (State.DepthClamp)
                    {
                        GL.Enable(DepthClamp);
                    }
                    else
                    {
                        GL.Disable(DepthClamp);
                    }
                }
            }

            if (commandList.RasterizerBoundState.NeedCulling != State.NeedCulling)
            {
                commandList.RasterizerBoundState.NeedCulling = State.NeedCulling;
                if (State.NeedCulling)
                {
                    GL.Enable(EnableCap.CullFace);
                }
                else
                {
                    GL.Disable(EnableCap.CullFace);
                }
            }

            if (commandList.RasterizerBoundState.CullMode != State.CullMode)
            {
                commandList.RasterizerBoundState.CullMode = State.CullMode;
                GL.CullFace(State.CullMode);
            }

            if (commandList.RasterizerBoundState.ScissorTestEnable != State.ScissorTestEnable)
            {
                commandList.RasterizerBoundState.ScissorTestEnable = State.ScissorTestEnable;

                if (State.ScissorTestEnable)
                {
                    GL.Enable(EnableCap.ScissorTest);
                }
                else
                {
                    GL.Disable(EnableCap.ScissorTest);
                }
            }
        }
 public override void EndDraw(CommandList commandList, bool present)
 {
 }
 public virtual void BeginDraw(CommandList commandList)
 {
 }