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