/// <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; }
/// <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); }
/// <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; }
protected override void DoRender(RenderEventArgs arg) { ShaderProgram program = this.shaderProgram; if (program == null) { return; } // 绑定shader program.Bind(); var updatedUniforms = (from item in this.uniformVariables where item.Updated select item).ToArray(); foreach (var item in updatedUniforms) { item.SetUniform(program); } int count = this.switchList.Count; for (int i = 0; i < count; i++) { this.switchList[i].On(); } IndexBufferPtr indexBufferPtr = this.indexBufferPtr; if (this.vertexArrayObject == null) { PropertyBufferPtr[] propertyBufferPtrs = this.propertyBufferPtrs; if (indexBufferPtr != null && propertyBufferPtrs != null) { var vertexArrayObject = new VertexArrayObject( indexBufferPtr, propertyBufferPtrs); vertexArrayObject.Create(arg, program); this.vertexArrayObject = vertexArrayObject; } } { VertexArrayObject vertexArrayObject = this.vertexArrayObject; if (vertexArrayObject != null) { if (vertexArrayObject.IndexBufferPtr != indexBufferPtr) { vertexArrayObject.IndexBufferPtr = indexBufferPtr; } vertexArrayObject.Render(arg, program); } } for (int i = count - 1; i >= 0; i--) { this.switchList[i].Off(); } foreach (var item in updatedUniforms) { item.ResetUniform(program); } // 解绑shader program.Unbind(); }
protected override void DoInitialize() { // init shader program. ShaderProgram program = this.shaderCodes.CreateProgram(); VertexAttributeBufferPtr positionBufferPtr = null; IBufferable model = this.Model; VertexAttributeBufferPtr[] vertexAttributeBufferPtrs; { var list = new List <VertexAttributeBufferPtr>(); foreach (var item in this.attributeMap) { VertexAttributeBufferPtr bufferPtr = model.GetVertexAttributeBufferPtr( item.NameInIBufferable, item.VarNameInShader); if (bufferPtr == null) { throw new Exception(string.Format("[{0}] returns null buffer pointer!", model)); } if (item.NameInIBufferable == this.PositionNameInIBufferable) { positionBufferPtr = new VertexAttributeBufferPtr( "in_Position",// in_Postion same with in the PickingShader.vert shader bufferPtr.BufferId, bufferPtr.Config, bufferPtr.Length, bufferPtr.ByteLength); break; } list.Add(bufferPtr); } vertexAttributeBufferPtrs = list.ToArray(); } // 由于picking.vert/frag只支持vec3的position buffer,所以有此硬性规定。 if (positionBufferPtr == null || positionBufferPtr.Config != VertexAttributeConfig.Vec3) { throw new Exception(string.Format("Position buffer must use a type composed of 3 float as PropertyBuffer<T>'s T!")); } // init index buffer. IndexBufferPtr indexBufferPtr = model.GetIndexBufferPtr(); // 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 = indexBufferPtr as OneIndexBufferPtr; if (ptr != null) { GLSwitch glSwitch = new PrimitiveRestartSwitch(ptr); this.switchList.Add(glSwitch); } // init VAO. var vertexArrayObject = new VertexArrayObject(indexBufferPtr, positionBufferPtr); vertexArrayObject.Initialize(program); // sets fields. this.Program = program; this.vertexAttributeBufferPtrs = new VertexAttributeBufferPtr[] { positionBufferPtr }; this.indexBufferPtr = indexBufferPtr; this.vertexArrayObject = vertexArrayObject; }
/// <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.switches)); }
/// <summary> /// A smallest unit that can render somthing. /// </summary> /// <param name="program"></param> /// <param name="vao"></param> /// <param name="positionBuffer"></param> /// <param name="states"></param> public IPickableRenderMethod(ShaderProgram program, VertexArrayObject vao, VertexBuffer positionBuffer, params GLState[] states) : base(program, vao, states) { this.PositionBuffer = positionBuffer; }
/// <summary> /// /// </summary> protected override void DoInitialize() { // init shader program. ShaderProgram program = this.shaderCodes.CreateProgram(); // init property buffer objects. VertexAttributeBufferPtr positionBufferPtr = null; IBufferable model = this.Model; VertexAttributeBufferPtr[] vertexAttributeBufferPtrs; { var list = new List <VertexAttributeBufferPtr>(); foreach (var item in this.attributeMap) { VertexAttributeBufferPtr bufferPtr = model.GetVertexAttributeBufferPtr( item.NameInIBufferable, item.VarNameInShader); if (bufferPtr == null) { throw new Exception(string.Format("[{0}] returns null buffer pointer!", model)); } if (item.NameInIBufferable == positionNameInIBufferable) { positionBufferPtr = new VertexAttributeBufferPtr( "in_Position",// in_Postion same with in the PickingShader.vert shader bufferPtr.BufferId, bufferPtr.Config, bufferPtr.Length, bufferPtr.ByteLength); } list.Add(bufferPtr); } vertexAttributeBufferPtrs = list.ToArray(); } // init index buffer OneIndexBufferPtr indexBufferPtr; { using (var buffer = new OneIndexBuffer(IndexElementType.UInt, DrawMode.Points, // any mode is OK as we'll update it later in other place. BufferUsage.DynamicDraw)) { buffer.Create(positionBufferPtr.ByteLength / (positionBufferPtr.DataSize * positionBufferPtr.DataTypeByteLength)); indexBufferPtr = buffer.GetBufferPtr() as OneIndexBufferPtr; } this.maxElementCount = indexBufferPtr.ElementCount; indexBufferPtr.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. GLSwitch glSwitch = new PrimitiveRestartSwitch(indexBufferPtr); this.switchList.Add(glSwitch); } // init VAO. var vertexArrayObject = new VertexArrayObject(indexBufferPtr, vertexAttributeBufferPtrs); vertexArrayObject.Initialize(program); // sets fields. this.Program = program; this.vertexAttributeBufferPtrs = vertexAttributeBufferPtrs; this.indexBufferPtr = indexBufferPtr; this.vertexArrayObject = vertexArrayObject; this.positionBufferPtr = positionBufferPtr; }