A shader program object.
Example #1
0
        /// <summary>
        /// Bind this uniform buffer object and a uniform block to the same binding point.
        /// </summary>
        /// <param name="uniformBlockIndex">index of uniform block got by (glGetUniformBlockIndex).</param>
        /// <param name="uniformBlockBindingPoint">binding point maintained by OpenGL context.</param>
        /// <param name="program">shader program.</param>
        public void Binding(ShaderProgram program, uint uniformBlockIndex, uint uniformBlockBindingPoint)
        {
            if (glBindBufferBase == null) { glBindBufferBase = OpenGL.GetDelegateFor<OpenGL.glBindBufferBase>(); }
            if (glUniformBlockBinding == null) { glUniformBlockBinding = OpenGL.GetDelegateFor<OpenGL.glUniformBlockBinding>(); }

            glBindBufferBase(OpenGL.GL_UNIFORM_BUFFER, uniformBlockBindingPoint, this.BufferId);
            glUniformBlockBinding(program.ProgramId, uniformBlockIndex, uniformBlockBindingPoint);
        }
 public override void ResetUniform(ShaderProgram program)
 {
     //base.ResetUniform(program);
     //if (glActiveTexture == null)
     //{ glActiveTexture = OpenGL.GetDelegateFor<OpenGL.glActiveTexture>(); }
     //glActiveTexture(value.ActiveTextureIndex);
     ////OpenGL.BindTexture(OpenGL.GL_TEXTURE_2D, 0);
     //OpenGL.BindTexture(value.target, 0);
 }
        /// <summary>
        /// Bind this uniform buffer object and a uniform block to the same binding point.
        /// </summary>
        /// <param name="program">shader program.</param>
        /// <param name="storageBlockName">name of buffer block in shader.</param>
        /// <param name="storageBlockBindingPoint">binding point maintained by OpenGL context.</param>
        public void Binding(ShaderProgram program, string storageBlockName, uint storageBlockBindingPoint)
        {
            if (glGetProgramResourceIndex == null) { glGetProgramResourceIndex = OpenGL.GetDelegateFor<OpenGL.glGetProgramResourceIndex>(); }
            if (glBindBufferBase == null) { glBindBufferBase = OpenGL.GetDelegateFor<OpenGL.glBindBufferBase>(); }
            if (glShaderStorageBlockBinding == null) { glShaderStorageBlockBinding = OpenGL.GetDelegateFor<OpenGL.glShaderStorageBlockBinding>(); }

            uint storageBlockIndex = glGetProgramResourceIndex(program.ProgramId, OpenGL.GL_SHADER_STORAGE_BLOCK, storageBlockName);
            glBindBufferBase(OpenGL.GL_SHADER_STORAGE_BUFFER, storageBlockBindingPoint, this.BufferId);
            glShaderStorageBlockBinding(program.ProgramId, storageBlockIndex, storageBlockBindingPoint);
        }
        public static ShaderProgram GetHighlightShaderProgram()
        {
            var shaderCodes = new ShaderCode[2];
            shaderCodes[0] = new ShaderCode(GetShaderSource(ShaderType.VertexShader), ShaderType.VertexShader);
            shaderCodes[1] = new ShaderCode(GetShaderSource(ShaderType.FragmentShader), ShaderType.FragmentShader);

            var shaderProgram = new ShaderProgram();
            shaderProgram.Create((from item in shaderCodes select item.CreateShader()).ToArray());

            return shaderProgram;
        }
 public override void SetUniform(ShaderProgram program)
 {
     if (glActiveTexture == null)
     { glActiveTexture = OpenGL.GetDelegateFor<OpenGL.glActiveTexture>(); }
     for (int i = 0; i < this.value.Length; i++)
     {
         glActiveTexture(this.value[i].ActiveTextureIndex);
         //OpenGL.BindTexture(OpenGL.GL_TEXTURE_2D, this.value[i].TextureId);
         OpenGL.BindTexture(this.value[i].target, this.value[i].TextureId);
         // TODO: assign the first location or last?
         this.Location = program.SetUniform(VarName, this.value[i].activeTextureIndex);
     }
 }
        public static ShaderProgram GetPickingShaderProgram()
        {
            var shaderCodes = new ShaderCode[2];
            shaderCodes[0] = new ShaderCode(GetShaderSource(ShaderType.VertexShader), ShaderType.VertexShader);
            shaderCodes[1] = new ShaderCode(GetShaderSource(ShaderType.FragmentShader), ShaderType.FragmentShader);

            ShaderProgram program = new ShaderProgram();
            var shaders = (from item in shaderCodes select item.CreateShader()).ToArray();
            program.Create(shaders);
            foreach (var item in shaders) { item.Delete(); }

            return program;
        }
