예제 #1
0
        //private readonly IBufferSource model;

        /// <summary>
        /// Scene node that supports 'Color-Coded-Picking'.
        /// </summary>
        ///<param name="model">Only <see cref="DrawArraysCmd"/> and <see cref="DrawElementsCmd"/> are supported as <see cref="IDrawCommand"/>.</param>
        /// <param name="positionNameInIBufferSource">The 'in' variable name which represents position buffer vertex shader.</param>
        ///<param name="builders"></param>
        public PickableNode(IBufferSource model, string positionNameInIBufferSource, params RenderMethodBuilder[] builders)
            : base(model, builders)
        {
            var pickProgramProvider = PickingShaderHelper.GetPickingShaderProgramProvider();

            this.pickingRenderUnitBuilder = new IPickableRenderMethodBuilder(pickProgramProvider, positionNameInIBufferSource);
        }
        /// <summary>
        /// 根据<see cref="IndexBufferPtr"/>的具体类型获取一个<see cref="PickableRenderer"/>
        /// </summary>
        /// <param name="bufferable"></param>
        /// <param name="propertyNameMap"></param>
        /// <param name="positionNameInIBufferable"></param>
        /// <param name="switches"></param>
        /// <returns></returns>
        public static InnerPickableRenderer GetRenderer(
            this IBufferable bufferable,
            PropertyNameMap propertyNameMap,
            string positionNameInIBufferable,
            params GLSwitch[] switches)
        {
            if (bufferable == null || propertyNameMap == null || string.IsNullOrEmpty(positionNameInIBufferable))
            {
                throw new ArgumentNullException();
            }

            IndexBufferPtr indexBufferPtr = bufferable.GetIndex();

            if (indexBufferPtr is ZeroIndexBufferPtr)
            {
                return(new ZeroIndexRenderer(bufferable, PickingShaderHelper.GetShaderCodes(), propertyNameMap, positionNameInIBufferable, switches));
            }
            else if (indexBufferPtr is OneIndexBufferPtr)
            {
                return(new OneIndexRenderer(bufferable, PickingShaderHelper.GetShaderCodes(), propertyNameMap, positionNameInIBufferable, switches));
            }
            else
            {
                throw new NotImplementedException();
            }
        }
예제 #3
0
        protected override void DoInitialize()
        {
            // init shader program
            this.Program = PickingShaderHelper.GetPickingShaderProgram();

            // init property buffer objects
            var propertyBufferPtrs = new PropertyBufferPtr[propertyNameMap.Count()];
            int index = 0;

            foreach (var item in propertyNameMap)
            {
                PropertyBufferPtr bufferPtr = this.bufferable.GetProperty(
                    item.NameInIBufferable, item.VarNameInShader);
                if (bufferPtr == null)
                {
                    throw new Exception();
                }
                propertyBufferPtrs[index++] = bufferPtr;
            }

            this.propertyBufferPtrs = propertyBufferPtrs;
            this.indexBufferPtr     = this.bufferable.GetIndex();

            foreach (var item in propertyNameMap)
            {
                PropertyBufferPtr bufferPtr = this.bufferable.GetProperty(
                    item.NameInIBufferable, item.VarNameInShader);
                if (bufferPtr == null)
                {
                    throw new Exception();
                }

                if (item.NameInIBufferable == positionNameInIBufferable)
                {
                    this.positionBufferPtr = new PropertyBufferPtr(
                        "in_Position",// in_Postion same with in the PickingShader.vert shader
                        bufferPtr.BufferId,
                        bufferPtr.DataSize,
                        bufferPtr.DataType,
                        bufferPtr.Length,
                        bufferPtr.ByteLength);
                    break;
                }
            }

            // 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 = this.indexBufferPtr as OneIndexBufferPtr;

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

            // 由于picking.vert/frag只支持vec3的position buffer,所以有此硬性规定。
            if (this.positionBufferPtr.DataSize != 3 || this.positionBufferPtr.DataType != OpenGL.GL_FLOAT)
            {
                throw new Exception(string.Format("Position buffer must use a type composed of 3 float as PropertyBuffer<T>'s T!"));
            }
        }
예제 #4
0
        /// <summary>
        /// 支持"拾取"的渲染器
        /// </summary>
        /// <param name="model">一种渲染方式</param>
        /// <param name="renderProgramProvider">各种类型的shader代码</param>
        /// <param name="attributeMap">关联<paramref name="model"/>和<paramref name="shaderProgramProvider"/>中的属性</param>
        /// <param name="positionNameInVertexShader">vertex shader种描述顶点位置信息的in变量的名字</param>
        ///<param name="switches"></param>
        public PickableRenderer(IBufferable model, IShaderProgramProvider renderProgramProvider,
                                AttributeMap attributeMap, string positionNameInVertexShader,
                                params GLState[] switches)
        {
            this.PositionNameInVertexShader = positionNameInVertexShader;
            this.pickProgramProvider        = PickingShaderHelper.GetPickingShaderProgramProvider();

            this.DataSource            = model;
            this.renderProgramProvider = renderProgramProvider;
            this.attributeMap          = attributeMap;
            this.stateList.AddRange(switches);
        }
