/// <summary>
        ///
        /// </summary>
        protected override void DoInitialize()
        {
            // init shader program.
            ShaderProgram program = this.shaderCodes.CreateProgram();

            // init property buffer objects.
            VertexBuffer positionBuffer = null;
            IBufferable model = this.DataSource;
            VertexBuffer[] vertexAttributeBuffers;
            {
                var list = new List<VertexBuffer>();
                foreach (AttributeMap.NamePair item in this.attributeMap)
                {
                    VertexBuffer buffer = model.GetVertexAttributeBuffer(
                               item.NameInIBufferable, item.VarNameInShader);
                    if (buffer == null) { throw new Exception(string.Format("[{0}] returns null buffer pointer!", model)); }
                    if (item.NameInIBufferable == positionNameInIBufferable)
                    {
                        if (positionBuffer != null)
                        { throw new Exception(string.Format("Duplicate position buffer is not allowed!")); }

                        positionBuffer = buffer.Clone() as VertexBuffer;
                        positionBuffer.VarNameInVertexShader = "in_Position";// in_Postion same with in the PickingShader.vert shader
                    }
                    list.Add(buffer);
                }
                vertexAttributeBuffers = list.ToArray();
            }

            // init index buffer
            OneIndexBuffer indexBuffer;
            {
                var mode = DrawMode.Points;//any mode is OK as we'll update it later in other place.
                indexBuffer = Buffer.Create(IndexBufferElementType.UInt, positionBuffer.ByteLength / (positionBuffer.Config.GetDataSize() * positionBuffer.Config.GetDataTypeByteLength()), mode, BufferUsage.StaticDraw);
                this.maxElementCount = indexBuffer.ElementCount;
                indexBuffer.ElementCount = 0;// 高亮0个图元
                // RULE: Renderer takes uint.MaxValue, ushort.MaxValue or byte.MaxValue as PrimitiveRestartIndex. So take care this rule when designing a model's index buffer.
                GLState glState = new PrimitiveRestartState(indexBuffer.ElementType);
                this.stateList.Add(glState);
            }

            // init VAO.
            var vertexArrayObject = new VertexArrayObject(indexBuffer, vertexAttributeBuffers);
            vertexArrayObject.Initialize(program);

            // sets fields.
            this.Program = program;
            this.vertexAttributeBuffers = vertexAttributeBuffers;
            this.indexBuffer = indexBuffer;
            this.vertexArrayObject = vertexArrayObject;

            this.positionBuffer = positionBuffer;
        }
        protected override void DoInitialize()
        {
            // init shader program.
            ShaderProgram program = this.shaderCodes.CreateProgram();

            VertexBuffer positionBuffer = null;
            IBufferable model = this.DataSource;
            VertexBuffer[] vertexAttributeBuffers;
            {
                var list = new List<VertexBuffer>();
                foreach (AttributeMap.NamePair item in this.attributeMap)
                {
                    VertexBuffer buffer = model.GetVertexAttributeBuffer(
                     item.NameInIBufferable, item.VarNameInShader);
                    if (buffer == null) { throw new Exception(string.Format("[{0}] returns null buffer pointer!", model)); }

                    if (item.NameInIBufferable == this.PositionNameInIBufferable)
                    {
                        positionBuffer = buffer.Clone() as VertexBuffer;
                        positionBuffer.VarNameInVertexShader = "in_Position";// in_Postion same with in the PickingShader.vert shader
                        break;
                    }
                    list.Add(buffer);
                }
                vertexAttributeBuffers = list.ToArray();
            }

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

            // init index buffer.
            IndexBuffer indexBuffer = model.GetIndexBuffer();

            // 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 = indexBuffer as OneIndexBuffer;
            if (ptr != null)
            {
                GLState glState = new PrimitiveRestartState(ptr.ElementType);
                this.stateList.Add(glState);
            }

            // init VAO.
            var vertexArrayObject = new VertexArrayObject(indexBuffer, positionBuffer);
            vertexArrayObject.Initialize(program);

            // sets fields.
            this.Program = program;
            this.vertexAttributeBuffers = new VertexBuffer[] { positionBuffer };
            this.indexBuffer = indexBuffer;
            this.vertexArrayObject = vertexArrayObject;
        }
        /// <summary>
        ///
        /// </summary>
        protected override void DoInitialize()
        {
            // init shader program.
            ShaderProgram program = this.shaderCodes.CreateProgram();

            // init vertex attribute buffer objects.
            IBufferable model = this.DataSource;
            VertexBuffer[] vertexAttributeBuffers;
            {
                var list = new List<VertexBuffer>();
                foreach (AttributeMap.NamePair item in this.attributeMap)
                {
                    VertexBuffer buffer = model.GetVertexAttributeBuffer(
                        item.NameInIBufferable, item.VarNameInShader);
                    if (buffer == null) { throw new Exception(string.Format("[{0}] returns null buffer pointer!", model)); }
                    list.Add(buffer);
                }
                vertexAttributeBuffers = list.ToArray();
            }

            // init index buffer.
            IndexBuffer indexBuffer = model.GetIndexBuffer();

            // 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 = indexBuffer as OneIndexBuffer;
            if (ptr != null)
            {
                GLState glState = new PrimitiveRestartState(ptr.ElementType);
                this.stateList.Add(glState);
            }

            // init VAO.
            var vertexArrayObject = new VertexArrayObject(indexBuffer, vertexAttributeBuffers);
            vertexArrayObject.Initialize(program);

            // sets fields.
            this.Program = program;
            this.vertexAttributeBuffers = vertexAttributeBuffers;
            this.indexBuffer = indexBuffer;
            this.vertexArrayObject = vertexArrayObject;
        }
        /// <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);
            }

            var renderUnit = new RenderMethod(program, vaos, this.states);

            // RULE: Renderer takes uint.MaxValue, ushort.MaxValue or byte.MaxValue as PrimitiveRestartIndex. So take care of this rule when designing a model's index buffer.
            foreach (var cmd in drawCmds)
            {
                var ptr = cmd as IHasIndexBuffer;
                if (ptr != null)
                {
                    GLState glState = new PrimitiveRestartState(ptr.IndexBufferObject.ElementType);
                    renderUnit.StateList.Add(glState);
                    break;
                }
            }

            return(renderUnit);
        }