Example #7
0
 public override void Render(RenderEventArgs arg, ShaderProgram shaderProgram)
 {
     if (arg.RenderMode == RenderModes.ColorCodedPicking
         && arg.PickingGeometryType == GeometryType.Point
         && this.Mode.ToGeometryType() == GeometryType.Line)// picking point from a line
     {
         // this maybe render points that should not appear.
         // so need to select by another picking
         OpenGL.DrawArrays(DrawMode.Points, this.FirstVertex, this.VertexCount);
     }
     else
     {
         OpenGL.DrawArrays(this.Mode, this.FirstVertex, this.VertexCount);
     }
 }
        /// <summary>
        /// 在OpenGL中创建VAO。
        /// 创建的过程就是执行一次渲染的过程。
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="shaderProgram"></param>
        public void Create(RenderEventArg arg, ShaderProgram shaderProgram)
        {
            if (this.ID != 0)
            { throw new Exception(string.Format("ID[{0}] is already generated!", this.ID)); }

            uint[] buffers = new uint[1];
            glGenVertexArrays(1, buffers);

            this.ID = buffers[0];

            this.Bind();
            BufferPtr[] propertyBufferPtrs = this.propertyBufferPtrs;
            if (propertyBufferPtrs != null)
            {
                foreach (var item in propertyBufferPtrs)
                {
                    item.Render(arg, shaderProgram);
                }
            }
            this.Unbind();
        }
Example #9
0
 /// <summary>
 /// 默认重置Updated = false;
 /// <para>以避免重复设置。</para>
 /// <para>某些类型的uniform可能需要重复调用SetUniform()(例如纹理类型的uniform sampler2D)</para>
 /// </summary>
 /// <param name="program"></param>
 public virtual void ResetUniform(ShaderProgram program)
 {
     this.Updated = false;
 }
Example #10
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="program"></param>
 public override void SetUniform(ShaderProgram program)
 {
     this.Location = program.SetUniform(VarName, value.x, value.y, value.z);
 }
Example #11
0
 public override void SetUniform(ShaderProgram program)
 {
     this.Location = program.SetUniformMatrix3(VarName, this.value);
 }
Example #12
0
 public override void SetUniform(ShaderProgram program)
 {
     program.SetUniformMatrix4(VarName, this.value.to_array());
 }
Example #13
0
        /// <summary>
        /// Creates a shader program by multiple shaders.
        /// </summary>
        /// <param name="shaderCodes"></param>
        /// <returns></returns>
        public static ShaderProgram CreateProgram(this ShaderCode[] shaderCodes)
        {
            var program = new ShaderProgram();
            Shader[] shaders = (from item in shaderCodes select item.CreateShader()).ToArray();
            program.Initialize(shaders);

            foreach (Shader item in shaders) { item.Dispose(); }

            return program;
        }
Example #14
0
        /// <summary>
        /// Creates a shader program object by a single shader.
        /// </summary>
        /// <param name="shaderCode"></param>
        /// <returns></returns>
        public static ShaderProgram CreateProgram(this ShaderCode shaderCode)
        {
            var program = new ShaderProgram();
            Shader shader = shaderCode.CreateShader();
            program.Initialize(shader);

            shader.Dispose();

            return program;
        }