예제 #5
0
        protected override void DoInitialize()
        {
            // init shader program
            this.shaderProgram = PickingShaderHelper.GetPickingShaderProgram();

            // init property buffer objects
            var propertyBufferPtrs = new PropertyBufferPtr[propertyNameMap.Count()];
            int index = 0;

            foreach (var item in propertyNameMap)
            {
                PropertyBufferPtr bufferPtr = this.bufferable.GetProperty(
                    item.nameInIBufferable, item.VarNameInShader);
                if (bufferPtr == null)
                {
                    throw new Exception();
                }
                propertyBufferPtrs[index++] = bufferPtr;
            }

            this.propertyBufferPtrs = propertyBufferPtrs;
            this.indexBufferPtr     = this.bufferable.GetIndex();

            foreach (var item in propertyNameMap)
            {
                PropertyBufferPtr bufferPtr = this.bufferable.GetProperty(
                    item.nameInIBufferable, item.VarNameInShader);
                if (bufferPtr == null)
                {
                    throw new Exception();
                }

                if (item.nameInIBufferable == positionNameInIBufferable)
                {
                    this.positionBufferPtr = new PropertyBufferPtr(
                        "in_Position",// in_Postion same with in the PickingShader.vert shader
                        bufferPtr.BufferId,
                        bufferPtr.DataSize,
                        bufferPtr.DataType,
                        bufferPtr.Length,
                        bufferPtr.ByteLength);
                    break;
                }
            }

            // 由于picking.vert/frag只支持vec3的position buffer,所以有此硬性规定。
            if (this.positionBufferPtr.DataSize != 3 || this.positionBufferPtr.DataType != OpenGL.GL_FLOAT)
            {
                throw new Exception(string.Format("Position buffer must use a type composed of 3 float as PropertyBuffer<T>'s T!"));
            }
        }
예제 #6
0
        protected override void DoInitialize()
        {
            // init shader program
            ShaderProgram program = PickingShaderHelper.GetPickingShaderProgram();
            var           shaders = (from item in shaderCodes select item.CreateShader()).ToArray();

            program.Create(shaders);
            this.shaderProgram = program;
            foreach (var item in shaders)
            {
                item.Delete();
            }

            // init property buffer objects
            var propertyBufferPtrs = new PropertyBufferPtr[propertyNameMap.Count()];
            int index = 0;

            foreach (var item in propertyNameMap)
            {
                if (index <= 0)
                {
                    if (item.nameInIBufferable == this.positionNameInIBufferable)
                    {
                        PropertyBufferPtr bufferPtr = this.bufferable.GetProperty(
                            item.nameInIBufferable, item.VarNameInShader);
                        if (bufferPtr == null)
                        {
                            throw new Exception();
                        }
                        propertyBufferPtrs[index++] = bufferPtr;
                        this.positionBufferPtr      = bufferPtr;
                    }
                }
                else
                {
                    if (item.nameInIBufferable == this.positionNameInIBufferable)
                    {
                        throw new Exception("More than 1 property named as position buffer~");
                    }
                }
            }

            this.propertyBufferPtrs = propertyBufferPtrs;
            this.indexBufferPtr     = this.bufferable.GetIndex();
        }
        private void ColorCodedPickingRender(RenderEventArgs e)
        {
            if (this.pickingShaderProgram == null)
            {
                this.pickingShaderProgram = PickingShaderHelper.GetPickingShaderProgram();
            }

            ShaderProgram program = this.pickingShaderProgram;

            // 绑定shader
            program.Bind();
            var picking = this as IColorCodedPicking;

            // TODO: use uint/int/float or ? use UniformUInt instead
            program.SetUniform("pickingBaseID", picking.PickingBaseID);
            pickingMVP.SetUniform(program);

            foreach (var item in switchList)
            {
                item.On();
            }

            if (this.vertexArrayObject4Picking == null)
            {
                var vertexArrayObject4Picking = new VertexArrayObject(
                    this.indexBufferPtr, this.positionBufferPtr);
                vertexArrayObject4Picking.Create(e, program);

                this.vertexArrayObject4Picking = vertexArrayObject4Picking;
            }
            //else
            {
                this.vertexArrayObject4Picking.Render(e, program);
            }

            foreach (var item in switchList)
            {
                item.Off();
            }

            pickingMVP.ResetUniform(program);

            // 解绑shader
            program.Unbind();
        }
        /// <summary>
        /// 根据<see cref="IndexBuffer"/>的具体类型获取一个<see cref="PickableRenderer"/>
        /// </summary>
        /// <param name="model"></param>
        /// <param name="attributeMap"></param>
        /// <param name="positionNameInIBufferable"></param>
        /// <param name="switches"></param>
        /// <returns></returns>
        public static InnerPickableRenderer GetRenderer(
            this IBufferable model,
            AttributeMap attributeMap,
            string positionNameInIBufferable,
            params GLState[] switches)
        {
            if (model == null || attributeMap == null || string.IsNullOrEmpty(positionNameInIBufferable))
            {
                throw new ArgumentNullException();
            }

            AttributeMap map = null;

            foreach (AttributeMap.NamePair item in attributeMap)
            {
                if (item.NameInIBufferable == positionNameInIBufferable)
                {
                    map = new AttributeMap();
                    map.Add(item.VarNameInShader, item.NameInIBufferable);
                    break;
                }
            }
            if (map == null)
            {
                throw new Exception(string.Format("No matching variable name in shader for [{0}]", positionNameInIBufferable));
            }

            if (model.UsesZeroIndexBuffer())
            {
                return(new ZeroIndexRenderer(model, PickingShaderHelper.GetShaderCodes(), map, positionNameInIBufferable, switches));
            }
            else
            {
                return(new OneIndexRenderer(model, PickingShaderHelper.GetShaderCodes(), map, positionNameInIBufferable, switches));
            }
        }