/// <inheritdoc/> public void SetTexture(Int32 sampler, Texture2D texture) { Contract.EnsureRange(sampler >= 0 && sampler < maxTextureStages, nameof(sampler)); Contract.EnsureNotDisposed(this, Disposed); Ultraviolet.ValidateResource(texture); if (texture != null && texture.BoundForWriting) { throw new InvalidOperationException(OpenGLStrings.RenderBufferCannotBeUsedAsTexture); } if (texture != null && texture.WillNotBeSampled) { throw new InvalidOperationException(OpenGLStrings.RenderBufferWillNotBeSampled); } if (this.textures[sampler] != texture) { var textureName = (texture == null) ? 0 : ((IOpenGLResource)texture).OpenGLName; OpenGLState.ActiveTexture((uint)(gl.GL_TEXTURE0 + sampler)); OpenGLState.Texture2D(textureName); if (this.textures[sampler] != null) { ((IBindableResource)this.textures[sampler]).UnbindRead(); } this.textures[sampler] = texture; if (this.textures[sampler] != null) { ((IBindableResource)this.textures[sampler]).BindRead(); } if (!capabilities.SupportsIndependentSamplerState) { var samplerState = (OpenGLSamplerState)(GetSamplerState(sampler) ?? SamplerState.LinearClamp); for (int i = 0; i < samplerStates.Length; i++) { if (this.textures[i] == texture) { samplerState.Apply(sampler); } } } } }
/// <summary> /// Applies the sampler state to the device. /// </summary> /// <param name="sampler">The sampler index on which to set the state.</param> /// <param name="target">GL_TEXTURE_2D or GL_TEXTURE_3D, as appropriate.</param> internal void Apply(Int32 sampler, UInt32 target) { if (Ultraviolet.GetGraphics().Capabilities.SupportsIndependentSamplerState) { throw new InvalidOperationException(UltravioletStrings.GenericError); } OpenGLState.ActiveTexture((uint)(gl.GL_TEXTURE0 + sampler)); if (Ultraviolet.GetGraphics().Capabilities.Supports3DTextures) { gl.TexParameteri(target, gl.GL_TEXTURE_WRAP_R, GetTextureAddressModeGL(AddressW)); gl.ThrowIfError(); } gl.TexParameteri(target, gl.GL_TEXTURE_WRAP_S, GetTextureAddressModeGL(AddressU)); gl.ThrowIfError(); gl.TexParameteri(target, gl.GL_TEXTURE_WRAP_T, GetTextureAddressModeGL(AddressV)); gl.ThrowIfError(); if (MipMapLevelOfDetailBias != 0) { gl.ThrowIfGLES(OpenGLStrings.UnsupportedLODBiasGLES); gl.TexParameterf(target, gl.GL_TEXTURE_LOD_BIAS, MipMapLevelOfDetailBias); gl.ThrowIfError(); } switch (Filter) { case TextureFilter.Point: gl.TexParameterf(target, gl.GL_TEXTURE_MAX_ANISOTROPY_EXT, 1f); gl.ThrowIfError(); gl.TexParameteri(target, gl.GL_TEXTURE_MIN_FILTER, (int)gl.GL_NEAREST); gl.ThrowIfError(); gl.TexParameteri(target, gl.GL_TEXTURE_MAG_FILTER, (int)gl.GL_NEAREST); gl.ThrowIfError(); break; case TextureFilter.Linear: if (gl.IsAnisotropicFilteringAvailable) { gl.TexParameterf(target, gl.GL_TEXTURE_MAX_ANISOTROPY_EXT, 1f); gl.ThrowIfError(); } gl.TexParameteri(target, gl.GL_TEXTURE_MIN_FILTER, (int)gl.GL_LINEAR); gl.ThrowIfError(); gl.TexParameteri(target, gl.GL_TEXTURE_MAG_FILTER, (int)gl.GL_LINEAR); gl.ThrowIfError(); break; case TextureFilter.Anisotropic: if (gl.IsAnisotropicFilteringAvailable) { gl.TexParameterf(target, gl.GL_TEXTURE_MAX_ANISOTROPY_EXT, Math.Min(1f, MaxAnisotropy)); gl.ThrowIfError(); } gl.TexParameteri(target, gl.GL_TEXTURE_MIN_FILTER, (int)gl.GL_LINEAR); gl.ThrowIfError(); gl.TexParameteri(target, gl.GL_TEXTURE_MAG_FILTER, (int)gl.GL_LINEAR); gl.ThrowIfError(); break; default: throw new NotSupportedException(); } }