Example #15
0
 /// <summary>
 /// 执行一次渲染的过程。
 /// </summary>
 /// <param name="arg"></param>
 /// <param name="shaderProgram"></param>
 /// <param name="temporaryIndexBufferPtr">render by a temporary index buffer</param>
 public void Render(RenderEventArg arg, ShaderProgram shaderProgram, IndexBufferPtr temporaryIndexBufferPtr = null)
 {
     if (temporaryIndexBufferPtr != null)
     {
         this.Bind();
         temporaryIndexBufferPtr.Render(arg, shaderProgram);
         this.Unbind();
     }
     else
     {
         IndexBufferPtr indexBufferPtr = this.IndexBufferPtr;
         if (indexBufferPtr != null)
         {
             this.Bind();
             indexBufferPtr.Render(arg, shaderProgram);
             this.Unbind();
         }
     }
 }
Example #16
0
 /// <summary>
 /// 执行一次渲染的过程。
 /// <para>Execute rendering command.</para>
 /// </summary>
 /// <param name="arg"></param>
 /// <param name="shaderProgram"></param>
 /// <param name="temporaryIndexBuffer">render by a temporary index buffer</param>
 public void Render(RenderEventArgs arg, ShaderProgram shaderProgram, IndexBuffer temporaryIndexBuffer = null)
 {
     if (temporaryIndexBuffer != null)
     {
         this.Bind();
         temporaryIndexBuffer.Render(arg);
         this.Unbind();
     }
     else
     {
         this.Bind();
         this.IndexBuffer.Render(arg);
         this.Unbind();
     }
 }
Example #17
0
        /// <summary>
        /// 在使用<see cref="VertexArrayObject"/>后,此方法只会执行一次。
        /// This method will only be invoked once when using <see cref="VertexArrayObject"/>.
        /// </summary>
        /// <param name="shaderProgram"></param>
        public void Standby(ShaderProgram shaderProgram)
        {
            int location = shaderProgram.GetAttributeLocation(this.VarNameInVertexShader);
            if (location < 0) { throw new ArgumentException(); }

            uint loc = (uint)location;
            VBOConfigDetail detail = this.Config.Parse();
            int patchVertexes = this.PatchVertexes;
            uint divisor = this.InstancedDivisor;
            // 选中此VBO
            // select this VBO.
            if (glBindBuffer == null) { glBindBuffer = OpenGL.GetDelegateFor<OpenGL.glBindBuffer>(); }
            glBindBuffer(OpenGL.GL_ARRAY_BUFFER, this.BufferId);
            for (uint i = 0; i < detail.locationCount; i++)
            {
                // 指定格式
                // set up data format.
                switch (detail.pointerType)
                {
                    case VertexAttribPointerType.Default:
                        if (glVertexAttribPointer == null) { glVertexAttribPointer = OpenGL.GetDelegateFor<OpenGL.glVertexAttribPointer>(); }
                        glVertexAttribPointer(loc + i, detail.dataSize, detail.dataType, false, detail.stride, new IntPtr(i * detail.startOffsetUnit));
                        break;

                    case VertexAttribPointerType.Integer:
                        if (glVertexAttribIPointer != null)
                        {
                            if (glVertexAttribIPointer == null) { glVertexAttribIPointer = OpenGL.GetDelegateFor<OpenGL.glVertexAttribIPointer>(); }
                            glVertexAttribIPointer(loc + i, detail.dataSize, detail.dataType, detail.stride, new IntPtr(i * detail.startOffsetUnit));
                        }
                        else
                        {
                            if (glVertexAttribPointer == null) { glVertexAttribPointer = OpenGL.GetDelegateFor<OpenGL.glVertexAttribPointer>(); }
                            glVertexAttribPointer(loc + i, detail.dataSize, detail.dataType, false, detail.stride, new IntPtr(i * detail.startOffsetUnit));
                        }
                        break;

                    case VertexAttribPointerType.Long:
                        if (glVertexAttribLPointer != null)
                        {
                            if (glVertexAttribLPointer == null) { glVertexAttribLPointer = OpenGL.GetDelegateFor<OpenGL.glVertexAttribLPointer>(); }
                            glVertexAttribLPointer(loc + i, detail.dataSize, detail.dataType, detail.stride, new IntPtr(i * detail.startOffsetUnit));
                        }
                        else
                        {
                            if (glVertexAttribPointer == null) { glVertexAttribPointer = OpenGL.GetDelegateFor<OpenGL.glVertexAttribPointer>(); }
                            glVertexAttribPointer(loc + i, detail.dataSize, detail.dataType, false, detail.stride, new IntPtr(i * detail.startOffsetUnit));
                        }
                        break;

                    default:
                        throw new NotImplementedException();
                }

                if (patchVertexes > 0)// tessellation shading.
                {
                    if (glPatchParameteri != null)
                    {
                        if (glPatchParameteri == null) { glPatchParameteri = OpenGL.GetDelegateFor<OpenGL.glPatchParameteri>(); }
                        glPatchParameteri(OpenGL.GL_PATCH_VERTICES, patchVertexes);
                    }
                }
                // 启用
                // enable this VBO.
                if (glEnableVertexAttribArray == null) { glEnableVertexAttribArray = OpenGL.GetDelegateFor<OpenGL.glEnableVertexAttribArray>(); }
                glEnableVertexAttribArray(loc + i);
                if (divisor > 0)// instanced rendering.
                {
                    if (glVertexAttribDivisor == null) { glVertexAttribDivisor = OpenGL.GetDelegateFor<OpenGL.glVertexAttribDivisor>(); }
                    glVertexAttribDivisor(loc + i, divisor);
                }
            }
            glBindBuffer(OpenGL.GL_ARRAY_BUFFER, 0);
        }
