/// <summary> /// Sets the current render target. /// </summary> private void SetRenderTargetInternal(RenderTarget2D renderTarget, Color?clearColor = null, Double?clearDepth = null, Int32?clearStencil = null) { Ultraviolet.ValidateResource(renderTarget); var usage = renderTarget?.RenderTargetUsage ?? backBufferRenderTargetUsage; if (usage == RenderTargetUsage.PlatformContents) { usage = Capabilities.SupportsPreservingRenderTargetContentInHardware ? RenderTargetUsage.PreserveContents : RenderTargetUsage.DiscardContents; } var oglRenderTarget = (OpenGLRenderTarget2D)renderTarget; if (oglRenderTarget != this.renderTarget) { var targetName = gl.DefaultFramebuffer; var targetSize = Size2.Zero; if (oglRenderTarget != null) { oglRenderTarget.ValidateStatus(); targetName = oglRenderTarget.OpenGLName; targetSize = renderTarget.Size; } else { var currentWindow = Ultraviolet.GetPlatform().Windows.GetCurrent(); if (currentWindow != null) { targetSize = currentWindow.DrawableSize; } } OpenGLState.BindFramebuffer(targetName); if (this.renderTarget != null) { this.renderTarget.UnbindWrite(); } this.renderTarget = oglRenderTarget; if (this.renderTarget != null) { this.renderTarget.BindWrite(); } this.viewport = default(Viewport); SetViewport(new Viewport(0, 0, targetSize.Width, targetSize.Height)); if (usage == RenderTargetUsage.DiscardContents) { Clear(clearColor ?? Color.FromArgb(0xFF442288), clearDepth ?? 1.0, clearStencil ?? 0); } } }
/// <inheritdoc/> public override void Attach(IndexBuffer ibuffer) { Contract.Require(ibuffer, nameof(ibuffer)); Contract.EnsureNot(HasIndices, UltravioletStrings.GeometryStreamAlreadyHasIndices); Contract.EnsureNotDisposed(this, Disposed); Ultraviolet.ValidateResource(ibuffer); var sdlIndexBuffer = (OpenGLIndexBuffer)ibuffer; var sdlIndexBufferName = sdlIndexBuffer.OpenGLName; this.ibuffer = sdlIndexBuffer; if (IsUsingVertexArrayObject) { using (OpenGLState.ScopedBindVertexArrayObject(vao, 0, 0, true)) { gl.BindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, sdlIndexBufferName); gl.ThrowIfError(); } } this.glElementArrayBufferBinding = sdlIndexBufferName; this.indexBufferElementType = ibuffer.IndexElementType; }
/// <inheritdoc/> public override void Attach(RenderBuffer2D buffer) { Contract.Require(buffer, nameof(buffer)); Contract.Ensure <ArgumentException>( buffer.Width == width && buffer.Height == height, OpenGLStrings.RenderBufferIsWrongSize); Contract.EnsureNotDisposed(this, Disposed); Ultraviolet.ValidateResource(buffer); var oglBuffer = (OpenGLRenderBuffer2D)buffer; Ultraviolet.QueueWorkItem(state => { using (OpenGLState.ScopedBindFramebuffer(framebuffer)) { AttachRenderBuffer(oglBuffer); framebufferStatus = gl.CheckNamedFramebufferStatus(framebuffer, gl.GL_FRAMEBUFFER); gl.ThrowIfError(); } }).Wait(); oglBuffer.MarkAttached(); buffers.Add(oglBuffer); }
/// <inheritdoc/> public override void Attach(VertexBuffer vbuffer) { Contract.Require(vbuffer, nameof(vbuffer)); Ultraviolet.ValidateResource(vbuffer); AttachInternal(vbuffer, 0); }
/// <inheritdoc/> public override void Blit(Surface2D dst, Rectangle dstRect) { Contract.EnsureNotDisposed(this, Disposed); Contract.Require(dst, nameof(dst)); Ultraviolet.ValidateResource(dst); BlitInternal(this, new Rectangle(0, 0, Width, Height), (SDL2Surface2D)dst, dstRect); }
/// <inheritdoc/> public override void Blit(Rectangle srcRect, Surface2D dst, Rectangle dstRect) { Contract.EnsureNotDisposed(this, Disposed); Contract.Require(dst, nameof(dst)); Ultraviolet.ValidateResource(dst); BlitInternal(this, srcRect, (SDL2Surface2D)dst, dstRect); }
/// <inheritdoc/> public override void Blit(Surface2D dst, Point2 position, SurfaceFlipDirection direction) { Contract.EnsureNotDisposed(this, Disposed); Contract.Require(dst, nameof(dst)); Ultraviolet.ValidateResource(dst); BlitInternal(this, (SDL2Surface2D)dst, position, direction); }
/// <summary> /// Plays the specified song. /// </summary> private Boolean PlayInternal(Song song, Single volume, Single pitch, Single pan, TimeSpan?loopStart, TimeSpan?loopLength) { Ultraviolet.ValidateResource(song); Stop(); stream = ((BASSSong)song).CreateStream(BASSNative.BASS_STREAM_DECODE); stream = BASSFXNative.TempoCreate(stream, BASSNative.BASS_FX_FREESOURCE | BASSNative.BASS_STREAM_AUTOFREE); if (!BASSUtil.IsValidHandle(stream)) { throw new BASSException(); } var autoloop = loopStart.HasValue && !loopLength.HasValue; var syncloop = loopStart.HasValue && !autoloop; BASSUtil.SetIsLooping(stream, autoloop); BASSUtil.SetVolume(stream, MathUtil.Clamp(volume, 0f, 1f)); BASSUtil.SetPitch(stream, MathUtil.Clamp(pitch, -1f, 1f)); BASSUtil.SetPan(stream, MathUtil.Clamp(pan, -1f, 1f)); if (loopStart > TimeSpan.Zero && loopLength <= TimeSpan.Zero) { throw new ArgumentException(nameof(loopLength)); } if (syncloop) { var loopStartInBytes = BASSNative.ChannelSeconds2Bytes(stream, loopStart.Value.TotalSeconds); var loopEndInBytes = BASSNative.ChannelSeconds2Bytes(stream, (loopStart + loopLength).Value.TotalSeconds); syncLoopDelegate = SyncLoop; syncLoop = BASSNative.ChannelSetSync(stream, BASSSync.SYNC_POS, loopEndInBytes, syncLoopDelegate, new IntPtr((Int32)loopStartInBytes)); if (syncLoop == 0) { throw new BASSException(); } } syncEndDelegate = SyncEnd; syncEnd = BASSNative.ChannelSetSync(stream, BASSSync.SYNC_END, 0, syncEndDelegate, IntPtr.Zero); if (syncEnd == 0) { throw new BASSException(); } if (!BASSNative.ChannelPlay(stream, true)) { throw new BASSException(); } OnStateChanged(); OnSongStarted(); return(true); }
/// <inheritdoc/> public override Boolean Play(SoundEffect soundEffect, Single volume, Single pitch, Single pan, Boolean loop = false) { Contract.EnsureNotDisposed(this, Disposed); Contract.Require(soundEffect, nameof(soundEffect)); Ultraviolet.ValidateResource(soundEffect); var sound = ((FMODSoundEffect)soundEffect).Sound; var channelgroup = ((FMODSoundEffect)soundEffect).ChannelGroup; return(channelPlayer.Play(sound, channelgroup, soundEffect.Duration, volume, pitch, pan, loop)); }
/// <inheritdoc/> public override void Attach(VertexBuffer vbuffer, Int32 instanceFrequency) { Contract.Require(vbuffer, nameof(vbuffer)); Contract.EnsureRange(instanceFrequency >= 0, nameof(instanceFrequency)); Contract.EnsureNotDisposed(this, Disposed); Contract.Ensure <NotSupportedException>(SupportsInstancedRendering || instanceFrequency == 0); Ultraviolet.ValidateResource(vbuffer); AttachInternal(vbuffer, instanceFrequency); }
/// <inheritdoc/> public void SetRasterizerState(RasterizerState state) { Contract.Require(state, nameof(state)); Contract.EnsureNotDisposed(this, Disposed); Ultraviolet.ValidateResource(state); if (this.rasterizerState != state) { this.rasterizerState = (OpenGLRasterizerState)state; this.rasterizerState.Apply(); } }
/// <inheritdoc/> public void SetDepthStencilState(DepthStencilState state) { Contract.Require(state, nameof(state)); Contract.EnsureNotDisposed(this, Disposed); Ultraviolet.ValidateResource(state); if (this.depthStencilState != state) { this.depthStencilState = (OpenGLDepthStencilState)state; this.depthStencilState.Apply(); } }
/// <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> /// Plays a sound effect. /// </summary> private Boolean PlayInternal(SoundEffect soundEffect, Single volume, Single pitch, Single pan, Boolean loop = false) { Contract.EnsureNotDisposed(this, Disposed); // Stop any sound that's already playing. Stop(); // Retrieve the sample data from the sound effect. Ultraviolet.ValidateResource(soundEffect); var bassfx = (BASSSoundEffect)soundEffect; var sample = bassfx.GetSampleData(out this.sampleData, out this.sampleInfo); // Get a channel on which to play the sample. channel = BASSNative.SampleGetChannel(sample, true); if (!BASSUtil.IsValidHandle(channel)) { var error = BASSNative.ErrorGetCode(); if (error == BASSNative.BASS_ERROR_NOCHAN) { return(false); } throw new BASSException(error); } // Set the channel's attributes. if (pitch == 0) { BASSUtil.SetIsLooping(channel, loop); BASSUtil.SetVolume(channel, MathUtil.Clamp(volume, 0f, 1f)); BASSUtil.SetPan(channel, MathUtil.Clamp(pan, -1f, 1f)); } else { PromoteToStream(volume, MathUtil.Clamp(pitch, -1f, 1f), pan, loop); } // Play the channel. if (!BASSNative.ChannelPlay(channel, true)) { throw new BASSException(); } this.playing = soundEffect; return(true); }
/// <inheritdoc/> public override Boolean Play(Song song, Single volume, Single pitch, Single pan, TimeSpan loopStart, TimeSpan?loopLength) { Contract.EnsureNotDisposed(this, Disposed); Contract.Require(song, nameof(song)); Ultraviolet.ValidateResource(song); var sound = ((FMODSong)song).Sound; var channelgroup = ((FMODSong)song).ChannelGroup; if (channelPlayer.Play(sound, channelgroup, song.Duration, volume, pitch, pan, loopStart, loopLength)) { OnStateChanged(); OnSongStarted(); return(true); } return(false); }
/// <inheritdoc/> public override Boolean Play(Song song, Boolean loop = false) { Contract.EnsureNotDisposed(this, Disposed); Contract.Require(song, nameof(song)); Ultraviolet.ValidateResource(song); var sound = ((FMODSong)song).Sound; var channelgroup = ((FMODSong)song).ChannelGroup; if (channelPlayer.Play(sound, channelgroup, song.Duration, loop)) { OnStateChanged(); OnSongStarted(); return(true); } return(false); }
/// <inheritdoc/> public void SetSamplerState(Int32 sampler, SamplerState state) { Contract.EnsureRange(sampler >= 0 && sampler < maxTextureStages, nameof(sampler)); Contract.Require(state, nameof(state)); Contract.EnsureNotDisposed(this, Disposed); Ultraviolet.ValidateResource(state); var oglstate = (OpenGLSamplerState)state; if (this.samplerStates[sampler] != state) { if (capabilities.SupportsIndependentSamplerState) { var samplerObject = this.samplerObjects[sampler]; samplerObject.ApplySamplerState(state); this.samplerStates[sampler] = state; } else { this.samplerStates[sampler] = state; var texture = this.textures[sampler]; if (texture != null) { var target = (texture is Texture3D) ? gl.GL_TEXTURE_3D : gl.GL_TEXTURE_2D; oglstate.Apply(sampler, target); for (int i = 0; i < samplerStates.Length; i++) { if (i == sampler) { continue; } if (this.textures[i] == texture && this.samplerStates[i] != oglstate) { oglstate.Apply(sampler, target); this.samplerStates[sampler] = state; } } } } } }
/// <summary> /// Initializes a new instance of the OpenGLShaderProgram class. /// </summary> /// <param name="uv">The Ultraviolet context.</param> /// <param name="vertexShader">The program's vertex shader.</param> /// <param name="fragmentShader">The program's fragment shader.</param> /// <param name="programOwnsShaders">A value indicating whether the program owns the shader objects.</param> public OpenGLShaderProgram(UltravioletContext uv, OpenGLVertexShader vertexShader, OpenGLFragmentShader fragmentShader, Boolean programOwnsShaders) : base(uv) { Contract.Require(vertexShader, nameof(vertexShader)); Contract.Require(fragmentShader, nameof(fragmentShader)); Ultraviolet.ValidateResource(vertexShader); Ultraviolet.ValidateResource(fragmentShader); this.vertexShader = vertexShader; this.fragmentShader = fragmentShader; this.programOwnsShaders = programOwnsShaders; var program = 0u; uv.QueueWorkItemAndWait(() => { program = gl.CreateProgram(); gl.ThrowIfError(); gl.AttachShader(program, vertexShader.OpenGLName); gl.ThrowIfError(); gl.AttachShader(program, fragmentShader.OpenGLName); gl.ThrowIfError(); gl.LinkProgram(program); gl.ThrowIfError(); var log = gl.GetProgramInfoLog(program); gl.ThrowIfError(); var status = gl.GetProgrami(program, gl.GL_LINK_STATUS); gl.ThrowIfError(); if (status == 0) { throw new InvalidOperationException(log); } }); this.program = program; this.uniforms = CreateUniformCollection(); }
/// <inheritdoc/> public void SetGeometryStream(GeometryStream stream) { Contract.EnsureNotDisposed(this, Disposed); Ultraviolet.ValidateResource(stream); if (stream == null) { this.geometryStream = null; OpenGLState.BindVertexArrayObject(0, 0); } else { if (this.geometryStream != stream) { this.geometryStream = (OpenGLGeometryStream)stream; this.geometryStream.Apply(); } } }
/// <summary> /// Appends another styling document to the end of this document. /// </summary> /// <param name="document">The document to append to the end of this document.</param> public void Append(UvssDocument document) { Contract.Require(document, nameof(document)); Ultraviolet.ValidateResource(document); this.ruleSets.AddRange(document.RuleSets); this.storyboardDefinitions.AddRange(document.StoryboardDefinitions); foreach (var storyboardDefinition in document.storyboardDefinitions) { this.storyboardDefinitionsByName[storyboardDefinition.Name] = storyboardDefinition; } foreach (var storyboardInstance in document.storyboardInstancesByName) { this.storyboardInstancesByName[storyboardInstance.Key] = storyboardInstance.Value; } CategorizeRuleSets(); }
/// <inheritdoc/> public override void Attach(IndexBuffer ibuffer) { Contract.Require(ibuffer, nameof(ibuffer)); Contract.EnsureNot(HasIndices, UltravioletStrings.GeometryStreamAlreadyHasIndices); Contract.EnsureNotDisposed(this, Disposed); Ultraviolet.ValidateResource(ibuffer); var oglIndexBuffer = (OpenGLIndexBuffer)ibuffer; var oglIndexBufferName = oglIndexBuffer.OpenGLName; this.ibuffer = oglIndexBuffer; if (IsUsingVertexArrayObject) { using (OpenGLState.ScopedBindVertexArrayObject(vao, 0, force: true)) { OpenGLState.BindElementArrayBuffer(oglIndexBufferName); } } this.glElementArrayBufferBinding = oglIndexBufferName; this.indexBufferElementType = ibuffer.IndexElementType; }
/// <summary> /// Initializes a new instance of the OpenGLShaderProgram class. /// </summary> /// <param name="uv">The Ultraviolet context.</param> /// <param name="vertexShader">The program's vertex shader.</param> /// <param name="fragmentShader">The program's fragment shader.</param> /// <param name="programOwnsShaders">A value indicating whether the program owns the shader objects.</param> public OpenGLShaderProgram(UltravioletContext uv, OpenGLVertexShader vertexShader, OpenGLFragmentShader fragmentShader, Boolean programOwnsShaders) : base(uv) { Contract.Require(vertexShader, nameof(vertexShader)); Contract.Require(fragmentShader, nameof(fragmentShader)); Ultraviolet.ValidateResource(vertexShader); Ultraviolet.ValidateResource(fragmentShader); this.vertexShader = vertexShader; this.fragmentShader = fragmentShader; this.programOwnsShaders = programOwnsShaders; var program = 0u; uv.QueueWorkItemAndWait(() => { program = gl.CreateProgram(); gl.ThrowIfError(); gl.AttachShader(program, vertexShader.OpenGLName); gl.ThrowIfError(); gl.AttachShader(program, fragmentShader.OpenGLName); gl.ThrowIfError(); gl.LinkProgram(program); gl.ThrowIfError(); var log = gl.GetProgramInfoLog(program); gl.ThrowIfError(); var status = gl.GetProgrami(program, gl.GL_LINK_STATUS); gl.ThrowIfError(); var attributeCount = gl.GetProgrami(program, gl.GL_ACTIVE_ATTRIBUTES); gl.ThrowIfError(); unsafe { var namebuf = Marshal.AllocHGlobal(256); try { for (int i = 0; i < attributeCount; i++) { var attrNameLen = 0; var attrName = default(String); var attrSize = 0; var attrType = 0u; gl.GetActiveAttrib(program, (uint)i, 256, &attrNameLen, &attrSize, &attrType, (sbyte *)namebuf); gl.ThrowIfError(); attrName = Marshal.PtrToStringAnsi(namebuf); var location = gl.GetAttribLocation(program, attrName); gl.ThrowIfError(); attributeLocations[attrName] = location; attributeTypes[attrName] = attrType; } } finally { Marshal.FreeHGlobal(namebuf); } } if (status == 0) { throw new InvalidOperationException(log); } }); this.program = program; this.uniforms = CreateUniformCollection(); }