public override void Start() { base.Start(); customEffect = EffectSystem.LoadEffect("Effect").WaitForResult(); customEffectInstance = new EffectInstance(customEffect); spriteBatch = new SpriteBatch(GraphicsDevice) { VirtualResolution = new Vector3(1) }; // set fixed parameters once customEffectInstance.Parameters.Set(TexturingKeys.Sampler, samplerState); customEffectInstance.Parameters.Set(EffectKeys.Center, new Vector2(0.5f, 0.5f)); customEffectInstance.Parameters.Set(EffectKeys.Frequency, 40); customEffectInstance.Parameters.Set(EffectKeys.Spread, 0.5f); customEffectInstance.Parameters.Set(EffectKeys.Amplitude, 0.015f); customEffectInstance.Parameters.Set(EffectKeys.InvAspectRatio, GraphicsDevice.Presenter.BackBuffer.Height / (float)GraphicsDevice.Presenter.BackBuffer.Width); // NOTE: Linear-Wrap sampling is not available for non-square non-power-of-two textures on opengl es 2.0 samplerState = SamplerState.New(GraphicsDevice, new SamplerStateDescription(TextureFilter.Linear, TextureAddressMode.Clamp)); // Add Effect rendering to the end of the pipeline var scene = SceneSystem.SceneInstance.Scene; var compositor = ((SceneGraphicsCompositorLayers)scene.Settings.GraphicsCompositor); renderer = new SceneDelegateRenderer(RenderQuad); compositor.Master.Renderers.Add(renderer); }
/// <summary> /// Gets (or creates) an entry to the DescriptorSetLayout and gets its index. /// </summary> /// <returns>The future entry index.</returns> public void AddBinding(ParameterKey key, string logicalGroup, EffectParameterClass @class, EffectParameterType type, int arraySize = 1, SamplerState immutableSampler = null) { hashBuilder.Write(key.Name); hashBuilder.Write(@class); hashBuilder.Write(arraySize); ElementCount += arraySize; Entries.Add(new Entry { Key = key, LogicalGroup = logicalGroup, Class = @class, Type = type, ArraySize = arraySize, ImmutableSampler = immutableSampler }); }
/// <summary> /// Sets a sampler state descriptor. /// </summary> /// <param name="slot">The slot.</param> /// <param name="samplerState">The sampler state.</param> public void SetSamplerState(int slot, SamplerState samplerState) { // For now, immutable samplers appears in the descriptor set and should be ignored // TODO GRAPHICS REFACTOR can't we just hide them somehow? var bindingSlot = BindingOffsets[slot]; if (bindingSlot == -1) return; Device.NativeDevice.CopyDescriptorsSimple(1, SamplerStart + BindingOffsets[slot], samplerState.NativeSampler, DescriptorHeapType.Sampler); }
public static SamplerState New(GraphicsDevice graphicsDevice, SamplerStateDescription samplerStateDescription) { // Store SamplerState in a cache (D3D seems to have quite bad concurrency when using CreateSampler while rendering) SamplerState samplerState; lock (graphicsDevice.CachedSamplerStates) { if (graphicsDevice.CachedSamplerStates.TryGetValue(samplerStateDescription, out samplerState)) { // TODO: Appropriate destroy samplerState.AddReferenceInternal(); } else { samplerState = new SamplerState(graphicsDevice, samplerStateDescription); graphicsDevice.CachedSamplerStates.Add(samplerStateDescription, samplerState); } } return samplerState; }
internal void Apply(bool hasMipmap, SamplerState oldSamplerState, TextureTarget target) { #if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES // TODO: support texture array, 3d and cube if (!GraphicsDevice.IsOpenGLES2) #endif { if (Description.MinMipLevel != oldSamplerState.Description.MinMipLevel) GL.TexParameter(target, TextureParameterName.TextureMinLod, Description.MinMipLevel); if (Description.MaxMipLevel != oldSamplerState.Description.MaxMipLevel) GL.TexParameter(target, TextureParameterName.TextureMaxLod, Description.MaxMipLevel); if (textureWrapR != oldSamplerState.textureWrapR) GL.TexParameter(target, TextureParameterName.TextureWrapR, (int)textureWrapR); if (compareFunc != oldSamplerState.compareFunc) GL.TexParameter(target, TextureParameterName.TextureCompareFunc, (int)compareFunc); } #if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES if (borderColor != oldSamplerState.borderColor) GL.TexParameter(target, TextureParameterName.TextureBorderColor, borderColor); if (Description.MipMapLevelOfDetailBias != oldSamplerState.Description.MipMapLevelOfDetailBias) GL.TexParameter(target, TextureParameterName.TextureLodBias, Description.MipMapLevelOfDetailBias); if (minFilter != oldSamplerState.minFilter) GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)minFilter); #else // On OpenGL ES, we need to choose the appropriate min filter ourself if the texture doesn't contain mipmaps (done at PreDraw) if (minFilter != oldSamplerState.minFilter) GL.TexParameter(target, TextureParameterName.TextureMinFilter, hasMipmap ? (int)minFilter : (int)minFilterNoMipmap); #endif #if !SILICONSTUDIO_PLATFORM_IOS if (Description.MaxAnisotropy != oldSamplerState.Description.MaxAnisotropy) GL.TexParameter(target, (TextureParameterName)OpenTK.Graphics.ES20.ExtTextureFilterAnisotropic.TextureMaxAnisotropyExt, Description.MaxAnisotropy); #endif if (magFilter != oldSamplerState.magFilter) GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)magFilter); if (textureWrapS != oldSamplerState.textureWrapS) GL.TexParameter(target, TextureParameterName.TextureWrapS, (int)textureWrapS); if (textureWrapT != oldSamplerState.textureWrapT) GL.TexParameter(target, TextureParameterName.TextureWrapT, (int)textureWrapT); }
/// <summary> /// Draws a fullscreen texture using the specified sampler /// and the texture color multiplied by a custom color. See <see cref="Draw+a+texture"/> to learn how to use it. /// </summary> /// <param name="texture">The texture. Expecting an instance of <see cref="Texture"/>.</param> /// <param name="sampler">The sampler.</param> /// <param name="color">The color.</param> /// <param name="applyEffectStates">The flag to apply effect states.</param> public static void DrawTexture(this GraphicsContext graphicsContext, Texture texture, SamplerState sampler, Color4 color, BlendStateDescription? blendState = null) { graphicsContext.CommandList.GraphicsDevice.PrimitiveQuad.Draw(graphicsContext, texture, sampler, color, blendState); }
/// <summary> /// Draws a fullscreen texture using the specified sampler. See <see cref="Draw+a+texture"/> to learn how to use it. /// </summary> /// <param name="texture">The texture. Expecting an instance of <see cref="Texture"/>.</param> /// <param name="sampler">The sampler.</param> /// <param name="applyEffectStates">The flag to apply effect states.</param> public static void DrawTexture(this GraphicsContext graphicsContext, Texture texture, SamplerState sampler, BlendStateDescription? blendState = null) { graphicsContext.DrawTexture(texture, sampler, Color4.White, blendState); }
/// <summary> /// Sets a sampler state descriptor. /// </summary> /// <param name="slot">The slot.</param> /// <param name="samplerState">The sampler state.</param> public void SetSamplerState(int slot, SamplerState samplerState) { HeapObjects[DescriptorStartOffset + slot].Value = samplerState; }
/// <summary> /// Sets a sampler state to the shader pipeline. /// </summary> /// <param name="stage">The shader stage.</param> /// <param name="slot">The binding slot.</param> /// <param name="samplerState">The sampler state to set.</param> internal void SetSamplerState(ShaderStage stage, int slot, SamplerState samplerState) { if (stage == ShaderStage.None) throw new ArgumentException("Cannot use Stage.None", "stage"); int stageIndex = (int)stage - 1; int slotIndex = stageIndex * SamplerStateCount + slot; if (samplerStates[slotIndex] != samplerState) { samplerStates[slotIndex] = samplerState; shaderStages[stageIndex].SetSampler(slot, samplerState != null ? (SharpDX.Direct3D11.SamplerState)samplerState.NativeDeviceChild : null); } }
/// <summary> /// Sets a sampler state to the shader pipeline. /// </summary> /// <param name="stage">The shader stage.</param> /// <param name="slot">The binding slot.</param> /// <param name="samplerState">The sampler state to set.</param> public void SetSamplerState(ShaderStage stage, int slot, SamplerState samplerState) { throw new NotImplementedException(); }
/// <summary> /// Begins a sprite batch rendering using the specified sorting mode and blend state, sampler, depth stencil, rasterizer state objects, plus a custom effect and a 2D transformation matrix. Passing null for any of the state objects selects the default default state objects (BlendState.AlphaBlend, DepthStencilState.Default, RasterizerState.CullCounterClockwise, SamplerState.LinearClamp). Passing a null effect selects the default SpriteBatch Class shader. /// </summary> /// <param name="viewMatrix">The view matrix to use for the batch session</param> /// <param name="projectionMatrix">The projection matrix to use for the batch session</param> /// <param name="sortMode">The sprite drawing order to use for the batch session</param> /// <param name="blendState">The blending state to use for the batch session</param> /// <param name="samplerState">The sampling state to use for the batch session</param> /// <param name="depthStencilState">The depth stencil state to use for the batch session</param> /// <param name="rasterizerState">The rasterizer state to use for the batch session</param> /// <param name="effect">The effect to use for the batch session</param> /// <param name="parameterCollectionGroup">The parameter collection group.</param> /// <param name="stencilValue">The value of the stencil buffer to take as reference for the batch session</param> public void Begin(Matrix viewMatrix, Matrix projectionMatrix, SpriteSortMode sortMode = SpriteSortMode.Deferred, BlendState blendState = null, SamplerState samplerState = null, DepthStencilState depthStencilState = null, RasterizerState rasterizerState = null, Effect effect = null, EffectParameterCollectionGroup parameterCollectionGroup = null, int stencilValue = 0) { CheckEndHasBeenCalled("begin"); userViewMatrix = viewMatrix; userProjectionMatrix = projectionMatrix; Begin(effect, parameterCollectionGroup, sortMode, blendState, samplerState, depthStencilState, rasterizerState, stencilValue); }
private void InitializeFromImpl(DataBox[] dataBoxes = null) { if (ParentTexture != null) { TextureId = ParentTexture.TextureId; // copy parameters TextureInternalFormat = ParentTexture.TextureInternalFormat; TextureFormat = ParentTexture.TextureFormat; TextureType = ParentTexture.TextureType; TextureTarget = ParentTexture.TextureTarget; DepthPitch = ParentTexture.DepthPitch; RowPitch = ParentTexture.RowPitch; IsDepthBuffer = ParentTexture.IsDepthBuffer; HasStencil = ParentTexture.HasStencil; IsRenderbuffer = ParentTexture.IsRenderbuffer; stencilId = ParentTexture.StencilId; pixelBufferObjectId = ParentTexture.PixelBufferObjectId; } if (TextureId == 0) { switch (Dimension) { case TextureDimension.Texture1D: #if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES if (ArraySize > 1) throw new PlatformNotSupportedException("Texture1DArray is not implemented under OpenGL"); TextureTarget = TextureTarget.Texture1D; break; #endif case TextureDimension.Texture2D: TextureTarget = ArraySize > 1 ? TextureTarget.Texture2DArray : TextureTarget.Texture2D; break; case TextureDimension.Texture3D: TextureTarget = TextureTarget.Texture3D; break; case TextureDimension.TextureCube: if (ArraySize > 6) throw new PlatformNotSupportedException("TextureCubeArray is not implemented under OpenGL"); TextureTarget = TextureTarget.TextureCubeMap; break; default: throw new ArgumentOutOfRangeException(); } bool compressed; OpenGLConvertExtensions.ConvertPixelFormat(GraphicsDevice, ref textureDescription.Format, out TextureInternalFormat, out TextureFormat, out TextureType, out TexturePixelSize, out compressed); DepthPitch = Description.Width * Description.Height * TexturePixelSize; RowPitch = Description.Width * TexturePixelSize; if ((Description.Flags & TextureFlags.DepthStencil) != 0) { IsDepthBuffer = true; HasStencil = InternalHasStencil(Format); } else { IsDepthBuffer = false; HasStencil = false; } if ((Description.Flags & TextureFlagsCustomResourceId) != 0) return; using (var openglContext = GraphicsDevice.UseOpenGLCreationContext()) { // Depth texture are render buffer for now // TODO: enable switch if ((Description.Flags & TextureFlags.DepthStencil) != 0 && (Description.Flags & TextureFlags.ShaderResource) == 0) { RenderbufferStorage depth, stencil; ConvertDepthFormat(GraphicsDevice, Description.Format, out depth, out stencil); GL.GenRenderbuffers(1, out TextureId); GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, TextureId); GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, depth, Width, Height); if (stencil != 0) { // separate stencil GL.GenRenderbuffers(1, out stencilId); GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, stencilId); GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, stencil, Width, Height); } else if (HasStencil) { // depth+stencil in a single texture stencilId = TextureId; } GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, 0); IsRenderbuffer = true; return; } IsRenderbuffer = false; TextureTotalSize = ComputeBufferTotalSize(); if (Description.Usage == GraphicsResourceUsage.Staging) { InitializeStagingPixelBufferObject(dataBoxes); return; } GL.GenTextures(1, out TextureId); GL.BindTexture(TextureTarget, TextureId); // No filtering on depth buffer if ((Description.Flags & (TextureFlags.RenderTarget | TextureFlags.DepthStencil)) != TextureFlags.None) { GL.TexParameter(TextureTarget, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); GL.TexParameter(TextureTarget, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); GL.TexParameter(TextureTarget, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); GL.TexParameter(TextureTarget, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); BoundSamplerState = GraphicsDevice.SamplerStates.PointClamp; if (HasStencil) { // depth+stencil in a single texture stencilId = TextureId; } } #if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES else if (Description.MipLevels <= 1) { GL.TexParameter(TextureTarget, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); GL.TexParameter(TextureTarget, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); } #endif #if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES if (!GraphicsDevice.IsOpenGLES2) #endif { GL.TexParameter(TextureTarget, TextureParameterName.TextureBaseLevel, 0); GL.TexParameter(TextureTarget, TextureParameterName.TextureMaxLevel, Description.MipLevels - 1); } if (Description.MipLevels == 0) throw new NotImplementedException(); var setSize = TextureSetSize(TextureTarget); for (var arrayIndex = 0; arrayIndex < Description.ArraySize; ++arrayIndex) { var offsetArray = arrayIndex*Description.MipLevels; for (int i = 0; i < Description.MipLevels; ++i) { DataBox dataBox; var width = CalculateMipSize(Description.Width, i); var height = CalculateMipSize(Description.Height, i); var depth = CalculateMipSize(Description.Depth, i); if (dataBoxes != null && i < dataBoxes.Length) { if (setSize > 1 && !compressed && dataBoxes[i].RowPitch != width*TexturePixelSize) throw new NotSupportedException("Can't upload texture with pitch in glTexImage2D/3D."); // Might be possible, need to check API better. dataBox = dataBoxes[offsetArray + i]; } else { dataBox = new DataBox(); } switch (TextureTarget) { #if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES case TextureTarget.Texture1D: if (compressed) { GL.CompressedTexImage1D(TextureTarget, i, TextureInternalFormat, width, 0, dataBox.SlicePitch, dataBox.DataPointer); } else { GL.TexImage1D(TextureTarget, i, TextureInternalFormat, width, 0, TextureFormat, TextureType, dataBox.DataPointer); } break; #endif case TextureTarget.Texture2D: case TextureTarget.TextureCubeMap: { var dataSetTarget = GetTextureTargetForDataSet2D(TextureTarget, arrayIndex); if (compressed) { GL.CompressedTexImage2D(dataSetTarget, i, (CompressedInternalFormat2D)TextureInternalFormat, width, height, 0, dataBox.SlicePitch, dataBox.DataPointer); } else { GL.TexImage2D(dataSetTarget, i, (TextureComponentCount2D)TextureInternalFormat, width, height, 0, TextureFormat, TextureType, dataBox.DataPointer); } break; } case TextureTarget.Texture3D: { if (compressed) { GL.CompressedTexImage3D((TextureTarget3d)TextureTarget, i, (CompressedInternalFormat3D)TextureInternalFormat, width, height, depth, 0, dataBox.SlicePitch, dataBox.DataPointer); } else { GL.TexImage3D((TextureTarget3d)TextureTarget, i, (TextureComponentCount3D)TextureInternalFormat, width, height, depth, 0, TextureFormat, TextureType, dataBox.DataPointer); } break; } case TextureTarget.Texture2DArray: { // We create all array slices at once, but upload them one by one if (arrayIndex == 0) { if (compressed) { GL.CompressedTexImage3D((TextureTarget3d)TextureTarget, i, (CompressedInternalFormat3D)TextureInternalFormat, width, height, ArraySize, 0, 0, IntPtr.Zero); } else { GL.TexImage3D((TextureTarget3d)TextureTarget, i, (TextureComponentCount3D)TextureInternalFormat, width, height, ArraySize, 0, TextureFormat, TextureType, IntPtr.Zero); } } if (dataBox.DataPointer != IntPtr.Zero) { if (compressed) { GL.CompressedTexSubImage3D((TextureTarget3d)TextureTarget, i, 0, 0, arrayIndex, width, height, 1, TextureFormat, dataBox.SlicePitch, dataBox.DataPointer); } else { GL.TexSubImage3D((TextureTarget3d)TextureTarget, i, 0, 0, arrayIndex, width, height, 1, TextureFormat, TextureType, dataBox.DataPointer); } } break; } } } } GL.BindTexture(TextureTarget, 0); if (openglContext.CommandList != null) { // If we messed up with some states of a command list, mark dirty states openglContext.CommandList.boundShaderResourceViews[openglContext.CommandList.activeTexture] = null; } } GraphicsDevice.TextureMemory += (Depth * DepthStride) / (float)0x100000; } }
/// <summary> /// Sets a sampler state to the shader pipeline. /// </summary> /// <param name="stage">The shader stage.</param> /// <param name="slot">The binding slot.</param> /// <param name="samplerState">The sampler state to set.</param> public void SetSamplerState(ShaderStage stage, int slot, SamplerState samplerState) { #if DEBUG GraphicsDevice.EnsureContextActive(); #endif samplerStates[slot] = samplerState; }
/// <summary> /// Draws a quad with a texture. This Draw method is using a simple pixel shader that is sampling the texture. /// </summary> /// <param name="texture">The texture to draw.</param> /// <param name="samplerState">State of the sampler. If null, default sampler is <see cref="SamplerStateFactory.LinearClamp" />.</param> /// <param name="color">The color.</param> /// <param name="applyEffectStates">The flag to apply effect states.</param> /// <exception cref="System.ArgumentException">Expecting a Texture;texture</exception> public void Draw(GraphicsContext graphicsContext, Texture texture, SamplerState samplerState, Color4 color, BlendStateDescription? blendState = null) { pipelineState.State.RootSignature = simpleEffect.RootSignature; pipelineState.State.EffectBytecode = simpleEffect.Effect.Bytecode; pipelineState.State.BlendState = blendState ?? BlendStates.Default; pipelineState.State.Output.CaptureState(graphicsContext.CommandList); pipelineState.Update(); graphicsContext.CommandList.SetPipelineState(pipelineState.CurrentState); // Make sure that we are using our vertex shader simpleEffect.Parameters.Set(SpriteEffectKeys.Color, color); simpleEffect.Parameters.Set(TexturingKeys.Texture0, texture); simpleEffect.Parameters.Set(TexturingKeys.Sampler, samplerState ?? GraphicsDevice.SamplerStates.LinearClamp); simpleEffect.Apply(graphicsContext); Draw(graphicsContext.CommandList); // TODO ADD QUICK UNBIND FOR SRV //GraphicsDevice.Context.PixelShader.SetShaderResource(0, null); }
/// <summary> /// Draws a quad with a texture. This Draw method is using a simple pixel shader that is sampling the texture. /// </summary> /// <param name="texture">The texture to draw.</param> /// <param name="samplerState">State of the sampler. If null, default sampler is <see cref="SamplerStateFactory.LinearClamp" />.</param> /// <param name="color">The color.</param> /// <param name="applyEffectStates">The flag to apply effect states.</param> /// <exception cref="System.ArgumentException">Expecting a Texture;texture</exception> public void Draw(Texture texture, SamplerState samplerState, Color4 color, bool applyEffectStates = false) { // Make sure that we are using our vertex shader parameters.Set(SpriteEffectKeys.Color, color); parameters.Set(TexturingKeys.Texture0, texture); parameters.Set(TexturingKeys.Sampler, samplerState ?? GraphicsDevice.SamplerStates.LinearClamp); simpleEffect.Apply(GraphicsDevice, parameterCollectionGroup, applyEffectStates); Draw(); // TODO ADD QUICK UNBIND FOR SRV //GraphicsDevice.Context.PixelShader.SetShaderResource(0, null); }
private void InitializeFromImpl(DataBox[] dataBoxes = null) { if (ParentTexture != null) { resourceId = ParentTexture.ResourceId; // copy parameters InternalFormat = ParentTexture.InternalFormat; FormatGl = ParentTexture.FormatGl; Type = ParentTexture.Type; Target = ParentTexture.Target; DepthPitch = ParentTexture.DepthPitch; RowPitch = ParentTexture.RowPitch; IsDepthBuffer = ParentTexture.IsDepthBuffer; HasStencil = ParentTexture.HasStencil; IsRenderbuffer = ParentTexture.IsRenderbuffer; resourceIdStencil = ParentTexture.ResourceIdStencil; pixelBufferObjectId = ParentTexture.PixelBufferObjectId; } if (resourceId == 0) { switch (Dimension) { case TextureDimension.Texture1D: #if !SILICONSTUDIO_PLATFORM_MONO_MOBILE Target = TextureTarget.Texture1D; break; #endif case TextureDimension.Texture2D: Target = TextureTarget.Texture2D; break; case TextureDimension.Texture3D: Target = TextureTarget.Texture3D; break; case TextureDimension.TextureCube: Target = TextureTarget.TextureCubeMap; break; default: throw new ArgumentOutOfRangeException(); } PixelInternalFormat internalFormat; PixelFormatGl format; PixelType type; int pixelSize; bool compressed; OpenGLConvertExtensions.ConvertPixelFormat(GraphicsDevice, ref textureDescription.Format, out internalFormat, out format, out type, out pixelSize, out compressed); InternalFormat = internalFormat; FormatGl = format; Type = type; DepthPitch = Description.Width * Description.Height * pixelSize; RowPitch = Description.Width * pixelSize; if ((Description.Flags & TextureFlags.DepthStencil) != 0) { IsDepthBuffer = true; HasStencil = InternalHasStencil(Format); } else { IsDepthBuffer = false; HasStencil = false; } if ((Description.Flags & TextureFlagsCustomResourceId) != 0) return; using (GraphicsDevice.UseOpenGLCreationContext()) { // Depth texture are render buffer for now // TODO: enable switch if ((Description.Flags & TextureFlags.DepthStencil) != 0 && (Description.Flags & TextureFlags.ShaderResource) == 0) { RenderbufferStorage depth, stencil; ConvertDepthFormat(GraphicsDevice, Description.Format, out depth, out stencil); GL.GenRenderbuffers(1, out resourceId); GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, resourceId); GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, depth, Width, Height); if (stencil != 0) { // separate stencil GL.GenRenderbuffers(1, out resourceIdStencil); GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, resourceIdStencil); GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, stencil, Width, Height); } else if (HasStencil) { // depth+stencil in a single texture resourceIdStencil = resourceId; } GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, 0); IsRenderbuffer = true; return; } else { GL.GenTextures(1, out resourceId); GL.BindTexture(Target, resourceId); IsRenderbuffer = false; } // No filtering on depth buffer if ((Description.Flags & (TextureFlags.RenderTarget | TextureFlags.DepthStencil)) != TextureFlags.None) { GL.TexParameter(Target, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); GL.TexParameter(Target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); GL.TexParameter(Target, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); GL.TexParameter(Target, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); BoundSamplerState = GraphicsDevice.SamplerStates.PointClamp; } #if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES else if (Description.MipLevels <= 1) { GL.TexParameter(Target, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); GL.TexParameter(Target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); } #endif #if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES if (!GraphicsDevice.IsOpenGLES2) #endif { GL.TexParameter(Target, TextureParameterName.TextureBaseLevel, 0); GL.TexParameter(Target, TextureParameterName.TextureMaxLevel, Description.MipLevels - 1); } if (Description.MipLevels == 0) throw new NotImplementedException(); var setSize = TextureSetSize(Target); for (var arrayIndex = 0; arrayIndex < Description.ArraySize; ++arrayIndex) { var offsetArray = arrayIndex*Description.MipLevels; for (int i = 0; i < Description.MipLevels; ++i) { IntPtr data = IntPtr.Zero; var width = CalculateMipSize(Description.Width, i); var height = CalculateMipSize(Description.Height, i); if (dataBoxes != null && i < dataBoxes.Length) { if (setSize > 1 && !compressed && dataBoxes[i].RowPitch != width*pixelSize) throw new NotSupportedException("Can't upload texture with pitch in glTexImage2D."); // Might be possible, need to check API better. data = dataBoxes[offsetArray + i].DataPointer; } if (setSize == 2) { var dataSetTarget = GetTextureTargetForDataSet2D(Target, arrayIndex); if (compressed) { GL.CompressedTexImage2D(dataSetTarget, i, (CompressedInternalFormat2D)internalFormat, width, height, 0, dataBoxes[offsetArray + i].SlicePitch, data); } else { GL.TexImage2D(dataSetTarget, i, internalFormat, width, height, 0, format, type, data); } } else if (setSize == 3) { var dataSetTarget = GetTextureTargetForDataSet3D(Target); var depth = Target == TextureTarget.Texture2DArray ? Description.Depth : CalculateMipSize(Description.Depth, i); // no depth mipmaps in Texture2DArray if (compressed) { GL.CompressedTexImage3D(dataSetTarget, i, (CompressedInternalFormat3D)internalFormat, width, height, depth, 0, dataBoxes[offsetArray + i].SlicePitch, data); } else { GL.TexImage3D(dataSetTarget, i, (TextureComponentCount3D)internalFormat, width, height, depth, 0, format, type, data); } } #if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES else if (setSize == 1) { if (compressed) { GL.CompressedTexImage1D(TextureTarget.Texture1D, i, internalFormat, width, 0, dataBoxes[offsetArray + i].SlicePitch, data); } else { GL.TexImage1D(TextureTarget.Texture1D, i, internalFormat, width, 0, format, type, data); } } #endif } } GL.BindTexture(Target, 0); InitializePixelBufferObject(); } GraphicsDevice.TextureMemory += (Depth * DepthStride) / (float)0x100000; } }
/// <summary> /// Begins a sprite batch rendering using the specified sorting mode and blend state, sampler, depth stencil, rasterizer state objects, plus a custom effect and a 2D transformation matrix. Passing null for any of the state objects selects the default default state objects (BlendState.AlphaBlend, DepthStencilState.Default, RasterizerState.CullCounterClockwise, SamplerState.LinearClamp). Passing a null effect selects the default SpriteBatch Class shader. /// </summary> /// <param name="viewMatrix">The view matrix to use for the batch session</param> /// <param name="sortMode">The sprite drawing order to use for the batch session</param> /// <param name="blendState">The blending state to use for the batch session</param> /// <param name="samplerState">The sampling state to use for the batch session</param> /// <param name="depthStencilState">The depth stencil state to use for the batch session</param> /// <param name="rasterizerState">The rasterizer state to use for the batch session</param> /// <param name="effect">The effect to use for the batch session</param> /// <param name="parameterCollectionGroup">The parameter collection group.</param> /// <param name="stencilValue">The value of the stencil buffer to take as reference for the batch session</param> public void Begin(Matrix viewMatrix, SpriteSortMode sortMode = SpriteSortMode.Deferred, BlendState blendState = null, SamplerState samplerState = null, DepthStencilState depthStencilState = null, RasterizerState rasterizerState = null, Effect effect = null, EffectParameterCollectionGroup parameterCollectionGroup = null, int stencilValue = 0) { UpdateDefaultProjectionMatrix(); Begin(viewMatrix, defaultProjectionMatrix, sortMode, blendState, samplerState, depthStencilState, rasterizerState, effect, parameterCollectionGroup, stencilValue); }