예제 #1
0
        protected override void DoInitialize()
        {
            // init shader program.
            ShaderProgram program = this.shaderProgramProvider.GetShaderProgram();

            VertexShaderAttribute positionBuffer = null;
            IBufferable           model          = this.DataSource;

            {
                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));
                    }

                    if (item.NameInIBufferable == this.PositionNameInIBufferable)
                    {
                        positionBuffer = new VertexShaderAttribute(buffer, item.VarNameInShader);
                        //positionBuffer.VarNameInVertexShader = "in_Position";// in_Postion same with in the PickingShader.vert shader
                        break;
                    }
                }
            }

            // 由于picking.vert/frag只支持vec3的position buffer,所以有此硬性规定。
            if (positionBuffer == null || positionBuffer.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 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.vertexShaderAttribute = new VertexShaderAttribute[] { positionBuffer };
            this.indexBuffer           = indexBuffer;
            this.vertexArrayObject     = vertexArrayObject;
        }
예제 #2
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.
            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);
            }

            return(new IPickableRenderMethod(pickProgram, pickingVAOs, positionBuffers.ToArray(), this.switches));
        }
예제 #3
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.states));
        }
        /// <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);
        }
예제 #5
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);
            }

            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);
        }