コード例 #1
0
        /// <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);
                }
            }
        }
コード例 #2
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;
        }
コード例 #3
0
        /// <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);
        }
コード例 #4
0
        /// <inheritdoc/>
        public override void Attach(VertexBuffer vbuffer)
        {
            Contract.Require(vbuffer, nameof(vbuffer));

            Ultraviolet.ValidateResource(vbuffer);

            AttachInternal(vbuffer, 0);
        }
コード例 #5
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);
        }
コード例 #6
0
        /// <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);
        }
コード例 #7
0
        /// <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);
        }
コード例 #8
0
        /// <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);
        }
コード例 #9
0
        /// <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));
        }
コード例 #10
0
        /// <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);
        }
コード例 #11
0
        /// <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();
            }
        }
コード例 #12
0
        /// <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();
            }
        }
コード例 #13
0
        /// <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);
                        }
                    }
                }
            }
        }
コード例 #14
0
        /// <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);
        }
コード例 #15
0
        /// <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);
        }
コード例 #16
0
        /// <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);
        }
コード例 #17
0
        /// <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;
                            }
                        }
                    }
                }
            }
        }
コード例 #18
0
        /// <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();
        }
コード例 #19
0
        /// <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();
                }
            }
        }
コード例 #20
0
        /// <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();
        }
コード例 #21
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 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;
        }
コード例 #22
0
        /// <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();
        }