示例#1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public IPickableRenderMethod ToRenderMethod(IBufferSource model)
        {
            // init shader program.
            ShaderProgram pickProgram = this.programProvider.GetShaderProgram();

            // init vertex attribute buffer objects.
            VertexBuffer positionBuffer = model.GetVertexAttributeBuffer(this.positionNameInIBufferSource);

            // RULE: 由于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();

            // init VAO.
            var pickingVAO = new VertexArrayObject(indexBuffer, pickProgram, new VertexShaderAttribute(positionBuffer, PickingShaderHelper.in_Position));

            var renderUnit = new IPickableRenderMethod(pickProgram, pickingVAO, positionBuffer, this.states);

            // 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);
                renderUnit.StateList.Add(glState);
            }

            return(renderUnit);
        }
示例#2
0
        /// <summary>
        ///
        /// </summary>
        protected override void DoInitialize()
        {
            base.DoInitialize();

            IPickableRenderMethod renderUnit = this.pickingRenderUnitBuilder.ToRenderMethod(this.RenderUnit.Model);
            var pickerList = new List <PickerBase>();

            foreach (var vao in renderUnit.VertexArrayObjects)
            {
                IDrawCommand cmd = vao.DrawCommand;
                if (cmd is DrawArraysCmd)
                //|| cmd is MultiDrawArraysCmd)
                {
                    //I don't know what will happen during picking if 'overlap' exists in glMultiDrawArrays(..). I don't care either, because that is a problem that should be solved in modeling stage.
                    VertexBuffer positionBuffer = vao.VertexAttributes[0].Buffer; // according to base.DoInitialize(), this is the position buffer of the only vertex attribute.
                    pickerList.Add(new DrawArraysPicker(this, positionBuffer, cmd as DrawArraysCmd));
                }
                else if (cmd is DrawElementsCmd)
                //|| cmd is MultiDrawElementsCmd)
                {
                    //I don't know what will happen during picking if 'overlap' exists in glMultiDrawElements(..). I don't care either, because that is a problem that should be solved in modeling stage.
                    VertexBuffer positionBuffer = vao.VertexAttributes[0].Buffer; // according to base.DoInitialize(), this is the position buffer of the only vertex attribute.
                    pickerList.Add(new DrawElementsPicker(this, positionBuffer, cmd as DrawElementsCmd));
                }
                else
                {
                    throw new NotImplementedException(string.Format("`{0}` is a IDrawCommand type that has not been supported for `IPickable`.", cmd.GetType()));
                }
            }
            this.picker = pickerList.ToArray();

            this.PickingRenderUnit = renderUnit;
        }
        /// <summary>
        /// This method should only be invoked once.
        /// </summary>
        private void DoInitialize()
        {
            IBufferSource model = this.Model;

            for (int i = 0; i < this.builders.Length; i++)
            {
                IPickableRenderMethod method = this.builders[i].ToRenderMethod(model);
                this.Methods[i] = method;
            }
        }
示例#4
0
        /// <summary>
        ///
        /// </summary>
        protected override void DoInitialize()
        {
            base.DoInitialize();

            {
                IPickableRenderMethod renderUnit = this.pickingRenderUnitBuilder.ToRenderMethod(this.RenderUnit.Model);
                if (renderUnit.VertexArrayObject.IndexBuffer is ZeroIndexBuffer)
                {
                    this.picker = new ZeroIndexPicker(this);
                }
                else if (renderUnit.VertexArrayObject.IndexBuffer is OneIndexBuffer)
                {
                    this.picker = new OneIndexPicker(this);
                }

                this.PickingRenderUnit = renderUnit;
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public IPickableRenderMethod ToRenderMethod(IBufferSource model)
        {
            // init shader program.
            ShaderProgram pickProgram = this.programProvider.GetShaderProgram();

            // init vertex attribute buffer objects.
            var positionBuffers = new List <VertexBuffer>(); // position attribute is divided into blocks.

            // we only care about the position attribute.
            foreach (var buffer in model.GetVertexAttributeBuffer(this.positionNameInIBufferSource))
            {
                if (buffer == null)
                {
                    throw new Exception(string.Format("[{0}] returns null buffer pointer!", model));
                }
                positionBuffers.Add(buffer);
            }
            int blockCount = positionBuffers.Count;


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

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

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

            // init VAO.
            var pickingVAOs = new VertexArrayObject[cmdCount];

            for (int b = 0; b < cmdCount; b++)
            {
                var vertexAttributeBuffers = new VertexShaderAttribute(positionBuffers[b], PickingShaderHelper.in_Position);
                pickingVAOs[b] = new VertexArrayObject(allDrawCommands[b], pickProgram, vertexAttributeBuffers);
            }

            var renderUnit = new IPickableRenderMethod(pickProgram, pickingVAOs, positionBuffers.ToArray(), this.states);

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

            return(renderUnit);
        }