Ejemplo n.º 1
0
        /// <summary>
        /// Initializes a new instance of the OpenGLRenderTarget2D class.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="width">The render target's width in pixels.</param>
        /// <param name="height">The render target's height in pixels.</param>
        /// <param name="usage">A <see cref="RenderTargetUsage"/> value specifying whether the 
        /// render target's data is discarded or preserved when it is bound to the graphics device.</param>
        /// <param name="buffers">The collection of render buffers to attach to the target.</param>
        public OpenGLRenderTarget2D(UltravioletContext uv, Int32 width, Int32 height, RenderTargetUsage usage, IEnumerable<RenderBuffer2D> buffers = null)
            : base(uv)
        {
            Contract.EnsureRange(width > 0, nameof(width));
            Contract.EnsureRange(height > 0, nameof(height));

            // NOTE: If we're in an older version of GLES, we need to use glFramebufferTexture2D()
            glFramebufferTextureIsSupported = !gl.IsGLES || gl.IsVersionAtLeast(3, 2);

            glDrawBuffersIsSupported = !gl.IsGLES2 || gl.IsExtensionSupported("GL_ARB_draw_buffers");
            glDrawBufferIsSupported = !gl.IsGLES;

            var framebuffer = 0u;

            uv.QueueWorkItemAndWait(() =>
            {
                using (OpenGLState.ScopedCreateFramebuffer(out framebuffer))
                {
                    if (buffers != null)
                    {
                        foreach (OpenGLRenderBuffer2D buffer in buffers)
                        {
                            AttachRenderBuffer(buffer);
                        }
                    }
                }
            });

            this.width = width;
            this.height = height;
            this.framebuffer = framebuffer;
            this.renderTargetUsage = usage;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Initializes a new instance of the OpenGLRenderTarget2D class.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="width">The render target's width in pixels.</param>
        /// <param name="height">The render target's height in pixels.</param>
        /// <param name="usage">A <see cref="RenderTargetUsage"/> value specifying whether the
        /// render target's data is discarded or preserved when it is bound to the graphics device.</param>
        /// <param name="buffers">The collection of render buffers to attach to the target.</param>
        public OpenGLRenderTarget2D(UltravioletContext uv, Int32 width, Int32 height, RenderTargetUsage usage, IEnumerable <RenderBuffer2D> buffers = null)
            : base(uv)
        {
            Contract.EnsureRange(width > 0, nameof(width));
            Contract.EnsureRange(height > 0, nameof(height));

            // NOTE: If we're in an older version of GLES, we need to use glFramebufferTexture2D()
            glFramebufferTextureIsSupported = !gl.IsGLES || gl.IsVersionAtLeast(3, 2);

            var framebuffer = 0u;

            uv.QueueWorkItemAndWait(() =>
            {
                using (OpenGLState.ScopedCreateFramebuffer(out framebuffer))
                {
                    if (buffers != null)
                    {
                        foreach (OpenGLRenderBuffer2D buffer in buffers)
                        {
                            AttachRenderBuffer(buffer);
                        }
                    }
                }
            });

            this.width             = width;
            this.height            = height;
            this.framebuffer       = framebuffer;
            this.renderTargetUsage = usage;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="OpenGLSamplerObject"/> class.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        public OpenGLSamplerObject(UltravioletContext uv)
            : base(uv)
        {
            var sampler = 0u;

            uv.QueueWorkItemAndWait(() =>
            {
                sampler = gl.GenSampler();
                gl.ThrowIfError();
            });

            this.sampler = sampler;
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="OpenGLSamplerObject"/> class.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        public OpenGLSamplerObject(UltravioletContext uv)
            : base(uv)
        {
            var sampler = 0u;

            uv.QueueWorkItemAndWait(() =>
            {
                sampler = gl.GenSampler();
                gl.ThrowIfError();
            });

            this.sampler = sampler;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Initializes a new instance of the OpenGLGeometryStream class.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        public OpenGLGeometryStream(UltravioletContext uv)
            : base(uv)
        {
            var vao = 0u;

            if (OpenGLState.SupportsVertexArrayObjects)
            {
                uv.QueueWorkItemAndWait(() =>
                {
                    vao = gl.GenVertexArray();
                    gl.ThrowIfError();
                });
            }

            this.vao = vao;
        }
        /// <summary>
        /// Initializes a new instance of the OpenGLGeometryStream class.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        public OpenGLGeometryStream(UltravioletContext uv)
            : base(uv)
        {
            var vao = 0u;

            if (OpenGLState.SupportsVertexArrayObjects)
            {
                uv.QueueWorkItemAndWait(() =>
                {
                    vao = gl.GenVertexArray();
                    gl.ThrowIfError();
                });
            }

            this.vao = vao;
        }
Ejemplo n.º 7
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();
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Initializes a new instance of the OpenGLFragmentShader class.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="source">The shader source.</param>
        public OpenGLFragmentShader(UltravioletContext uv, String[] source)
            : base(uv)
        {
            Contract.Require(source, nameof(source));

            var shader = 0u;

            uv.QueueWorkItemAndWait(() =>
            {
                shader = gl.CreateShader(gl.GL_FRAGMENT_SHADER);
                gl.ThrowIfError();

                var log = String.Empty;
                if (!ShaderCompiler.Compile(shader, source, out log))
                    throw new InvalidOperationException(log);
            });

            this.shader = shader;
        }
Ejemplo n.º 9
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();
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Initializes a new instance of the OpenGLVertexShader class.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="source">The shader source.</param>
        public OpenGLVertexShader(UltravioletContext uv, String[] source)
            : base(uv)
        {
            Contract.Require(source, nameof(source));

            var shader = 0u;

            uv.QueueWorkItemAndWait(() =>
            {
                shader = gl.CreateShader(gl.GL_VERTEX_SHADER);
                gl.ThrowIfError();

                var log = String.Empty;
                if (!ShaderCompiler.Compile(shader, source, out log))
                {
                    throw new InvalidOperationException(log);
                }
            });

            this.shader = shader;
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Initializes a new instance of the OpenGLIndexBuffer.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="itype">The index element type.</param>
        /// <param name="icount">The index element count.</param>
        /// <param name="usage">The buffer's usage type.</param>
        public OpenGLIndexBuffer(UltravioletContext uv, IndexBufferElementType itype, Int32 icount, UInt32 usage)
            : base(uv, itype, icount)
        {
            Contract.EnsureRange(icount >= 0, nameof(icount));

            this.usage = usage;
            this.size  = new IntPtr(GetElementSize() * icount);

            var buffer = 0u;

            uv.QueueWorkItemAndWait(() =>
            {
                using (OpenGLState.ScopedCreateElementArrayBuffer(out buffer))
                {
                    gl.NamedBufferData(buffer, gl.GL_ELEMENT_ARRAY_BUFFER, size, null, usage);
                    gl.ThrowIfError();
                }
            });

            this.buffer = buffer;
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Initializes a new instance of the OpenGLVertexBuffer.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="vdecl">The vertex declaration for this buffer.</param>
        /// <param name="vcount">The number of vertices in the buffer.</param>
        /// <param name="usage">The buffer's usage type.</param>
        public OpenGLVertexBuffer(UltravioletContext uv, VertexDeclaration vdecl, Int32 vcount, UInt32 usage)
            : base(uv, vdecl, vcount)
        {
            Contract.Require(vdecl, nameof(vdecl));

            this.vdecl = vdecl;
            this.usage = usage;
            this.size  = new IntPtr(vdecl.VertexStride * vcount);

            var buffer = 0u;

            uv.QueueWorkItemAndWait(() =>
            {
                using (OpenGLState.ScopedCreateArrayBuffer(out buffer))
                {
                    gl.NamedBufferData(buffer, gl.GL_ARRAY_BUFFER, size, null, usage);
                    gl.ThrowIfError();
                }
            });

            this.buffer = buffer;
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Creates the underlying native OpenGL texture with the specified format and data.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="internalformat">The texture's internal format.</param>
        /// <param name="width">The texture's width in pixels.</param>
        /// <param name="height">The texture's height in pixels.</param>
        /// <param name="format">The texel format.</param>
        /// <param name="type">The texel data type.</param>
        /// <param name="pixels">A pointer to the beginning of the texture's pixel data.</param>
        /// <param name="immutable">A value indicating whether to use immutable texture storage.</param>
        private void CreateNativeTexture(UltravioletContext uv, UInt32 internalformat, Int32 width, Int32 height, UInt32 format, UInt32 type, void *pixels, Boolean immutable)
        {
            if (uv.IsRunningInServiceMode)
            {
                throw new NotSupportedException(UltravioletStrings.NotSupportedInServiceMode);
            }

            this.width          = width;
            this.height         = height;
            this.internalformat = internalformat;
            this.format         = format;
            this.type           = type;
            this.immutable      = immutable;

            this.texture = uv.QueueWorkItemAndWait(() =>
            {
                uint glname;

                using (OpenGLState.ScopedCreateTexture2D(out glname))
                {
                    if (!gl.IsGLES2)
                    {
                        gl.TextureParameteri(glname, gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAX_LEVEL, 0);
                        gl.ThrowIfError();
                    }

                    gl.TextureParameteri(glname, gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, (int)gl.GL_LINEAR);
                    gl.ThrowIfError();

                    gl.TextureParameteri(glname, gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, (int)gl.GL_LINEAR);
                    gl.ThrowIfError();

                    gl.TextureParameteri(glname, gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, (int)gl.GL_CLAMP_TO_EDGE);
                    gl.ThrowIfError();

                    gl.TextureParameteri(glname, gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, (int)gl.GL_CLAMP_TO_EDGE);
                    gl.ThrowIfError();

                    if (immutable)
                    {
                        if (gl.IsTextureStorageAvailable)
                        {
                            gl.TextureStorage2D(glname, gl.GL_TEXTURE_2D, 1, internalformat, width, height);
                            gl.ThrowIfError();

                            if (pixels != null)
                            {
                                gl.TextureSubImage2D(glname, gl.GL_TEXTURE_2D, 0, 0, 0, width, height, format, type, pixels);
                                gl.ThrowIfError();
                            }
                        }
                        else
                        {
                            gl.TextureImage2D(glname, gl.GL_TEXTURE_2D, 0, (int)internalformat, width, height, 0, format, type, pixels);
                            gl.ThrowIfError();
                        }
                    }
                }

                if (!immutable)
                {
                    using (OpenGLState.ScopedBindTexture2D(glname, true))
                    {
                        gl.TexImage2D(gl.GL_TEXTURE_2D, 0, (int)internalformat, width, height, 0, format, type, pixels);
                        gl.ThrowIfError();
                    }
                }

                return(glname);
            });
        }
Ejemplo n.º 14
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();
        }