Example #18
0
 public override void SetUniform(ShaderProgram program)
 {
     this.Location = program.SetUniform(VarName, value.x, value.y);
 }
Example #19
0
 /// <summary>
 /// A smallest unit that can render somthing.
 /// </summary>
 /// <param name="program"></param>
 /// <param name="vao"></param>
 /// <param name="positionBuffers"></param>
 /// <param name="switches"></param>
 public IPickableRenderMethod(ShaderProgram program, VertexArrayObject[] vao, VertexBuffer[] positionBuffers, params GLSwitch[] switches)
     : base(program, vao, switches)
 {
     this.PositionBuffers = positionBuffers;
 }
Example #20
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="program"></param>
 public override void SetUniform(ShaderProgram program)
 {
     this.Location = program.SetUniformMatrix4(VarName, this.Value.Array);
 }
Example #21
0
        protected override void DoRender(RenderEventArgs arg)
        {
            ShaderProgram program = this.shaderProgram;

            if (program == null)
            {
                return;
            }

            // 绑定shader
            program.Bind();

            var updatedUniforms = (from item in this.uniformVariables where item.Updated select item).ToArray();

            foreach (var item in updatedUniforms)
            {
                item.SetUniform(program);
            }

            int count = this.switchList.Count;

            for (int i = 0; i < count; i++)
            {
                this.switchList[i].On();
            }

            IndexBufferPtr indexBufferPtr = this.indexBufferPtr;

            if (this.vertexArrayObject == null)
            {
                PropertyBufferPtr[] propertyBufferPtrs = this.propertyBufferPtrs;
                if (indexBufferPtr != null && propertyBufferPtrs != null)
                {
                    var vertexArrayObject = new VertexArrayObject(
                        indexBufferPtr, propertyBufferPtrs);
                    vertexArrayObject.Create(arg, program);

                    this.vertexArrayObject = vertexArrayObject;
                }
            }
            {
                VertexArrayObject vertexArrayObject = this.vertexArrayObject;
                if (vertexArrayObject != null)
                {
                    if (vertexArrayObject.IndexBufferPtr != indexBufferPtr)
                    {
                        vertexArrayObject.IndexBufferPtr = indexBufferPtr;
                    }
                    vertexArrayObject.Render(arg, program);
                }
            }

            for (int i = count - 1; i >= 0; i--)
            {
                this.switchList[i].Off();
            }

            foreach (var item in updatedUniforms)
            {
                item.ResetUniform(program);
            }

            // 解绑shader
            program.Unbind();
        }
