/// <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); }
/// <summary> /// /// </summary> protected override void DoInitialize() { foreach (var item in this.builders) { RenderUnit renderUnit = item.ToRenderUnit(this.model); this.renderUnits.Add(renderUnit); } { IPickableRenderUnit renderUnit = this.pickingRenderUnitBuilder.ToRenderUnit(this.model); if (renderUnit.VertexArrayObject.IndexBuffer is ZeroIndexBuffer) { this.picker = new ZeroIndexPicker(this); } else if (renderUnit.VertexArrayObject.IndexBuffer is OneIndexBuffer) { this.picker = new OneIndexPicker(this); } this.PickingRenderUnit = renderUnit; } }