Example #1
0
        /// <summary>
        /// 遍历以<paramref name="lastVertexId"/>为最后一个顶点的图元,
        /// 瞄准每个图元的索引(例如1个三角形有3个索引)中的最后一个索引,
        /// 将此索引在<see cref="IndexBuffer"/>中的索引(位置)收集起来。
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="lastVertexId"></param>
        /// <returns></returns>
        private List <RecognizedPrimitiveInfo> GetLastIndexIdList(RenderEventArgs arg, uint lastVertexId)
        {
            PrimitiveRecognizer recognizer = PrimitiveRecognizerFactory.Create(
                (arg.PickingGeometryType == PickingGeometryType.Point &&
                 this.indexBuffer.Mode.ToGeometryType() == PickingGeometryType.Line) ?
                DrawMode.Points : this.indexBuffer.Mode);

            PrimitiveRestartState glState = GetPrimitiveRestartState();

            var    buffer  = this.indexBuffer as OneIndexBuffer;
            IntPtr pointer = buffer.MapBuffer(MapBufferAccess.ReadOnly);
            List <RecognizedPrimitiveInfo> primitiveInfoList = null;

            if (glState == null)
            {
                primitiveInfoList = recognizer.Recognize(lastVertexId, pointer, this.indexBuffer as OneIndexBuffer);
            }
            else
            {
                primitiveInfoList = recognizer.Recognize(lastVertexId, pointer, this.indexBuffer as OneIndexBuffer, glState.RestartIndex);
            }
            buffer.UnmapBuffer();

            return(primitiveInfoList);
        }
Example #2
0
        /// <summary>
        /// 遍历以<paramref name="lastVertexId"/>为最后一个顶点的图元,
        /// 瞄准每个图元的索引(例如1个三角形有3个索引)中的最后一个索引,
        /// 将此索引在<see cref="IndexBuffer"/>中的索引(位置)收集起来。
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="lastVertexId"></param>
        /// <returns></returns>
        private List <RecognizedPrimitiveInfo> GetLastIndexIdList(PickingEventArgs arg, uint lastVertexId)
        {
            var indexBuffer = this.Renderer.PickingRenderUnit.VertexArrayObject.IndexBuffer;
            PrimitiveRecognizer recognizer = PrimitiveRecognizerFactory.Create(
                (arg.GeometryType.Contains(GeometryType.Point) &&
                 indexBuffer.Mode.ToGeometryType() == GeometryType.Line) ?
                DrawMode.Points : indexBuffer.Mode);

            PrimitiveRestartState glState = GetPrimitiveRestartState();

            var    buffer  = indexBuffer as OneIndexBuffer;
            IntPtr pointer = buffer.MapBuffer(MapBufferAccess.ReadOnly);
            List <RecognizedPrimitiveInfo> primitiveInfoList = null;

            if (glState == null)
            {
                primitiveInfoList = recognizer.Recognize(lastVertexId, pointer, indexBuffer as OneIndexBuffer);
            }
            else
            {
                primitiveInfoList = recognizer.Recognize(lastVertexId, pointer, indexBuffer as OneIndexBuffer, glState.RestartIndex);
            }
            buffer.UnmapBuffer();

            return(primitiveInfoList);
        }
Example #3
0
        /// <summary>
        /// 遍历以<paramref name="lastVertexId"/>为最后一个顶点的图元,
        /// 瞄准每个图元的索引(例如1个三角形有3个索引)中的最后一个索引,
        /// 将此索引在<see cref="IndexBuffer"/>中的索引(位置)收集起来。
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="lastVertexId"></param>
        /// <returns></returns>
        private List <RecognizedPrimitiveInfo> GetLastIndexIdList(PickingEventArgs arg, uint lastVertexId)
        {
            var drawCmd = this.DrawCommand;
            PrimitiveRecognizer recognizer = PrimitiveRecognizerFactory.Create(
                (arg.GeometryType.Contains(GeometryType.Point) &&
                 drawCmd.Mode.ToGeometryType() == GeometryType.Line) ?
                DrawMode.Points : drawCmd.Mode);

            PrimitiveRestartState glState = GetPrimitiveRestartState();

            var    buffer  = (drawCmd as IHasIndexBuffer).IndexBufferObject;
            IntPtr pointer = buffer.MapBuffer(MapBufferAccess.ReadOnly);
            List <RecognizedPrimitiveInfo> primitiveInfoList = null;

            if (glState == null)
            {
                primitiveInfoList = recognizer.Recognize(lastVertexId, pointer, drawCmd as DrawElementsCmd);
            }
            else
            {
                primitiveInfoList = recognizer.Recognize(lastVertexId, pointer, drawCmd as DrawElementsCmd, glState.RestartIndex);
            }
            buffer.UnmapBuffer();

            return(primitiveInfoList);
        }
        private PrimitiveRestartState GetPrimitiveRestartState(OneIndexBuffer indexBuffer)
        {
            PrimitiveRestartState result = null;
            switch (indexBuffer.ElementType)
            {
                case IndexBufferElementType.UByte:
                    if (this.ubyteRestartIndexState == null)
                    { this.ubyteRestartIndexState = new PrimitiveRestartState(indexBuffer.ElementType); }
                    result = this.ubyteRestartIndexState;
                    break;

                case IndexBufferElementType.UShort:
                    if (this.ushortRestartIndexState == null)
                    { this.ushortRestartIndexState = new PrimitiveRestartState(indexBuffer.ElementType); }
                    result = this.ushortRestartIndexState;
                    break;

                case IndexBufferElementType.UInt:
                    if (this.uintRestartIndexState == null)
                    { this.uintRestartIndexState = new PrimitiveRestartState(indexBuffer.ElementType); }
                    result = this.uintRestartIndexState;
                    break;

                default:
                    throw new NotImplementedException();
            }

            return result;
        }