Example #22
0
        public override void SetUniform(ShaderProgram program)
        {
            vec2 value = this.value;

            program.SetUniform(VarName, value.x, value.y);
        }
        protected override void DoInitialize()
        {
            // init shader program.
            ShaderProgram program = this.shaderCodes.CreateProgram();

            VertexAttributeBufferPtr positionBufferPtr = null;
            IBufferable model = this.Model;

            VertexAttributeBufferPtr[] vertexAttributeBufferPtrs;
            {
                var list = new List <VertexAttributeBufferPtr>();
                foreach (var item in this.attributeMap)
                {
                    VertexAttributeBufferPtr bufferPtr = model.GetVertexAttributeBufferPtr(
                        item.NameInIBufferable, item.VarNameInShader);
                    if (bufferPtr == null)
                    {
                        throw new Exception(string.Format("[{0}] returns null buffer pointer!", model));
                    }

                    if (item.NameInIBufferable == this.PositionNameInIBufferable)
                    {
                        positionBufferPtr = new VertexAttributeBufferPtr(
                            "in_Position",// in_Postion same with in the PickingShader.vert shader
                            bufferPtr.BufferId,
                            bufferPtr.Config,
                            bufferPtr.Length,
                            bufferPtr.ByteLength);
                        break;
                    }
                    list.Add(bufferPtr);
                }
                vertexAttributeBufferPtrs = list.ToArray();
            }

            // 由于picking.vert/frag只支持vec3的position buffer,所以有此硬性规定。
            if (positionBufferPtr == null || positionBufferPtr.Config != VertexAttributeConfig.Vec3)
            {
                throw new Exception(string.Format("Position buffer must use a type composed of 3 float as PropertyBuffer<T>'s T!"));
            }

            // init index buffer.
            IndexBufferPtr indexBufferPtr = model.GetIndexBufferPtr();

            // RULE: Renderer takes uint.MaxValue, ushort.MaxValue or byte.MaxValue as PrimitiveRestartIndex. So take care this rule when designing a model's index buffer.
            var ptr = indexBufferPtr as OneIndexBufferPtr;

            if (ptr != null)
            {
                GLSwitch glSwitch = new PrimitiveRestartSwitch(ptr);
                this.switchList.Add(glSwitch);
            }

            // init VAO.
            var vertexArrayObject = new VertexArrayObject(indexBufferPtr, positionBufferPtr);

            vertexArrayObject.Initialize(program);

            // sets fields.
            this.Program = program;
            this.vertexAttributeBufferPtrs = new VertexAttributeBufferPtr[] { positionBufferPtr };
            this.indexBufferPtr            = indexBufferPtr;
            this.vertexArrayObject         = vertexArrayObject;
        }
 /// <summary>
 /// A smallest unit that can render somthing.
 /// </summary>
 /// <param name="program"></param>
 /// <param name="vao"></param>
 /// <param name="positionBuffer"></param>
 /// <param name="states"></param>
 public IPickableRenderMethod(ShaderProgram program, VertexArrayObject vao, VertexBuffer positionBuffer, params GLState[] states)
     : base(program, vao, states)
 {
     this.PositionBuffer = positionBuffer;
 }