Beispiel #5
0
        /// <summary>
        ///
        /// </summary>
        protected override void DoInitialize()
        {
            // init shader program.
            ShaderProgram program     = this.renderProgramProvider.GetShaderProgram();
            ShaderProgram pickProgram = this.pickProgramProvider.GetShaderProgram();

            // init vertex attribute buffer objects.
            IBufferable  model          = this.DataSource;
            VertexBuffer positionBuffer = null;

            VertexShaderAttribute[] vertexAttributeBuffers;
            {
                var list = new List <VertexShaderAttribute>();
                foreach (AttributeMap.NamePair item in this.attributeMap)
                {
                    VertexBuffer buffer = model.GetVertexAttributeBuffer(
                        item.NameInIBufferable, item.VarNameInShader);
                    if (buffer == null)
                    {
                        throw new Exception(string.Format("[{0}] returns null buffer pointer!", model));
                    }
                    list.Add(new VertexShaderAttribute(buffer, item.VarNameInShader));

                    if (item.VarNameInShader == this.PositionNameInVertexShader)
                    {
                        positionBuffer = buffer;
                    }
                }
                vertexAttributeBuffers = list.ToArray();
            }

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


            // init index buffer.
            IndexBuffer indexBuffer = model.GetIndexBuffer();

            // 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 = indexBuffer as OneIndexBuffer;

            if (ptr != null)
            {
                GLState glState = new PrimitiveRestartState(ptr.ElementType);
                this.stateList.Add(glState);

                this.picker = new OneIndexPicker(this);
            }
            else
            {
                this.picker = new ZeroIndexPicker(this);
            }

            // init VAO.
            var vertexArrayObject = new VertexArrayObject(indexBuffer, vertexAttributeBuffers);

            vertexArrayObject.Initialize(program);
            var pickingVAO = new VertexArrayObject(indexBuffer, new VertexShaderAttribute(positionBuffer, "in_Position"));

            pickingVAO.Initialize(pickProgram);

            // sets fields.
            this.RenderProgram          = program;
            this.PickProgram            = pickProgram;
            this.vertexShaderAttributes = vertexAttributeBuffers;
            this.positionBuffer         = positionBuffer;
            this.indexBuffer            = indexBuffer;
            this.vertexArrayObject      = vertexArrayObject;
            this.pickVertexArrayObject  = pickingVAO;
        }
Beispiel #6
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();
        }
        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;
        }
Beispiel #8
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));
        }
 /// <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;
 }
        /// <summary>
        ///
        /// </summary>
        protected override void DoInitialize()
        {
            // init shader program.
            ShaderProgram program = this.shaderCodes.CreateProgram();

            // init property buffer objects.
            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 == positionNameInIBufferable)
                    {
                        positionBufferPtr = new VertexAttributeBufferPtr(
                            "in_Position",// in_Postion same with in the PickingShader.vert shader
                            bufferPtr.BufferId,
                            bufferPtr.Config,
                            bufferPtr.Length,
                            bufferPtr.ByteLength);
                    }
                    list.Add(bufferPtr);
                }
                vertexAttributeBufferPtrs = list.ToArray();
            }

            // init index buffer
            OneIndexBufferPtr indexBufferPtr;
            {
                using (var buffer = new OneIndexBuffer(IndexElementType.UInt,
                                                       DrawMode.Points, // any mode is OK as we'll update it later in other place.
                                                       BufferUsage.DynamicDraw))
                {
                    buffer.Create(positionBufferPtr.ByteLength / (positionBufferPtr.DataSize * positionBufferPtr.DataTypeByteLength));
                    indexBufferPtr = buffer.GetBufferPtr() as OneIndexBufferPtr;
                }
                this.maxElementCount        = indexBufferPtr.ElementCount;
                indexBufferPtr.ElementCount = 0;// 高亮0个图元
                // RULE: Renderer takes uint.MaxValue, ushort.MaxValue or byte.MaxValue as PrimitiveRestartIndex. So take care this rule when designing a model's index buffer.
                GLSwitch glSwitch = new PrimitiveRestartSwitch(indexBufferPtr);
                this.switchList.Add(glSwitch);
            }

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

            vertexArrayObject.Initialize(program);

            // sets fields.
            this.Program = program;
            this.vertexAttributeBufferPtrs = vertexAttributeBufferPtrs;
            this.indexBufferPtr            = indexBufferPtr;
            this.vertexArrayObject         = vertexArrayObject;

            this.positionBufferPtr = positionBufferPtr;
        }