Example #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public IPickableRenderUnit ToRenderUnit(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 IPickableRenderUnit(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);
        }
Example #6
0
        /// <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;
        }
        private void RenderForPicking(PickingEventArgs arg, ControlMode controlMode, IDrawCommand tmpCmd)
        {
            if (!this.IsInitialized)
            {
                this.Initialize();
            }

            this.polygonModeState.Mode = arg.GeometryType.GetPolygonMode();

            ShaderProgram program = this.PickingRenderUnit.Program;

            // 绑定shader
            program.Bind();
            {
                mat4 projection = arg.Scene.Camera.GetProjectionMatrix();
                mat4 view       = arg.Scene.Camera.GetViewMatrix();
                mat4 model      = this.GetModelMatrix();
                program.glUniform("MVP", projection * view * model);
            }

            this.polygonModeState.On();
            this.lineWidthState.On();
            this.pointSizeState.On();

            PrimitiveRestartState restart = null;
            var hasIndexBuffer            = tmpCmd as IHasIndexBuffer;

            if (hasIndexBuffer != null)
            {
                restart = this.GetPrimitiveRestartState(hasIndexBuffer.IndexBufferObject.ElementType);
            }
            if (restart != null)
            {
                restart.On();
            }
            {
                var  pickable = this as IPickable;
                uint baseId   = pickable.PickingBaseId;
                foreach (var vao in this.PickingRenderUnit.VertexArrayObjects)
                {
                    program.glUniform("pickingBaseId", (int)(baseId));
                    vao.Draw(controlMode, tmpCmd);
                    baseId += (uint)vao.VertexAttributes[0].Buffer.Length;
                }
            }
            if (restart != null)
            {
                restart.Off();
            }

            this.pointSizeState.Off();
            this.lineWidthState.Off();
            this.polygonModeState.Off();

            // 解绑shader
            program.Unbind();
        }
        /// <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;
        }
Example #12
0
        private void RenderForPicking(PickingEventArgs arg, IndexBuffer tempIndexBuffer)
        {
            if (!this.IsInitialized)
            {
                this.Initialize();
            }

            this.polygonModeState.Mode = arg.GeometryType.GetPolygonMode();

            ShaderProgram program = this.PickingRenderUnit.Program;

            // 绑定shader
            program.Bind();
            program.glUniform("pickingBaseId", (int)(((IPickable)this).PickingBaseId));
            {
                mat4 projection = arg.Scene.Camera.GetProjectionMatrix();
                mat4 view       = arg.Scene.Camera.GetViewMatrix();
                mat4 model      = this.GetModelMatrix();
                program.glUniform("MVP", projection * view * model);
            }

            this.polygonModeState.On();
            this.lineWidthState.On();
            this.pointSizeState.On();

            var oneIndexBuffer = tempIndexBuffer as OneIndexBuffer;

            if (oneIndexBuffer != null)
            {
                PrimitiveRestartState glState = this.GetPrimitiveRestartState(oneIndexBuffer);
                glState.On();
                this.PickingRenderUnit.VertexArrayObject.Draw(this.ControlMode, tempIndexBuffer);
                glState.Off();
            }
            else
            {
                this.PickingRenderUnit.VertexArrayObject.Draw(this.ControlMode, tempIndexBuffer);
            }

            this.pointSizeState.Off();
            this.lineWidthState.Off();
            this.polygonModeState.Off();

            // 解绑shader
            program.Unbind();
        }
        private void NoPrimitiveRestartIndex(List <RecognizedPrimitiveInfo> primitiveInfoList)
        {
            PrimitiveRestartState glState = GetPrimitiveRestartState();

            if (glState != null)
            {
                foreach (RecognizedPrimitiveInfo info in primitiveInfoList)
                {
                    foreach (uint vertexId in info.VertexIds)
                    {
                        if (vertexId == glState.RestartIndex)
                        {
                            throw new Exception();
                        }
                    }
                }
            }
        }
        /// <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>
        /// render with specified index buffer.
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="temporaryIndexBuffer"></param>
        private void Render4Picking(RenderEventArgs arg, IndexBuffer temporaryIndexBuffer)
        {
            UpdatePolygonMode(arg.PickingGeometryType);

            ShaderProgram program = this.Program;

            // 绑定shader
            program.Bind();
            program.glUniform("pickingBaseId", 0);
            UniformMat4 uniformmMVP4Picking = this.uniformmMVP4Picking;

            {
                mat4 projection = arg.Camera.GetProjectionMatrix();
                mat4 view       = arg.Camera.GetViewMatrix();
                mat4 model      = this.GetModelMatrix().Value;
                uniformmMVP4Picking.Value = projection * view * model;
            }
            uniformmMVP4Picking.SetUniform(program);

            PickingStateesOn();
            var oneIndexBuffer = temporaryIndexBuffer as OneIndexBuffer;

            if (oneIndexBuffer != null)
            {
                PrimitiveRestartState glState = this.GetPrimitiveRestartState(oneIndexBuffer);
                glState.On();
                this.vertexArrayObject.Render(arg, program, temporaryIndexBuffer);
                glState.Off();
            }
            else
            {
                this.vertexArrayObject.Render(arg, program, temporaryIndexBuffer);
            }
            PickingStateesOff();

            //if (mvpUpdated) { uniformmMVP4Picking.ResetUniform(program); }

            // 解绑shader
            program.Unbind();
        }