Example #25
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public RenderMethod ToRenderMethod(IBufferSource model)
        {
            // init shader program.
            ShaderProgram program = this.programProvider.GetShaderProgram();

            // init vertex attribute buffer objects.
            var attrCount  = this.map.Count(); // how many kinds of vertex attributes?
            var allBlocks  = new List <VertexBuffer> [attrCount];
            var allNames   = new string[attrCount];
            int blockCount = 0; // how many blocks an attribute is divided into?
            int index      = 0;

            foreach (AttributeMap.NamePair item in this.map)
            {
                blockCount       = 0;
                allBlocks[index] = new List <VertexBuffer>();
                foreach (var buffer in model.GetVertexAttributeBuffer(item.NameInIBufferSource))
                {
                    if (buffer == null)
                    {
                        throw new Exception(string.Format("[{0}] returns null buffer pointer!", model));
                    }
                    allBlocks[index].Add(buffer);
                    allNames[index] = item.VarNameInShader;
                    blockCount++;
                }
                if (blockCount != allBlocks[0].Count)
                {
                    throw new Exception("Not all vertex attribute buffers' block count are the same!");
                }

                index++;
            }

            // init draw commands.
            var drawCmds = (from item in model.GetDrawCommand()
                            where (item != null)
                            select item).ToArray();
            int cmdCount = drawCmds.Length;

            if (attrCount > 0 && cmdCount != blockCount)
            {
                throw new Exception("Draw Commands count != vertex buffer block count.");
            }

            // init VAOs.
            var vaos = new VertexArrayObject[cmdCount];

            for (int c = 0; c < cmdCount; c++)
            {
                var vertexShaderAttributes = new VertexShaderAttribute[attrCount];
                for (int a = 0; a < attrCount; a++)
                {
                    List <VertexBuffer> vertexAttribute = allBlocks[a];
                    string varNameInShader = allNames[a];
                    vertexShaderAttributes[a] = new VertexShaderAttribute(vertexAttribute[c], varNameInShader);
                }
                vaos[c] = new VertexArrayObject(drawCmds[c], program, vertexShaderAttributes);
            }

            return(new RenderMethod(program, vaos, this.switches));
        }
Example #26
0
 /// <summary>
 /// 执行此VBO的渲染操作。
 /// </summary>
 /// <param name="arg"></param>
 /// <param name="shaderProgram">此VBO使用的shader program。</param>
 public abstract void Render(RenderEventArgs arg, ShaderProgram shaderProgram);
Example #27
0
        /// <summary>
        /// 在OpenGL中创建VAO。
        /// 创建的过程就是执行一次渲染的过程。
        /// <para>Creates VAO and bind it to specified VBOs.</para>
        /// <para>The whole process of binding is also the process of rendering.</para>
        /// </summary>
        /// <param name="shaderProgram"></param>
        public void Initialize(ShaderProgram shaderProgram)
        {
            if (this.Id != 0)
            { throw new Exception(string.Format("Id[{0}] is already generated!", this.Id)); }

            if (glGenVertexArrays == null)
            {
                glGenVertexArrays = OpenGL.GetDelegateFor<OpenGL.glGenVertexArrays>();
                glBindVertexArray = OpenGL.GetDelegateFor<OpenGL.glBindVertexArray>();
                glDeleteVertexArrays = OpenGL.GetDelegateFor<OpenGL.glDeleteVertexArrays>();
            }

            glGenVertexArrays(1, ids);

            this.Bind();// this vertex array object will record all stand-by actions.
            VertexBuffer[] vertexAttributeBuffers = this.VertexAttributeBuffers;
            if (vertexAttributeBuffers != null)
            {
                foreach (VertexBuffer item in vertexAttributeBuffers)
                {
                    item.Standby(shaderProgram);
                }
            }
            this.Unbind();// this vertex array object has recorded all stand-by actions.
        }
Example #28
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="program"></param>
 public abstract void SetUniform(ShaderProgram program);
Example #29
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="program"></param>
 public override void SetUniform(ShaderProgram program)
 {
     this.Location = program.SetUniformMatrix2(VarName, this.value.ToArray());
 }