Example #16
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public RenderUnit ToRenderUnit(IBufferSource model)
        {
            // init shader program.
            ShaderProgram program = this.programProvider.GetShaderProgram();

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

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

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

            var result = new RenderUnit(program, vertexArrayObject, 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.
            var ptr = indexBuffer as OneIndexBuffer;

            if (ptr != null)
            {
                GLState glState = new PrimitiveRestartState(ptr.ElementType);
                result.StateList.Add(glState);
            }

            return(result);
        }
Example #17
0
        private PrimitiveRestartState GetPrimitiveRestartState(OneIndexBuffer indexBuffer)
        {
            PrimitiveRestartState result = null;

            switch (indexBuffer.ElementType)
            {
            case IndexBufferElementType.UByte:
                if (this.ubyteRestartIndexState == null)
                {
                    this.ubyteRestartIndexState = new PrimitiveRestartState(indexBuffer.ElementType);
                }
                result = this.ubyteRestartIndexState;
                break;

            case IndexBufferElementType.UShort:
                if (this.ushortRestartIndexState == null)
                {
                    this.ushortRestartIndexState = new PrimitiveRestartState(indexBuffer.ElementType);
                }
                result = this.ushortRestartIndexState;
                break;

            case IndexBufferElementType.UInt:
                if (this.uintRestartIndexState == null)
                {
                    this.uintRestartIndexState = new PrimitiveRestartState(indexBuffer.ElementType);
                }
                result = this.uintRestartIndexState;
                break;

            default:
                throw new NotDealWithNewEnumItemException(typeof(IndexBufferElementType));
            }

            return(result);
        }
Example #18
0
        /// <summary>
        /// 遍历以<paramref name="lastVertexId"/>为最后一个顶点的图元,
        /// 瞄准每个图元的索引(例如1个三角形有3个索引)中的最后一个索引,
        /// 将此索引在<see cref="IndexBuffer"/>中的索引(位置)收集起来。
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="lastVertexId"></param>
        /// <returns></returns>
        private List <RecognizedPrimitiveInfo> GetLastIndexIdList(PickingEventArgs arg, uint lastVertexId)
        {
            var                 drawCmd    = this.DrawCommand;
            DrawMode            mode       = drawCmd.Mode;
            PrimitiveRecognizer recognizer = PrimitiveRecognizerFactory.Create(
                (arg.GeometryType.Contains(GeometryType.Point) &&
                 mode.ToGeometryType() == GeometryType.Line) ?
                DrawMode.Points : mode);

            PrimitiveRestartState glState = GetPrimitiveRestartState();

            List <RecognizedPrimitiveInfo> primitiveInfoList = null;

            if (glState == null)
            {
                primitiveInfoList = recognizer.Recognize(lastVertexId, drawCmd);
            }
            else
            {
                primitiveInfoList = recognizer.Recognize(lastVertexId, drawCmd, glState.RestartIndex);
            }

            return(primitiveInfoList);
        }
Example #19
0
        private PrimitiveRestartState GetPrimitiveRestartState(OneIndexBuffer indexBuffer)
        {
            PrimitiveRestartState result = null;

            switch (indexBuffer.ElementType)
            {
            case IndexBufferElementType.UByte:
                if (this.ubyteRestartIndexState == null)
                {
                    this.ubyteRestartIndexState = new PrimitiveRestartState(indexBuffer.ElementType);
                }
                result = this.ubyteRestartIndexState;
                break;

            case IndexBufferElementType.UShort:
                if (this.ushortRestartIndexState == null)
                {
                    this.ushortRestartIndexState = new PrimitiveRestartState(indexBuffer.ElementType);
                }
                result = this.ushortRestartIndexState;
                break;

            case IndexBufferElementType.UInt:
                if (this.uintRestartIndexState == null)
                {
                    this.uintRestartIndexState = new PrimitiveRestartState(indexBuffer.ElementType);
                }
                result = this.uintRestartIndexState;
                break;

            default:
                throw new Exception("Unexpected IndexBufferElementType!");
            }

            return(result);
        }
Example #20
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;
        }
        /// <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);
        }
        /// <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);
        }